From 241ff1eb7ada00cb83b69d5bea8edb9ecbed8dc5 Mon Sep 17 00:00:00 2001 From: Lalle <29478339+LalleSX@users.noreply.github.com> Date: Wed, 19 Apr 2023 03:33:50 +0200 Subject: [PATCH] Added types and bug fixes --- src/Linkification/Embedding.js | 20 +- src/Menu/ArchiveLink.js | 5 - src/Menu/{CopyTextLink.js => CopyTextLink.ts} | 14 +- src/Menu/{DownloadLink.js => DownloadLink.ts} | 12 +- src/Menu/{Menu.js => Menu.ts} | 18 +- src/Menu/{ReportLink.js => ReportLink.ts} | 31 +-- .../{CustomCSS.js => CustomCSS.ts} | 22 +- src/Miscellaneous/Fourchan.js | 193 +++++++----------- src/Miscellaneous/IDColor.js | 89 ++++---- src/Miscellaneous/IDHighlight.js | 51 ++--- src/Miscellaneous/{PSA.js => PSA.ts} | 8 +- src/Miscellaneous/{Time.js => Time.ts} | 63 +++--- src/site/{SW.js => SW.ts} | 2 +- src/site/{Site.js => Site.ts} | 16 +- 14 files changed, 227 insertions(+), 317 deletions(-) rename src/Menu/{CopyTextLink.js => CopyTextLink.ts} (80%) rename src/Menu/{DownloadLink.js => DownloadLink.ts} (76%) rename src/Menu/{Menu.js => Menu.ts} (78%) rename src/Menu/{ReportLink.js => ReportLink.ts} (67%) rename src/Miscellaneous/{CustomCSS.js => CustomCSS.ts} (55%) rename src/Miscellaneous/{PSA.js => PSA.ts} (84%) rename src/Miscellaneous/{Time.js => Time.ts} (75%) rename src/site/{SW.js => SW.ts} (59%) rename src/site/{Site.js => Site.ts} (88%) diff --git a/src/Linkification/Embedding.js b/src/Linkification/Embedding.js index 3495d1d..8779b23 100644 --- a/src/Linkification/Embedding.js +++ b/src/Linkification/Embedding.js @@ -874,8 +874,9 @@ var Embedding = { { key: 'YouTube', regExp: - /^\w+:\/\/(?:youtu.be\/|[\w.]*youtube[\w.]*\/.*(?:v=|\bembed\/|\bv\/))([\w\-]{11})(.*)/, + /^\w+:\/\/(?:www\.)?youtube\.com\/(?:watch\?v=|embed\/|v\/)?(\w+)/, el(a) { + const isShort = a.href.includes('youtube.com/shorts/') let start = a.dataset.options.match(/\b(?:star)?t\=(\w+)/) if (start) { start = start[1] @@ -888,11 +889,15 @@ var Embedding = { 1 * start.match(/(\d+)s/)[1] } const el = $.el('iframe', { - src: `//www.youtube.com/embed/${a.dataset.uid}?rel=0&wmode=opaque${ - start ? '&start=' + start : '' - }`, + src: `//www.youtube.com/embed/${a.dataset.uid}${isShort ? '?t=0s&enablejsapi=1&controls=0&loop=1&mute=1&playsinline=1' : `?rel=0&wmode=opaque${start ? '&start=' + start : ''}`}`, }) el.setAttribute('allowfullscreen', 'true') + if (isShort) { + el.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share') + el.setAttribute('allowfullscreen', '') + el.setAttribute('loading', 'lazy') + el.setAttribute('class', 'youtube-short') + } return el }, title: { @@ -907,17 +912,18 @@ var Embedding = { const m = _.error.match(/^(\d*)\s*(.*)/) return [+m[1], m[2]] } else { - return [200, 'OK'] + return [200, null] } }, }, preview: { url(uid) { - return `https://img.youtube.com/vi/${uid}/0.jpg` + const isShort = uid.includes('shorts') + return `https://img.youtube.com/vi/${uid}${isShort ? '/mqdefault.jpg' : '/0.jpg'}` }, height: 360, }, - }, + }, ], } export default Embedding diff --git a/src/Menu/ArchiveLink.js b/src/Menu/ArchiveLink.js index aa9071e..eb88c12 100644 --- a/src/Menu/ArchiveLink.js +++ b/src/Menu/ArchiveLink.js @@ -4,11 +4,6 @@ import Filter from '../Filtering/Filter' import { g, Conf } from '../globals/globals' import Menu from './Menu' -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ const ArchiveLink = { init() { if ( diff --git a/src/Menu/CopyTextLink.js b/src/Menu/CopyTextLink.ts similarity index 80% rename from src/Menu/CopyTextLink.js rename to src/Menu/CopyTextLink.ts index 7cef327..e2c1dd8 100644 --- a/src/Menu/CopyTextLink.js +++ b/src/Menu/CopyTextLink.ts @@ -2,12 +2,14 @@ import { g, Conf, d } from '../globals/globals' import $ from '../platform/$' import Menu from './Menu' -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ -var CopyTextLink = { +interface CopyTextLink { + text: string + init(): VoidFunction + copy(): VoidFunction +} + +const CopyTextLink: CopyTextLink = { + text: '', init() { if ( !['index', 'thread'].includes(g.VIEW) || diff --git a/src/Menu/DownloadLink.js b/src/Menu/DownloadLink.ts similarity index 76% rename from src/Menu/DownloadLink.js rename to src/Menu/DownloadLink.ts index 78736f1..3b84a9d 100644 --- a/src/Menu/DownloadLink.js +++ b/src/Menu/DownloadLink.ts @@ -3,13 +3,9 @@ import ImageCommon from '../Images/ImageCommon' import $ from '../platform/$' import Menu from './Menu' -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ + const DownloadLink = { - init() { + init(): VoidFunction { if ( !['index', 'thread'].includes(g.VIEW) || !Conf['Menu'] || @@ -18,7 +14,7 @@ const DownloadLink = { return } - const a = $.el('a', { + const a: HTMLAnchorElement = $.el('a', { className: 'download-link', textContent: 'Download file', }) @@ -37,7 +33,7 @@ const DownloadLink = { a.download = file.name return true }, - }) + }) as VoidFunction }, } export default DownloadLink diff --git a/src/Menu/Menu.js b/src/Menu/Menu.ts similarity index 78% rename from src/Menu/Menu.js rename to src/Menu/Menu.ts index 1a56882..cc7b4f5 100644 --- a/src/Menu/Menu.js +++ b/src/Menu/Menu.ts @@ -2,14 +2,10 @@ import Callbacks from '../classes/Callbacks' import UI from '../General/UI' import { g, Conf } from '../globals/globals' import $ from '../platform/$' +import Post from '../classes/Post' -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ -var Menu = { - init() { +var Menu: any = { + init(): VoidFunction { if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu']) { return } @@ -33,7 +29,7 @@ var Menu = { }) }, - node() { + node(): HTMLElement { if (this.isClone) { const button = $('.menu-button', this.nodes.info) $.rmClass(button, 'active') @@ -44,15 +40,15 @@ var Menu = { return $.add(this.nodes.info, Menu.makeButton(this)) }, - catalogNode() { + catalogNode(): HTMLElement { return $.after(this.nodes.icons, Menu.makeButton(this.thread.OP)) }, - makeButton(post, button) { + makeButton(post: Post, button?: HTMLElement): HTMLElement { if (!button) { button = Menu.button.cloneNode(true) } - $.on(button, 'click', function (e) { + $.on(button, 'click', (e: Event) => { return Menu.menu.toggle(e, this, post) }) return button diff --git a/src/Menu/ReportLink.js b/src/Menu/ReportLink.ts similarity index 67% rename from src/Menu/ReportLink.js rename to src/Menu/ReportLink.ts index fd39752..06284f3 100644 --- a/src/Menu/ReportLink.js +++ b/src/Menu/ReportLink.ts @@ -1,23 +1,24 @@ import { g, Conf, d } from '../globals/globals' import $ from '../platform/$' import Menu from './Menu' +import Post from '../classes/Post' -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ -var ReportLink = { +type ReportLinkType = { + init: () => void + report: () => void + url: string + dims: string +} + +const ReportLink: ReportLinkType = { init() { - if ( - !['index', 'thread'].includes(g.VIEW) || + if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu'] || - !Conf['Report Link'] - ) { + !Conf['Report Link']) { return } - const a = $.el('a', { + const a: HTMLAnchorElement = $.el('a', { className: 'report-link', href: 'javascript:;', textContent: 'Report', @@ -27,10 +28,8 @@ var ReportLink = { return Menu.menu.addEntry({ el: a, order: 10, - open(post) { - ReportLink.url = `//sys.${location.hostname.split('.')[1]}.org/${ - post.board - }/imgboard.php?mode=report&no=${post}` + open(post: Post) { + ReportLink.url = `//sys.${location.hostname.split('.')[1]}.org/${post.board}/imgboard.php?mode=report&no=${post}` if (d.cookie.indexOf('pass_enabled=1') >= 0) { ReportLink.dims = 'width=350,height=275' } else { @@ -47,5 +46,7 @@ var ReportLink = { const set = `toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,${dims}` return window.open(url, `report${id}`, set) }, + url: '', + dims: '' } export default ReportLink diff --git a/src/Miscellaneous/CustomCSS.js b/src/Miscellaneous/CustomCSS.ts similarity index 55% rename from src/Miscellaneous/CustomCSS.js rename to src/Miscellaneous/CustomCSS.ts index bd8ec36..0e23503 100644 --- a/src/Miscellaneous/CustomCSS.js +++ b/src/Miscellaneous/CustomCSS.ts @@ -2,20 +2,16 @@ import $ from '../platform/$' import CSS from '../css/CSS' import { Conf } from '../globals/globals' -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ + const CustomCSS = { - init() { + init(): void { if (!Conf['Custom CSS']) { return } return this.addStyle() }, - addStyle() { + addStyle(): HTMLStyleElement { return (this.style = $.addStyle( CSS.sub(Conf['usercss']), 'custom-css', @@ -23,18 +19,18 @@ const CustomCSS = { )) }, - rmStyle() { + rmStyle(): boolean { if (this.style) { $.rm(this.style) return delete this.style } }, - update() { - if (!this.style) { - return this.addStyle() + update(): void { + if (this.style) { + this.rmStyle() + this.addStyle() } - return (this.style.textContent = CSS.sub(Conf['usercss'])) - }, + } } export default CustomCSS diff --git a/src/Miscellaneous/Fourchan.js b/src/Miscellaneous/Fourchan.js index ae51356..b9a6001 100644 --- a/src/Miscellaneous/Fourchan.js +++ b/src/Miscellaneous/Fourchan.js @@ -1,10 +1,10 @@ -import Callbacks from '../classes/Callbacks' -import BoardConfig from '../General/BoardConfig' -import { d, doc, g } from '../globals/globals' -import Main from '../main/Main' -import $ from '../platform/$' -import $$ from '../platform/$$' -import ExpandComment from './ExpandComment' +import Callbacks from "../classes/Callbacks"; +import BoardConfig from "../General/BoardConfig"; +import { d, doc, g } from "../globals/globals"; +import Main from "../main/Main"; +import $ from "../platform/$"; +import $$ from "../platform/$$"; +import ExpandComment from "./ExpandComment"; /* * decaffeinate suggestions: @@ -13,161 +13,110 @@ import ExpandComment from './ExpandComment' */ var Fourchan = { init() { - if ( - g.SITE.software !== 'yotsuba' || - !['index', 'thread', 'archive'].includes(g.VIEW) - ) { - return - } - BoardConfig.ready(this.initBoard) - return Main.ready(this.initReady) + if ((g.SITE.software !== 'yotsuba') || !['index', 'thread', 'archive'].includes(g.VIEW)) { return; } + BoardConfig.ready(this.initBoard); + return Main.ready(this.initReady); }, initBoard() { if (g.BOARD.config.code_tags) { $.on(window, 'prettyprint:cb', function (e) { - let post, pre - if (!(post = g.posts.get(e.detail.ID))) { - return - } - if (!(pre = $$('.prettyprint', post.nodes.comment)[+e.detail.i])) { - return - } + let post, pre; + if (!(post = g.posts.get(e.detail.ID))) { return; } + if (!(pre = $$('.prettyprint', post.nodes.comment)[+e.detail.i])) { return; } if (!$.hasClass(pre, 'prettyprinted')) { - pre.innerHTML = e.detail.html - return $.addClass(pre, 'prettyprinted') + pre.innerHTML = e.detail.html; + return $.addClass(pre, 'prettyprinted'); } - }) - $.global(() => - window.addEventListener( - 'prettyprint', - (e) => - window.dispatchEvent( - new CustomEvent('prettyprint:cb', { - detail: { - ID: e.detail.ID, - i: e.detail.i, - html: window.prettyPrintOne(e.detail.html), - }, - }), - ), - false, - ), - ) + }); + $.global(() => window.addEventListener('prettyprint', e => window.dispatchEvent(new CustomEvent('prettyprint:cb', { + detail: { + ID: e.detail.ID, + i: e.detail.i, + html: window.prettyPrintOne(e.detail.html) + } + })) + , false)); Callbacks.Post.push({ name: 'Parse [code] tags', - cb: Fourchan.code, - }) + cb: Fourchan.code + }); g.posts.forEach(function (post) { if (post.callbacksExecuted) { - return Callbacks.Post.execute(post, ['Parse [code] tags'], true) + return Callbacks.Post.execute(post, ['Parse [code] tags'], true); } - }) - ExpandComment.callbacks.push(Fourchan.code) + }); + ExpandComment.callbacks.push(Fourchan.code); } if (g.BOARD.config.math_tags) { - $.global(() => - window.addEventListener( - 'mathjax', - function (e) { - if (window.MathJax) { - return window.MathJax.Hub.Queue([ - 'Typeset', - window.MathJax.Hub, - e.target, - ]) - } else { - if ( - !document.querySelector('script[src^="//cdn.mathjax.org/"]') - ) { - // don't load MathJax if already loading - window.loadMathJax() - window.loadMathJax = function () {} - } - // 4chan only handles post comments on MathJax load; anything else (e.g. the QR preview) must be queued explicitly. - if (!e.target.classList.contains('postMessage')) { - return document - .querySelector('script[src^="//cdn.mathjax.org/"]') - .addEventListener( - 'load', - () => - window.MathJax.Hub.Queue([ - 'Typeset', - window.MathJax.Hub, - e.target, - ]), - false, - ) - } - } - }, - false, - ), - ) + $.global(() => window.addEventListener('mathjax', function (e) { + if (window.MathJax) { + return window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target]); + } else { + if (!document.querySelector('script[src^="//cdn.mathjax.org/"]')) { // don't load MathJax if already loading + window.loadMathJax(); + window.loadMathJax = function () { }; + } + // 4chan only handles post comments on MathJax load; anything else (e.g. the QR preview) must be queued explicitly. + if (!e.target.classList.contains('postMessage')) { + return document.querySelector('script[src^="//cdn.mathjax.org/"]').addEventListener('load', () => window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target]) + , false); + } + } + } + , false)); Callbacks.Post.push({ name: 'Parse [math] tags', - cb: Fourchan.math, - }) + cb: Fourchan.math + }); g.posts.forEach(function (post) { if (post.callbacksExecuted) { - return Callbacks.Post.execute(post, ['Parse [math] tags'], true) + return Callbacks.Post.execute(post, ['Parse [math] tags'], true); } - }) - return ExpandComment.callbacks.push(Fourchan.math) + }); + return ExpandComment.callbacks.push(Fourchan.math); } }, // Disable 4chan's ID highlighting (replaced by IDHighlight) and reported post hiding. initReady() { return $.global(function () { - window.clickable_ids = false + window.clickable_ids = false; for (var node of document.querySelectorAll('.posteruid, .capcode')) { - node.removeEventListener('click', window.idClick, false) + node.removeEventListener('click', window.idClick, false); } - }) + }); }, code() { - if (this.isClone) { - return - } + if (this.isClone) { return; } return $.ready(() => { - const iterable = $$('.prettyprint', this.nodes.comment) + const iterable = $$('.prettyprint', this.nodes.comment); for (let i = 0; i < iterable.length; i++) { - var pre = iterable[i] + var pre = iterable[i]; if (!$.hasClass(pre, 'prettyprinted')) { - $.event( - 'prettyprint', - { ID: this.fullID, i, html: pre.innerHTML }, - window, - ) + $.event('prettyprint', { ID: this.fullID, i, html: pre.innerHTML }, window); } } - }) + }); }, math() { - let wbrs - if (!/\[(math|eqn)\]/.test(this.nodes.comment.textContent)) { - return - } + let wbrs; + if (!/\[(math|eqn)\]/.test(this.nodes.comment.textContent)) { return; } // XXX tags frequently break MathJax; remove them. if ((wbrs = $$('wbr', this.nodes.comment)).length) { - for (var wbr of wbrs) { - $.rm(wbr) - } - this.nodes.comment.normalize() + for (var wbr of wbrs) { $.rm(wbr); } + this.nodes.comment.normalize(); } var cb = () => { - if (!doc.contains(this.nodes.comment)) { - return - } - $.off(d, 'PostsInserted', cb) - return $.event('mathjax', null, this.nodes.comment) - } - $.on(d, 'PostsInserted', cb) - return cb() - }, -} -export default Fourchan + if (!doc.contains(this.nodes.comment)) { return; } + $.off(d, 'PostsInserted', cb); + return $.event('mathjax', null, this.nodes.comment); + }; + $.on(d, 'PostsInserted', cb); + return cb(); + } +}; +export default Fourchan; diff --git a/src/Miscellaneous/IDColor.js b/src/Miscellaneous/IDColor.js index 76e21d1..b13fcd0 100644 --- a/src/Miscellaneous/IDColor.js +++ b/src/Miscellaneous/IDColor.js @@ -1,70 +1,55 @@ -import Callbacks from '../classes/Callbacks' -import { g, Conf } from '../globals/globals' -import $ from '../platform/$' -import { dict } from '../platform/helpers' +import Callbacks from "../classes/Callbacks"; +import { g, Conf } from "../globals/globals"; +import $ from "../platform/$"; +import { dict } from "../platform/helpers"; + -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ var IDColor = { init() { - if (!['index', 'thread'].includes(g.VIEW) || !Conf['Color User IDs']) { - return - } - this.ids = dict() - this.ids['Heaven'] = [0, 0, 0, '#fff'] + if (!['index', 'thread'].includes(g.VIEW) || !Conf['Color User IDs']) { return; } + this.ids = dict(); + this.ids['Heaven'] = [0, 0, 0, '#fff']; return Callbacks.Post.push({ name: 'Color User IDs', - cb: this.node, - }) + cb: this.node + }); }, node() { - let span, uid - if ( - this.isClone || - !((uid = this.info.uniqueID) && (span = this.nodes.uniqueID)) - ) { - return - } + let span, uid; + if (this.isClone || !((uid = this.info.uniqueID) && (span = this.nodes.uniqueID))) { return; } - const rgb = IDColor.ids[uid] || IDColor.compute(uid) + const rgb = IDColor.ids[uid] || IDColor.compute(uid); // Style the damn node. - const { style } = span - style.color = rgb[3] - style.backgroundColor = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})` - return $.addClass(span, 'painted') + const { style } = span; + style.color = rgb[3]; + style.backgroundColor = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`; + return $.addClass(span, 'painted'); }, compute(uid) { // Convert chars to integers, bitshift and math to create a larger integer // Create a nice string of binary - let hash; - if (typeof g !== 'undefined' && g.SITE && g.SITE.uidColor) { - hash = g.SITE.uidColor(uid); - } else { - hash = parseInt(uid, 16); - } - + const hash = g.SITE.uidColor ? g.SITE.uidColor(uid) : parseInt(uid, 16); + // Convert binary string to numerical values with bitshift and '&' truncation. - const rgb = [(hash >> 16) & 0xff, (hash >> 8) & 0xff, hash & 0xff]; - - // Weight color luminance values, assign a font color that should be readable. - const fontColor = $.luma ? ($.luma(rgb) > 125 ? '#000' : '#fff') : '#000'; - - // Cache color and font color. - const colorCode = `rgb(${rgb.join(',')})`; - this.ids[uid] = { - color: colorCode, - fontColor: fontColor - }; - - // Return only the color. - return colorCode; - }, -} -export default IDColor + const rgb = [ + (hash >> 16) & 0xFF, + (hash >> 8) & 0xFF, + hash & 0xFF + ]; + + // Weight color luminance values, assign a font color that should be readable. + rgb.push($.luma(rgb) > 125 ? + '#000' + : + '#fff' + ); + + // Cache. + return this.ids[uid] = rgb; + } +}; +export default IDColor; diff --git a/src/Miscellaneous/IDHighlight.js b/src/Miscellaneous/IDHighlight.js index 6108872..43c349b 100644 --- a/src/Miscellaneous/IDHighlight.js +++ b/src/Miscellaneous/IDHighlight.js @@ -1,50 +1,37 @@ -import Callbacks from '../classes/Callbacks' -import { g } from '../globals/globals' -import $ from '../platform/$' +import Callbacks from "../classes/Callbacks"; +import { 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 - */ var IDHighlight = { init() { - if (!['index', 'thread'].includes(g.VIEW)) { - return - } + if (!['index', 'thread'].includes(g.VIEW)) { return; } return Callbacks.Post.push({ name: 'Highlight by User ID', - cb: this.node, - }) + cb: this.node + }); }, uniqueID: null, node() { - if (this.nodes.uniqueIDRoot) { - $.on(this.nodes.uniqueIDRoot, 'click', IDHighlight.click(this)) - } - if (this.nodes.capcode) { - $.on(this.nodes.capcode, 'click', IDHighlight.click(this)) - } - if (!this.isClone) { - return IDHighlight.set(this) - } + if (this.nodes.uniqueIDRoot) { $.on(this.nodes.uniqueIDRoot, 'click', IDHighlight.click(this)); } + if (this.nodes.capcode) { $.on(this.nodes.capcode, 'click', IDHighlight.click(this)); } + if (!this.isClone) { return IDHighlight.set(this); } }, set(post) { - const match = - (post.info.uniqueID || post.info.capcode) === IDHighlight.uniqueID - return $[match ? 'addClass' : 'rmClass'](post.nodes.post, 'highlight') + const match = (post.info.uniqueID || post.info.capcode) === IDHighlight.uniqueID; + return $[match ? 'addClass' : 'rmClass'](post.nodes.post, 'highlight'); }, click(post) { return function () { - const uniqueID = post.info.uniqueID || post.info.capcode - IDHighlight.uniqueID = IDHighlight.uniqueID === uniqueID ? null : uniqueID - return g.posts.forEach(IDHighlight.set) - } - }, -} -export default IDHighlight + const uniqueID = post.info.uniqueID || post.info.capcode; + IDHighlight.uniqueID = IDHighlight.uniqueID === uniqueID ? null : uniqueID; + return g.posts.forEach(IDHighlight.set); + }; + } +}; +export default IDHighlight; diff --git a/src/Miscellaneous/PSA.js b/src/Miscellaneous/PSA.ts similarity index 84% rename from src/Miscellaneous/PSA.js rename to src/Miscellaneous/PSA.ts index 98d5681..e0a9f7e 100644 --- a/src/Miscellaneous/PSA.js +++ b/src/Miscellaneous/PSA.ts @@ -4,15 +4,15 @@ import Main from '../main/Main' import $ from '../platform/$' const PSA = { - init() { - let el + init(): void { + let el: HTMLElement if (g.SITE.software === 'yotsuba' && g.BOARD.ID === 'qa') { const announcement = { innerHTML: 'Stay in touch with your /qa/ friends!', } - el = $.el('div', { className: 'fcx-announcement' }, announcement) - $.onExists(doc, '.boardBanner', (banner) => $.after(banner, el)) + el = $.el('span', announcement) as HTMLElement + $.onExists(doc, '.boardBanner', (banner: HTMLElement) => $.after(banner, el)) } if ( 'samachan.org' in Conf['siteProperties'] && diff --git a/src/Miscellaneous/Time.js b/src/Miscellaneous/Time.ts similarity index 75% rename from src/Miscellaneous/Time.js rename to src/Miscellaneous/Time.ts index 022bc45..61281cb 100644 --- a/src/Miscellaneous/Time.js +++ b/src/Miscellaneous/Time.ts @@ -8,7 +8,7 @@ import { g, Conf } from '../globals/globals' * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md */ var Time = { - init() { + init(): VoidFunction { if ( !['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Time Formatting'] @@ -22,18 +22,15 @@ var Time = { }) }, - node() { - if (!this.info.date || this.isClone) { - return + node(): any { + 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]) + 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]; }, - format(formatString, date) { + format(formatString: string, date: Date): string { return formatString.replace(/%(.)/g, function (s, c) { if ($.hasOwn(Time.formatters, c)) { return Time.formatters[c].call(date) @@ -68,16 +65,16 @@ var Time = { 'December', ], - localeFormat(date, options, defaultValue) { + localeFormat(date: Date, options: any, defaultValue: string): string { if (Conf['timeLocale']) { try { return Intl.DateTimeFormat(Conf['timeLocale'], options).format(date) - } catch (error) {} + } catch (error) { } } return defaultValue }, - localeFormatPart(date, options, part, defaultValue) { + localeFormatPart(date: Date, options: any, part: string, defaultValue: string): string { if (Conf['timeLocale']) { try { const parts = Intl.DateTimeFormat( @@ -93,12 +90,12 @@ var Time = { } }) .join('') - } catch (error) {} + } catch (error) { } } return defaultValue }, - zeroPad(n) { + zeroPad(n: number): number | string { if (n < 10) { return `0${n}` } else { @@ -107,59 +104,59 @@ var Time = { }, formatters: { - a() { + a(): string { return Time.localeFormat( this, { weekday: 'short' }, Time.day[this.getDay()].slice(0, 3), ) }, - A() { + A(): string { return Time.localeFormat( this, { weekday: 'long' }, Time.day[this.getDay()], ) }, - b() { + b(): string { return Time.localeFormat( this, { month: 'short' }, Time.month[this.getMonth()].slice(0, 3), ) }, - B() { + B(): string { return Time.localeFormat( this, { month: 'long' }, Time.month[this.getMonth()], ) }, - d() { + d(): string | number { return Time.zeroPad(this.getDate()) }, - e() { + e(): number { return this.getDate() }, - H() { + H(): string | number { return Time.zeroPad(this.getHours()) }, - I() { + I(): string | number { return Time.zeroPad(this.getHours() % 12 || 12) }, - k() { + k(): number { return this.getHours() }, - l() { + l(): number { return this.getHours() % 12 || 12 }, - m() { + m(): string | number { return Time.zeroPad(this.getMonth() + 1) }, - M() { + M(): string | number { return Time.zeroPad(this.getMinutes()) }, - p() { + p(): string { return Time.localeFormatPart( this, { hour: 'numeric', hour12: true }, @@ -167,19 +164,19 @@ var Time = { this.getHours() < 12 ? 'AM' : 'PM', ) }, - P() { + P(): string { return Time.formatters.p.call(this).toLowerCase() }, - S() { + S(): string | number { return Time.zeroPad(this.getSeconds()) }, - y() { + y(): string { return this.getFullYear().toString().slice(2) }, - Y() { + Y(): number { return this.getFullYear() }, - '%'() { + '%'(): string { return '%' }, }, diff --git a/src/site/SW.js b/src/site/SW.ts similarity index 59% rename from src/site/SW.js rename to src/site/SW.ts index 4d48b8d..28ccdb2 100644 --- a/src/site/SW.js +++ b/src/site/SW.ts @@ -1,5 +1,5 @@ import SWTinyboard from './SW.tinyboard' import SWYotsuba from './SW.yotsuba' -const SW = { tinyboard: SWTinyboard, yotsuba: SWYotsuba } +const SW = { tinyboard: SWTinyboard, yotsuba: SWYotsuba } as const export default SW diff --git a/src/site/Site.js b/src/site/Site.ts similarity index 88% rename from src/site/Site.js rename to src/site/Site.ts index fb9cb72..4ef698a 100644 --- a/src/site/Site.js +++ b/src/site/Site.ts @@ -19,7 +19,7 @@ var Site = { 'smug.nepu.moe': { canonical: 'smuglo.li' }, }, - init(cb) { + init(cb: () => void): void { $.extend(Conf['siteProperties'], Site.defaultProperties) let hostname = Site.resolve() if (hostname && $.hasOwn(SW, Conf['siteProperties'][hostname].software)) { @@ -28,7 +28,7 @@ var Site = { } return $.onExists(doc, 'body', () => { for (var software in SW) { - var changes + var changes: { [key: string]: string } if ((changes = SW[software].detect?.())) { changes.software = software hostname = location.hostname.replace(/^www\./, '') @@ -55,7 +55,7 @@ var Site = { }) }, - resolve(url = location) { + resolve(url = location): string { let { hostname } = url while (hostname && !$.hasOwn(Conf['siteProperties'], hostname)) { hostname = hostname.replace(/^[^.]*\.?/, '') @@ -69,14 +69,14 @@ var Site = { return hostname }, - parseURL(url) { - const siteID = Site.resolve(url) - return Main.parseURL(g.sites[siteID], url) + parseURL(url: Location): ReturnType { + var siteID = Site.resolve(url) + return siteID ? g.sites[siteID].parseURL(url) : null }, - set(hostname) { + set(hostname: string): typeof g.SITE { for (var ID in Conf['siteProperties']) { - var site + var site: typeof g.SITE var properties = Conf['siteProperties'][ID] if (properties.canonical) { continue