diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index 03156999..31bf2eba 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -1,20 +1,20 @@ -import Application from "./Application" -import Diff from "./Diff" -import StatusMessage from "./StatusMessage" -import PushManager from "./PushManager" -import TouchController from "./TouchController" -import NotificationManager from "./NotificationManager" -import AudioPlayer from "./AudioPlayer" -import VideoPlayer from "./VideoPlayer" -import Analytics from "./Analytics" -import SideBar from "./SideBar" -import InfiniteScroller from "./InfiniteScroller" -import ServiceWorkerManager from "./ServiceWorkerManager" -import ServerEvents from "./ServerEvents" -import { displayAiringDate, displayDate, displayTime } from "./DateView" -import { findAll, supportsWebP, requestIdleCallback, swapElements, delay, findAllInside } from "./Utils" -import ToolTip from "./Elements/tool-tip/tool-tip" import * as actions from "./Actions" +import Analytics from "./Analytics" +import Application from "./Application" +import AudioPlayer from "./AudioPlayer" +import { displayAiringDate, displayDate, displayTime } from "./DateView" +import Diff from "./Diff" +import ToolTip from "./Elements/tool-tip/tool-tip" +import InfiniteScroller from "./InfiniteScroller" +import NotificationManager from "./NotificationManager" +import PushManager from "./PushManager" +import ServerEvents from "./ServerEvents" +import ServiceWorkerManager from "./ServiceWorkerManager" +import SideBar from "./SideBar" +import StatusMessage from "./StatusMessage" +import TouchController from "./TouchController" +import { delay, findAll, findAllInside, requestIdleCallback, supportsWebP, swapElements } from "./Utils" +import VideoPlayer from "./VideoPlayer" import * as WebComponents from "./WebComponents" export default class AnimeNotifier { @@ -1459,4 +1459,4 @@ export default class AnimeNotifier { console.warn("Failed reporting the error to the website staff:", err) } } -} \ No newline at end of file +} diff --git a/scripts/Application.ts b/scripts/Application.ts index fa67fb9d..2b5afecf 100644 --- a/scripts/Application.ts +++ b/scripts/Application.ts @@ -1,21 +1,18 @@ import Diff from "./Diff" +import LoadOptions from "./LoadOptions" import { delay } from "./Utils" -class LoadOptions { - addToHistory?: boolean - forceReload?: boolean -} - export default class Application { - fadeOutClass: string - activeLinkClass: string - content: HTMLElement - loading: HTMLElement - currentPath: string - originalPath: string - lastRequestController: AbortController | null - contentInvisible: boolean - onError: (err: Error) => void + public originalPath: string + public currentPath: string + public content: HTMLElement + public loading: HTMLElement + public fadeOutClass: string + public onError: (err: Error) => void + + private activeLinkClass: string + private lastRequestController: AbortController | null + private contentInvisible: boolean constructor() { this.currentPath = window.location.pathname @@ -25,18 +22,11 @@ export default class Application { this.onError = console.error } - init() { + public init() { document.addEventListener("DOMContentLoaded", this.onContentLoaded.bind(this)) } - onContentLoaded() { - let links = document.getElementsByTagName("a") - - this.markActiveLinks(links) - this.ajaxify(links) - } - - async get(url: string): Promise { + public async get(url: string): Promise { if(this.lastRequestController) { this.lastRequestController.abort() } @@ -59,7 +49,7 @@ export default class Application { } } - load(url: string, options?: LoadOptions) { + public load(url: string, options?: LoadOptions) { // Remove protocol and hostname if it was specified if(url.startsWith(location.origin)) { url = url.substr(location.origin.length) @@ -68,7 +58,7 @@ export default class Application { // Start sending a network request let request: Promise - let retry = () => { + const retry = () => { return this.get("/_" + url).catch(async error => { // Are we still on that page? if(this.currentPath !== url) { @@ -112,8 +102,8 @@ export default class Application { // Mark active links this.markActiveLinks() - let consume = async () => { - let html = await request + const consume = async () => { + const html = await request if(this.currentPath !== url) { return @@ -124,7 +114,7 @@ export default class Application { this.scrollToTop() // Fade in listener - let onFadedIn: EventListener = (e: Event) => { + const onFadedIn: EventListener = (e: Event) => { // Ignore transitions of child elements. // We only care about the transition event on the content element. if(e.target !== this.content) { @@ -152,7 +142,7 @@ export default class Application { consume() } else { // Fade out listener - let onFadedOut: EventListener = (e: Event) => { + const onFadedOut: EventListener = (e: Event) => { // Ignore transitions of child elements. // We only care about the transition event on the content element. if(e.target !== this.content) { @@ -183,36 +173,12 @@ export default class Application { return request } - setContent(html: string) { - this.content.innerHTML = html - } - - markActiveLinks(links?: HTMLCollectionOf) { + public ajaxify(links?: HTMLCollectionOf) { if(!links) { links = document.getElementsByTagName("a") } - for(let i = 0; i < links.length; i++) { - let link = links[i] - - Diff.mutations.queue(() => { - if(link.getAttribute("href") === this.currentPath) { - link.classList.add(this.activeLinkClass) - } else { - link.classList.remove(this.activeLinkClass) - } - }) - } - } - - ajaxify(links?: HTMLCollectionOf) { - if(!links) { - links = document.getElementsByTagName("a") - } - - for(let i = 0; i < links.length; i++) { - let link = links[i] as HTMLAnchorElement - + for(const link of links) { // Don't ajaxify links to a different host if(link.hostname !== window.location.hostname) { if(!link.target) { @@ -227,7 +193,7 @@ export default class Application { continue } - let self = this + const self = this link.onclick = function(e) { // Middle mouse button and Ctrl clicks should have standard behaviour @@ -238,7 +204,7 @@ export default class Application { e.preventDefault() // Prevent loading the same page - let url = (this as HTMLAnchorElement).getAttribute("href") + const url = (this as HTMLAnchorElement).getAttribute("href") if(!url || url === self.currentPath) { return @@ -251,17 +217,45 @@ export default class Application { } } - scrollToTop() { - let parent: any = this.content + public markActiveLinks(links?: HTMLCollectionOf) { + if(!links) { + links = document.getElementsByTagName("a") + } + + for(const link of links) { + Diff.mutations.queue(() => { + if(link.getAttribute("href") === this.currentPath) { + link.classList.add(this.activeLinkClass) + } else { + link.classList.remove(this.activeLinkClass) + } + }) + } + } + + public emit(eventName: string) { + document.dispatchEvent(new Event(eventName)) + } + + private onContentLoaded() { + const links = document.getElementsByTagName("a") + + this.markActiveLinks(links) + this.ajaxify(links) + } + + private setContent(html: string) { + this.content.innerHTML = html + } + + private scrollToTop() { + let parent: HTMLElement | null = this.content Diff.mutations.queue(() => { - while(parent = parent.parentElement) { + while(parent) { parent.scrollTop = 0 + parent = parent.parentElement } }) } - - emit(eventName: string) { - document.dispatchEvent(new Event(eventName)) - } -} \ No newline at end of file +} diff --git a/scripts/LoadOptions.ts b/scripts/LoadOptions.ts new file mode 100644 index 00000000..67d12307 --- /dev/null +++ b/scripts/LoadOptions.ts @@ -0,0 +1,4 @@ +export default class LoadOptions { + public addToHistory?: boolean + public forceReload?: boolean +} diff --git a/scripts/StatusMessage.ts b/scripts/StatusMessage.ts index ebe99cb5..cd7d2f3c 100644 --- a/scripts/StatusMessage.ts +++ b/scripts/StatusMessage.ts @@ -1,16 +1,32 @@ import { delay } from "./Utils" export default class StatusMessage { - container: HTMLElement - text: HTMLElement + private container: HTMLElement + private text: HTMLElement constructor(container: HTMLElement, text: HTMLElement) { this.container = container this.text = text } - show(message: string, duration: number) { - let messageId = String(Date.now()) + public showError(message: string | Error, duration?: number) { + this.clearStyle() + this.show(message.toString(), duration || 4000) + this.container.classList.add("error-message") + } + + public showInfo(message: string, duration?: number) { + this.clearStyle() + this.show(message, duration || 2000) + this.container.classList.add("info-message") + } + + public close() { + this.container.classList.add("fade-out") + } + + private show(message: string, duration: number) { + const messageId = String(Date.now()) this.text.textContent = message @@ -31,24 +47,8 @@ export default class StatusMessage { }) } - clearStyle() { + private clearStyle() { this.container.classList.remove("info-message") this.container.classList.remove("error-message") } - - showError(message: string | Error, duration?: number) { - this.clearStyle() - this.show(message.toString(), duration || 4000) - this.container.classList.add("error-message") - } - - showInfo(message: string, duration?: number) { - this.clearStyle() - this.show(message, duration || 2000) - this.container.classList.add("info-message") - } - - close() { - this.container.classList.add("fade-out") - } -} \ No newline at end of file +} diff --git a/scripts/TouchController.ts b/scripts/TouchController.ts index 29d7bc89..9990004c 100644 --- a/scripts/TouchController.ts +++ b/scripts/TouchController.ts @@ -1,13 +1,12 @@ export default class TouchController { - x: number - y: number + public leftSwipe: Function + public rightSwipe: Function + public upSwipe: Function + public downSwipe: Function - threshold: number - - leftSwipe: Function - rightSwipe: Function - upSwipe: Function - downSwipe: Function + private x: number + private y: number + private threshold: number constructor() { document.addEventListener("touchstart", evt => this.handleTouchStart(evt), false) @@ -19,21 +18,21 @@ export default class TouchController { this.y = -1 } - handleTouchStart(evt) { + private handleTouchStart(evt) { this.x = evt.touches[0].clientX this.y = evt.touches[0].clientY } - handleTouchMove(evt) { + private handleTouchMove(evt) { if(this.x === -1 || this.y === -1) { return } - let xUp = evt.touches[0].clientX - let yUp = evt.touches[0].clientY + const xUp = evt.touches[0].clientX + const yUp = evt.touches[0].clientY - let xDiff = this.x - xUp - let yDiff = this.y - yUp + const xDiff = this.x - xUp + const yDiff = this.y - yUp if(Math.abs(xDiff) > Math.abs(yDiff)) { if(xDiff > this.threshold) { @@ -52,4 +51,4 @@ export default class TouchController { this.x = -1 this.y = -1 } -} \ No newline at end of file +} diff --git a/scripts/main.ts b/scripts/main.ts index eac027e8..8528a97c 100644 --- a/scripts/main.ts +++ b/scripts/main.ts @@ -1,10 +1,7 @@ -import Application from "./Application" import AnimeNotifier from "./AnimeNotifier" +import Application from "./Application" -let app = new Application() -let arn = new AnimeNotifier(app) +const app = new Application() +const arn = new AnimeNotifier(app) arn.init() - -// For debugging purposes -window["arn"] = arn \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000..5da094d7 --- /dev/null +++ b/tslint.json @@ -0,0 +1,15 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended" + ], + "jsRules": {}, + "rules": { + "semicolon": false, + "indent": [true, "tabs", 4], + "whitespace": false, + "arrow-parens": false, + "trailing-comma": false + }, + "rulesDirectory": [] +}