diff --git a/.eslintrc b/.eslintrc index 18d8730..8089947 100644 --- a/.eslintrc +++ b/.eslintrc @@ -28,12 +28,6 @@ "never" ], "simple-import-sort/imports": "error", - "simple-import-sort/exports": "error", - "prettier/prettier": [ - "error", - { - "semi": false - } - ] + "simple-import-sort/exports": "error" } } \ No newline at end of file diff --git a/src/Archive/Redirect.js b/src/Archive/Redirect.js index 9af2ff6..e496918 100644 --- a/src/Archive/Redirect.js +++ b/src/Archive/Redirect.js @@ -10,7 +10,7 @@ import archives from './archives.json' * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Redirect = { +const Redirect = { archives, init() { diff --git a/src/Filtering/Filter.ts b/src/Filtering/Filter.ts index 54771d0..32ccb7d 100644 --- a/src/Filtering/Filter.ts +++ b/src/Filtering/Filter.ts @@ -4,7 +4,7 @@ import type Post from '../classes/Post' import Config from '../config/Config' import Get from '../General/Get' import Settings from '../General/Settings' -import { Conf, doc,g } from '../globals/globals' +import { Conf, doc, g } from '../globals/globals' import Menu from '../Menu/Menu' import Unread from '../Monitoring/Unread' import $ from '../platform/$' @@ -52,7 +52,7 @@ type FilterType = | 'filesize' | 'MD5' -var Filter = { +const Filter = { /** * Uses a Map for string types, with the value to filter for as the key. * This allows faster lookup than iterating over every filter. @@ -183,7 +183,7 @@ var Filter = { if (!this.filters.size) return // conversion from array to map for string types - for (const type of ['MD5', 'uniqueID'] satisfies FilterType[]) { + for (const type of ['MD5', 'uniqueID']satisfies FilterType[]) { const filtersForType = this.filters.get(type) if (!filtersForType) continue @@ -352,10 +352,9 @@ var Filter = { if (![200, 404].includes(this.status)) { new Notice( 'warning', - `Failed to fetch catalog JSON data. ${ - this.status - ? `Error ${this.statusText} (${this.status})` - : 'Connection Error' + `Failed to fetch catalog JSON data. ${this.status + ? `Error ${this.statusText} (${this.status})` + : 'Connection Error' }`, 1 ) @@ -659,7 +658,7 @@ var Filter = { ['Image dimensions', 'dimensions'], ['Filesize', 'filesize'], ['Image MD5', 'MD5'], - ] satisfies [string, FilterType][]) { + ]satisfies[string, FilterType][]) { // Add a sub entry for each filter type. entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1])) } diff --git a/src/Filtering/PostHiding.js b/src/Filtering/PostHiding.js index 3af923c..cd782e8 100644 --- a/src/Filtering/PostHiding.js +++ b/src/Filtering/PostHiding.js @@ -13,7 +13,7 @@ import Recursive from './Recursive' * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var PostHiding = { +const PostHiding = { init() { if ( !['index', 'thread'].includes(g.VIEW) || diff --git a/src/Filtering/Recursive.js b/src/Filtering/Recursive.js index 40ec47f..7831828 100644 --- a/src/Filtering/Recursive.js +++ b/src/Filtering/Recursive.js @@ -8,7 +8,7 @@ import { dict } from '../platform/helpers' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Recursive = { +const Recursive = { recursives: dict(), init() { if (!['index', 'thread'].includes(g.VIEW)) { diff --git a/src/Filtering/ThreadHiding.js b/src/Filtering/ThreadHiding.js index f4bf39c..458b1cd 100644 --- a/src/Filtering/ThreadHiding.js +++ b/src/Filtering/ThreadHiding.js @@ -10,7 +10,7 @@ import $ from '../platform/$' import $$ from '../platform/$$' import { dict } from '../platform/helpers' -var ThreadHiding = { +const ThreadHiding = { init() { if ( !['index', 'catalog'].includes(g.VIEW) || diff --git a/src/Images/FappeTyme.js b/src/Images/FappeTyme.js index 707bbaf..93d6f6f 100644 --- a/src/Images/FappeTyme.js +++ b/src/Images/FappeTyme.js @@ -9,7 +9,7 @@ import $ from '../platform/$' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var FappeTyme = { +const FappeTyme = { init() { if ( (!Conf['Fappe Tyme'] && !Conf['Werk Tyme']) || diff --git a/src/Images/Gallery.js b/src/Images/Gallery.js index 530a7b0..e7b2cb0 100644 --- a/src/Images/Gallery.js +++ b/src/Images/Gallery.js @@ -21,7 +21,7 @@ import ImageCommon from './ImageCommon' import Sauce from './Sauce' import Volume from './Volume' -var Gallery = { +const Gallery = { init() { if ( !(this.enabled = Conf['Gallery'] && ['index', 'thread'].includes(g.VIEW)) diff --git a/src/Images/ImageCommon.js b/src/Images/ImageCommon.js index 379f916..38a02c4 100644 --- a/src/Images/ImageCommon.js +++ b/src/Images/ImageCommon.js @@ -14,7 +14,7 @@ import Volume from './Volume' * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var ImageCommon = { +const ImageCommon = { // Pause and mute video in preparation for removing the element from the document. pause(video) { if (video.nodeName !== 'VIDEO') { diff --git a/src/Images/ImageExpand.js b/src/Images/ImageExpand.js index 2b5889d..8097706 100644 --- a/src/Images/ImageExpand.js +++ b/src/Images/ImageExpand.js @@ -16,7 +16,7 @@ import Volume from './Volume' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var ImageExpand = { +const ImageExpand = { init() { if ( !(this.enabled = diff --git a/src/Images/ImageHost.js b/src/Images/ImageHost.js index 8f7fcc1..b107266 100644 --- a/src/Images/ImageHost.js +++ b/src/Images/ImageHost.js @@ -7,7 +7,7 @@ import $$ from '../platform/$$' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var ImageHost = { +const ImageHost = { init() { if ( !(this.useFaster = /\S/.test(Conf['fourchanImageHost'])) || diff --git a/src/Images/ImageHover.js b/src/Images/ImageHover.js index 70135e6..5ca984d 100644 --- a/src/Images/ImageHover.js +++ b/src/Images/ImageHover.js @@ -13,7 +13,7 @@ import Volume from './Volume' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var ImageHover = { +const ImageHover = { init() { if (!['index', 'thread'].includes(g.VIEW)) { return diff --git a/src/Images/ImageLoader.js b/src/Images/ImageLoader.js index 88ddea4..3775a13 100644 --- a/src/Images/ImageLoader.js +++ b/src/Images/ImageLoader.js @@ -9,7 +9,7 @@ import $ from '../platform/$' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var ImageLoader = { +const ImageLoader = { init() { if (!['index', 'thread', 'archive'].includes(g.VIEW)) { return diff --git a/src/Images/Metadata.js b/src/Images/Metadata.js index 35472bf..4ffa429 100644 --- a/src/Images/Metadata.js +++ b/src/Images/Metadata.js @@ -10,7 +10,7 @@ import CrossOrigin from '../platform/CrossOrigin' * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Metadata = { +const Metadata = { init() { if (!Conf['WEBM Metadata'] || !['index', 'thread'].includes(g.VIEW)) { return diff --git a/src/Images/Sauce.js b/src/Images/Sauce.js index 131bcb6..68016f2 100644 --- a/src/Images/Sauce.js +++ b/src/Images/Sauce.js @@ -13,7 +13,7 @@ import { dict } from '../platform/helpers' * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Sauce = { +const Sauce = { init() { let link if (!['index', 'thread'].includes(g.VIEW) || !Conf['Sauce']) { diff --git a/src/Images/Volume.js b/src/Images/Volume.js index 3bce85b..d573e10 100644 --- a/src/Images/Volume.js +++ b/src/Images/Volume.js @@ -10,7 +10,7 @@ import $ from '../platform/$' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Volume = { +const Volume = { init() { if ( !['index', 'thread'].includes(g.VIEW) || diff --git a/src/Linkification/Embedding.js b/src/Linkification/Embedding.js index 2288941..568c279 100644 --- a/src/Linkification/Embedding.js +++ b/src/Linkification/Embedding.js @@ -18,7 +18,7 @@ import EmbeddingPage from './Embedding/Embed.html' * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Embedding = { +const Embedding = { init() { if ( !['index', 'thread', 'archive'].includes(g.VIEW) || diff --git a/src/Linkification/Linkify.js b/src/Linkification/Linkify.js index 1cc40dc..ca57da8 100644 --- a/src/Linkification/Linkify.js +++ b/src/Linkification/Linkify.js @@ -12,7 +12,7 @@ import Embedding from './Embedding' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Linkify = { +const Linkify = { init() { if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Linkify']) { return diff --git a/src/Menu/DeleteLink.js b/src/Menu/DeleteLink.js index 38db89e..13a89ac 100644 --- a/src/Menu/DeleteLink.js +++ b/src/Menu/DeleteLink.js @@ -10,7 +10,7 @@ import Menu from './Menu' * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var DeleteLink = { +const DeleteLink = { auto: [dict(), dict()], init() { diff --git a/src/Menu/Menu.ts b/src/Menu/Menu.ts index ef6c55f..2059f73 100644 --- a/src/Menu/Menu.ts +++ b/src/Menu/Menu.ts @@ -1,10 +1,10 @@ import Callbacks from '../classes/Callbacks' import Post from '../classes/Post' import UI from '../General/UI' -import { Conf,g } from '../globals/globals' +import { Conf, g } from '../globals/globals' import $ from '../platform/$' -var Menu: any = { +const Menu: any = { init(): VoidFunction { if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu']) { return diff --git a/src/Monitoring/Favicon.js b/src/Monitoring/Favicon.js index 43443fb..21a8ee1 100644 --- a/src/Monitoring/Favicon.js +++ b/src/Monitoring/Favicon.js @@ -46,7 +46,7 @@ import xat_unreadSFWY from './Favicon/xat-.unreadSFWY.png' * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Favicon = { +const Favicon = { init() { return $.asap( () => d.head && (Favicon.el = $('link[rel="shortcut icon"]', d.head)), diff --git a/src/Monitoring/MarkNewIPs.js b/src/Monitoring/MarkNewIPs.js index 104c91b..05b9a3f 100644 --- a/src/Monitoring/MarkNewIPs.js +++ b/src/Monitoring/MarkNewIPs.js @@ -2,7 +2,7 @@ import Callbacks from '../classes/Callbacks' import { Conf, d, g } from '../globals/globals' import $ from '../platform/$' -var MarkNewIPs = { +const MarkNewIPs = { init() { if ( g.SITE.software !== 'yotsuba' || diff --git a/src/Monitoring/ReplyPruning.js b/src/Monitoring/ReplyPruning.js index 5ceec05..3cfde1e 100644 --- a/src/Monitoring/ReplyPruning.js +++ b/src/Monitoring/ReplyPruning.js @@ -5,7 +5,7 @@ import { Conf, d,E, g } from '../globals/globals' import $ from '../platform/$' import QuoteThreading from '../Quotelinks/QuoteThreading' -var ReplyPruning = { +const ReplyPruning = { init() { if (g.VIEW !== 'thread' || !Conf['Reply Pruning']) { return diff --git a/src/Monitoring/ThreadStats.js b/src/Monitoring/ThreadStats.js index 44804fa..10d5c1e 100644 --- a/src/Monitoring/ThreadStats.js +++ b/src/Monitoring/ThreadStats.js @@ -10,7 +10,7 @@ import { MINUTE, SECOND } from '../platform/helpers' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var ThreadStats = { +const ThreadStats = { postCount: 0, fileCount: 0, postIndex: 0, diff --git a/src/Monitoring/ThreadUpdater.js b/src/Monitoring/ThreadUpdater.js index 02a9eed..3b978d6 100644 --- a/src/Monitoring/ThreadUpdater.js +++ b/src/Monitoring/ThreadUpdater.js @@ -21,7 +21,7 @@ import Unread from './Unread' * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var ThreadUpdater = { +const ThreadUpdater = { init() { let el, name, sc if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { diff --git a/src/Monitoring/ThreadWatcher.ts b/src/Monitoring/ThreadWatcher.ts index f3c82ae..aab3233 100644 --- a/src/Monitoring/ThreadWatcher.ts +++ b/src/Monitoring/ThreadWatcher.ts @@ -21,7 +21,7 @@ import ThreadWatcherPage from './ThreadWatcher/ThreadWatcher.html' import Unread from './Unread' import UnreadIndex from './UnreadIndex' -var ThreadWatcher = { +const ThreadWatcher = { db: null as DataBoard, dbLM: null as DataBoard, dialog: null as HTMLDivElement, @@ -289,7 +289,7 @@ var ThreadWatcher = { } else if (Conf['Auto Watch Reply']) { return ThreadWatcher.add( g.threads.get(boardID + '.' + threadID) || - new Thread(threadID + '', boardID), + new Thread(threadID + '', boardID), cb ) } @@ -417,7 +417,7 @@ var ThreadWatcher = { const { db } = ThreadWatcher const interval = Conf['Show Page'] || - (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) + (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) ? 5 * MINUTE : 2 * HOUR const now = Date.now() @@ -460,8 +460,8 @@ var ThreadWatcher = { delete ThreadWatcher.syncing if ( 0 > - (middle = - Date.now() - (ThreadWatcher.db.data.lastChecked || 0)) || + (middle = + Date.now() - (ThreadWatcher.db.data.lastChecked || 0)) || middle >= interval ) { // not checked in another tab @@ -564,7 +564,7 @@ var ThreadWatcher = { const { threadID, data } = thread if (threads[threadID]) { var index, modified, replies - ;({ page, index, modified, replies } = threads[threadID]) + ; ({ page, index, modified, replies } = threads[threadID]) if (Conf['Show Page']) { const lastPage = g.sites[siteID].isPrunedByAge?.({ siteID, boardID }) ? threadID === oldest diff --git a/src/Monitoring/Unread.js b/src/Monitoring/Unread.js index f716024..89ae81d 100644 --- a/src/Monitoring/Unread.js +++ b/src/Monitoring/Unread.js @@ -16,7 +16,7 @@ import ThreadWatcher from './ThreadWatcher' * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Unread = { +const Unread = { init() { if ( g.VIEW !== 'thread' || diff --git a/src/Monitoring/UnreadIndex.js b/src/Monitoring/UnreadIndex.js index ad57e73..d18a327 100644 --- a/src/Monitoring/UnreadIndex.js +++ b/src/Monitoring/UnreadIndex.js @@ -16,7 +16,7 @@ import ThreadWatcher from './ThreadWatcher' * DS205: Consider reworking code to avoid use of IIFEs * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var UnreadIndex = { +const UnreadIndex = { lastReadPost: dict(), hr: dict(), markReadLink: dict(), diff --git a/src/Quotelinks/QuoteBacklink.js b/src/Quotelinks/QuoteBacklink.js index 005a2df..b6a5c59 100644 --- a/src/Quotelinks/QuoteBacklink.js +++ b/src/Quotelinks/QuoteBacklink.js @@ -11,7 +11,7 @@ import QuoteYou from './QuoteYou' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var QuoteBacklink = { +const QuoteBacklink = { // Backlinks appending need to work for: // - previous, same, and following posts. // - existing and yet-to-exist posts. diff --git a/src/Quotelinks/QuoteCT.js b/src/Quotelinks/QuoteCT.js index 4923955..73615fb 100644 --- a/src/Quotelinks/QuoteCT.js +++ b/src/Quotelinks/QuoteCT.js @@ -9,7 +9,7 @@ import $ from '../platform/$' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var QuoteCT = { +const QuoteCT = { init() { if ( !['index', 'thread'].includes(g.VIEW) || diff --git a/src/Quotelinks/QuoteInline.js b/src/Quotelinks/QuoteInline.js index 60e6325..2be5b21 100644 --- a/src/Quotelinks/QuoteInline.js +++ b/src/Quotelinks/QuoteInline.js @@ -12,7 +12,7 @@ import $ from '../platform/$' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var QuoteInline = { +const QuoteInline = { init() { if (!['index', 'thread'].includes(g.VIEW) || !Conf['Quote Inlining']) { return diff --git a/src/Quotelinks/QuoteOP.js b/src/Quotelinks/QuoteOP.js index 6878416..de0be8c 100644 --- a/src/Quotelinks/QuoteOP.js +++ b/src/Quotelinks/QuoteOP.js @@ -9,7 +9,7 @@ import $ from '../platform/$' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var QuoteOP = { +const QuoteOP = { init() { if (!['index', 'thread'].includes(g.VIEW) || !Conf['Mark OP Quotes']) { return diff --git a/src/Quotelinks/QuotePreview.js b/src/Quotelinks/QuotePreview.js index fd2aa89..b0d9839 100644 --- a/src/Quotelinks/QuotePreview.js +++ b/src/Quotelinks/QuotePreview.js @@ -13,7 +13,7 @@ import $ from '../platform/$' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var QuotePreview = { +const QuotePreview = { init() { if (!Conf['Quote Previewing']) { return diff --git a/src/Quotelinks/QuoteThreading.js b/src/Quotelinks/QuoteThreading.js index 6feab7c..64164de 100644 --- a/src/Quotelinks/QuoteThreading.js +++ b/src/Quotelinks/QuoteThreading.js @@ -16,7 +16,7 @@ import { dict } from '../platform/helpers' <3 aeosynth */ -var QuoteThreading = { +const QuoteThreading = { init() { if (!Conf['Quote Threading'] || g.VIEW !== 'thread') { return diff --git a/src/Quotelinks/QuoteYou.js b/src/Quotelinks/QuoteYou.js index 8ba4578..33e4183 100644 --- a/src/Quotelinks/QuoteYou.js +++ b/src/Quotelinks/QuoteYou.js @@ -15,7 +15,7 @@ import PostRedirect from '../Posting/PostRedirect' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var QuoteYou = { +const QuoteYou = { init() { if (!Conf['Remember Your Posts']) { return diff --git a/src/Quotelinks/Quotify.js b/src/Quotelinks/Quotify.js index cd38727..6417663 100644 --- a/src/Quotelinks/Quotify.js +++ b/src/Quotelinks/Quotify.js @@ -12,7 +12,7 @@ import $$ from '../platform/$$' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Quotify = { +const Quotify = { init() { if (!['index', 'thread'].includes(g.VIEW) || !Conf['Resurrect Quotes']) { return diff --git a/src/classes/Fetcher.ts b/src/classes/Fetcher.ts index 1138c6b..85a3459 100644 --- a/src/classes/Fetcher.ts +++ b/src/classes/Fetcher.ts @@ -1,7 +1,7 @@ import Redirect from '../Archive/Redirect' import Get from '../General/Get' import Index from '../General/Index' -import { Conf, d,E, g } from '../globals/globals' +import { Conf, d, E, g } from '../globals/globals' import ImageHost from '../Images/ImageHost' import Main from '../main/Main' import $ from '../platform/$' @@ -23,7 +23,7 @@ export default class Fetcher { '[/moot]': { innerHTML: string } '[banned]': { innerHTML: string } '[/banned]': { innerHTML: string } - '[fortune]'(text: any): { innerHTML: string } + '[fortune]'(text: string): { innerHTML: string } '[/fortune]': { innerHTML: string } '[i]': { innerHTML: string } '[/i]': { innerHTML: string } @@ -34,11 +34,11 @@ export default class Fetcher { '[blue]': { innerHTML: string } '[/blue]': { innerHTML: string } } - boardID: string | number + boardID: string threadID: string | number - postID: string | number - root: HTMLElement - quoter: any + postID: number + root: Document | HTMLElement + quoter: HTMLElement | Post static flagCSS: HTMLStyleElement | HTMLElement static initClass() { this.prototype.archiveTags = { @@ -75,9 +75,9 @@ export default class Fetcher { '[/blue]': { innerHTML: '' }, } } - constructor(boardID, threadID, postID, root, quoter) { - let post, thread - this.boardID = boardID + constructor(boardID: number | string, threadID: number, postID: number, root: Document | HTMLElement, quoter: Post) { + let post: Post, thread: Thread + this.boardID = boardID as string this.threadID = threadID this.postID = postID this.root = root @@ -106,22 +106,20 @@ export default class Fetcher { this.root.textContent = `Loading post No.${this.postID}...` if (this.threadID) { - const that = this Fetcher.fetchThread( this.boardID, this.threadID, function (req) { - that.fetchedThread(req) + this.fetchedThread(req) }, true ) } else { - const that = this Fetcher.fetchPost( this.boardID, this.postID, function (req, isCached) { - that.fetchedPost(req, isCached) + this.fetchedPost(req, isCached) }, true ) @@ -161,11 +159,9 @@ export default class Fetcher { return } const thread = new Thread( - g.SITE.Build.threadFromObject(response, boardID), - board - ) + g.SITE.Build.threadFromObject(response, boardID), board.ID) Main.callbackNodes('Thread', [thread]) - const post = thread.posts.get(this.postID) + const post = thread.posts.get(`${boardID}.${this.postID}`) if (post) { this.insert(post) } else { @@ -182,7 +178,7 @@ export default class Fetcher { } const clone = post.addClone( this.quoter.context, - $.hasClass(this.root, 'dialog') + $.hasClass(this.root.appendChild($.el('div')), 'backlink') ) Main.callbackNodes('Post', [clone]) @@ -221,7 +217,7 @@ export default class Fetcher { $.rmAll(this.root) $.add(this.root, nodes.root) - return $.event('PostsInserted', null, this.root) + return $.event('PostsInserted', null, Document.apply(this.root)) } fetchedPost(req: XMLHttpRequest, isCached: boolean) { @@ -252,7 +248,7 @@ export default class Fetcher { const board = g.boards[boardID] || new Board(boardID) const threadKey = `${boardID}.${threadID}` - const thread = g.threads.get(threadKey) || new Thread(threadID, board) + const thread = g.threads.get(threadKey) || new Thread(threadID as string, board) const newPost = new Post( g.SITE.Build.postFromObject(foundPost, boardID), thread, @@ -272,10 +268,7 @@ export default class Fetcher { handlePostNotFound(isCached: boolean, req?: XMLHttpRequest) { if (isCached) { - const api = g.SITE.urls.threadJSON({ - boardID: this.boardID, - threadID: this.threadID, - }, true) + const api = g.SITE.urls.threadJSON(this.boardID as string, this.threadID as string) $.cleanCache((url: string) => url === api) $.cache(api, () => this.fetchedPost(req, false)) return @@ -285,7 +278,7 @@ export default class Fetcher { return } - $.addClass(this.root, 'warning') + $.addClass(this.root.appendChild($.el('div')), 'backlink') this.root.textContent = `Post No.${this.postID} was not found.` } @@ -306,7 +299,6 @@ export default class Fetcher { const encryptionOK = /^https:\/\//.test(url) || location.protocol === 'http:' if (encryptionOK || Conf['Exempt Archives from Encryption']) { - const that = this CrossOrigin.cache(url, function () { if (!encryptionOK && this.response?.media) { const { media } = this.response @@ -320,14 +312,14 @@ export default class Fetcher { } } } - return that.parseArchivedPost(this.response, url, archive) + return this.parseArchivedPost(this.response, url, archive) }) return true } return false } - parseArchivedPost(data: any, url, archive: any) { + parseArchivedPost(data: any, url: string, archive: any) { // In case of multiple callbacks for the same request, // don't parse the same original post more than once. let post: Post @@ -337,13 +329,13 @@ export default class Fetcher { } if (data == null) { - $.addClass(this.root, 'warning') + $.addClass(this.root.appendChild($.el('div')), 'backlink') this.root.textContent = `Error fetching Post No.${this.postID} from ${archive.name}.` return } if (data.error) { - $.addClass(this.root, 'warning') + $.addClass(this.root.appendChild($.el('div')), 'backlink') this.root.textContent = data.error return } @@ -391,8 +383,14 @@ export default class Fetcher { threadID: this.threadID, boardID: this.boardID, isReply: this.postID !== this.threadID, + info: null, + file: data.media, + time: +data.timestamp, + fileDeleted: data.media_status === 'b', + extra: null, } o.info = { + uniqueID: data.poster_hash, subject: data.title, email: data.email, name: data.name || '', @@ -414,7 +412,6 @@ export default class Fetcher { return 'Manager' } })(), - uniqueID: data.poster_hash, flagCode: data.poster_country, flagCodeTroll: data.troll_country_code, flag: data.poster_country_name || data.troll_country_name, @@ -480,7 +477,7 @@ export default class Fetcher { post = new Post(g.SITE.Build.post(o), thread, board, { isFetchedQuote: true, }) - post.kill() + post.kill(post.file) if (post.file) { post.file.thumbURL = o.file.thumbURL } diff --git a/src/classes/Post.ts b/src/classes/Post.ts index 8b72720..ed0454f 100644 --- a/src/classes/Post.ts +++ b/src/classes/Post.ts @@ -1,5 +1,5 @@ import Get from '../General/Get' -import { Conf,g } from '../globals/globals' +import { Conf, g } from '../globals/globals' import ImageExpand from '../Images/ImageExpand' import $ from '../platform/$' import $$ from '../platform/$$' @@ -62,7 +62,7 @@ export default class Post { return this.ID } - constructor(root?: HTMLElement, thread?: Thread, board?: Board, flags = {}) { + constructor(root: HTMLElement, thread?: Thread, board?: Board, flags?: any) { // <% if (readJSON('/.tests_enabled')) { %> // @normalizedOriginal = Test.normalize root // <% } %> @@ -180,8 +180,8 @@ export default class Post { archivelinks: HTMLAnchorElement[] embedlinks: HTMLAnchorElement[] backlinks: HTMLCollectionOf - uniqueIDRoot: any - uniqueID: any + uniqueIDRoot: string + uniqueID: string } const nodes: Node & Partial> = { @@ -199,8 +199,8 @@ export default class Post { backlinks: post.getElementsByClassName( 'backlink' ) as HTMLCollectionOf, - uniqueIDRoot: undefined as any, - uniqueID: undefined as any, + uniqueIDRoot: null, + uniqueID: null, } for (const key in s.info) { const selector = s.info[key] @@ -332,6 +332,7 @@ export default class Post { parseFile(fileRoot: HTMLElement) { interface File { + thumbURL: string isImage: boolean isVideo: boolean url: string @@ -454,7 +455,7 @@ export default class Post { this.board.posts.rm(this) } - addClone(context, contractThumb) { + addClone(context: HTMLElement, contractThumb: boolean): PostClone { // Callbacks may not have been run yet due to anti-browser-lock delay in Main.callbackNodesDB. Callbacks.Post.execute(this) return new PostClone(this, context, contractThumb) @@ -482,7 +483,8 @@ export class PostClone extends Post { static suffix = 0 constructor(origin: Post, context: any, contractThumb: boolean) { - super() + //super(root, thread, board) + super(Document, origin.thread, origin.board) this.isClone = true let file: any, fileRoots: HTMLAnchorElement, key: string @@ -585,7 +587,7 @@ export class PostClone extends Post { } else if (node.nodeType === Node.ELEMENT_NODE && node.querySelector('video')) { const clone = node.cloneNode(false) as Element for (const child of node.childNodes) { - clone.appendChild(cloneWithoutVideo(child)) + clone.appendChild(this.cloneWithoutVideo(child)) } return clone } else { diff --git a/src/classes/SimpleDict.ts b/src/classes/SimpleDict.ts index 33eac4e..581e977 100644 --- a/src/classes/SimpleDict.ts +++ b/src/classes/SimpleDict.ts @@ -15,12 +15,17 @@ export default class SimpleDict { return (this[key] = data) } - rm(key: string) { - let i: number - key = `${key}` - if ((i = this.keys.indexOf(key)) !== -1) { - this.keys.splice(i, 1) - return delete this[key] + rm(key: string | Object) { + if (typeof key === 'string') { + key = `${key}` + if (this[key]) { + delete this[key] + this.keys.splice(this.keys.indexOf(key), 1) + } + } else { + for (const k of Object.keys(key)) { + this.rm(k) + } } } diff --git a/src/main/Main.js b/src/main/Main.js index cd4a543..f4184ea 100644 --- a/src/main/Main.js +++ b/src/main/Main.js @@ -91,7 +91,7 @@ import Quotify from '../Quotelinks/Quotify' import Site from '../site/Site' import SW from '../site/SW' -var Main = { +const Main = { init() { // XXX dwb userscripts extension reloads scripts run at document-start when replaceState/pushState is called. // XXX Firefox reinjects WebExtension content scripts when extension is updated / reloaded. diff --git a/src/meta/eventPage.js b/src/meta/eventPage.js index 1f64e83..f319eff 100644 --- a/src/meta/eventPage.js +++ b/src/meta/eventPage.js @@ -13,7 +13,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { } }) -var handlers = { +const handlers = { permission(request, cb) { const origins = request.origins || ['*://*/'] return chrome.permissions.contains({ origins }, function (result) { diff --git a/src/platform/$.ts b/src/platform/$.ts index 50ebfb4..634208c 100644 --- a/src/platform/$.ts +++ b/src/platform/$.ts @@ -8,6 +8,7 @@ import { ElementProperties, WhenModifiedOptions, } from '../types/$' +import { cloneInto } from '../types/globals' import CrossOrigin from './CrossOrigin' import { debounce, dict, MINUTE, platform, SECOND } from './helpers' // not chainable @@ -197,7 +198,6 @@ $.ajax = (function () { $.ajaxPageInit = function () { $.global(function () { - //@ts-ignore window.FCX.requests = Object.create(null) document.addEventListener( '4chanXAjax', @@ -214,7 +214,7 @@ $.ajax = (function () { headers, id, } = e.detail - //@ts-ignore + window.FCX.requests[id] = r = new pageXHR() r.open(type, url, true) const object = headers || {} @@ -238,7 +238,7 @@ $.ajax = (function () { } } r.onloadend = function () { - //@ts-ignore + delete window.FCX.requests[id] const { status, statusText, response } = this const responseHeaderString = this.getAllResponseHeaders() @@ -276,7 +276,7 @@ $.ajax = (function () { '4chanXAjaxAbort', function (e) { let r - //@ts-ignore + if (!(r = window.FCX.requests[e.detail.id])) { return } @@ -518,9 +518,9 @@ $.X = function (path: string, root?: HTMLElement) { return d.evaluate(path, root, null, 7, null) } -$.addClass = function (el: HTMLElement, ...classNames: string[]) { +$.addClass = function (el: HTMLElement, ...classNames: string[]): void { for (const className of classNames) { - el.classList.add(className) + !el.classList.contains(className) && el.classList.add(className) } } @@ -598,10 +598,10 @@ $.one = function (el, events, handler) { return $.on(el, events, cb) } -$.event = function (event, detail, root = d) { +$.event = function (event: string, detail: any, root: Document = d) { if (!globalThis.chrome?.extension) { if (detail != null && typeof cloneInto === 'function') { - detail = cloneInto(detail, d.defaultView) + detail = cloneInto(detail, root.defaultView) } } return root.dispatchEvent( diff --git a/src/site/Site.ts b/src/site/Site.ts index 7b042a2..cf65316 100644 --- a/src/site/Site.ts +++ b/src/site/Site.ts @@ -9,7 +9,7 @@ import SW from './SW' * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ -var Site = { +const Site = { defaultProperties: { '4chan.org': { software: 'yotsuba' }, '4channel.org': { canonical: '4chan.org' }, diff --git a/src/types/globals.d.ts b/src/types/globals.d.ts index b6bca78..80a23ea 100644 --- a/src/types/globals.d.ts +++ b/src/types/globals.d.ts @@ -1,2 +1,8 @@ declare const cloneInto: Function declare const XPCNativeWrapper: any +export interface threeClover { + siteID: string + boardID: string + threadID: string +} + diff --git a/tsconfig.json b/tsconfig.json index 6212422..2ef868a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,17 +9,20 @@ "allowJs": true, "checkJs": true, "noEmit": true, - "strict": true, + "strict": false, "jsx": "react", - "jsxFactory": "jsx", - "jsxFragmentFactory": "h", + "jsxFactory": "h", + "jsxFragmentFactory": "hFragment", "types": [ "@violentmonkey/types", "@types/chrome", "@types/jquery", "@types/node" ], - "lib": ["DOM", "ES2020"], + "lib": [ + "DOM", + "ES2020" + ], "outDir": "builds/test/crx/tsOutput", "esModuleInterop": true }, @@ -29,4 +32,4 @@ "./tools/*", "dist/*" ] -} +} \ No newline at end of file