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 * 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"
|
import * as WebComponents from "./WebComponents"
|
||||||
|
|
||||||
export default class AnimeNotifier {
|
export default class AnimeNotifier {
|
||||||
@ -1459,4 +1459,4 @@ export default class AnimeNotifier {
|
|||||||
console.warn("Failed reporting the error to the website staff:", err)
|
console.warn("Failed reporting the error to the website staff:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
import Diff from "./Diff"
|
import Diff from "./Diff"
|
||||||
|
import LoadOptions from "./LoadOptions"
|
||||||
import { delay } from "./Utils"
|
import { delay } from "./Utils"
|
||||||
|
|
||||||
class LoadOptions {
|
|
||||||
addToHistory?: boolean
|
|
||||||
forceReload?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class Application {
|
export default class Application {
|
||||||
fadeOutClass: string
|
public originalPath: string
|
||||||
activeLinkClass: string
|
public currentPath: string
|
||||||
content: HTMLElement
|
public content: HTMLElement
|
||||||
loading: HTMLElement
|
public loading: HTMLElement
|
||||||
currentPath: string
|
public fadeOutClass: string
|
||||||
originalPath: string
|
public onError: (err: Error) => void
|
||||||
lastRequestController: AbortController | null
|
|
||||||
contentInvisible: boolean
|
private activeLinkClass: string
|
||||||
onError: (err: Error) => void
|
private lastRequestController: AbortController | null
|
||||||
|
private contentInvisible: boolean
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.currentPath = window.location.pathname
|
this.currentPath = window.location.pathname
|
||||||
@ -25,18 +22,11 @@ export default class Application {
|
|||||||
this.onError = console.error
|
this.onError = console.error
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
public init() {
|
||||||
document.addEventListener("DOMContentLoaded", this.onContentLoaded.bind(this))
|
document.addEventListener("DOMContentLoaded", this.onContentLoaded.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
onContentLoaded() {
|
public async get(url: string): Promise<string> {
|
||||||
let links = document.getElementsByTagName("a")
|
|
||||||
|
|
||||||
this.markActiveLinks(links)
|
|
||||||
this.ajaxify(links)
|
|
||||||
}
|
|
||||||
|
|
||||||
async get(url: string): Promise<string> {
|
|
||||||
if(this.lastRequestController) {
|
if(this.lastRequestController) {
|
||||||
this.lastRequestController.abort()
|
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
|
// Remove protocol and hostname if it was specified
|
||||||
if(url.startsWith(location.origin)) {
|
if(url.startsWith(location.origin)) {
|
||||||
url = url.substr(location.origin.length)
|
url = url.substr(location.origin.length)
|
||||||
@ -68,7 +58,7 @@ export default class Application {
|
|||||||
// Start sending a network request
|
// Start sending a network request
|
||||||
let request: Promise<string>
|
let request: Promise<string>
|
||||||
|
|
||||||
let retry = () => {
|
const retry = () => {
|
||||||
return this.get("/_" + url).catch(async error => {
|
return this.get("/_" + url).catch(async error => {
|
||||||
// Are we still on that page?
|
// Are we still on that page?
|
||||||
if(this.currentPath !== url) {
|
if(this.currentPath !== url) {
|
||||||
@ -112,8 +102,8 @@ export default class Application {
|
|||||||
// Mark active links
|
// Mark active links
|
||||||
this.markActiveLinks()
|
this.markActiveLinks()
|
||||||
|
|
||||||
let consume = async () => {
|
const consume = async () => {
|
||||||
let html = await request
|
const html = await request
|
||||||
|
|
||||||
if(this.currentPath !== url) {
|
if(this.currentPath !== url) {
|
||||||
return
|
return
|
||||||
@ -124,7 +114,7 @@ export default class Application {
|
|||||||
this.scrollToTop()
|
this.scrollToTop()
|
||||||
|
|
||||||
// Fade in listener
|
// Fade in listener
|
||||||
let onFadedIn: EventListener = (e: Event) => {
|
const onFadedIn: EventListener = (e: Event) => {
|
||||||
// Ignore transitions of child elements.
|
// Ignore transitions of child elements.
|
||||||
// We only care about the transition event on the content element.
|
// We only care about the transition event on the content element.
|
||||||
if(e.target !== this.content) {
|
if(e.target !== this.content) {
|
||||||
@ -152,7 +142,7 @@ export default class Application {
|
|||||||
consume()
|
consume()
|
||||||
} else {
|
} else {
|
||||||
// Fade out listener
|
// Fade out listener
|
||||||
let onFadedOut: EventListener = (e: Event) => {
|
const onFadedOut: EventListener = (e: Event) => {
|
||||||
// Ignore transitions of child elements.
|
// Ignore transitions of child elements.
|
||||||
// We only care about the transition event on the content element.
|
// We only care about the transition event on the content element.
|
||||||
if(e.target !== this.content) {
|
if(e.target !== this.content) {
|
||||||
@ -183,36 +173,12 @@ export default class Application {
|
|||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
|
|
||||||
setContent(html: string) {
|
public ajaxify(links?: HTMLCollectionOf<HTMLAnchorElement>) {
|
||||||
this.content.innerHTML = html
|
|
||||||
}
|
|
||||||
|
|
||||||
markActiveLinks(links?: HTMLCollectionOf<HTMLAnchorElement>) {
|
|
||||||
if(!links) {
|
if(!links) {
|
||||||
links = document.getElementsByTagName("a")
|
links = document.getElementsByTagName("a")
|
||||||
}
|
}
|
||||||
|
|
||||||
for(let i = 0; i < links.length; i++) {
|
for(const link of links) {
|
||||||
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
|
|
||||||
|
|
||||||
// Don't ajaxify links to a different host
|
// Don't ajaxify links to a different host
|
||||||
if(link.hostname !== window.location.hostname) {
|
if(link.hostname !== window.location.hostname) {
|
||||||
if(!link.target) {
|
if(!link.target) {
|
||||||
@ -227,7 +193,7 @@ export default class Application {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this
|
const self = this
|
||||||
|
|
||||||
link.onclick = function(e) {
|
link.onclick = function(e) {
|
||||||
// Middle mouse button and Ctrl clicks should have standard behaviour
|
// Middle mouse button and Ctrl clicks should have standard behaviour
|
||||||
@ -238,7 +204,7 @@ export default class Application {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
// Prevent loading the same page
|
// Prevent loading the same page
|
||||||
let url = (this as HTMLAnchorElement).getAttribute("href")
|
const url = (this as HTMLAnchorElement).getAttribute("href")
|
||||||
|
|
||||||
if(!url || url === self.currentPath) {
|
if(!url || url === self.currentPath) {
|
||||||
return
|
return
|
||||||
@ -251,17 +217,45 @@ export default class Application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollToTop() {
|
public markActiveLinks(links?: HTMLCollectionOf<HTMLAnchorElement>) {
|
||||||
let parent: any = this.content
|
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(() => {
|
Diff.mutations.queue(() => {
|
||||||
while(parent = parent.parentElement) {
|
while(parent) {
|
||||||
parent.scrollTop = 0
|
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"
|
import { delay } from "./Utils"
|
||||||
|
|
||||||
export default class StatusMessage {
|
export default class StatusMessage {
|
||||||
container: HTMLElement
|
private container: HTMLElement
|
||||||
text: HTMLElement
|
private text: HTMLElement
|
||||||
|
|
||||||
constructor(container: HTMLElement, text: HTMLElement) {
|
constructor(container: HTMLElement, text: HTMLElement) {
|
||||||
this.container = container
|
this.container = container
|
||||||
this.text = text
|
this.text = text
|
||||||
}
|
}
|
||||||
|
|
||||||
show(message: string, duration: number) {
|
public showError(message: string | Error, duration?: number) {
|
||||||
let messageId = String(Date.now())
|
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
|
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("info-message")
|
||||||
this.container.classList.remove("error-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 {
|
export default class TouchController {
|
||||||
x: number
|
public leftSwipe: Function
|
||||||
y: number
|
public rightSwipe: Function
|
||||||
|
public upSwipe: Function
|
||||||
|
public downSwipe: Function
|
||||||
|
|
||||||
threshold: number
|
private x: number
|
||||||
|
private y: number
|
||||||
leftSwipe: Function
|
private threshold: number
|
||||||
rightSwipe: Function
|
|
||||||
upSwipe: Function
|
|
||||||
downSwipe: Function
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
document.addEventListener("touchstart", evt => this.handleTouchStart(evt), false)
|
document.addEventListener("touchstart", evt => this.handleTouchStart(evt), false)
|
||||||
@ -19,21 +18,21 @@ export default class TouchController {
|
|||||||
this.y = -1
|
this.y = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTouchStart(evt) {
|
private handleTouchStart(evt) {
|
||||||
this.x = evt.touches[0].clientX
|
this.x = evt.touches[0].clientX
|
||||||
this.y = evt.touches[0].clientY
|
this.y = evt.touches[0].clientY
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTouchMove(evt) {
|
private handleTouchMove(evt) {
|
||||||
if(this.x === -1 || this.y === -1) {
|
if(this.x === -1 || this.y === -1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let xUp = evt.touches[0].clientX
|
const xUp = evt.touches[0].clientX
|
||||||
let yUp = evt.touches[0].clientY
|
const yUp = evt.touches[0].clientY
|
||||||
|
|
||||||
let xDiff = this.x - xUp
|
const xDiff = this.x - xUp
|
||||||
let yDiff = this.y - yUp
|
const yDiff = this.y - yUp
|
||||||
|
|
||||||
if(Math.abs(xDiff) > Math.abs(yDiff)) {
|
if(Math.abs(xDiff) > Math.abs(yDiff)) {
|
||||||
if(xDiff > this.threshold) {
|
if(xDiff > this.threshold) {
|
||||||
@ -52,4 +51,4 @@ export default class TouchController {
|
|||||||
this.x = -1
|
this.x = -1
|
||||||
this.y = -1
|
this.y = -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
import Application from "./Application"
|
|
||||||
import AnimeNotifier from "./AnimeNotifier"
|
import AnimeNotifier from "./AnimeNotifier"
|
||||||
|
import Application from "./Application"
|
||||||
|
|
||||||
let app = new Application()
|
const app = new Application()
|
||||||
let arn = new AnimeNotifier(app)
|
const arn = new AnimeNotifier(app)
|
||||||
|
|
||||||
arn.init()
|
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