Started using TSLint
This commit is contained in:
parent
5394928ea9
commit
62d63740bb
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<string> {
|
||||
public async get(url: string): Promise<string> {
|
||||
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<string>
|
||||
|
||||
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<HTMLAnchorElement>) {
|
||||
public ajaxify(links?: HTMLCollectionOf<HTMLAnchorElement>) {
|
||||
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<HTMLAnchorElement>) {
|
||||
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<HTMLAnchorElement>) {
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
scripts/LoadOptions.ts
Normal file
4
scripts/LoadOptions.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export default class LoadOptions {
|
||||
public addToHistory?: boolean
|
||||
public forceReload?: boolean
|
||||
}
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
15
tslint.json
Normal file
15
tslint.json
Normal file
@ -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": []
|
||||
}
|
Loading…
Reference in New Issue
Block a user