From 878f1913e3afc2c26fe8cbcc27870eb43264adfc Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sun, 17 Nov 2019 18:25:14 +0900 Subject: [PATCH] Use const variables when applicable --- scripts/Actions/AnimeList.ts | 16 +- scripts/Actions/Audio.ts | 4 +- scripts/Actions/Diff.ts | 4 +- scripts/Actions/Editor.ts | 24 +-- scripts/Actions/Explore.ts | 30 ++-- scripts/Actions/Forum.ts | 56 +++---- scripts/Actions/Group.ts | 4 +- scripts/Actions/InfiniteScroller.ts | 8 +- scripts/Actions/Like.ts | 4 +- scripts/Actions/Object.ts | 12 +- scripts/Actions/Publish.ts | 4 +- scripts/Actions/Search.ts | 40 ++--- scripts/Actions/Serialization.ts | 42 ++--- scripts/Actions/Shop.ts | 16 +- scripts/Actions/SideBar.ts | 2 +- scripts/Actions/Theme.ts | 16 +- scripts/Actions/Upload.ts | 42 ++--- scripts/Actions/User.ts | 6 +- scripts/Actions/Video.ts | 16 +- scripts/Analytics.ts | 4 +- scripts/AnimeNotifier.ts | 204 ++++++++++++------------- scripts/AudioPlayer.ts | 24 +-- scripts/DateView.ts | 38 ++--- scripts/Diff.ts | 38 ++--- scripts/Elements/svg-icon/svg-icon.ts | 12 +- scripts/Elements/tool-tip/tool-tip.ts | 8 +- scripts/InfiniteScroller.ts | 4 +- scripts/MutationQueue.ts | 4 +- scripts/NotificationManager.ts | 4 +- scripts/PushManager.ts | 24 +-- scripts/ServerEvents.ts | 14 +- scripts/ServiceWorker/ServiceWorker.ts | 52 +++---- scripts/ServiceWorkerManager.ts | 4 +- scripts/SideBar.ts | 2 +- scripts/Utils/findAll.ts | 4 +- scripts/Utils/hexToHSL.ts | 10 +- scripts/Utils/swapElements.ts | 4 +- scripts/Utils/uploadWithProgress.ts | 4 +- tslint.json | 4 +- 39 files changed, 405 insertions(+), 403 deletions(-) diff --git a/scripts/Actions/AnimeList.ts b/scripts/Actions/AnimeList.ts index ba879ffe..41b0de3a 100644 --- a/scripts/Actions/AnimeList.ts +++ b/scripts/Actions/AnimeList.ts @@ -4,22 +4,22 @@ import AnimeNotifier from "../AnimeNotifier" export async function addAnimeToCollection(arn: AnimeNotifier, button: HTMLButtonElement) { button.disabled = true - let {animeId} = button.dataset + const {animeId} = button.dataset if(!animeId) { console.error("Button without anime ID:", button) return } - let apiEndpoint = arn.findAPIEndpoint(button) + const apiEndpoint = arn.findAPIEndpoint(button) try { await arn.post(apiEndpoint + "/add/" + animeId) arn.reloadContent() // Show status message - let response = await fetch("/api/anime/" + animeId) - let anime = await response.json() + const response = await fetch("/api/anime/" + animeId) + const anime = await response.json() arn.statusMessage.showInfo(`Added ${anime.title.canonical} to your collection.`) } catch(err) { arn.statusMessage.showError(err) @@ -33,15 +33,15 @@ export async function removeAnimeFromCollection(arn: AnimeNotifier, button: HTML } button.textContent = "Removing..." - let {animeId, nick} = button.dataset + const {animeId, nick} = button.dataset if(!animeId || !nick) { console.error("Button without nick or anime ID:", button) return } - let apiEndpoint = arn.findAPIEndpoint(button) - let status = document.getElementById("Status") as HTMLSelectElement + const apiEndpoint = arn.findAPIEndpoint(button) + const status = document.getElementById("Status") as HTMLSelectElement try { await arn.post(apiEndpoint + "/remove/" + animeId) @@ -58,7 +58,7 @@ export async function deleteAnimeList(arn: AnimeNotifier, button: HTMLElement) { } button.textContent = "Deleting..." - let {returnPath} = button.dataset + const {returnPath} = button.dataset if(!returnPath) { console.error("Button without data-return-path:", button) diff --git a/scripts/Actions/Audio.ts b/scripts/Actions/Audio.ts index 3e268b33..fa599a76 100644 --- a/scripts/Actions/Audio.ts +++ b/scripts/Actions/Audio.ts @@ -2,7 +2,7 @@ import AnimeNotifier from "../AnimeNotifier" // Play audio export function playAudio(arn: AnimeNotifier, element: HTMLElement) { - let {mediaId, audioSrc} = element.dataset + const {mediaId, audioSrc} = element.dataset if(!mediaId || !audioSrc) { console.error("Invalid media ID or audio source:", element) @@ -39,7 +39,7 @@ export async function playNextTrack(arn: AnimeNotifier) { // Set volume export function setVolume(arn: AnimeNotifier, element: HTMLInputElement) { - let volume = parseFloat(element.value) / 100.0 + const volume = parseFloat(element.value) / 100.0 arn.audioPlayer.setVolume(volume) } diff --git a/scripts/Actions/Diff.ts b/scripts/Actions/Diff.ts index c4f7d4b3..fa6dc820 100644 --- a/scripts/Actions/Diff.ts +++ b/scripts/Actions/Diff.ts @@ -3,7 +3,7 @@ import { requestIdleCallback } from "../Utils" // Load export function load(arn: AnimeNotifier, element: HTMLElement) { - let url = element.dataset.url || (element as HTMLAnchorElement).getAttribute("href") + const url = element.dataset.url || (element as HTMLAnchorElement).getAttribute("href") if(!url) { arn.statusMessage.showError("Link doesn't have a target") @@ -15,7 +15,7 @@ export function load(arn: AnimeNotifier, element: HTMLElement) { // Diff export async function diff(arn: AnimeNotifier, element: HTMLElement) { - let url = element.dataset.url || (element as HTMLAnchorElement).getAttribute("href") + const url = element.dataset.url || (element as HTMLAnchorElement).getAttribute("href") if(!url) { arn.statusMessage.showError("Link doesn't have a target") diff --git a/scripts/Actions/Editor.ts b/scripts/Actions/Editor.ts index fb336d53..6524f680 100644 --- a/scripts/Actions/Editor.ts +++ b/scripts/Actions/Editor.ts @@ -6,8 +6,8 @@ export async function newAnimeDiffIgnore(arn: AnimeNotifier, button: HTMLButtonE return } - let id = button.dataset.id - let hash = button.dataset.hash + const id = button.dataset.id + const hash = button.dataset.hash try { await arn.post(`/api/new/ignoreanimedifference`, { @@ -27,15 +27,15 @@ export async function importKitsuAnime(arn: AnimeNotifier, button: HTMLButtonEle return } - let newTab = window.open() + const newTab = window.open() if(!newTab) { arn.statusMessage.showError("Error opening new tab") return } - let animeId = button.dataset.id - let response = await fetch(`/api/import/kitsu/anime/${animeId}`, { + const animeId = button.dataset.id + const response = await fetch(`/api/import/kitsu/anime/${animeId}`, { method: "POST", credentials: "same-origin" }) @@ -54,22 +54,22 @@ export async function deleteKitsuAnime(arn: AnimeNotifier, button: HTMLButtonEle return } - let animeId = button.dataset.id + const animeId = button.dataset.id await arn.post(`/api/delete/kitsu/anime/${animeId}`) arn.reloadContent() } // Multi-search anime export async function multiSearchAnime(arn: AnimeNotifier, textarea: HTMLTextAreaElement) { - let results = document.getElementById("multi-search-anime") as HTMLDivElement - let animeTitles = textarea.value.split("\n") + const results = document.getElementById("multi-search-anime") as HTMLDivElement + const animeTitles = textarea.value.split("\n") results.innerHTML = "" for(let i = 0; i < animeTitles.length; i++) { console.log(animeTitles[i]) - let response = await fetch("/_/anime-search/" + animeTitles[i]) - let html = await response.text() + const response = await fetch("/_/anime-search/" + animeTitles[i]) + const html = await response.text() results.innerHTML += "

" + animeTitles[i] + "

" + html } @@ -79,7 +79,7 @@ export async function multiSearchAnime(arn: AnimeNotifier, textarea: HTMLTextAre // Download soundtrack file export async function downloadSoundTrackFile(arn: AnimeNotifier, button: HTMLButtonElement) { - let id = button.dataset.id + const id = button.dataset.id try { await arn.post(`/api/soundtrack/${id}/download`) @@ -96,7 +96,7 @@ export async function startJob(arn: AnimeNotifier, button: HTMLButtonElement) { return } - let jobName = button.dataset.job + const jobName = button.dataset.job if(!confirm(`Are you sure you want to start the "${jobName}" job?`)) { return diff --git a/scripts/Actions/Explore.ts b/scripts/Actions/Explore.ts index d6ea4467..63bffbba 100644 --- a/scripts/Actions/Explore.ts +++ b/scripts/Actions/Explore.ts @@ -3,24 +3,24 @@ import { findAll } from "scripts/Utils" // Filter anime on explore page export function filterAnime(arn: AnimeNotifier, _: HTMLInputElement) { - let root = document.getElementById("filter-root") as HTMLElement + const root = document.getElementById("filter-root") as HTMLElement - let elementYear = document.getElementById("filter-year") as HTMLSelectElement - let elementSeason = document.getElementById("filter-season") as HTMLSelectElement - let elementStatus = document.getElementById("filter-status") as HTMLSelectElement - let elementType = document.getElementById("filter-type") as HTMLSelectElement + const elementYear = document.getElementById("filter-year") as HTMLSelectElement + const elementSeason = document.getElementById("filter-season") as HTMLSelectElement + const elementStatus = document.getElementById("filter-status") as HTMLSelectElement + const elementType = document.getElementById("filter-type") as HTMLSelectElement - for(let element of findAll("anime-grid-image")) { - let img = element as HTMLImageElement + for(const element of findAll("anime-grid-image")) { + const img = element as HTMLImageElement img.src = arn.emptyPixel() img.classList.remove("element-found") img.classList.remove("element-color-preview") } - let year = elementYear.value || "any" - let season = elementSeason.value || "any" - let status = elementStatus.value || "any" - let type = elementType.value || "any" + const year = elementYear.value || "any" + const season = elementSeason.value || "any" + const status = elementStatus.value || "any" + const type = elementType.value || "any" arn.diff(`${root.dataset.url}/${year}/${season}/${status}/${type}`) } @@ -32,7 +32,7 @@ export function toggleHideAddedAnime() { // Hides anime that are already in your list. export function hideAddedAnime() { - for(let anime of findAll("anime-grid-cell")) { + for(const anime of findAll("anime-grid-cell")) { if(anime.dataset.added !== "true") { continue } @@ -43,7 +43,7 @@ export function hideAddedAnime() { // Hides anime that are not in your list. export async function calendarShowAddedAnimeOnly(arn: AnimeNotifier, element: HTMLInputElement) { - let calendar = document.getElementById("calendar") + const calendar = document.getElementById("calendar") if(!calendar || calendar.dataset.showAddedAnimeOnly === undefined) { return @@ -57,8 +57,8 @@ export async function calendarShowAddedAnimeOnly(arn: AnimeNotifier, element: HT } // Save the state in the database - let showAddedAnimeOnly = calendar.dataset.showAddedAnimeOnly === "true" - let apiEndpoint = arn.findAPIEndpoint(element) + const showAddedAnimeOnly = calendar.dataset.showAddedAnimeOnly === "true" + const apiEndpoint = arn.findAPIEndpoint(element) try { await arn.post(apiEndpoint, { diff --git a/scripts/Actions/Forum.ts b/scripts/Actions/Forum.ts index d1e668ca..153dd92b 100644 --- a/scripts/Actions/Forum.ts +++ b/scripts/Actions/Forum.ts @@ -2,22 +2,22 @@ import AnimeNotifier from "../AnimeNotifier" // Edit post export function editPost(_: AnimeNotifier, element: HTMLElement) { - let postId = element.dataset.id + const postId = element.dataset.id if(!postId) { console.error("Post missing post ID:", postId) return } - let render = document.getElementById("render-" + postId) as HTMLElement - let source = document.getElementById("source-" + postId) as HTMLElement - let edit = document.getElementById("edit-toolbar-" + postId) as HTMLElement + const render = document.getElementById("render-" + postId) as HTMLElement + const source = document.getElementById("source-" + postId) as HTMLElement + const edit = document.getElementById("edit-toolbar-" + postId) as HTMLElement render.classList.toggle("hidden") source.classList.toggle("hidden") edit.classList.toggle("hidden") - let title = document.getElementById("title-" + postId) + const title = document.getElementById("title-" + postId) if(title) { title.classList.toggle("hidden") @@ -26,12 +26,12 @@ export function editPost(_: AnimeNotifier, element: HTMLElement) { // Save post export async function savePost(arn: AnimeNotifier, element: HTMLElement) { - let postId = element.dataset.id - let source = document.getElementById("source-" + postId) as HTMLTextAreaElement - let title = document.getElementById("title-" + postId) as HTMLInputElement - let text = source.value + const postId = element.dataset.id + const source = document.getElementById("source-" + postId) as HTMLTextAreaElement + const title = document.getElementById("title-" + postId) as HTMLInputElement + const text = source.value - let updates: any = { + const updates: any = { Text: text, } @@ -40,7 +40,7 @@ export async function savePost(arn: AnimeNotifier, element: HTMLElement) { updates.Title = title.value } - let apiEndpoint = arn.findAPIEndpoint(element) + const apiEndpoint = arn.findAPIEndpoint(element) try { await arn.post(apiEndpoint, updates) @@ -56,7 +56,7 @@ export async function deletePost(arn: AnimeNotifier, element: HTMLElement) { return } - let endpoint = arn.findAPIEndpoint(element) + const endpoint = arn.findAPIEndpoint(element) try { await arn.post(endpoint + "/delete") @@ -68,10 +68,10 @@ export async function deletePost(arn: AnimeNotifier, element: HTMLElement) { // Create post export async function createPost(arn: AnimeNotifier, element: HTMLElement) { - let textarea = document.getElementById("new-post-text") as HTMLTextAreaElement - let {parentId, parentType} = element.dataset + const textarea = document.getElementById("new-post-text") as HTMLTextAreaElement + const {parentId, parentType} = element.dataset - let post = { + const post = { text: textarea.value, parentId, parentType, @@ -89,11 +89,11 @@ export async function createPost(arn: AnimeNotifier, element: HTMLElement) { // Create thread export async function createThread(arn: AnimeNotifier) { - let title = document.getElementById("title") as HTMLInputElement - let text = document.getElementById("text") as HTMLTextAreaElement - let category = document.getElementById("tag") as HTMLInputElement + const title = document.getElementById("title") as HTMLInputElement + const text = document.getElementById("text") as HTMLTextAreaElement + const category = document.getElementById("tag") as HTMLInputElement - let thread = { + const thread = { title: title.value, text: text.value, tags: [category.value] @@ -109,9 +109,9 @@ export async function createThread(arn: AnimeNotifier) { // Reply to a post export async function reply(arn: AnimeNotifier, element: HTMLElement) { - let apiEndpoint = arn.findAPIEndpoint(element) - let repliesId = `replies-${element.dataset.postId}` - let replies = document.getElementById(repliesId) + const apiEndpoint = arn.findAPIEndpoint(element) + const repliesId = `replies-${element.dataset.postId}` + const replies = document.getElementById(repliesId) if(!replies) { console.error("Missing replies container:", element) @@ -119,14 +119,14 @@ export async function reply(arn: AnimeNotifier, element: HTMLElement) { } // Delete old reply area - let oldReplyArea = document.getElementById("new-post") + const oldReplyArea = document.getElementById("new-post") if(oldReplyArea) { oldReplyArea.remove() } // Delete old reply button - let oldPostActions = document.getElementsByClassName("new-post-actions")[0] + const oldPostActions = document.getElementsByClassName("new-post-actions")[0] if(oldPostActions) { oldPostActions.remove() @@ -134,8 +134,8 @@ export async function reply(arn: AnimeNotifier, element: HTMLElement) { // Fetch new reply UI try { - let response = await fetch(`${apiEndpoint}/reply/ui`) - let html = await response.text() + const response = await fetch(`${apiEndpoint}/reply/ui`) + const html = await response.text() replies.innerHTML = html + replies.innerHTML arn.onNewContent(replies) arn.assignActions() @@ -161,13 +161,13 @@ export function unlockThread(arn: AnimeNotifier, element: HTMLButtonElement) { // Set thread locked state async function setThreadLock(arn: AnimeNotifier, element: HTMLButtonElement, state: boolean) { - let verb = state ? "lock" : "unlock" + const verb = state ? "lock" : "unlock" if(!confirm(`Are you sure you want to ${verb} this Thread?`)) { return } - let endpoint = arn.findAPIEndpoint(element) + const endpoint = arn.findAPIEndpoint(element) try { await arn.post(`${endpoint}/${verb}`) diff --git a/scripts/Actions/Group.ts b/scripts/Actions/Group.ts index 44068879..0c07f244 100644 --- a/scripts/Actions/Group.ts +++ b/scripts/Actions/Group.ts @@ -6,7 +6,7 @@ export async function join(arn: AnimeNotifier, element: HTMLElement) { return } - let apiEndpoint = arn.findAPIEndpoint(element) + const apiEndpoint = arn.findAPIEndpoint(element) try { await arn.post(`${apiEndpoint}/join`) @@ -23,7 +23,7 @@ export async function leave(arn: AnimeNotifier, element: HTMLElement) { return } - let apiEndpoint = arn.findAPIEndpoint(element) + const apiEndpoint = arn.findAPIEndpoint(element) try { await arn.post(`${apiEndpoint}/leave`) diff --git a/scripts/Actions/InfiniteScroller.ts b/scripts/Actions/InfiniteScroller.ts index bc4d961c..6fde07c9 100644 --- a/scripts/Actions/InfiniteScroller.ts +++ b/scripts/Actions/InfiniteScroller.ts @@ -17,10 +17,10 @@ export async function loadMore(arn: AnimeNotifier, button: HTMLButtonElement) { arn.loading(true) button.disabled = true - let index = button.dataset.index + const index = button.dataset.index try { - let response = await fetch("/_" + arn.app.currentPath + "/from/" + index, { + const response = await fetch("/_" + arn.app.currentPath + "/from/" + index, { credentials: "same-origin" }) @@ -28,7 +28,7 @@ export async function loadMore(arn: AnimeNotifier, button: HTMLButtonElement) { throw response.statusText } - let newIndex = response.headers.get("X-LoadMore-Index") + const newIndex = response.headers.get("X-LoadMore-Index") // End of data? if(!newIndex || newIndex === "-1") { @@ -39,7 +39,7 @@ export async function loadMore(arn: AnimeNotifier, button: HTMLButtonElement) { } // Get the HTML response - let html = await response.text() + const html = await response.text() // Add the HTML to the existing target Diff.mutations.queue(() => { diff --git a/scripts/Actions/Like.ts b/scripts/Actions/Like.ts index 7424ac5f..fd063df0 100644 --- a/scripts/Actions/Like.ts +++ b/scripts/Actions/Like.ts @@ -3,7 +3,7 @@ import AnimeNotifier from "../AnimeNotifier" // like export async function like(arn: AnimeNotifier, element: HTMLElement) { arn.statusMessage.showInfo("Liked!", 1000) - let apiEndpoint = arn.findAPIEndpoint(element) + const apiEndpoint = arn.findAPIEndpoint(element) try { await arn.post(apiEndpoint + "/like") @@ -16,7 +16,7 @@ export async function like(arn: AnimeNotifier, element: HTMLElement) { // unlike export async function unlike(arn: AnimeNotifier, element: HTMLElement) { arn.statusMessage.showInfo("Disliked!", 1000) - let apiEndpoint = arn.findAPIEndpoint(element) + const apiEndpoint = arn.findAPIEndpoint(element) try { await arn.post(apiEndpoint + "/unlike") diff --git a/scripts/Actions/Object.ts b/scripts/Actions/Object.ts index 63beb2b8..37e72b46 100644 --- a/scripts/Actions/Object.ts +++ b/scripts/Actions/Object.ts @@ -2,7 +2,7 @@ import AnimeNotifier from "../AnimeNotifier" // New export async function newObject(arn: AnimeNotifier, button: HTMLButtonElement) { - let dataType = button.dataset.type + const dataType = button.dataset.type if(!dataType) { console.error("Missing data type:", button) @@ -10,13 +10,13 @@ export async function newObject(arn: AnimeNotifier, button: HTMLButtonElement) { } try { - let response = await arn.post(`/api/new/${dataType}`) + const response = await arn.post(`/api/new/${dataType}`) if(!response) { throw `Failed creating ${dataType}` } - let json = await response.json() + const json = await response.json() await arn.app.load(`/${dataType}/${json.id}/edit`) } catch(err) { arn.statusMessage.showError(err) @@ -25,8 +25,8 @@ export async function newObject(arn: AnimeNotifier, button: HTMLButtonElement) { // Delete export async function deleteObject(arn: AnimeNotifier, button: HTMLButtonElement) { - let confirmType = button.dataset.confirmType - let returnPath = button.dataset.returnPath + const confirmType = button.dataset.confirmType + const returnPath = button.dataset.returnPath if(!confirm(`Are you sure you want to delete this ${confirmType}?`)) { return @@ -39,7 +39,7 @@ export async function deleteObject(arn: AnimeNotifier, button: HTMLButtonElement } } - let endpoint = arn.findAPIEndpoint(button) + const endpoint = arn.findAPIEndpoint(button) try { await arn.post(endpoint + "/delete") diff --git a/scripts/Actions/Publish.ts b/scripts/Actions/Publish.ts index 31597f93..76e765c6 100644 --- a/scripts/Actions/Publish.ts +++ b/scripts/Actions/Publish.ts @@ -2,7 +2,7 @@ import AnimeNotifier from "../AnimeNotifier" // Publish export async function publish(arn: AnimeNotifier, button: HTMLButtonElement) { - let endpoint = arn.findAPIEndpoint(button) + const endpoint = arn.findAPIEndpoint(button) try { await arn.post(endpoint + "/publish") @@ -14,7 +14,7 @@ export async function publish(arn: AnimeNotifier, button: HTMLButtonElement) { // Unpublish export async function unpublish(arn: AnimeNotifier, button: HTMLButtonElement) { - let endpoint = arn.findAPIEndpoint(button) + const endpoint = arn.findAPIEndpoint(button) try { await arn.post(endpoint + "/unpublish") diff --git a/scripts/Actions/Search.ts b/scripts/Actions/Search.ts index bc54f4ac..a8bfa136 100644 --- a/scripts/Actions/Search.ts +++ b/scripts/Actions/Search.ts @@ -3,10 +3,10 @@ import { delay, requestIdleCallback } from "../Utils" import Diff from "scripts/Diff"; // Search page reference -var emptySearchHTML = "" -var searchPage: HTMLElement -var searchPageTitle: HTMLElement -var correctResponseRendered = { +let emptySearchHTML = "" +let searchPage: HTMLElement +let searchPageTitle: HTMLElement +const correctResponseRendered = { "anime": false, "character": false, "posts": false, @@ -18,13 +18,13 @@ var correctResponseRendered = { } // Search types -var searchTypes = Object.keys(correctResponseRendered) +const searchTypes = Object.keys(correctResponseRendered) // Save old term to compare -var oldTerm = "" +let oldTerm = "" // Containers for all the search results -var results = new Map() +const results = new Map() // Delay before a request is sent const searchDelay = 140 @@ -44,10 +44,10 @@ export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: } // Determine if we're already seeing the search page - let searchPageActivated = (searchPage === arn.app.content.children[0]) + const searchPageActivated = (searchPage === arn.app.content.children[0]) // Check if the search term really changed - let term = search.value.trim() + const term = search.value.trim() if(term === oldTerm && searchPageActivated) { return @@ -56,12 +56,12 @@ export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: oldTerm = term // Reset - for(let key of searchTypes) { + for(const key of searchTypes) { correctResponseRendered[key] = false } // Set browser URL - let url = "/search/" + term + const url = "/search/" + term document.title = "Search: " + term arn.app.currentPath = url @@ -74,7 +74,7 @@ export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: try { // Fetch empty search frame if needed if(emptySearchHTML === "") { - let response = await fetch("/_/empty-search") + const response = await fetch("/_/empty-search") emptySearchHTML = await response.text() } @@ -101,7 +101,7 @@ export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: } if(!results["anime"]) { - for(let key of searchTypes) { + for(const key of searchTypes) { results[key] = document.getElementById(`${key}-search-results`) } @@ -128,7 +128,7 @@ export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: } // Search the other types (everything except anime) - for(let key of searchTypes) { + for(const key of searchTypes) { if(key === "anime") { continue } @@ -151,7 +151,7 @@ function showResponseInElement(arn: AnimeNotifier, url: string, typeName: string throw response.statusText } - let html = await response.text() + const html = await response.text() if(html.includes("no-search-results")) { Diff.mutations.queue(() => (element.parentElement as HTMLElement).classList.add("search-section-disabled")) @@ -179,10 +179,10 @@ export function searchBySpeech(arn: AnimeNotifier, element: HTMLElement) { return } - let searchInput = document.getElementById("search") as HTMLInputElement - let oldPlaceholder = searchInput.placeholder + const searchInput = document.getElementById("search") as HTMLInputElement + const oldPlaceholder = searchInput.placeholder - let SpeechRecognition: any = window["SpeechRecognition"] || window["webkitSpeechRecognition"] + const SpeechRecognition: any = window["SpeechRecognition"] || window["webkitSpeechRecognition"] recognition = new SpeechRecognition() recognition.continuous = false recognition.interimResults = false @@ -190,8 +190,8 @@ export function searchBySpeech(arn: AnimeNotifier, element: HTMLElement) { recognition.onresult = evt => { if(evt.results.length > 0) { - let result = evt.results.item(0).item(0) - let term = result.transcript + const result = evt.results.item(0).item(0) + const term = result.transcript if(term !== "") { searchInput.value = term diff --git a/scripts/Actions/Serialization.ts b/scripts/Actions/Serialization.ts index f212558f..1f362d8d 100644 --- a/scripts/Actions/Serialization.ts +++ b/scripts/Actions/Serialization.ts @@ -8,8 +8,8 @@ export async function save(arn: AnimeNotifier, input: HTMLElement) { return } - let obj = {} - let isContentEditable = input.isContentEditable + const obj = {} + const isContentEditable = input.isContentEditable let value = isContentEditable ? input.textContent : (input as HTMLInputElement).value if(value === undefined || value === null) { @@ -35,7 +35,7 @@ export async function save(arn: AnimeNotifier, input: HTMLElement) { (input as HTMLInputElement).disabled = true } - let apiEndpoint = arn.findAPIEndpoint(input) + const apiEndpoint = arn.findAPIEndpoint(input) try { await arn.post(apiEndpoint, obj) @@ -71,8 +71,8 @@ export async function enable(arn: AnimeNotifier, button: HTMLButtonElement) { return } - let obj = {} - let apiEndpoint = arn.findAPIEndpoint(button) + const obj = {} + const apiEndpoint = arn.findAPIEndpoint(button) obj[button.dataset.field] = true button.disabled = true @@ -99,8 +99,8 @@ export async function disable(arn: AnimeNotifier, button: HTMLButtonElement) { return } - let obj = {} - let apiEndpoint = arn.findAPIEndpoint(button) + const obj = {} + const apiEndpoint = arn.findAPIEndpoint(button) obj[button.dataset.field] = false button.disabled = true @@ -122,9 +122,9 @@ export async function disable(arn: AnimeNotifier, button: HTMLButtonElement) { // Append new element to array export async function arrayAppend(arn: AnimeNotifier, element: HTMLElement) { - let field = element.dataset.field - let object = element.dataset.object || "" - let apiEndpoint = arn.findAPIEndpoint(element) + const field = element.dataset.field + const object = element.dataset.object || "" + const apiEndpoint = arn.findAPIEndpoint(element) try { await arn.post(apiEndpoint + "/field/" + field + "/append", object) @@ -140,9 +140,9 @@ export async function arrayRemove(arn: AnimeNotifier, element: HTMLElement) { return } - let field = element.dataset.field - let index = element.dataset.index - let apiEndpoint = arn.findAPIEndpoint(element) + const field = element.dataset.field + const index = element.dataset.index + const apiEndpoint = arn.findAPIEndpoint(element) try { await arn.post(apiEndpoint + "/field/" + field + "/remove/" + index) @@ -158,14 +158,14 @@ export function increaseEpisode(arn: AnimeNotifier, element: HTMLElement) { return } - let prev = element.previousSibling + const prev = element.previousSibling if(prev === null || !(prev instanceof HTMLElement) || prev.textContent === null) { console.error("Previous sibling is invalid:", element) return } - let episodes = parseInt(prev.textContent) + const episodes = parseInt(prev.textContent) prev.textContent = String(episodes + 1) return save(arn, prev) } @@ -181,12 +181,12 @@ export function addNumber(arn: AnimeNotifier, element: HTMLElement) { return } - let input = document.getElementById(element.dataset.id) as HTMLInputElement - let add = parseInt(element.dataset.add) - let num = parseInt(input.value) - let newValue = num + add - let min = parseInt(input.min) - let max = parseInt(input.max) + const input = document.getElementById(element.dataset.id) as HTMLInputElement + const add = parseInt(element.dataset.add) + const num = parseInt(input.value) + const newValue = num + add + const min = parseInt(input.min) + const max = parseInt(input.max) if(newValue > max) { arn.statusMessage.showError("Maximum: " + max) diff --git a/scripts/Actions/Shop.ts b/scripts/Actions/Shop.ts index b4efe28e..ccf6b0c1 100644 --- a/scripts/Actions/Shop.ts +++ b/scripts/Actions/Shop.ts @@ -2,7 +2,7 @@ import AnimeNotifier from "../AnimeNotifier" // Charge up export function chargeUp(arn: AnimeNotifier, button: HTMLElement) { - let amount = button.dataset.amount + const amount = button.dataset.amount arn.loading(true) arn.statusMessage.showInfo("Creating PayPal transaction... This might take a few seconds.") @@ -18,7 +18,7 @@ export function chargeUp(arn: AnimeNotifier, button: HTMLElement) { throw "Error creating PayPal payment" } - let link = payment.links.find(link => link.rel === "approval_url") + const link = payment.links.find(link => link.rel === "approval_url") if(!link) { throw "Error finding PayPal payment link" @@ -26,7 +26,7 @@ export function chargeUp(arn: AnimeNotifier, button: HTMLElement) { arn.statusMessage.showInfo("Redirecting to PayPal...", 5000) - let url = link.href + const url = link.href window.location.href = url }) .catch(err => arn.statusMessage.showError(err)) @@ -35,14 +35,14 @@ export function chargeUp(arn: AnimeNotifier, button: HTMLElement) { // Toggle fade export function toggleFade(_: AnimeNotifier, button: HTMLElement) { - let elementId = button.dataset.elementId + const elementId = button.dataset.elementId if(!elementId) { console.error("Missing element ID:", elementId) return } - let element = document.getElementById(elementId) + const element = document.getElementById(elementId) if(!element) { console.error("Invalid element ID:", elementId) @@ -58,9 +58,9 @@ export function toggleFade(_: AnimeNotifier, button: HTMLElement) { // Buy item export function buyItem(arn: AnimeNotifier, button: HTMLElement) { - let itemId = button.dataset.itemId - let itemName = button.dataset.itemName - let price = button.dataset.price + const itemId = button.dataset.itemId + const itemName = button.dataset.itemName + const price = button.dataset.price if(!confirm(`Would you like to buy ${itemName} for ${price} gems?`)) { return diff --git a/scripts/Actions/SideBar.ts b/scripts/Actions/SideBar.ts index b7d98a26..cb25d03a 100644 --- a/scripts/Actions/SideBar.ts +++ b/scripts/Actions/SideBar.ts @@ -2,6 +2,6 @@ import AnimeNotifier from "../AnimeNotifier" // Toggle sidebar export function toggleSidebar(_: AnimeNotifier) { - let sidebar = document.getElementById("sidebar") as HTMLElement + const sidebar = document.getElementById("sidebar") as HTMLElement sidebar.classList.toggle("sidebar-visible") } \ No newline at end of file diff --git a/scripts/Actions/Theme.ts b/scripts/Actions/Theme.ts index f7644772..addb8366 100644 --- a/scripts/Actions/Theme.ts +++ b/scripts/Actions/Theme.ts @@ -102,7 +102,7 @@ export function nextTheme(arn: AnimeNotifier) { // Find current index and apply theme of next index for(let i = 0; i < themesSorted.length; i++) { if(themesSorted[i] === currentThemeName) { - let newIndex = (i + 1) % themesSorted.length + const newIndex = (i + 1) % themesSorted.length applyThemeAndPreview(arn, themesSorted[newIndex]) break } @@ -135,15 +135,15 @@ export function applyThemeAndPreview(arn: AnimeNotifier, themeName: string) { // Apply theme export function applyTheme(themeName: string) { - let rootStyle = document.documentElement.style - let theme = themes[themeName] + const rootStyle = document.documentElement.style + const theme = themes[themeName] // Apply base theme if(theme["base-theme"]) { applyTheme(theme["base-theme"]) } - for(let property in theme) { + for(const property in theme) { if(!theme.hasOwnProperty(property)) { continue } @@ -164,13 +164,13 @@ export function applyTheme(themeName: string) { // Color picker export function pickColor(_: AnimeNotifier, element: HTMLElement) { - let rootStyle = document.documentElement.style - let variableName = `--${element.dataset.variable}` - let input = document.createElement("input") + const rootStyle = document.documentElement.style + const variableName = `--${element.dataset.variable}` + const input = document.createElement("input") input.type = "color" input.oninput = () => { - let color = hexToHSL(input.value) + const color = hexToHSL(input.value) if(!color) { return diff --git a/scripts/Actions/Upload.ts b/scripts/Actions/Upload.ts index 58b5df46..a311eeb9 100644 --- a/scripts/Actions/Upload.ts +++ b/scripts/Actions/Upload.ts @@ -3,8 +3,8 @@ import { bytesHumanReadable, uploadWithProgress } from "../Utils" // Select file export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) { - let fileType = button.dataset.type - let endpoint = button.dataset.endpoint + const fileType = button.dataset.type + const endpoint = button.dataset.endpoint if(endpoint === "/api/upload/user/cover" && arn.user && arn.user.dataset.pro !== "true") { alert("Please buy a PRO account to use this feature.") @@ -12,7 +12,7 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) { } // Click on virtual file input element - let input = document.createElement("input") + const input = document.createElement("input") input.setAttribute("type", "file") input.value = "" @@ -26,7 +26,7 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) { return } - let file = input.files[0] + const file = input.files[0] // Check mime type for images if(fileType === "image" && !file.type.startsWith("image/")) { @@ -42,9 +42,9 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) { // Preview image if(fileType === "image") { - let previews = document.getElementsByClassName(button.id + "-preview") - let dataURL = await readImageAsDataURL(file) - let img = await loadImage(dataURL) + const previews = document.getElementsByClassName(button.id + "-preview") + const dataURL = await readImageAsDataURL(file) + const img = await loadImage(dataURL) switch(endpoint) { case "/api/upload/user/image": @@ -73,11 +73,11 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) { // Upload file function uploadFile(file: File, fileType: string, endpoint: string, arn: AnimeNotifier) { - let reader = new FileReader() + const reader = new FileReader() reader.onloadend = async () => { - let result = reader.result as ArrayBuffer - let fileSize = result.byteLength + const result = reader.result as ArrayBuffer + const fileSize = result.byteLength if(fileSize === 0) { arn.statusMessage.showError("File is empty") @@ -87,7 +87,7 @@ function uploadFile(file: File, fileType: string, endpoint: string, arn: AnimeNo arn.statusMessage.showInfo(`Preparing to upload ${fileType} (${bytesHumanReadable(fileSize)})`, -1) try { - let responseText = await uploadWithProgress(endpoint, { + const responseText = await uploadWithProgress(endpoint, { method: "POST", credentials: "include", headers: { @@ -95,7 +95,7 @@ function uploadFile(file: File, fileType: string, endpoint: string, arn: AnimeNo }, body: reader.result }, e => { - let progress = e.loaded / (e.lengthComputable ? e.total : fileSize) * 100 + const progress = e.loaded / (e.lengthComputable ? e.total : fileSize) * 100 arn.statusMessage.showInfo(`Uploading ${fileType}...${progress.toFixed(1)}%`, -1) }) @@ -118,10 +118,10 @@ function uploadFile(file: File, fileType: string, endpoint: string, arn: AnimeNo // Read image as data URL function readImageAsDataURL(file: File): Promise { return new Promise((resolve, reject) => { - let reader = new FileReader() + const reader = new FileReader() reader.onloadend = () => { - let dataURL = reader.result as string + const dataURL = reader.result as string resolve(dataURL) } @@ -137,7 +137,7 @@ function readImageAsDataURL(file: File): Promise { // Load image and resolve when loading has finished function loadImage(url: string): Promise { return new Promise((resolve, reject) => { - let img = new Image() + const img = new Image() img.src = url img.onload = () => { @@ -153,15 +153,15 @@ function loadImage(url: string): Promise { // Preview image function previewImage(dataURL: string, endpoint: string, previews: HTMLCollectionOf) { if(endpoint === "/api/upload/user/image") { - let svgPreview = document.getElementById("avatar-input-preview-svg") as HTMLImageElement + const svgPreview = document.getElementById("avatar-input-preview-svg") as HTMLImageElement if(svgPreview) { svgPreview.classList.add("hidden") } } - for(let preview of previews) { - let img = preview as HTMLImageElement + for(const preview of previews) { + const img = preview as HTMLImageElement img.classList.remove("hidden") // Make not found images visible again @@ -176,9 +176,9 @@ function previewImage(dataURL: string, endpoint: string, previews: HTMLCollectio // Update sidebar avatar function updateSideBarAvatar(url: string) { - let sidebar = document.getElementById("sidebar") as HTMLElement - let userImage = sidebar.getElementsByClassName("user-image")[0] as HTMLImageElement - let lazyLoad = userImage["became visible"] + const sidebar = document.getElementById("sidebar") as HTMLElement + const userImage = sidebar.getElementsByClassName("user-image")[0] as HTMLImageElement + const lazyLoad = userImage["became visible"] if(lazyLoad) { userImage.dataset.src = url diff --git a/scripts/Actions/User.ts b/scripts/Actions/User.ts index ff0d7430..82257739 100644 --- a/scripts/Actions/User.ts +++ b/scripts/Actions/User.ts @@ -13,8 +13,8 @@ export async function unfollowUser(arn: AnimeNotifier, element: HTMLElement) { // Update follow async function updateFollow(arn: AnimeNotifier, element: HTMLElement, message: string) { - let api = element.dataset.api - let nick = document.getElementById("nick") + const api = element.dataset.api + const nick = document.getElementById("nick") if(!api || !nick || !nick.textContent) { console.error("Missing data-api or invalid nick:", element) @@ -34,7 +34,7 @@ async function updateFollow(arn: AnimeNotifier, element: HTMLElement, message: s export function showMore(_: AnimeNotifier, showMoreElement: HTMLElement) { const elements = [...document.getElementsByClassName("show-more")] - for(let element of elements) { + for(const element of elements) { Diff.mutations.queue(() => element.classList.remove("show-more")) } diff --git a/scripts/Actions/Video.ts b/scripts/Actions/Video.ts index f6e1af4b..f6382d84 100644 --- a/scripts/Actions/Video.ts +++ b/scripts/Actions/Video.ts @@ -2,21 +2,21 @@ import AnimeNotifier from "../AnimeNotifier" // Toggle play video export function togglePlayVideo(arn: AnimeNotifier, element: HTMLElement) { - let mediaId = element.dataset.mediaId + const mediaId = element.dataset.mediaId if(!mediaId) { console.error("Missing data-media-id:", element) return } - let container = document.getElementById(mediaId) + const container = document.getElementById(mediaId) if(!container) { console.error("Invalid data-media-id:", element) return } - let video = container.getElementsByTagName("video")[0] + const video = container.getElementsByTagName("video")[0] video.volume = arn.audioPlayer.volume if(video.readyState >= 2) { @@ -41,23 +41,23 @@ function togglePlayVideoElement(video: HTMLVideoElement) { // Toggle fullscreen export function toggleFullscreen(_: AnimeNotifier, button: HTMLElement) { - let elementId = button.dataset.id + const elementId = button.dataset.id if(!elementId) { console.error("Missing data-id:", button) return } - let element = document.getElementById(elementId) + const element = document.getElementById(elementId) if(!element) { console.error("Invalid data-id:", button) return } - let requestFullscreen = element.requestFullscreen || element["mozRequestFullScreen"] || element["webkitRequestFullScreen"] || element["msRequestFullscreen"] - let exitFullscreen = document.exitFullscreen || document["mozCancelFullScreen"] || document["webkitExitFullscreen"] || document["msExitFullscreen"] - let fullscreen = document.fullscreen || document["webkitIsFullScreen"] || document["mozFullScreen"] + const requestFullscreen = element.requestFullscreen || element["mozRequestFullScreen"] || element["webkitRequestFullScreen"] || element["msRequestFullscreen"] + const exitFullscreen = document.exitFullscreen || document["mozCancelFullScreen"] || document["webkitExitFullscreen"] || document["msExitFullscreen"] + const fullscreen = document.fullscreen || document["webkitIsFullScreen"] || document["mozFullScreen"] if(fullscreen) { exitFullscreen.call(document) diff --git a/scripts/Analytics.ts b/scripts/Analytics.ts index 40b02154..3ccf92e7 100644 --- a/scripts/Analytics.ts +++ b/scripts/Analytics.ts @@ -1,6 +1,6 @@ export default class Analytics { push() { - let analytics = { + const analytics = { general: { timezoneOffset: new Date().getTimezoneOffset() }, @@ -23,7 +23,7 @@ export default class Analytics { } if("connection" in navigator) { - let connection = navigator["connection"] as any + const connection = navigator["connection"] as any analytics.connection = { downLink: connection.downlink, diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index 31bf2eba..6288b512 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -115,7 +115,7 @@ export default class AnimeNotifier { // Enable lazy load this.visibilityObserver = new IntersectionObserver( entries => { - for(let entry of entries) { + for(const entry of entries) { if(entry.isIntersecting) { entry.target["became visible"]() this.visibilityObserver.unobserve(entry.target) @@ -203,7 +203,7 @@ export default class AnimeNotifier { // Auto-focus first input element on welcome page. if(location.pathname === "/welcome") { - let firstInput = this.app.content.getElementsByTagName("input")[0] as HTMLInputElement + const firstInput = this.app.content.getElementsByTagName("input")[0] as HTMLInputElement if(firstInput) { firstInput.focus() @@ -212,7 +212,7 @@ export default class AnimeNotifier { } applyPageTitle() { - let headers = document.getElementsByTagName("h1") + const headers = document.getElementsByTagName("h1") if(this.app.currentPath === "/" || headers.length === 0 || headers[0].textContent === "NOTIFY.MOE") { if(document.title !== this.title) { @@ -281,8 +281,8 @@ export default class AnimeNotifier { const minHeight = 800 if(window.outerWidth <= minWidth || window.outerHeight <= minHeight) { - let finalWidth = window.outerWidth < minWidth ? minWidth : window.outerWidth - let finalHeight = window.outerHeight < minHeight ? minHeight : window.outerHeight + const finalWidth = window.outerWidth < minWidth ? minWidth : window.outerWidth + const finalHeight = window.outerHeight < minHeight ? minHeight : window.outerHeight window.resizeTo(finalWidth, finalHeight) } @@ -332,7 +332,7 @@ export default class AnimeNotifier { this.tip.setAttribute("active", "false") // Assign mouse enter event handler - for(let element of elements) { + for(const element of elements) { element.onmouseenter = () => { this.tip.classList.remove("fade-out") this.tip.show(element) @@ -346,21 +346,21 @@ export default class AnimeNotifier { dragAndDrop() { if(location.pathname.includes("/animelist/")) { - for(let listItem of findAll("anime-list-item")) { + for(const listItem of findAll("anime-list-item")) { // Skip elements that have their event listeners attached already if(listItem["drag-listeners-attached"]) { continue } - let name = listItem.getElementsByClassName("anime-list-item-name")[0] - let imageContainer = listItem.getElementsByClassName("anime-list-item-image-container")[0] + const name = listItem.getElementsByClassName("anime-list-item-name")[0] + const imageContainer = listItem.getElementsByClassName("anime-list-item-image-container")[0] - let onDrag = evt => { + const onDrag = evt => { if(!evt.dataTransfer) { return } - let image = imageContainer.getElementsByClassName("anime-list-item-image")[0] + const image = imageContainer.getElementsByClassName("anime-list-item-image")[0] if(image) { evt.dataTransfer.setDragImage(image, 0, 0) @@ -381,7 +381,7 @@ export default class AnimeNotifier { listItem["drag-listeners-attached"] = true } - for(let element of findAll("tab")) { + for(const element of findAll("tab")) { // Skip elements that have their event listeners attached already if(element["drop-listeners-attached"]) { continue @@ -400,7 +400,7 @@ export default class AnimeNotifier { return } - let data = e.dataTransfer.getData("text/plain") + const data = e.dataTransfer.getData("text/plain") let json: any try { @@ -416,7 +416,7 @@ export default class AnimeNotifier { e.stopPropagation() e.preventDefault() - let tabText = toElement.textContent + const tabText = toElement.textContent if(!tabText) { return @@ -459,7 +459,7 @@ export default class AnimeNotifier { } if(location.pathname.startsWith("/inventory")) { - for(let element of findAll("inventory-slot")) { + for(const element of findAll("inventory-slot")) { // Skip elements that have their event listeners attached already if(element["drag-listeners-attached"]) { continue @@ -478,13 +478,13 @@ export default class AnimeNotifier { return } - let itemName = element.getAttribute("aria-label") + const itemName = element.getAttribute("aria-label") if(element.dataset.consumable !== "true") { return this.statusMessage.showError(itemName + " is not a consumable item.") } - let apiEndpoint = this.findAPIEndpoint(element) + const apiEndpoint = this.findAPIEndpoint(element) try { await this.post(apiEndpoint + "/use/" + element.dataset.index) @@ -513,20 +513,20 @@ export default class AnimeNotifier { e.stopPropagation() e.preventDefault() - let inventory = element.parentElement + const inventory = element.parentElement if(!inventory || !e.dataTransfer) { return } - let fromIndex = e.dataTransfer.getData("text") + const fromIndex = e.dataTransfer.getData("text") if(!fromIndex) { return } - let fromElement = inventory.childNodes[fromIndex] as HTMLElement - let toIndex = element.dataset.index + const fromElement = inventory.childNodes[fromIndex] as HTMLElement + const toIndex = element.dataset.index if(!toIndex || fromElement === element || fromIndex === toIndex) { console.error("Invalid drag & drop from", fromIndex, "to", toIndex) @@ -534,7 +534,7 @@ export default class AnimeNotifier { } // Swap in database - let apiEndpoint = this.findAPIEndpoint(inventory) + const apiEndpoint = this.findAPIEndpoint(inventory) try { await this.post(apiEndpoint + "/swap/" + fromIndex + "/" + toIndex) @@ -560,9 +560,9 @@ export default class AnimeNotifier { return } - let enableButton = document.getElementById("enable-notifications") as HTMLButtonElement - let disableButton = document.getElementById("disable-notifications") as HTMLButtonElement - let testButton = document.getElementById("test-notification") as HTMLButtonElement + const enableButton = document.getElementById("enable-notifications") as HTMLButtonElement + const disableButton = document.getElementById("disable-notifications") as HTMLButtonElement + const testButton = document.getElementById("test-notification") as HTMLButtonElement if(!this.pushManager.pushSupported) { enableButton.classList.add("hidden") @@ -571,7 +571,7 @@ export default class AnimeNotifier { return } - let subscription = await this.pushManager.subscription() + const subscription = await this.pushManager.subscription() if(subscription) { enableButton.classList.add("hidden") @@ -587,16 +587,16 @@ export default class AnimeNotifier { return } - for(let element of findAll("character-ranking")) { + for(const element of findAll("character-ranking")) { fetch(`/api/character/${element.dataset.characterId}/ranking`).then(async response => { - let ranking = await response.json() + const ranking = await response.json() if(!ranking.rank) { return } Diff.mutations.queue(() => { - let percentile = Math.ceil(ranking.percentile * 100) + const percentile = Math.ceil(ranking.percentile * 100) element.textContent = "#" + ranking.rank.toString() element.title = "Top " + percentile + "%" @@ -610,7 +610,7 @@ export default class AnimeNotifier { return } - for(let element of findAll("color-box")) { + for(const element of findAll("color-box")) { Diff.mutations.queue(() => { if(!element.dataset.color) { console.error("color-box missing data-color attribute:", element) @@ -627,19 +627,19 @@ export default class AnimeNotifier { return } - for(let element of findAll("count-up")) { + for(const element of findAll("count-up")) { if(!element.textContent) { console.error("count-up missing text content:", element) continue } - let final = parseInt(element.textContent) - let duration = 2000.0 - let start = Date.now() + const final = parseInt(element.textContent) + const duration = 2000.0 + const start = Date.now() element.textContent = "0" - let callback = () => { + const callback = () => { let progress = (Date.now() - start) / duration if(progress > 1) { @@ -658,7 +658,7 @@ export default class AnimeNotifier { } markPlayingMedia() { - for(let element of findAll("media-play-area")) { + for(const element of findAll("media-play-area")) { if(element.dataset.mediaId === this.currentMediaId) { element.classList.add("playing") } @@ -666,8 +666,8 @@ export default class AnimeNotifier { } setSelectBoxValue() { - for(let element of document.getElementsByTagName("select")) { - let attributeValue = element.getAttribute("value") + for(const element of document.getElementsByTagName("select")) { + const attributeValue = element.getAttribute("value") if(!attributeValue) { console.error("Select box without a value:", element) @@ -681,21 +681,21 @@ export default class AnimeNotifier { displayLocalDates() { const now = new Date() - for(let element of findAll("utc-airing-date")) { + for(const element of findAll("utc-airing-date")) { displayAiringDate(element, now) } - for(let element of findAll("utc-date")) { + for(const element of findAll("utc-date")) { displayDate(element, now) } - for(let element of findAll("utc-date-absolute")) { + for(const element of findAll("utc-date-absolute")) { displayTime(element) } } reloadContent(cached?: boolean) { - let headers = new Headers() + const headers = new Headers() if(cached) { headers.set("X-Force-Cache", "true") @@ -703,7 +703,7 @@ export default class AnimeNotifier { headers.set("X-No-Cache", "true") } - let path = this.lastReloadContentPath = this.app.currentPath + const path = this.lastReloadContentPath = this.app.currentPath return fetch("/_" + path, { credentials: "same-origin", @@ -724,7 +724,7 @@ export default class AnimeNotifier { reloadPage() { console.log("reload page", this.app.currentPath) - let path = this.app.currentPath + const path = this.app.currentPath this.lastReloadContentPath = path return fetch(path, { @@ -756,16 +756,16 @@ export default class AnimeNotifier { } assignActions() { - for(let element of findAll("action")) { - let actionTrigger = element.dataset.trigger - let actionName = element.dataset.action + for(const element of findAll("action")) { + const actionTrigger = element.dataset.trigger + const actionName = element.dataset.action // Filter out invalid definitions if(!actionTrigger || !actionName) { continue } - let oldAction = element["action assigned"] + const oldAction = element["action assigned"] if(oldAction) { if(oldAction.trigger === actionTrigger && oldAction.action === actionName) { @@ -787,7 +787,7 @@ export default class AnimeNotifier { } // Register the actual action handler - let actionHandler = e => { + const actionHandler = e => { if(!actionName) { return } @@ -818,7 +818,7 @@ export default class AnimeNotifier { await this.webpCheck - for(let element of elements) { + for(const element of elements) { switch(element.tagName) { case "IMG": this.lazyLoadImage(element as HTMLImageElement) @@ -840,24 +840,24 @@ export default class AnimeNotifier { } lazyLoadImage(element: HTMLImageElement) { - let pixelRatio = window.devicePixelRatio + const pixelRatio = window.devicePixelRatio // Once the image becomes visible, load it element["became visible"] = () => { - let dataSrc = element.dataset.src + const dataSrc = element.dataset.src if(!dataSrc) { console.error("Image missing data-src attribute:", element) return } - let dotPos = dataSrc.lastIndexOf(".") + const dotPos = dataSrc.lastIndexOf(".") let base = dataSrc.substring(0, dotPos) let extension = "" // Replace URL with WebP if supported if(this.webpEnabled && element.dataset.webp === "true" && !dataSrc.endsWith(".svg")) { - let queryPos = dataSrc.lastIndexOf("?") + const queryPos = dataSrc.lastIndexOf("?") if(queryPos !== -1) { extension = ".webp" + dataSrc.substring(queryPos) @@ -875,7 +875,7 @@ export default class AnimeNotifier { } } - let finalSrc = base + extension + const finalSrc = base + extension if(element.src !== finalSrc && element.src !== "https:" + finalSrc && element.src !== "https://notify.moe" + finalSrc) { // Show average color @@ -945,7 +945,7 @@ export default class AnimeNotifier { // Once the video becomes visible, load it video["became visible"] = () => { if(!video["listeners attached"]) { - let videoParent = video.parentElement + const videoParent = video.parentElement if(!videoParent) { console.error("video has no parent element") @@ -956,16 +956,16 @@ export default class AnimeNotifier { video.addEventListener("contextmenu", e => e.preventDefault()) // Show and hide controls on mouse movement - let controls = videoParent.getElementsByClassName("video-controls")[0] - let playButton = videoParent.getElementsByClassName("video-control-play")[0] as HTMLElement - let pauseButton = videoParent.getElementsByClassName("video-control-pause")[0] as HTMLElement + const controls = videoParent.getElementsByClassName("video-controls")[0] + const playButton = videoParent.getElementsByClassName("video-control-play")[0] as HTMLElement + const pauseButton = videoParent.getElementsByClassName("video-control-pause")[0] as HTMLElement - let hideControls = () => { + const hideControls = () => { controls.classList.add("fade-out") video.style.cursor = "none" } - let showControls = () => { + const showControls = () => { controls.classList.remove("fade-out") video.style.cursor = "default" } @@ -976,9 +976,9 @@ export default class AnimeNotifier { video["hideControlsTimeout"] = setTimeout(hideControls, hideControlsDelay) }) - let progressElement = videoParent.getElementsByClassName("video-progress")[0] as HTMLElement - let progressClickable = videoParent.getElementsByClassName("video-progress-clickable")[0] - let timeElement = videoParent.getElementsByClassName("video-time")[0] + const progressElement = videoParent.getElementsByClassName("video-progress")[0] as HTMLElement + const progressClickable = videoParent.getElementsByClassName("video-progress-clickable")[0] + const timeElement = videoParent.getElementsByClassName("video-time")[0] video.addEventListener("canplay", () => { video["playable"] = true @@ -989,10 +989,10 @@ export default class AnimeNotifier { return } - let time = video.currentTime - let minutes = Math.trunc(time / 60) - let seconds = Math.trunc(time) % 60 - let paddedSeconds = ("00" + seconds).slice(-2) + const time = video.currentTime + const minutes = Math.trunc(time / 60) + const seconds = Math.trunc(time) % 60 + const paddedSeconds = ("00" + seconds).slice(-2) Diff.mutations.queue(() => { timeElement.textContent = `${minutes}:${paddedSeconds}` @@ -1019,9 +1019,9 @@ export default class AnimeNotifier { }) progressClickable.addEventListener("click", (e: MouseEvent) => { - let rect = progressClickable.getBoundingClientRect() - let x = e.clientX - let progress = (x - rect.left) / rect.width + const rect = progressClickable.getBoundingClientRect() + const x = e.clientX + const progress = (x - rect.left) / rect.width video.currentTime = progress * video.duration video.dispatchEvent(new Event("timeupdate")) e.stopPropagation() @@ -1032,12 +1032,12 @@ export default class AnimeNotifier { let modified = false - for(let child of video.children) { + for(const child of video.children) { if(child.tagName !== "SOURCE") { continue } - let element = child as HTMLSourceElement + const element = child as HTMLSourceElement if(!element.dataset.src || !element.dataset.type) { console.error("Source element missing data-src or data-type attribute:", element) @@ -1077,7 +1077,7 @@ export default class AnimeNotifier { } unmountMountables() { - for(let element of findAll("mountable")) { + for(const element of findAll("mountable")) { if(element.classList.contains("never-unmount")) { continue } @@ -1091,13 +1091,13 @@ export default class AnimeNotifier { const delay = 20 let time = 0 - let start = Date.now() - let maxTime = start + maxDelay + const start = Date.now() + const maxTime = start + maxDelay - let mountableTypes = new Map() - let mountableTypeMutations = new Map() + const mountableTypes = new Map() + const mountableTypeMutations = new Map() - for(let element of elements) { + for(const element of elements) { // Skip already mounted elements. // This helps a lot when dealing with infinite scrolling // where the first elements are already mounted. @@ -1105,8 +1105,8 @@ export default class AnimeNotifier { continue } - let type = element.dataset.mountableType || "general" - let typeTime = mountableTypes.get(type) + const type = element.dataset.mountableType || "general" + const typeTime = mountableTypes.get(type) if(typeTime !== undefined) { time = typeTime + delay @@ -1132,11 +1132,11 @@ export default class AnimeNotifier { for(const mutations of mountableTypeMutations.values()) { let mutationIndex = 0 - let updateBatch = () => { - let now = Date.now() + const updateBatch = () => { + const now = Date.now() for(; mutationIndex < mutations.length; mutationIndex++) { - let mutation = mutations[mutationIndex] + const mutation = mutations[mutationIndex] if(mutation.time > now) { break @@ -1159,11 +1159,11 @@ export default class AnimeNotifier { return null } - let path = "/_" + url + const path = "/_" + url try { // Start the request - let request = fetch(path, { + const request = fetch(path, { credentials: "same-origin" }) .then(response => response.text()) @@ -1178,7 +1178,7 @@ export default class AnimeNotifier { // Delay by mountable-transition-speed await delay(150) - let html = await request + const html = await request // If the response for the correct path has not arrived yet, show this response if(!this.diffCompletedForCurrentPath) { @@ -1251,22 +1251,22 @@ export default class AnimeNotifier { const contentPadding = 23 let newScroll = 0 - let finalScroll = Math.max(target.getBoundingClientRect().top - contentPadding, 0) + const finalScroll = Math.max(target.getBoundingClientRect().top - contentPadding, 0) // Calculating scrollTop will force a layout - careful! - let contentContainer = this.app.content.parentElement as HTMLElement - let oldScroll = contentContainer.scrollTop - let scrollDistance = finalScroll - oldScroll + const contentContainer = this.app.content.parentElement as HTMLElement + const oldScroll = contentContainer.scrollTop + const scrollDistance = finalScroll - oldScroll if(scrollDistance > 0 && scrollDistance < 1) { return } - let timeStart = Date.now() - let timeEnd = timeStart + duration + const timeStart = Date.now() + const timeEnd = timeStart + duration - let scroll = () => { - let time = Date.now() + const scroll = () => { + const time = Date.now() let progress = (time - timeStart) / duration if(progress > 1.0) { @@ -1322,7 +1322,7 @@ export default class AnimeNotifier { } onKeyDown(e: KeyboardEvent) { - let activeElement = document.activeElement + const activeElement = document.activeElement if(!activeElement) { return @@ -1343,7 +1343,7 @@ export default class AnimeNotifier { } // When called, this will prevent the default action for that key. - let preventDefault = () => { + const preventDefault = () => { e.preventDefault() e.stopPropagation() } @@ -1375,7 +1375,7 @@ export default class AnimeNotifier { // "F" = Search if(e.keyCode === 70) { - let search = document.getElementById("search") as HTMLInputElement + const search = document.getElementById("search") as HTMLInputElement search.focus() search.select() @@ -1429,11 +1429,11 @@ export default class AnimeNotifier { // Number keys activate sidebar menus for(let i = 48; i <= 57; i++) { if(e.keyCode === i) { - let index = i === 48 ? 9 : i - 49 - let links = [...findAll("sidebar-link")] + const index = i === 48 ? 9 : i - 49 + const links = [...findAll("sidebar-link")] if(index < links.length) { - let element = links[index] as HTMLElement + const element = links[index] as HTMLElement element.click() return preventDefault() @@ -1444,7 +1444,7 @@ export default class AnimeNotifier { // This is called every time an uncaught JavaScript error is thrown async onError(evt: ErrorEvent) { - let report = { + const report = { message: evt.message, stack: evt.error.stack, fileName: evt.filename, diff --git a/scripts/AudioPlayer.ts b/scripts/AudioPlayer.ts index 466aa370..3ce2cddf 100644 --- a/scripts/AudioPlayer.ts +++ b/scripts/AudioPlayer.ts @@ -53,7 +53,7 @@ export default class AudioPlayer { } this.playId++ - let currentPlayId = this.playId + const currentPlayId = this.playId if(this.lastRequest) { this.lastRequest.abort() @@ -73,7 +73,7 @@ export default class AudioPlayer { this.audioPlayer.classList.remove("decoded") // Request - let request = new XMLHttpRequest() + const request = new XMLHttpRequest() request.open("GET", trackUrl, true) request.responseType = "arraybuffer" @@ -133,7 +133,7 @@ export default class AudioPlayer { return } - let progress = e.loaded / e.total * 100 + const progress = e.loaded / e.total * 100 this.arn.statusMessage.showInfo(`Loading audio...${progress.toFixed(1)}%`, -1) } @@ -197,9 +197,9 @@ export default class AudioPlayer { this.arn.currentMediaId = "" // Remove CSS class "playing" - let playingElements = document.getElementsByClassName("playing") + const playingElements = document.getElementsByClassName("playing") - for(let playing of playingElements) { + for(const playing of playingElements) { playing.classList.remove("playing") } @@ -238,8 +238,8 @@ export default class AudioPlayer { // Next track async next() { // Get random track - let response = await fetch("/api/next/soundtrack") - let track = await response.json() + const response = await fetch("/api/next/soundtrack") + const track = await response.json() this.play(track.id, "https://notify.moe/audio/" + track.file) // arn.statusMessage.showInfo("Now playing: " + track.title) @@ -293,8 +293,8 @@ export default class AudioPlayer { // Update track info async updateTrackInfo(trackId: string) { // Set track title - let trackInfoResponse = await fetch("/api/soundtrack/" + trackId) - let track = await trackInfoResponse.json() + const trackInfoResponse = await fetch("/api/soundtrack/" + trackId) + const track = await trackInfoResponse.json() this.trackLink.href = "/soundtrack/" + track.id this.trackLink.textContent = track.title.canonical || track.title.native @@ -305,7 +305,7 @@ export default class AudioPlayer { return } - for(let tag of (track.tags as string[])) { + for(const tag of (track.tags as string[])) { if(tag.startsWith("anime:")) { animeId = tag.split(":")[1] break @@ -318,8 +318,8 @@ export default class AudioPlayer { // Set anime info this.animeInfo.classList.remove("hidden") - let animeResponse = await fetch("/api/anime/" + animeId) - let anime = await animeResponse.json() as Anime + const animeResponse = await fetch("/api/anime/" + animeId) + const anime = await animeResponse.json() as Anime this.animeLink.title = anime.title.canonical this.animeLink.href = "/anime/" + anime.id this.animeImage.dataset.src = "//media.notify.moe/images/anime/medium/" + anime.id + ".jpg?" + anime.image.lastModified.toString() diff --git a/scripts/DateView.ts b/scripts/DateView.ts index d769b4d4..845ea42d 100644 --- a/scripts/DateView.ts +++ b/scripts/DateView.ts @@ -8,14 +8,14 @@ const oneWeek = 7 * oneDay const oneMonth = 30 * oneDay const oneYear = 365.25 * oneDay -export var monthNames = [ +export let monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] -export var dayNames = [ +export let dayNames = [ "Sunday", "Monday", "Tuesday", @@ -26,7 +26,7 @@ export var dayNames = [ ] function getRemainingTime(remaining: number): string { - let remainingAbs = Math.abs(remaining) + const remainingAbs = Math.abs(remaining) if(remainingAbs >= oneYear) { return plural(Math.round(remaining / oneYear), "year") @@ -65,20 +65,20 @@ export function displayAiringDate(element: HTMLElement, now: Date) { return } - let startDate = new Date(element.dataset.startDate) - let endDate = new Date(element.dataset.endDate) + const startDate = new Date(element.dataset.startDate) + const endDate = new Date(element.dataset.endDate) let h = startDate.getHours() let m = startDate.getMinutes() - let startTime = (h <= 9 ? "0" + h : h) + ":" + (m <= 9 ? "0" + m : m) + const startTime = (h <= 9 ? "0" + h : h) + ":" + (m <= 9 ? "0" + m : m) h = endDate.getHours() m = endDate.getMinutes() - let endTime = (h <= 9 ? "0" + h : h) + ":" + (m <= 9 ? "0" + m : m) + const endTime = (h <= 9 ? "0" + h : h) + ":" + (m <= 9 ? "0" + m : m) let airingVerb = "will be airing" - let remaining = startDate.getTime() - now.getTime() + const remaining = startDate.getTime() - now.getTime() let remainingString = getRemainingTime(remaining) // Add "ago" if the date is in the past @@ -92,7 +92,7 @@ export function displayAiringDate(element: HTMLElement, now: Date) { airingVerb = "aired" } - let tooltip = "Episode " + element.dataset.episodeNumber + " " + airingVerb + " " + dayNames[startDate.getDay()] + " from " + startTime + " - " + endTime + const tooltip = "Episode " + element.dataset.episodeNumber + " " + airingVerb + " " + dayNames[startDate.getDay()] + " from " + startTime + " - " + endTime if(element.classList.contains("no-tip")) { element.title = tooltip @@ -108,13 +108,13 @@ export function displayDate(element: HTMLElement, now: Date) { return } - let startDate = new Date(element.dataset.date) + const startDate = new Date(element.dataset.date) - let h = startDate.getHours() - let m = startDate.getMinutes() - let startTime = (h <= 9 ? "0" + h : h) + ":" + (m <= 9 ? "0" + m : m) + const h = startDate.getHours() + const m = startDate.getMinutes() + const startTime = (h <= 9 ? "0" + h : h) + ":" + (m <= 9 ? "0" + m : m) - let remaining = startDate.getTime() - now.getTime() + const remaining = startDate.getTime() - now.getTime() let remainingString = getRemainingTime(remaining) // Add "ago" if the date is in the past @@ -123,7 +123,7 @@ export function displayDate(element: HTMLElement, now: Date) { } element.textContent = remainingString - let tooltip = dayNames[startDate.getDay()] + " " + startTime + const tooltip = dayNames[startDate.getDay()] + " " + startTime if(element.classList.contains("no-tip")) { element.title = tooltip @@ -139,11 +139,11 @@ export function displayTime(element: HTMLElement) { return } - let startDate = new Date(element.dataset.date) + const startDate = new Date(element.dataset.date) - let h = startDate.getHours() - let m = startDate.getMinutes() - let startTime = (h <= 9 ? "0" + h : h) + ":" + (m <= 9 ? "0" + m : m) + const h = startDate.getHours() + const m = startDate.getMinutes() + const startTime = (h <= 9 ? "0" + h : h) + ":" + (m <= 9 ? "0" + m : m) element.textContent = startTime } \ No newline at end of file diff --git a/scripts/Diff.ts b/scripts/Diff.ts index e3ca65ee..44ef8680 100644 --- a/scripts/Diff.ts +++ b/scripts/Diff.ts @@ -18,7 +18,7 @@ export default class Diff { // innerHTML will diff the element with the given HTML string and apply DOM mutations. static innerHTML(aRoot: HTMLElement, html: string): Promise { - let container = document.createElement("main") + const container = document.createElement("main") container.innerHTML = html return new Promise((resolve, _) => { @@ -30,7 +30,7 @@ export default class Diff { // root will diff the document root element with the given HTML string and apply DOM mutations. static root(aRoot: HTMLElement, html: string) { return new Promise((resolve, _) => { - let rootContainer = document.createElement("html") + const rootContainer = document.createElement("html") rootContainer.innerHTML = html.replace("", "") Diff.childNodes(aRoot.getElementsByTagName("body")[0], rootContainer.getElementsByTagName("body")[0]) @@ -40,12 +40,12 @@ export default class Diff { // childNodes diffs the child nodes of 2 given elements and applies DOM mutations. static childNodes(aRoot: Node, bRoot: Node) { - let aChild = [...aRoot.childNodes] - let bChild = [...bRoot.childNodes] - let numNodes = Math.max(aChild.length, bChild.length) + const aChild = [...aRoot.childNodes] + const bChild = [...bRoot.childNodes] + const numNodes = Math.max(aChild.length, bChild.length) for(let i = 0; i < numNodes; i++) { - let a = aChild[i] + const a = aChild[i] // Remove nodes at the end of a that do not exist in b if(i >= bChild.length) { @@ -53,7 +53,7 @@ export default class Diff { continue } - let b = bChild[i] + const b = bChild[i] // If a doesn't have that many nodes, simply append at the end of a if(i >= aChild.length) { @@ -77,13 +77,13 @@ export default class Diff { // HTML element: if(a.nodeType === Node.ELEMENT_NODE) { - let elemA = a as HTMLElement - let elemB = b as HTMLElement + const elemA = a as HTMLElement + const elemB = b as HTMLElement - let removeAttributes: Attr[] = [] + const removeAttributes: Attr[] = [] for(let x = 0; x < elemA.attributes.length; x++) { - let attrib = elemA.attributes[x] + const attrib = elemA.attributes[x] if(attrib.specified) { if(!elemB.hasAttribute(attrib.name) && !Diff.persistentAttributes.has(attrib.name)) { @@ -93,13 +93,13 @@ export default class Diff { } this.mutations.queue(() => { - for(let attr of removeAttributes) { + for(const attr of removeAttributes) { elemA.removeAttributeNode(attr) } }) for(let x = 0; x < elemB.attributes.length; x++) { - let attrib = elemB.attributes[x] + const attrib = elemB.attributes[x] if(!attrib.specified) { continue @@ -111,22 +111,22 @@ export default class Diff { } if(attrib.name === "class") { - let classesA = elemA.classList - let classesB = elemB.classList - let removeClasses: string[] = [] + const classesA = elemA.classList + const classesB = elemB.classList + const removeClasses: string[] = [] - for(let className of classesA) { + for(const className of classesA) { if(!classesB.contains(className) && !Diff.persistentClasses.has(className)) { removeClasses.push(className) } } this.mutations.queue(() => { - for(let className of removeClasses) { + for(const className of removeClasses) { classesA.remove(className) } - for(let className of classesB) { + for(const className of classesB) { if(!classesA.contains(className)) { classesA.add(className) } diff --git a/scripts/Elements/svg-icon/svg-icon.ts b/scripts/Elements/svg-icon/svg-icon.ts index 05a18f19..539ff9e1 100644 --- a/scripts/Elements/svg-icon/svg-icon.ts +++ b/scripts/Elements/svg-icon/svg-icon.ts @@ -14,10 +14,10 @@ export default class SVGIcon extends HTMLElement { } async render() { - let cache = SVGIcon.cache.get(this.name) + const cache = SVGIcon.cache.get(this.name) if(cache) { - let svg = await cache + const svg = await cache Diff.mutations.queue(() => { // Remove all existing child nodes @@ -33,8 +33,8 @@ export default class SVGIcon extends HTMLElement { } SVGIcon.cache.set(this.name, new Promise(async (resolve, reject) => { - let url = `//media.notify.moe/images/icons/${this.name}.svg` - let response = await fetch(url) + const url = `//media.notify.moe/images/icons/${this.name}.svg` + const response = await fetch(url) if(!response.ok) { console.warn(`Failed loading SVG icon: ${url}`) @@ -42,11 +42,11 @@ export default class SVGIcon extends HTMLElement { return } - let text = await response.text() + const text = await response.text() Diff.mutations.queue(() => { this.innerHTML = text - let svg = this.firstChild + const svg = this.firstChild if(!svg) { console.warn("Invalid SVG icon:", svg) diff --git a/scripts/Elements/tool-tip/tool-tip.ts b/scripts/Elements/tool-tip/tool-tip.ts index d7467e3d..cc9ee041 100644 --- a/scripts/Elements/tool-tip/tool-tip.ts +++ b/scripts/Elements/tool-tip/tool-tip.ts @@ -25,13 +25,13 @@ export default class ToolTip extends HTMLElement { this.anchor = anchor this.box.textContent = this.anchor.getAttribute("aria-label") - let anchorRect = this.anchor.getBoundingClientRect() - let boxRect = this.box.getBoundingClientRect() + const anchorRect = this.anchor.getBoundingClientRect() + const boxRect = this.box.getBoundingClientRect() let finalX = anchorRect.left + anchorRect.width / 2 - boxRect.width / 2 let finalY = anchorRect.top - boxRect.height - let contentRect = { + const contentRect = { left: distanceToBorder, top: distanceToBorder, right: document.body.clientWidth - distanceToBorder, @@ -54,7 +54,7 @@ export default class ToolTip extends HTMLElement { finalY += offsetY } - let arrowX = boxRect.width / 2 - offsetX + const arrowX = boxRect.width / 2 - offsetX Diff.mutations.queue(() => { this.style.left = finalX + "px" diff --git a/scripts/InfiniteScroller.ts b/scripts/InfiniteScroller.ts index c1c68dcf..61c8d21f 100644 --- a/scripts/InfiniteScroller.ts +++ b/scripts/InfiniteScroller.ts @@ -8,7 +8,7 @@ export default class InfiniteScroller { this.container = container this.threshold = threshold - let check = () => { + const check = () => { if(this.container.scrollTop + this.container.clientHeight >= this.container.scrollHeight - threshold) { this.loadMore() } @@ -28,7 +28,7 @@ export default class InfiniteScroller { } loadMore() { - let button = document.getElementById("load-more-button") + const button = document.getElementById("load-more-button") if(!button) { return diff --git a/scripts/MutationQueue.ts b/scripts/MutationQueue.ts index e0c14d7f..79cbcccc 100644 --- a/scripts/MutationQueue.ts +++ b/scripts/MutationQueue.ts @@ -26,7 +26,7 @@ export default class MutationQueue { } mutateAll() { - let start = performance.now() + const start = performance.now() for(let i = 0; i < this.mutations.length; i++) { if(performance.now() - start > timeCapacity) { @@ -49,7 +49,7 @@ export default class MutationQueue { this.mutations.length = 0 if(this.onClearCallBacks.length > 0) { - for(let callback of this.onClearCallBacks) { + for(const callback of this.onClearCallBacks) { callback() } diff --git a/scripts/NotificationManager.ts b/scripts/NotificationManager.ts index 5cae3f99..15ec7173 100644 --- a/scripts/NotificationManager.ts +++ b/scripts/NotificationManager.ts @@ -11,11 +11,11 @@ export default class NotificationManager { } async update() { - let response = await fetch("/api/count/notifications/unseen", { + const response = await fetch("/api/count/notifications/unseen", { credentials: "same-origin" }) - let body = await response.text() + const body = await response.text() this.setCounter(parseInt(body)) } diff --git a/scripts/PushManager.ts b/scripts/PushManager.ts index 56c9bc21..383ea44d 100644 --- a/scripts/PushManager.ts +++ b/scripts/PushManager.ts @@ -10,8 +10,8 @@ export default class PushManager { return Promise.resolve(null) } - let registration = await navigator.serviceWorker.ready - let subscription = await registration.pushManager.getSubscription() + const registration = await navigator.serviceWorker.ready + const subscription = await registration.pushManager.getSubscription() return Promise.resolve(subscription) } @@ -21,7 +21,7 @@ export default class PushManager { return } - let registration = await navigator.serviceWorker.ready + const registration = await navigator.serviceWorker.ready let subscription = await registration.pushManager.getSubscription() if(!subscription) { @@ -41,8 +41,8 @@ export default class PushManager { return } - let registration = await navigator.serviceWorker.ready - let subscription = await registration.pushManager.getSubscription() + const registration = await navigator.serviceWorker.ready + const subscription = await registration.pushManager.getSubscription() if(!subscription) { console.error("Subscription does not exist") @@ -57,15 +57,15 @@ export default class PushManager { subscribeOnServer(subscription: PushSubscription, userId: string) { console.log("Send subscription to server...") - let rawKey = subscription.getKey("p256dh") - let key = rawKey ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) : "" + const rawKey = subscription.getKey("p256dh") + const key = rawKey ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) : "" - let rawSecret = subscription.getKey("auth") - let secret = rawSecret ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawSecret))) : "" + const rawSecret = subscription.getKey("auth") + const secret = rawSecret ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawSecret))) : "" - let endpoint = subscription.endpoint + const endpoint = subscription.endpoint - let pushSubscription = { + const pushSubscription = { endpoint, p256dh: key, auth: secret, @@ -88,7 +88,7 @@ export default class PushManager { console.log("Send unsubscription to server...") console.log(subscription) - let pushSubscription = { + const pushSubscription = { endpoint: subscription.endpoint } diff --git a/scripts/ServerEvents.ts b/scripts/ServerEvents.ts index c3e40237..a04e48f7 100644 --- a/scripts/ServerEvents.ts +++ b/scripts/ServerEvents.ts @@ -49,9 +49,9 @@ export default class ServerEvents { } etag(e: ServerEvent) { - let data = JSON.parse(e.data) - let oldETag = this.etags.get(data.url) - let newETag = data.etag + const data = JSON.parse(e.data) + const oldETag = this.etags.get(data.url) + const newETag = data.etag if(oldETag && newETag && oldETag != newETag) { this.arn.statusMessage.showInfo("A new version of the website is available. Please refresh the page.", -1) @@ -65,7 +65,7 @@ export default class ServerEvents { return } - let isFollowingUser = JSON.parse(e.data) + const isFollowingUser = JSON.parse(e.data) // If we're on the followed only feed and we receive an activity // about a user we don't follow, ignore the message. @@ -73,19 +73,19 @@ export default class ServerEvents { return } - let button = document.getElementById("load-new-activities") + const button = document.getElementById("load-new-activities") if(!button || !button.dataset.count) { return } - let buttonText = document.getElementById("load-new-activities-text") + const buttonText = document.getElementById("load-new-activities-text") if(!buttonText) { return } - let newCount = parseInt(button.dataset.count) + 1 + const newCount = parseInt(button.dataset.count) + 1 button.dataset.count = newCount.toString() buttonText.textContent = plural(newCount, "new activity") } diff --git a/scripts/ServiceWorker/ServiceWorker.ts b/scripts/ServiceWorker/ServiceWorker.ts index 748334d2..3746b324 100644 --- a/scripts/ServiceWorker/ServiceWorker.ts +++ b/scripts/ServiceWorker/ServiceWorker.ts @@ -47,7 +47,7 @@ class MyCache { async store(request: RequestInfo, response: Response) { try { // This can fail if the disk space quota has been exceeded. - let cache = await caches.open(this.version) + const cache = await caches.open(this.version) await cache.put(request, response) } catch(err) { console.log("Disk quota exceeded, can't store in cache:", request, response, err) @@ -55,8 +55,8 @@ class MyCache { } async serve(request: RequestInfo): Promise { - let cache = await caches.open(this.version) - let matching = await cache.match(request) + const cache = await caches.open(this.version) + const matching = await cache.match(request) if(matching) { return matching @@ -100,12 +100,12 @@ function onActivate(_: any) { console.log("service worker activate") // Only keep current version of the cache and delete old caches - let cacheWhitelist = [cache.version] + const cacheWhitelist = [cache.version] // Query existing cache keys - let deleteOldCache = caches.keys().then(keyList => { + const deleteOldCache = caches.keys().then(keyList => { // Create a deletion for every key that's not whitelisted - let deletions = keyList.map(key => { + const deletions = keyList.map(key => { if(cacheWhitelist.indexOf(key) === -1) { return caches.delete(key) } @@ -118,7 +118,7 @@ function onActivate(_: any) { }) // Immediate claim helps us gain control over a new client immediately - let immediateClaim = self.clients.claim() + const immediateClaim = self.clients.claim() return Promise.all([ deleteOldCache, @@ -130,7 +130,7 @@ function onActivate(_: any) { // Simply returning, without calling evt.respondWith(), // will let the browser deal with the request normally. async function onRequest(evt: FetchEvent) { - let request = evt.request as Request + const request = evt.request as Request // If it's not a GET request, fetch it normally. // Let the browser handle XHR upload requests via POST, @@ -248,16 +248,16 @@ async function onRequest(evt: FetchEvent) { // onMessage is called when the service worker receives a message from a client (browser tab). async function onMessage(evt: ServiceWorkerMessageEvent) { - let message = JSON.parse(evt.data) - let clientId = (evt.source as any).id - let client = await MyClient.get(clientId) + const message = JSON.parse(evt.data) + const clientId = (evt.source as any).id + const client = await MyClient.get(clientId) client.onMessage(message) } // onPush is called on push events and requires the payload to contain JSON information about the notification. function onPush(evt: PushEvent) { - var payload = evt.data ? evt.data.json() : {} + const payload = evt.data ? evt.data.json() : {} // Notify all clients about the new notification so they can update their notification counter broadcast({ @@ -278,15 +278,15 @@ function onPushSubscriptionChange(evt: any) { .then(async subscription => { console.log("send subscription to server...") - let rawKey = subscription.getKey("p256dh") - let key = rawKey ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) : "" + const rawKey = subscription.getKey("p256dh") + const key = rawKey ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) : "" - let rawSecret = subscription.getKey("auth") - let secret = rawSecret ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawSecret))) : "" + const rawSecret = subscription.getKey("auth") + const secret = rawSecret ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawSecret))) : "" - let endpoint = subscription.endpoint + const endpoint = subscription.endpoint - let pushSubscription = { + const pushSubscription = { endpoint, p256dh: key, auth: secret, @@ -298,8 +298,8 @@ function onPushSubscriptionChange(evt: any) { } } - let response = await fetch("/api/me", {credentials: "same-origin"}) - let user = await response.json() + const response = await fetch("/api/me", {credentials: "same-origin"}) + const user = await response.json() return fetch("/api/pushsubscriptions/" + user.id + "/add", { method: "POST", @@ -311,12 +311,12 @@ function onPushSubscriptionChange(evt: any) { // onNotificationClick is called when the user clicks on a notification. function onNotificationClick(evt: NotificationEvent) { - let notification = evt.notification + const notification = evt.notification notification.close() return self.clients.matchAll().then(function(clientList) { // If we have a link, use that link to open a new window. - let url = notification.data + const url = notification.data if(url) { return self.clients.openWindow(url) @@ -337,7 +337,7 @@ function broadcast(msg: object) { const msgText = JSON.stringify(msg) self.clients.matchAll().then(function(clientList) { - for(let client of clientList) { + for(const client of clientList) { client.postMessage(msgText) } }) @@ -345,7 +345,7 @@ function broadcast(msg: object) { // installCache is called when the service worker is installed for the first time. function installCache() { - let urls = [ + const urls = [ "/", "/scripts", "/styles", @@ -353,8 +353,8 @@ function installCache() { "https://media.notify.moe/images/elements/noise-strong.png", ] - let requests = urls.map(async url => { - let request = new Request(url, { + const requests = urls.map(async url => { + const request = new Request(url, { credentials: "same-origin", mode: "cors" }) diff --git a/scripts/ServiceWorkerManager.ts b/scripts/ServiceWorkerManager.ts index bf777c87..5d7184a7 100644 --- a/scripts/ServiceWorkerManager.ts +++ b/scripts/ServiceWorkerManager.ts @@ -22,7 +22,7 @@ export default class ServiceWorkerManager { }) // This will send a message to the service worker that the DOM has been loaded - let sendContentLoadedEvent = () => { + const sendContentLoadedEvent = () => { if(!navigator.serviceWorker.controller) { return } @@ -71,7 +71,7 @@ export default class ServiceWorkerManager { } onMessage(evt: MessageEvent) { - let message = JSON.parse(evt.data) + const message = JSON.parse(evt.data) switch(message.type) { case "new notification": diff --git a/scripts/SideBar.ts b/scripts/SideBar.ts index db1fd050..7fb6df80 100644 --- a/scripts/SideBar.ts +++ b/scripts/SideBar.ts @@ -30,7 +30,7 @@ export default class SideBar { } toggle() { - let visible = this.element.style.display !== "none" + const visible = this.element.style.display !== "none" if(visible) { this.element.style.display = "none" diff --git a/scripts/Utils/findAll.ts b/scripts/Utils/findAll.ts index 3f1196e1..79b21b79 100644 --- a/scripts/Utils/findAll.ts +++ b/scripts/Utils/findAll.ts @@ -1,5 +1,5 @@ export function* findAll(className: string): IterableIterator { - let elements = document.getElementsByClassName(className) + const elements = document.getElementsByClassName(className) for(let i = 0; i < elements.length; ++i) { yield elements[i] as HTMLElement @@ -7,7 +7,7 @@ export function* findAll(className: string): IterableIterator { } export function* findAllInside(className: string, root: HTMLElement): IterableIterator { - let elements = root.getElementsByClassName(className) + const elements = root.getElementsByClassName(className) for(let i = 0; i < elements.length; ++i) { yield elements[i] as HTMLElement diff --git a/scripts/Utils/hexToHSL.ts b/scripts/Utils/hexToHSL.ts index 88e46b81..4ddabd74 100644 --- a/scripts/Utils/hexToHSL.ts +++ b/scripts/Utils/hexToHSL.ts @@ -1,5 +1,5 @@ export function hexToHSL(hex: string) { - let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) if(!result) { return null @@ -13,17 +13,17 @@ export function hexToHSL(hex: string) { g /= 255 b /= 255 - let max = Math.max(r, g, b) - let min = Math.min(r, g, b) + const max = Math.max(r, g, b) + const min = Math.min(r, g, b) let h = 0 let s = 0 - let l = (max + min) / 2 + const l = (max + min) / 2 if(max == min) { h = s = 0 } else { - let d = max - min + const d = max - min s = l > 0.5 ? d / (2 - max - min) : d / (max + min) switch(max) { diff --git a/scripts/Utils/swapElements.ts b/scripts/Utils/swapElements.ts index dcfc8113..ccaefe71 100644 --- a/scripts/Utils/swapElements.ts +++ b/scripts/Utils/swapElements.ts @@ -1,7 +1,7 @@ // swapElements assumes that both elements have valid parent nodes. export function swapElements(a: Node, b: Node) { - let bParent = b.parentNode as Node - let bNext = b.nextSibling + const bParent = b.parentNode as Node + const bNext = b.nextSibling // Special case for when a is the next sibling of b if(bNext === a) { diff --git a/scripts/Utils/uploadWithProgress.ts b/scripts/Utils/uploadWithProgress.ts index 22d32052..27e07381 100644 --- a/scripts/Utils/uploadWithProgress.ts +++ b/scripts/Utils/uploadWithProgress.ts @@ -1,6 +1,6 @@ export function uploadWithProgress(url, options: RequestInit, onProgress: ((ev: ProgressEvent) => any) | null): Promise { return new Promise((resolve, reject) => { - let xhr = new XMLHttpRequest() + const xhr = new XMLHttpRequest() xhr.onload = () => { if(xhr.status >= 400) { @@ -21,7 +21,7 @@ export function uploadWithProgress(url, options: RequestInit, onProgress: ((ev: xhr.open(options.method || "GET", url, true) if(options.headers) { - for(let key in options.headers) { + for(const key in options.headers) { xhr.setRequestHeader(key, options.headers[key]) } } diff --git a/tslint.json b/tslint.json index 5da094d7..a9121ecb 100644 --- a/tslint.json +++ b/tslint.json @@ -9,7 +9,9 @@ "indent": [true, "tabs", 4], "whitespace": false, "arrow-parens": false, - "trailing-comma": false + "trailing-comma": false, + "prefer-const": true, + "no-var-keyword": true }, "rulesDirectory": [] }