diff --git a/.vscode/settings.json b/.vscode/settings.json index 9c70c1a..ed4a5c0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,16 +1,17 @@ { - "search.exclude": { - "*.jst": true, - "*.md": true, - "*.yaml": true, - "*.yml": true, - "*.css": true, - "package*.json": true - }, - "typescript.tsdk": "node_modules/typescript/lib", - "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": true, - "source.fixAll": true - } - } \ No newline at end of file + "search.exclude": { + "*.jst": true, + "*.md": true, + "*.yaml": true, + "*.yml": true, + "*.css": true, + "non-property-errors-logs.txt": true, + "package*.json": true + }, + "typescript.tsdk": "node_modules/typescript/lib", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true, + "source.fixAll": true + } +} \ No newline at end of file diff --git a/src/Archive/Redirect.ts b/src/Archive/Redirect.ts index dbd3e2c..3e1e69e 100644 --- a/src/Archive/Redirect.ts +++ b/src/Archive/Redirect.ts @@ -125,7 +125,7 @@ const Redirect = { $.set(items) $.extend(Conf, items) Redirect.selectArchives() - return cb?.() + return cb }, to(dest, data) { diff --git a/src/Filtering/Filter.ts b/src/Filtering/Filter.ts index 862ac6f..4f50680 100644 --- a/src/Filtering/Filter.ts +++ b/src/Filtering/Filter.ts @@ -378,7 +378,7 @@ const Filter = { } }, - addFilter(type: FilterType, re: string, cb?: () => void) { + addFilter(type: FilterType, re: string, cb?: Callbacks) { if (!$.hasOwn(Config.filter, type)) { return } return $.get(type, Conf[type], function (item) { let save = item[type] @@ -392,7 +392,7 @@ const Filter = { }) }, - removeFilters(type: FilterType, res: FilterObj[] | Map, cb?: () => void) { + removeFilters(type: FilterType, res: FilterObj[] | Map, cb?: Callbacks) { return $.get(type, Conf[type], function (item) { let save = item[type] const filterArray = Array.isArray(res) ? res : [...res.values()].flat() diff --git a/src/General/BoardConfig.ts b/src/General/BoardConfig.ts index 9da6208..a891c6c 100644 --- a/src/General/BoardConfig.ts +++ b/src/General/BoardConfig.ts @@ -3,13 +3,7 @@ import { Conf, g } from "../globals/globals" import $ from "../platform/$" import { dict, HOUR } from "../platform/helpers" -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS104: Avoid inline assignments - * DS205: Consider reworking code to avoid use of IIFEs - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ + const BoardConfig = { cbs: [], @@ -19,7 +13,7 @@ const BoardConfig = { const now = Date.now() if (now - (2 * HOUR) >= ((middle = Conf['boardConfig'].lastChecked || 0)) || middle > now) { return $.ajax(`${location.protocol}//a.4cdn.org/boards.json`, - { onloadend: this.load }) + { onloadend: this.load }, dict()) } else { const { boards } = Conf['boardConfig'] return this.set(boards) diff --git a/src/General/Get.ts b/src/General/Get.ts index f471198..d0ac943 100644 --- a/src/General/Get.ts +++ b/src/General/Get.ts @@ -1,13 +1,7 @@ import { Conf, g } from "../globals/globals" import $ from "../platform/$" -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ + const Get = { url(type, IDs, ...args) { let f, site diff --git a/src/General/Header.ts b/src/General/Header.ts index 6e48eb8..99ecc3a 100644 --- a/src/General/Header.ts +++ b/src/General/Header.ts @@ -12,13 +12,7 @@ import Get from "./Get" import Settings from "./Settings" import UI from "./UI" -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * DS104: Avoid inline assignments - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ + const Header = { init() { $.onExists(doc, 'body', () => { @@ -404,7 +398,7 @@ const Header = { Header.setBarFixed(this.checked) Conf['Fixed Header'] = this.checked - return $.set('Fixed Header', this.checked) + return $.set('Fixed Header', this.checked, true) }, setShortcutIcons(show) { diff --git a/src/General/Settings.tsx b/src/General/Settings.tsx index c68b169..2fb8d8c 100644 --- a/src/General/Settings.tsx +++ b/src/General/Settings.tsx @@ -71,9 +71,9 @@ const Settings = { return localStorage.setItem('4chan-settings', JSON.stringify(settings)) } catch (error) { return Object.defineProperty(window, 'Config', {value: {disableAll: true}}) - }}) + }}, true) } else { - return $.global(() => Object.defineProperty(window, 'Config', {value: {disableAll: true}})) + return $.global(() => Object.defineProperty(window, 'Config', {value: {disableAll: true}}), true) } } }, @@ -81,7 +81,7 @@ const Settings = { open(openSection) { let dialog, sectionToOpen if (Settings.dialog) { return } - $.event('CloseMenu') + $.event('CloseMenu', null) Settings.dialog = (dialog = $.el('div', { id: 'overlay' } @@ -258,7 +258,7 @@ Enable it on boards.${location.hostname.split('.')[1]}.org in your browser's pri inputs[key].checked = val inputs[key].parentNode.parentNode.dataset.checked = val } - }) + }, 'Settings') const div = $.el('div', {innerHTML: ': Clear manually-hidden threads and posts on all boards. Reload the page to apply.'}) @@ -299,6 +299,8 @@ Enable it on boards.${location.hostname.split('.')[1]}.org in your browser's pri } } return button.textContent = `Hidden: ${hiddenNum}` + }, function() { + return button.textContent = 'Hidden: 0' }) $.on(button, 'click', function() { this.textContent = 'Hidden: 0' @@ -312,7 +314,7 @@ Enable it on boards.${location.hostname.split('.')[1]}.org in your browser's pri localStorage.removeItem(`4chan-hide-t-${boardID}`) } } - return ($.delete(['hiddenThreads', 'hiddenPosts'])) + return ($.delete(['hiddenThreads', 'hiddenPosts'], dict()) }) }) return $.after($('input[name="Stubs"]', section).parentNode.parentNode, div) @@ -326,7 +328,7 @@ Enable it on boards.${location.hostname.split('.')[1]}.org in your browser's pri // Don't export cached JSON data. delete Conf2['boardConfig'] return (Settings.downloadExport({version: g.VERSION, date: Date.now(), Conf: Conf2})) - }) + }, 'Settings') }, downloadExport(data) { @@ -918,6 +920,9 @@ vp-replace Settings[key].call(input) } } + }, function(err) { + if (err) { return } + return $.id('lastarchivecheck').textContent = new Date(Conf['lastarchivecheck']).toLocaleString() }) const listImageHost = $.id('list-fourchanImageHost') @@ -944,6 +949,9 @@ vp-replace $.extend(Conf, itemsArchive) Redirect.selectArchives() return Settings.addArchiveTable(section) + }, function(err) { + if (err) { return } + return $.id('lastarchivecheck').textContent = new Date(Conf['lastarchivecheck']).toLocaleString() }) const boardSelect = $('#archive-board-select', section) @@ -1069,7 +1077,7 @@ vp-replace saveSelectedArchive() { return $.get('selectedArchives', Conf['selectedArchives'], ({selectedArchives}) => { (selectedArchives[this.dataset.boardid] || (selectedArchives[this.dataset.boardid] = dict()))[this.dataset.type] = JSON.parse(this.value) - $.set('selectedArchives', selectedArchives) + $.set('selectedArchives', selectedArchives, () => Conf['selectedArchives'] = selectedArchives) Conf['selectedArchives'] = selectedArchives return Redirect.selectArchives() }) @@ -1157,7 +1165,7 @@ vp-replace const val = items[key] inputs[key].value = val } - }) + }, true) }, keybind(e) { diff --git a/src/Miscellaneous/IDPostCount.ts b/src/Miscellaneous/IDPostCount.ts index 3b7e6f2..d17e8ee 100644 --- a/src/Miscellaneous/IDPostCount.ts +++ b/src/Miscellaneous/IDPostCount.ts @@ -1,13 +1,10 @@ import Callbacks from "../classes/Callbacks" +import Post from "../classes/Post" +import Thread from "../classes/Thread" import Get from "../General/Get" import { Conf, g } from "../globals/globals" import $ from "../platform/$" -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ const IDPostCount = { init() { if ((g.VIEW !== 'thread') || !Conf['Count Posts by ID']) { return } @@ -21,19 +18,19 @@ const IDPostCount = { }) }, - node() { + node(): void { if (this.nodes.uniqueID && (this.thread === IDPostCount.thread)) { return $.on(this.nodes.uniqueID, 'mouseover', IDPostCount.count) } }, - count() { + count(): string { const { uniqueID } = Get.postFromNode(this).info let n = 0 - IDPostCount.thread.posts.forEach(function (post) { + IDPostCount.thread.posts.forEach((post: Post) => { if (post.info.uniqueID === uniqueID) { return n++ } }) return this.title = `${n} post${n === 1 ? '' : 's'} by this ID` } } -export default IDPostCount +export default IDPostCount \ No newline at end of file diff --git a/src/Miscellaneous/ThreadLinks.ts b/src/Miscellaneous/ThreadLinks.ts index e2a4d44..ab39c2c 100644 --- a/src/Miscellaneous/ThreadLinks.ts +++ b/src/Miscellaneous/ThreadLinks.ts @@ -1,18 +1,22 @@ import Callbacks from "../classes/Callbacks" -import { Conf,g } from "../globals/globals" +import type Post from "../classes/Post" +import { Conf, g } from "../globals/globals" const ThreadLinks = { init(): void { if ((g.VIEW !== 'index') || !Conf['Open Threads in New Tab']) { return } - Callbacks.Post.push({ + const postCallback: Post = { name: 'Thread Links', - cb: this.node.bind(this) - }) - Callbacks.CatalogThread.push({ + cb: this.node.bind(this) + } + const catalogThreadCallback: Post = { name: 'Thread Links', - cb: this.catalogNode.bind(this) - }) + cb: this.catalogNode.bind(this) + } + + Callbacks.Post.push(postCallback) + Callbacks.CatalogThread.push(catalogThreadCallback) }, node(): void { @@ -29,4 +33,4 @@ const ThreadLinks = { } } -export default ThreadLinks +export default ThreadLinks \ No newline at end of file diff --git a/src/Miscellaneous/Time.ts b/src/Miscellaneous/Time.ts index c7a6bf4..e7f9f49 100644 --- a/src/Miscellaneous/Time.ts +++ b/src/Miscellaneous/Time.ts @@ -2,31 +2,54 @@ import Callbacks from "../classes/Callbacks" import { Conf, g } from "../globals/globals" import $ from "../platform/$" -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ -const Time = { - init() { - if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Time Formatting']) { return } +interface TimeFormatters { + a(): string; + A(): string; + b(): string; + B(): string; + d(): string; + e(): number; + H(): string; + I(): string; + k(): number; + l(): number; + m(): string; + M(): string; + p(): string; + P(): string; + S(): string; + y(): string; + Y(): number; + '%'(): string; +} - return Callbacks.Post.push({ +const Time = { + init(): void { + if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Time Formatting']) { + return + } + + Callbacks.Post.push({ name: 'Time Formatting', - cb: this.node + cb: this.node, }) }, - node() { - if (!this.info.date || this.isClone) { return } + node(): void { + if (!this.info.date || this.isClone) { + return + } const { textContent } = this.nodes.date - return this.nodes.date.textContent = textContent.match(/^\s*/)[0] + Time.format(Conf['time'], this.info.date) + textContent.match(/\s*$/)[0] + this.nodes.date.textContent = + textContent.match(/^\s*/)[0] + + Time.format(Conf['time'], this.info.date) + + textContent.match(/\s*$/)[0] }, - format(formatString, date) { - return formatString.replace(/%(.)/g, function (s, c) { + format(formatString: string, date: Date): string { + return formatString.replace(/%(.)/g, (s: string, c: string): string => { if ($.hasOwn(Time.formatters, c)) { - return Time.formatters[c].call(date) + return (Time.formatters as TimeFormatters)[c].call(date) } else { return s } @@ -40,7 +63,7 @@ const Time = { 'Wednesday', 'Thursday', 'Friday', - 'Saturday' + 'Saturday', ], month: [ @@ -55,49 +78,95 @@ const Time = { 'September', 'October', 'November', - 'December' + 'December', ], - localeFormat(date, options, defaultValue) { + localeFormat(date: Date, options: Intl.DateTimeFormatOptions, defaultValue: string): string { if (Conf['timeLocale']) { try { return Intl.DateTimeFormat(Conf['timeLocale'], options).format(date) - } catch (error) { } + } catch (error) {/* empty */ } } return defaultValue }, - localeFormatPart(date, options, part, defaultValue) { + localeFormatPart( + date: Date, + options: Intl.DateTimeFormatOptions, + part: string, + defaultValue: string, + ): string { if (Conf['timeLocale']) { try { const parts = Intl.DateTimeFormat(Conf['timeLocale'], options).formatToParts(date) - return parts.map(function (x) { if (x.type === part) { return x.value } else { return '' } }).join('') - } catch (error) { } + return parts + .map((x) => (x.type === part ? x.value : '')) + .join('') + } catch (error) { /* empty */ } } return defaultValue }, - zeroPad(n) { if (n < 10) { return `0${n}` } else { return n } }, + zeroPad(n: number): string | number { + return n < 10 ? `0${n}` : n + }, formatters: { - a() { return Time.localeFormat(this, { weekday: 'short' }, Time.day[this.getDay()].slice(0, 3)) }, - A() { return Time.localeFormat(this, { weekday: 'long' }, Time.day[this.getDay()]) }, - b() { return Time.localeFormat(this, { month: 'short' }, Time.month[this.getMonth()].slice(0, 3)) }, - B() { return Time.localeFormat(this, { month: 'long' }, Time.month[this.getMonth()]) }, - d() { return Time.zeroPad(this.getDate()) }, - e() { return this.getDate() }, - H() { return Time.zeroPad(this.getHours()) }, - I() { return Time.zeroPad((this.getHours() % 12) || 12) }, - k() { return this.getHours() }, - l() { return (this.getHours() % 12) || 12 }, - m() { return Time.zeroPad(this.getMonth() + 1) }, - M() { return Time.zeroPad(this.getMinutes()) }, - p() { return Time.localeFormatPart(this, { hour: 'numeric', hour12: true }, 'dayperiod', (this.getHours() < 12 ? 'AM' : 'PM')) }, - P() { return Time.formatters.p.call(this).toLowerCase() }, - S() { return Time.zeroPad(this.getSeconds()) }, - y() { return this.getFullYear().toString().slice(2) }, - Y() { return this.getFullYear() }, - '%'() { return '%' } - } + a(): string { + return Time.localeFormat(this, { weekday: 'short' }, Time.day[this.getDay()].slice(0, 3)) + }, + A(): string { + return Time.localeFormat(this, { weekday: 'long' }, Time.day[this.getDay()]) + }, + b(): string { + return Time.localeFormat(this, { month: 'short' }, Time.month[this.getMonth()].slice(0, 3)) + }, + B(): string { + return Time.localeFormat(this, { month: 'long' }, Time.month[this.getMonth()]) + }, + d(): string | number { + return Time.zeroPad(this.getDate()) + }, + e(): number { + return this.getDate() + }, + H(): string | number { + return Time.zeroPad(this.getHours()) + }, + I(): string | number { + return Time.zeroPad((this.getHours() % 12) || 12) + }, + k(): number { + return this.getHours() + }, + l(): number { + return (this.getHours() % 12) || 12 + }, + m(): string | number { + return Time.zeroPad(this.getMonth() + 1) + }, + M(): string | number { + return Time.zeroPad(this.getMinutes()) + }, + p(): string { + return Time.localeFormatPart(this, { hour: 'numeric', hour12: true }, 'dayperiod', this.getHours() < 12 ? 'AM' : 'PM') + }, + P(): string { + return Time.formatters.p.call(this).toLowerCase() + }, + S(): string | number { + return Time.zeroPad(this.getSeconds()) + }, + y(): string { + return this.getFullYear().toString().slice(2) + }, + Y(): number { + return this.getFullYear() + }, + '%'(): string { + return '%' + }, + }, } -export default Time + +export default Time \ No newline at end of file diff --git a/src/Miscellaneous/Tinyboard.ts b/src/Miscellaneous/Tinyboard.ts index 8915b4f..55391e4 100644 --- a/src/Miscellaneous/Tinyboard.ts +++ b/src/Miscellaneous/Tinyboard.ts @@ -10,12 +10,11 @@ interface QRPostDetail { } const Tinyboard = { - init() { + init(): void { if (g.SITE.software !== 'tinyboard') { return } if (g.VIEW === 'thread') { - return Main.ready(() => $.global(function() { - let base - const { boardID, threadID } = document.currentScript.dataset + return Main.ready(() => $.global(function (data: { boardID: string, threadID: number }) { + const { boardID, threadID } = data const threadIdNum = +threadID const form = document.querySelector('form[name="post"]') as HTMLFormElement window.$(document).ajaxComplete((event, request, settings) => { @@ -29,16 +28,15 @@ const Tinyboard = { if (redirect && (originalNoko != null) && !originalNoko && !noko) { detail.redirect = redirect } - } catch (error) {} + } catch (error) { } event = new CustomEvent('QRPostSuccessful', { bubbles: true, detail }) return document.dispatchEvent(event) }) const originalNoko = window.tb_settings?.ajax?.always_noko_replies; - ((base = window.tb_settings || (window.tb_settings = {})).ajax || (base.ajax = {})).always_noko_replies = true - } - , { boardID: g.BOARD.ID, threadID: g.THREADID })) + ((window.tb_settings || (window.tb_settings = {})).ajax || (window.tb_settings.ajax = {})).always_noko_replies = true + }, { boardID: g.BOARD.ID, threadID: g.THREADID })) } } } -export default Tinyboard +export default Tinyboard \ No newline at end of file diff --git a/src/Posting/Captcha.t.ts b/src/Posting/Captcha.t.ts index 323e5b7..0a013e5 100644 --- a/src/Posting/Captcha.t.ts +++ b/src/Posting/Captcha.t.ts @@ -2,25 +2,22 @@ import { d, g } from "../globals/globals" import $ from "../platform/$" import QR from "./QR" -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ const CaptchaT = { init() { if (d.cookie.indexOf('pass_enabled=1') >= 0) { return } if (!(this.isEnabled = !!$('#t-root') || !$.id('postForm'))) { return } - const root = $.el('div', {className: 'captcha-root'}) - this.nodes = {root} + const root = $.el('div', { className: 'captcha-root' }) + this.nodes = { root } $.addClass(QR.nodes.el, 'has-captcha', 'captcha-t') return $.after(QR.nodes.com.parentNode, root) }, moreNeeded() { + return this.isEnabled && !this.nodes.container }, + currentThread: null, getThread() { let threadID @@ -30,26 +27,28 @@ const CaptchaT = { } else { threadID = '' + QR.posts[0].thread } - return {boardID, threadID} + return { boardID, threadID } }, - setup(focus) { + setup(focus?: boolean) { if (!this.isEnabled) { return } if (!this.nodes.container) { - this.nodes.container = $.el('div', {className: 'captcha-container'}) + this.nodes.container = $.el('div', { className: 'captcha-container' }) $.prepend(this.nodes.root, this.nodes.container) CaptchaT.currentThread = CaptchaT.getThread() - $.global(function() { + $.global(function () { const el = document.querySelector('#qr .captcha-container') window.TCaptcha.init(el, this.boardID, +this.threadID) - return window.TCaptcha.setErrorCb(err => window.dispatchEvent(new CustomEvent('CreateNotification', {detail: { - type: 'warning', - content: '' + err - }}) + return window.TCaptcha.setErrorCb(err => window.dispatchEvent(new CustomEvent('CreateNotification', { + detail: { + type: 'warning', + content: '' + err + } + }) )) } - , CaptchaT.currentThread) + , CaptchaT.currentThread) } if (focus) { @@ -59,14 +58,14 @@ const CaptchaT = { destroy() { if (!this.isEnabled || !this.nodes.container) { return } - $.global(() => window.TCaptcha.destroy()) + $.global(() => window.TCaptcha.destroy(), CaptchaT.currentThread) $.rm(this.nodes.container) return delete this.nodes.container }, updateThread() { if (!this.isEnabled) { return } - const {boardID, threadID} = (CaptchaT.currentThread || {}) + const { boardID, threadID } = (CaptchaT.currentThread || {}) const newThread = CaptchaT.getThread() if ((newThread.boardID !== boardID) || (newThread.threadID !== threadID)) { CaptchaT.destroy() @@ -91,7 +90,7 @@ const CaptchaT = { setUsed() { if (!this.isEnabled) { return } if (this.nodes.container) { - return $.global(() => window.TCaptcha.clearChallenge()) + return $.global(() => window.TCaptcha.clearChallenge(), CaptchaT.currentThread) } }, diff --git a/src/classes/DataBoard.ts b/src/classes/DataBoard.ts index a6d9aac..d01aaed 100644 --- a/src/classes/DataBoard.ts +++ b/src/classes/DataBoard.ts @@ -65,7 +65,7 @@ export default class DataBoard { this.data.version = (this.data.version || 0) + 1 return $.set(this.key, this.data, () => { if (needSync) { this.sync?.() } - return cb?.() + return cb }) }) } @@ -77,7 +77,7 @@ export default class DataBoard { for (const change of DataBoard.changes) { change() } this.sync?.() } - return cb?.() + return cb }) } diff --git a/src/classes/Notice.ts b/src/classes/Notice.ts index 6cb434a..19fbddf 100644 --- a/src/classes/Notice.ts +++ b/src/classes/Notice.ts @@ -3,6 +3,8 @@ import { d } from "../globals/globals" import $ from "../platform/$" import { SECOND } from "../platform/helpers" +type NoticeType = "success" | "warning" | "error" + export default class Notice { private el: HTMLDivElement private timeout?: number @@ -10,7 +12,7 @@ export default class Notice { private closed = false constructor( - private type: string, + private type: NoticeType, private content: string | Node, timeout?: number, onclose?: () => void @@ -36,7 +38,7 @@ export default class Notice { this.onclose = onclose } - private setType(type: string) { + private setType(type: NoticeType) { this.el.className = `notification ${type}` } @@ -69,4 +71,4 @@ export default class Notice { $.rm(this.el) this.onclose?.() } -} +} \ No newline at end of file diff --git a/src/classes/Thread.ts b/src/classes/Thread.ts index d0b8f27..f05b9c6 100644 --- a/src/classes/Thread.ts +++ b/src/classes/Thread.ts @@ -4,7 +4,6 @@ import Board from "./Board" import Post from "./Post" import SimpleDict from "./SimpleDict" - export default class Thread { ID: number | string OP: Post @@ -26,7 +25,6 @@ export default class Thread { json: JSON catalogView: Node nodes: { root: Post } - toString() { return this.ID } constructor(ID: number | string, board: Board) { this.board = board @@ -50,8 +48,7 @@ export default class Thread { this.OP = null this.catalogView = null - this.nodes = - { root: null } + this.nodes = { root: null } this.board.threads.push(this.ID, this) g.threads.push(this.fullID, this) @@ -66,14 +63,18 @@ export default class Thread { } icon.title = `This thread is on page ${pageNum} in the original index.` icon.textContent = `[${pageNum}]` - if (this.catalogView) { return this.catalogView.nodes.pageCount.textContent = pageNum } + if (this.catalogView) { this.catalogView.nodes.pageCount.textContent = pageNum } } setCount(type: string, count: number, reachedLimit: boolean) { if (!this.catalogView) { return } const el = this.catalogView.nodes[`${type}Count`] el.textContent = count - return (reachedLimit ? $.addClass : $.rmClass)(el, 'warning') + if (reachedLimit) { + $.addClass(el, 'warning') + } else { + $.rmClass(el, 'warning') + } } setStatus(type: string, status: boolean) { @@ -83,7 +84,7 @@ export default class Thread { if (!this.OP) { return } this.setIcon('Sticky', this.isSticky) this.setIcon('Closed', this.isClosed && !this.isArchived) - return this.setIcon('Archived', this.isArchived) + this.setIcon('Archived', this.isArchived) } setIcon(type: string, status: boolean) { @@ -118,21 +119,25 @@ export default class Thread { } kill() { - return this.isDead = true + this.isDead = true } collect() { let n = 0 - this.posts.forEach(function (post) { + this.posts.forEach(post => { if (post.clones.length) { - return n++ + n++ } else { - return post.collect() + post.collect() } }) if (!n) { g.threads.rm(this.fullID) - return this.board.threads.rm(this) + this.board.threads.rm(this) } } -} + + toString() { + return this.ID + } +} \ No newline at end of file diff --git a/src/platform/$.ts b/src/platform/$.ts index 2f12001..7199e19 100644 --- a/src/platform/$.ts +++ b/src/platform/$.ts @@ -93,7 +93,6 @@ $.ajaxPage = function (url: string, options: AjaxPageOptions) { xhr.send(form) return xhr } -$.cache = dict() $.ready = function (fc: () => void) { if (d.readyState !== 'loading') { @@ -293,7 +292,7 @@ $.ajax = (function () { // With the `If-Modified-Since` header we only receive the HTTP headers and no body for 304 responses. // This saves a lot of bandwidth and CPU time for both the users and the servers. $.lastModified = dict() -$.whenModified = function (url, bucket, cb, options) { +$.whenModified = function (url, bucket, cb, options = {}) { let t: string const { timeout, ajax } = options const params = [] @@ -315,42 +314,43 @@ $.whenModified = function (url, bucket, cb, options) { headers }) return r -}; +} -(function () { +$.cache = function (url, cb, options = {}) { const reqs = dict() - $.cache = function (url, cb, options) { - let req - const { ajax } = options - if (req = reqs[url]) { - if (req.callbacks) { - req.callbacks.push(cb) - } else { - $.queueTask(() => cb.call(req, { isCached: true })) - } - return req + let req + const { ajax } = options + if (req = reqs[url]) { + if (req.callbacks) { + req.callbacks.push(cb) + } else { + $.queueTask(() => cb.call(req, { isCached: true })) } - const onloadend = function () { - if (!this.status) { - delete reqs[url] - } - for (cb of this.callbacks) { - (cb => $.queueTask(() => cb.call(this, { isCached: false })))(cb) - } - return delete this.callbacks - } - req = (ajax || $.ajax)(url, { onloadend }) - req.callbacks = [cb] - return reqs[url] = req + return req } - return $.cleanCache = function (testf) { - for (const url in reqs) { - if (testf(url)) { - delete reqs[url] - } + const onloadend = function () { + if (!this.status) { + delete reqs[url] + } + for (cb of this.callbacks) { + (cb => $.queueTask(() => cb.call(this, { isCached: false })))(cb) + } + return delete this.callbacks + } + req = (ajax || $.ajax)(url, { onloadend }) + req.callbacks = [cb] + return reqs[url] = req +} + +$.cleanCache = function (testf) { + const reqs = dict() + for (const url in reqs) { + if (testf(url)) { + delete reqs[url] } } -})() +} + $.cb = { checked() { @@ -788,7 +788,7 @@ if (platform === 'crx') { c.error(err.message) setTimeout(setArea, MINUTE, area) timeout[area] = Date.now() + MINUTE - return cb?.(err) + return cb } delete timeout[area] @@ -807,7 +807,7 @@ if (platform === 'crx') { return result })())) } - return cb?.() + return cb }) } @@ -831,7 +831,7 @@ if (platform === 'crx') { c.error(chrome.runtime.lastError.message) } if (err == null) { err = chrome.runtime.lastError } - if (!--count) { return cb?.(err) } + if (!--count) { return cb } } chrome.storage.local.clear(done) return chrome.storage.sync.clear(done) @@ -862,7 +862,7 @@ if (platform === 'crx') { $.forceSync = function () { } - $.delete = function (keys, cb) { + $.delete = function (keys: string | string[], cb: Callbacks) { let key if (!(keys instanceof Array)) { keys = [keys] @@ -877,7 +877,7 @@ if (platform === 'crx') { const items = dict() for (key of keys) { items[key] = undefined } $.syncChannel.postMessage(items) - return cb?.() + return cb }) } @@ -905,7 +905,7 @@ if (platform === 'crx') { return result })()).then(function () { $.syncChannel.postMessage(items) - return cb?.() + return cb }) }) @@ -1044,7 +1044,7 @@ if (platform === 'crx') { const value = items[key] $.setValue(g.NAMESPACE + key, JSON.stringify(value), cb) } - return cb?.() + return cb }) }) @@ -1056,7 +1056,7 @@ if (platform === 'crx') { try { $.delete($.listValues().map(key => key.replace(g.NAMESPACE, '')), cb) } catch (error) { } - return cb?.() + return cb } } }