diff --git a/Makefile b/Makefile index 3ee9521..598c795 100644 --- a/Makefile +++ b/Makefile @@ -5,4 +5,4 @@ install: npm run build sneed: clean install - cat dist/4chan-XT.user.js | xclip -selection clipboard + cat dist/4chan-XT.user.js | xclip -selection clipboard \ No newline at end of file diff --git a/src/General/Get.ts b/src/General/Get.js similarity index 69% rename from src/General/Get.ts rename to src/General/Get.js index 66a5de1..23e37d4 100644 --- a/src/General/Get.ts +++ b/src/General/Get.js @@ -1,20 +1,16 @@ import { Conf, g } from '../globals/globals' import $ from '../platform/$' -import type Thread from '../classes/Thread' -import type Post from '../classes/Post' -interface Get { - url(type: any, IDs: { siteID: string }, ...args: any[]): string | undefined - threadExcerpt(thread: Thread): string - threadFromRoot(root: HTMLElement): Thread | null - threadFromNode(node: HTMLElement): Thread | null - postFromRoot(root: HTMLElement): Post | null - postFromNode(root: HTMLElement): Post | null - allQuotelinksLinkingTo(post: Post): HTMLAnchorElement[] - postDataFromLink(link: HTMLAnchorElement): { boardID: string; postID: number } -} - var Get: Get = { + +/* + * 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 + */ +var Get = { url(type, IDs, ...args) { - let f: ((IDs: { siteID: string }, ...args: any[]) => string) | undefined, site: typeof g.sites[0] + let f, site if ((site = g.sites[IDs.siteID]) && (f = $.getOwn(site.urls, type))) { return f(IDs, ...Array.from(args)) } else { @@ -47,7 +43,7 @@ interface Get { }, threadFromNode(node) { return Get.threadFromRoot( - $.x(`ancestor-or-self::${g.SITE.xpath.threadContainer}[1]`, node)[0], + $.x(`ancestor-or-self::${g.SITE.xpath.thread}`, node), ) }, postFromRoot(root) { @@ -64,23 +60,20 @@ interface Get { }, postFromNode(root) { return Get.postFromRoot( - $.x(`ancestor-or-self::${g.SITE.xpath.postContainer}`, root)[0], + $.x(`ancestor-or-self::${g.SITE.xpath.postContainer}[1]`, root), ) }, - postDataFromLink(link: any) { - let boardID: any, postID: any, threadID: any - if (link.dataset?.postID) { + postDataFromLink(link) { + let boardID, postID, threadID + if (link.dataset.postID) { // resurrected quote - ({ boardID, threadID, postID } = link.dataset) + ;({ boardID, threadID, postID } = link.dataset) if (!threadID) { - threadID = '0' + threadID = 0 } } else { - const match = link.href.match(g?.SITE?.regexp?.quotelink) - if (!match) { - throw new Error('Invalid link') - } - [boardID, threadID, postID] = match.slice(1) + const match = link.href.match(g.SITE.regexp.quotelink) + ;[boardID, threadID, postID] = Array.from(match.slice(1)) if (!postID) { postID = threadID } @@ -90,7 +83,7 @@ interface Get { threadID: +threadID, postID: +postID, } - }, + }, allQuotelinksLinkingTo(post) { // Get quotelinks & backlinks linking to the given post. const quotelinks = [] diff --git a/src/Menu/CopyTextLink.ts b/src/Menu/CopyTextLink.ts deleted file mode 100644 index 27e4a91..0000000 --- a/src/Menu/CopyTextLink.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { g, Conf, d } from '../globals/globals' -import $ from '../platform/$' -import Menu from './Menu' -import type Post from '../classes/Post' - -var CopyTextLink = { - text: '', - init(): void { - if ( - !['index', 'thread'].includes(g.VIEW) || - !Conf['Menu'] || - !Conf['Copy Text Link'] - ) { - return - } - - const a: HTMLAnchorElement = $.el('a', { - className: 'copy-text-link', - href: 'javascript:;', - textContent: 'Copy Text', - }) - $.on(a, 'click', CopyTextLink.copy) - - return Menu.menu.addEntry({ - el: a, - order: 12, - open(post: Post): boolean { - CopyTextLink.text = (post.origin || post).commentOrig() - return true - }, - }) - }, - - copy() { - const el: HTMLTextAreaElement = $.el('textarea', { - className: 'copy-text-element', - value: CopyTextLink.text, - }) - $.add(d.body, el) - el.select() - try { - d.execCommand('copy') - } catch (error) {} - return $.rm(el) - }, -} -export default CopyTextLink diff --git a/src/Menu/DownloadLink.ts b/src/Menu/DownloadLink.js similarity index 75% rename from src/Menu/DownloadLink.ts rename to src/Menu/DownloadLink.js index b7d138c..78736f1 100644 --- a/src/Menu/DownloadLink.ts +++ b/src/Menu/DownloadLink.js @@ -3,8 +3,13 @@ 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(): void { + init() { if ( !['index', 'thread'].includes(g.VIEW) || !Conf['Menu'] || @@ -13,7 +18,7 @@ const DownloadLink = { return } - const a: HTMLAnchorElement = $.el('a', { + const a = $.el('a', { className: 'download-link', textContent: 'Download file', }) @@ -24,7 +29,7 @@ const DownloadLink = { return Menu.menu.addEntry({ el: a, order: 100, - open({file}) { + open({ file }) { if (!file) { return false } diff --git a/src/Menu/Menu.js b/src/Menu/Menu.js new file mode 100644 index 0000000..1a56882 --- /dev/null +++ b/src/Menu/Menu.js @@ -0,0 +1,61 @@ +import Callbacks from '../classes/Callbacks' +import UI from '../General/UI' +import { g, Conf } 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 Menu = { + init() { + if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu']) { + return + } + + this.button = $.el('a', { + className: 'menu-button', + href: 'javascript:;', + }) + + $.extend(this.button, { innerHTML: '' }) + + this.menu = new UI.Menu('post') + Callbacks.Post.push({ + name: 'Menu', + cb: this.node, + }) + + return Callbacks.CatalogThread.push({ + name: 'Menu', + cb: this.catalogNode, + }) + }, + + node() { + if (this.isClone) { + const button = $('.menu-button', this.nodes.info) + $.rmClass(button, 'active') + $.rm($('.dialog', this.nodes.info)) + Menu.makeButton(this, button) + return + } + return $.add(this.nodes.info, Menu.makeButton(this)) + }, + + catalogNode() { + return $.after(this.nodes.icons, Menu.makeButton(this.thread.OP)) + }, + + makeButton(post, button) { + if (!button) { + button = Menu.button.cloneNode(true) + } + $.on(button, 'click', function (e) { + return Menu.menu.toggle(e, this, post) + }) + return button + }, +} +export default Menu diff --git a/src/Menu/Menu.ts b/src/Menu/Menu.ts deleted file mode 100644 index 0fd8d87..0000000 --- a/src/Menu/Menu.ts +++ /dev/null @@ -1,71 +0,0 @@ -import Callbacks from '../classes/Callbacks'; -import UI from '../General/UI'; -import { g, Conf } from '../globals/globals'; -import $ from '../platform/$'; - -interface Post { - isClone?: boolean; - nodes: { - info: HTMLElement; - icons: HTMLElement; - }; - thread?: { - OP: Post; - }; -} - -const Menu = { - button: document.createElement('a'), - menu: new UI.Menu('post'), - - init(): void | ReturnType { - if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu']) { - return; - } - - this.button = $.el('a', { - className: 'menu-button', - href: 'javascript:;', - }); - - $.extend(this.button, { innerHTML: '' }); - - this.menu = new UI.Menu('post'); - Callbacks.Post.push({ - name: 'Menu', - cb: this.node, - }); - - return Callbacks.CatalogThread.push({ - name: 'Menu', - cb: this.catalogNode, - }); - }, - - node(this: Post): void | HTMLElement { - if (this.isClone) { - const button = $('.menu-button', this.nodes.info); - $.rmClass(button, 'active'); - $.rm($('.dialog', this.nodes.info)); - Menu.makeButton(this, button); - return; - } - return $.add(this.nodes.info, Menu.makeButton(this)); - }, - - catalogNode(this: Post): void { - return $.after(this.nodes.icons, Menu.makeButton(this.thread!.OP)); - }, - - makeButton(post: Post, button?: HTMLElement): HTMLElement { - if (!button) { - button = Menu.button.cloneNode(true) as HTMLElement; - } - $.on(button, 'click', function (this: HTMLElement, e: Event) { - return Menu.menu.toggle(e, this, post); - }); - return button; - }, -}; - -export default Menu; diff --git a/src/Menu/ReportLink.js b/src/Menu/ReportLink.js index 4859e5f..3969948 100644 --- a/src/Menu/ReportLink.js +++ b/src/Menu/ReportLink.js @@ -2,6 +2,11 @@ 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 ReportLink = { init() { if ( diff --git a/src/platform/$$.js b/src/platform/$$.js deleted file mode 100644 index 11ec207..0000000 --- a/src/platform/$$.js +++ /dev/null @@ -1,12 +0,0 @@ -import { d } from '../globals/globals' - -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md - */ -const $$ = (selector, root = d.body) => [ - ...Array.from(root.querySelectorAll(selector)), -] -export default $$ diff --git a/src/platform/$$.ts b/src/platform/$$.ts new file mode 100644 index 0000000..83d413f --- /dev/null +++ b/src/platform/$$.ts @@ -0,0 +1,6 @@ +import { d } from '../globals/globals'; + +const $$ = (selector: string, root: HTMLElement | null = d.body): Element[] => + Array.from(root?.querySelectorAll(selector) ?? []) as Element[]; + +export default $$; \ No newline at end of file diff --git a/src/site/SW.yotsuba.Build/PostInfoHtml.tsx b/src/site/SW.yotsuba.Build/PostInfoHtml.tsx index 7eaf061..f24d248 100644 --- a/src/site/SW.yotsuba.Build/PostInfoHtml.tsx +++ b/src/site/SW.yotsuba.Build/PostInfoHtml.tsx @@ -2,29 +2,29 @@ import { g } from '../../globals/globals' import h, { EscapedHtml } from '../../globals/jsx' export default function generatePostInfoHtml( - ID, - o, - subject, - capcode, - email, - name, - tripcode, - pass, - capcodeLC, - capcodePlural, - staticPath, - gifIcon, - capcodeDescription, - uniqueID, - flag, - flagCode, - flagCodeTroll, - dateUTC, - dateText, - postLink, - quoteLink, - boardID, - threadID, + ID: number, + o: any, + subject: string, + capcode: string, + email: string, + name: string, + tripcode: string, + pass: string, + capcodeLC: string, + capcodePlural: string, + staticPath: string, + gifIcon: string, + capcodeDescription: string, + uniqueID: string, + flag: string, + flagCode: string, + flagCodeTroll: string, + dateUTC: string, + dateText: string, + postLink: string, + quoteLink: string, + boardID: string, + threadID: number, ): EscapedHtml { const nameHtml: (EscapedHtml | string)[] = [ {name}, diff --git a/src/site/Site.ts b/src/site/Site.js similarity index 86% rename from src/site/Site.ts rename to src/site/Site.js index 8a029ad..fb9cb72 100644 --- a/src/site/Site.ts +++ b/src/site/Site.js @@ -4,6 +4,11 @@ import $ from '../platform/$' import { dict } from '../platform/helpers' import SW from './SW' +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ var Site = { defaultProperties: { '4chan.org': { software: 'yotsuba' }, @@ -14,7 +19,7 @@ var Site = { 'smug.nepu.moe': { canonical: 'smuglo.li' }, }, - init(cb: () => void): void { + init(cb) { $.extend(Conf['siteProperties'], Site.defaultProperties) let hostname = Site.resolve() if (hostname && $.hasOwn(SW, Conf['siteProperties'][hostname].software)) { @@ -23,7 +28,7 @@ var Site = { } return $.onExists(doc, 'body', () => { for (var software in SW) { - var changes = null + var changes if ((changes = SW[software].detect?.())) { changes.software = software hostname = location.hostname.replace(/^www\./, '') @@ -50,13 +55,13 @@ var Site = { }) }, - resolve(url = location.href): string { - let { hostname: hostname } = new URL(url) + resolve(url = location) { + let { hostname } = url while (hostname && !$.hasOwn(Conf['siteProperties'], hostname)) { hostname = hostname.replace(/^[^.]*\.?/, '') } if (hostname) { - let canonical: string + let canonical if ((canonical = Conf['siteProperties'][hostname].canonical)) { hostname = canonical } @@ -64,13 +69,14 @@ var Site = { return hostname }, - parseURL(url: any): any { + parseURL(url) { const siteID = Site.resolve(url) return Main.parseURL(g.sites[siteID], url) }, - set(hostname: string) { + + set(hostname) { for (var ID in Conf['siteProperties']) { - var site: HTMLElement + var site var properties = Conf['siteProperties'][ID] if (properties.canonical) { continue