From 96f763e42ed2f05c6b6a4b1b60e6a0e38fdee8ba Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 12:56:18 +0100 Subject: [PATCH 01/11] Re-enable `no-extra-semi` and prettier Prettier re-enabled as the semi-colon removal made quite a few files uglier than they were previously. --- .eslintrc.js | 2 +- scripts/pretty.sh | 2 +- src/content.ts | 54 ++++++--- src/content/finding.ts | 51 +++++--- src/content/hinting.ts | 199 +++++++++++++++++++++++--------- src/excmds.ts | 165 ++++++++++---------------- src/lib/config.ts | 173 +++++++++++++++------------ src/lib/html-tagged-template.js | 6 +- 8 files changed, 379 insertions(+), 273 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 3eee6d9a..59afd2b1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -198,7 +198,7 @@ module.exports = { ], "no-empty-function": "off", "no-eval": "off", - "no-extra-semi": "off", //"off", + "no-extra-semi": "error", "no-fallthrough": "off", "no-invalid-this": "off", "no-multiple-empty-lines": "error", diff --git a/scripts/pretty.sh b/scripts/pretty.sh index 9d52aa2d..623773b4 100755 --- a/scripts/pretty.sh +++ b/scripts/pretty.sh @@ -40,7 +40,7 @@ main() { lock .git/index.lock case "$file" in *.md | *.css) prettier --write "$file";; - *) eslint --fix "$file";; + *) prettier --write "$file"; eslint --fix "$file";; esac unlock .git/index.lock git add "$file" diff --git a/src/content.ts b/src/content.ts index 39bfed17..8705c32e 100644 --- a/src/content.ts +++ b/src/content.ts @@ -35,12 +35,18 @@ import { EditorCmds } from "@src/content/editor" import * as hinting_content from "@src/content/hinting" controller.setExCmds({ "": excmds_content, - "ex": CmdlineCmds, - "text": EditorCmds, - "hint": hinting_content.getHintCommands() + ex: CmdlineCmds, + text: EditorCmds, + hint: hinting_content.getHintCommands(), }) -messaging.addListener("excmd_content", messaging.attributeCaller(excmds_content)) -messaging.addListener("controller_content", messaging.attributeCaller(controller)) +messaging.addListener( + "excmd_content", + messaging.attributeCaller(excmds_content), +) +messaging.addListener( + "controller_content", + messaging.attributeCaller(controller), +) // Hook the keyboard up to the controller import * as ContentController from "@src/content/controller_content" @@ -87,7 +93,7 @@ config.getAsync("preventautofocusjackhammer").then(allowautofocus => { const preventAutoFocus = () => { // First, blur whatever element is active. This will make sure // activeElement is the "default" active element - ; (document.activeElement as any).blur() + (document.activeElement as any).blur() const elem = document.activeElement as any // ???: We need to set tabIndex, otherwise we won't get focus/blur events! elem.tabIndex = 0 @@ -97,7 +103,9 @@ config.getAsync("preventautofocusjackhammer").then(allowautofocus => { // On top of blur/focusout events, we need to periodically check the // activeElement is the one we want because blur/focusout events aren't // always triggered when document.activeElement changes - const interval = setInterval(() => { if (document.activeElement != elem) focusElem() }, 200) + const interval = setInterval(() => { + if (document.activeElement != elem) focusElem() + }, 200) // When the user starts interacting with the page, stop resetting focus function stopResettingFocus(event: Event) { if (!event.isTrusted) return @@ -145,7 +153,7 @@ import * as scrolling from "@src/content/scrolling" import * as R from "ramda" import * as visual from "@src/lib/visual" /* tslint:disable:import-spacing */ -; (window as any).tri = Object.assign(Object.create(null), { +;(window as any).tri = Object.assign(Object.create(null), { browserBg: webext.browserBg, commandline_content, convert, @@ -240,7 +248,9 @@ config.getAsync("modeindicator").then(mode => { .then(container => { statusIndicator.setAttribute( "style", - `border: ${(container as any).colorCode} solid 1.5px !important`, + `border: ${ + (container as any).colorCode + } solid 1.5px !important`, ) }) .catch(error => { @@ -338,14 +348,12 @@ config.getAsync("modeindicator").then(mode => { function protectSlash(e) { if (!e.isTrusted) return - config.get("blacklistkeys").map( - protkey => { - if (protkey.indexOf(e.key) !== -1 && contentState.mode === "normal") { - e.cancelBubble = true - e.stopImmediatePropagation() - } + config.get("blacklistkeys").map(protkey => { + if (protkey.indexOf(e.key) !== -1 && contentState.mode === "normal") { + e.cancelBubble = true + e.stopImmediatePropagation() } - ) + }) } // Some sites like to prevent firefox's `/` from working so we need to protect @@ -366,11 +374,19 @@ config.getAsync("leavegithubalone").then(v => { document.addEventListener("selectionchange", () => { const selection = document.getSelection() - if ((contentState.mode == "visual") && (config.get("visualexitauto") == "true") && (selection.anchorOffset == selection.focusOffset)) { + if ( + contentState.mode == "visual" && + config.get("visualexitauto") == "true" && + selection.anchorOffset == selection.focusOffset + ) { contentState.mode = "normal" return } - if ((contentState.mode !== "normal") || (config.get("visualenterauto") == "false")) return + if ( + contentState.mode !== "normal" || + config.get("visualenterauto") == "false" + ) + return if (selection.anchorOffset !== selection.focusOffset) { contentState.mode = "visual" } @@ -380,6 +396,6 @@ document.addEventListener("selectionchange", () => { // background for collection. Attach the observer to the window object // since there's apparently a bug that causes performance observers to // be GC'd even if they're still the target of a callback. -; (window as any).tri = Object.assign(window.tri, { +;(window as any).tri = Object.assign(window.tri, { perfObserver: perf.listenForCounters(), }) diff --git a/src/content/finding.ts b/src/content/finding.ts index 36fba156..9bbdeb7a 100644 --- a/src/content/finding.ts +++ b/src/content/finding.ts @@ -19,7 +19,7 @@ function getFindHost() { elem.style.top = "0px" elem.style.left = "0px" document.body.appendChild(elem) - host = elem.attachShadow({mode: "closed"}) + host = elem.attachShadow({ mode: "closed" }) return host } @@ -28,14 +28,17 @@ class FindHighlight extends HTMLSpanElement { constructor(private rects, private node) { super() - ; (this as any).unfocus = () => { + ;(this as any).unfocus = () => { for (const node of this.children) { (node as HTMLElement).style.background = `rgba(127,255,255,0.5)` } } - ; (this as any).focus = () => { + ;(this as any).focus = () => { if (!DOM.isVisible(this.children[0])) { - this.children[0].scrollIntoView({ block: "center", inline: "center" }) + this.children[0].scrollIntoView({ + block: "center", + inline: "center", + }) } let parentNode = this.node.parentNode while (parentNode && !(parentNode instanceof HTMLAnchorElement)) { @@ -50,8 +53,8 @@ class FindHighlight extends HTMLSpanElement { } this.style.position = "absolute" - this.style.top = "0px"; - this.style.left = "0px"; + this.style.top = "0px" + this.style.left = "0px" for (const rect of rects) { if (rect.top < this.top) { this.top = rect.top @@ -67,9 +70,8 @@ class FindHighlight extends HTMLSpanElement { highlight.style.pointerEvents = "none" this.appendChild(highlight) } - ; (this as any).unfocus() + (this as any).unfocus() } - } customElements.define("find-highlight", FindHighlight, { extends: "span" }) @@ -82,7 +84,9 @@ let selected = 0 export async function jumpToMatch(searchQuery, reverse) { // First, search for the query const findcase = config.get("findcase") - const sensitive = findcase === "sensitive" || (findcase === "smart" && /[A-Z]/.test(searchQuery)) + const sensitive = + findcase === "sensitive" || + (findcase === "smart" && /[A-Z]/.test(searchQuery)) const findPromise = await browserBg.find.find(searchQuery, { tabId: await activeTabId(), caseSensitive: sensitive, @@ -95,7 +99,12 @@ export async function jumpToMatch(searchQuery, reverse) { removeHighlighting() // We need to grab all text nodes in order to find the corresponding element - const walker = document.createTreeWalker(document, NodeFilter.SHOW_TEXT, null, false) + const walker = document.createTreeWalker( + document, + NodeFilter.SHOW_TEXT, + null, + false, + ) const nodes = [] let node do { @@ -111,27 +120,31 @@ export async function jumpToMatch(searchQuery, reverse) { const data = results.rectData[i] if (data.rectsAndTexts.rectList.length < 1) { // When a result does not have any rectangles, it's not visible - continue; + continue } const range = results.rangeData[i] - const high = new FindHighlight(data.rectsAndTexts.rectList, nodes[range.startTextNodePos]) + const high = new FindHighlight( + data.rectsAndTexts.rectList, + nodes[range.startTextNodePos], + ) host.appendChild(high) lastHighlights.push(high) if (!focused && DOM.isVisible(high)) { focused = true - ; (high as any).focus() + ;(high as any).focus() selected = lastHighlights.length - 1 } } if (lastHighlights.length < 1) { throw new Error("Pattern not found: " + searchQuery) } - lastHighlights - .sort(reverse ? (a, b) => b.top - a.top : (a, b) => a.top - b.top) + lastHighlights.sort( + reverse ? (a, b) => b.top - a.top : (a, b) => a.top - b.top, + ) if (!focused) { selected = 0 /* tslint:disable:no-useless-cast */ - ; (lastHighlights[selected] as any).focus() + ;(lastHighlights[selected] as any).focus() } } @@ -141,7 +154,7 @@ function drawHighlights(highlights) { } export function removeHighlighting() { - const host = getFindHost(); + const host = getFindHost() while (host.firstChild) host.removeChild(host.firstChild) } @@ -158,8 +171,8 @@ export async function jumpToNextMatch(n: number) { throw new Error("Pattern not found: " + lastSearchQuery) } /* tslint:disable:no-useless-cast */ - ; (lastHighlights[selected] as any).unfocus() + (lastHighlights[selected] as any).unfocus() selected = (selected + n + lastHighlights.length) % lastHighlights.length /* tslint:disable:no-useless-cast */ - ; (lastHighlights[selected] as any).focus() + ;(lastHighlights[selected] as any).focus() } diff --git a/src/content/hinting.ts b/src/content/hinting.ts index bd034e72..d1c75e61 100644 --- a/src/content/hinting.ts +++ b/src/content/hinting.ts @@ -122,15 +122,29 @@ class HintState { const focusedRect = this.focusedHint.rect // Get all hints from the top area - const topHints = this.activeHints.filter(h => h.rect.top < focusedRect.top && h.rect.bottom < focusedRect.bottom) + const topHints = this.activeHints.filter( + h => + h.rect.top < focusedRect.top && + h.rect.bottom < focusedRect.bottom, + ) if (!topHints.length) { return } // Find the next top hint const nextFocusedHint = topHints.reduce((a, b) => { - const aDistance = distance(a.rect.left, a.rect.right, focusedRect.left, focusedRect.right) - const bDistance = distance(b.rect.left, b.rect.right, focusedRect.left, focusedRect.right) + const aDistance = distance( + a.rect.left, + a.rect.right, + focusedRect.left, + focusedRect.right, + ) + const bDistance = distance( + b.rect.left, + b.rect.right, + focusedRect.left, + focusedRect.right, + ) if (aDistance < bDistance) { return a } else if (aDistance > bDistance) { @@ -156,15 +170,29 @@ class HintState { const focusedRect = this.focusedHint.rect // Get all hints from the bottom area - const bottomHints = this.activeHints.filter(h => h.rect.top > focusedRect.top && h.rect.bottom > focusedRect.bottom) + const bottomHints = this.activeHints.filter( + h => + h.rect.top > focusedRect.top && + h.rect.bottom > focusedRect.bottom, + ) if (!bottomHints.length) { return } // Find the next bottom hint const nextFocusedHint = bottomHints.reduce((a, b) => { - const aDistance = distance(a.rect.left, a.rect.right, focusedRect.left, focusedRect.right) - const bDistance = distance(b.rect.left, b.rect.right, focusedRect.left, focusedRect.right) + const aDistance = distance( + a.rect.left, + a.rect.right, + focusedRect.left, + focusedRect.right, + ) + const bDistance = distance( + b.rect.left, + b.rect.right, + focusedRect.left, + focusedRect.right, + ) if (aDistance < bDistance) { return a } else if (aDistance > bDistance) { @@ -190,15 +218,29 @@ class HintState { const focusedRect = this.focusedHint.rect // Get all hints from the left area - const leftHints = this.activeHints.filter(h => h.rect.left < focusedRect.left && h.rect.right < focusedRect.right) + const leftHints = this.activeHints.filter( + h => + h.rect.left < focusedRect.left && + h.rect.right < focusedRect.right, + ) if (!leftHints.length) { return } // Find the next left hint const nextFocusedHint = leftHints.reduce((a, b) => { - const aDistance = distance(a.rect.top, a.rect.bottom, focusedRect.top, focusedRect.bottom) - const bDistance = distance(b.rect.top, b.rect.bottom, focusedRect.top, focusedRect.bottom) + const aDistance = distance( + a.rect.top, + a.rect.bottom, + focusedRect.top, + focusedRect.bottom, + ) + const bDistance = distance( + b.rect.top, + b.rect.bottom, + focusedRect.top, + focusedRect.bottom, + ) if (aDistance < bDistance) { return a } else if (aDistance > bDistance) { @@ -224,15 +266,29 @@ class HintState { const focusedRect = this.focusedHint.rect // Get all hints from the right area - const rightHints = this.activeHints.filter(h => h.rect.left > focusedRect.left && h.rect.right > focusedRect.right) + const rightHints = this.activeHints.filter( + h => + h.rect.left > focusedRect.left && + h.rect.right > focusedRect.right, + ) if (!rightHints.length) { return } // Find the next right hint const nextFocusedHint = rightHints.reduce((a, b) => { - const aDistance = distance(a.rect.top, a.rect.bottom, focusedRect.top, focusedRect.bottom) - const bDistance = distance(b.rect.top, b.rect.bottom, focusedRect.top, focusedRect.bottom) + const aDistance = distance( + a.rect.top, + a.rect.bottom, + focusedRect.top, + focusedRect.bottom, + ) + const bDistance = distance( + b.rect.top, + b.rect.bottom, + focusedRect.top, + focusedRect.bottom, + ) if (aDistance < bDistance) { return a } else if (aDistance > bDistance) { @@ -264,8 +320,12 @@ class HintState { // To do this, compute the number of hints between the last selected // hint and the hint selected before it - const lastIndex = this.hints.indexOf(this.selectedHints[this.selectedHints.length - 1]) - const prevIndex = this.hints.indexOf(this.selectedHints[this.selectedHints.length - 2]) + const lastIndex = this.hints.indexOf( + this.selectedHints[this.selectedHints.length - 1], + ) + const prevIndex = this.hints.indexOf( + this.selectedHints[this.selectedHints.length - 2], + ) const distance = lastIndex - prevIndex if (distance > 0) { @@ -302,7 +362,9 @@ class HintState { // Set the names that should go at the end for (let i = 0; i < savedNames.length; ++i) { - this.hints[this.hints.length + distance + i].setName(savedNames[i]) + this.hints[this.hints.length + distance + i].setName( + savedNames[i], + ) } } @@ -320,7 +382,7 @@ export function hintPage( hintableElements: Element[], onSelect: HintSelectedCallback, resolve = () => {}, // eslint-disable-line @typescript-eslint/no-empty-function - reject = () => {}, // eslint-disable-line @typescript-eslint/no-empty-function + reject = () => {}, // eslint-disable-line @typescript-eslint/no-empty-function rapid = false, ) { const buildHints: HintBuilder = defaultHintBuilder() @@ -339,13 +401,16 @@ export function hintPage( buildHints(hintableElements, hint => { hint.result = onSelect(hint.target) modeState.selectedHints.push(hint) - if (modeState.selectedHints.length > 1 && (config.get("hintshift") === "true")) { - modeState.shiftHints(); + if ( + modeState.selectedHints.length > 1 && + config.get("hintshift") === "true" + ) { + modeState.shiftHints() } }) } - if (! modeState.hints.length) { + if (!modeState.hints.length) { // No more hints to display reset() return @@ -364,22 +429,29 @@ export function hintPage( const firstTarget = modeState.hints[0].target const firstTargetIsSelectable = (): boolean => { - return firstTarget instanceof HTMLAnchorElement && + return ( + firstTarget instanceof HTMLAnchorElement && firstTarget.href !== "" && !firstTarget.href.startsWith("javascript:") + ) } const allTargetsAreEqual = (): boolean => { - return undefined === modeState.hints.find(h => { - return ( - !(h.target instanceof HTMLAnchorElement) || - h.target.href !== (firstTarget as HTMLAnchorElement).href - ) - }) + return ( + undefined === + modeState.hints.find(h => { + return ( + !(h.target instanceof HTMLAnchorElement) || + h.target.href !== (firstTarget as HTMLAnchorElement).href + ) + }) + ) } - if (modeState.hints.length == 1 || - (firstTargetIsSelectable() && allTargetsAreEqual())) { + if ( + modeState.hints.length == 1 || + (firstTargetIsSelectable() && allTargetsAreEqual()) + ) { // There is just a single link or all the links point to the same // place. Select it. modeState.cleanUpHints() @@ -552,7 +624,7 @@ class Hint { left: rect.left + offsetLeft, right: rect.right + offsetLeft, width: rect.width, - height: rect.height + height: rect.height, } this.flag.textContent = name @@ -631,9 +703,13 @@ export const vimpHelper = { // escape the hintchars string so that strange things don't happen // when special characters are used as hintchars (for example, ']') const escapedHintChars = defaultHintChars().replace( - /^\^|[-\\\]]/g, "\\$&") + /^\^|[-\\\]]/g, + "\\$&", + ) const filterableTextFilter = new RegExp( - "[" + escapedHintChars + "]", "g") + "[" + escapedHintChars + "]", + "g", + ) vimpHelper.filterableTextFilter = filterableTextFilter } return str.replace(vimpHelper.filterableTextFilter, "") @@ -751,7 +827,9 @@ function filterHintsVimperator(fstr, reflow = false) { active = active.filter(hint => hint.name.startsWith(run.str)) } else { // By text - active = active.filter(hint => vimpHelper.matchHint(hint.filterData, run.str)) + active = active.filter(hint => + vimpHelper.matchHint(hint.filterData, run.str), + ) if (reflow) rename(active) } @@ -848,7 +926,7 @@ export function hintables(selectors = DOM.HINTTAGS_selectors, withjs = false) { elems = [...elemSet] } elems = elems.filter(DOM.isVisible) - return changeHintablesToLargestChild(elems); + return changeHintablesToLargestChild(elems) } /** @@ -858,21 +936,24 @@ export function hintables(selectors = DOM.HINTTAGS_selectors, withjs = false) { */ function changeHintablesToLargestChild(elements: Element[]): Element[] { elements.forEach((element, index) => { - if (element.childNodes.length === 0) return; - let largestChild: Element; + if (element.childNodes.length === 0) return + let largestChild: Element // Find largest child. - element.childNodes.forEach((c) => { - const currentChild = (c as Element); - if (!largestChild || isElementLargerThan(currentChild, largestChild)) { - largestChild = currentChild; + element.childNodes.forEach(c => { + const currentChild = c as Element + if ( + !largestChild || + isElementLargerThan(currentChild, largestChild) + ) { + largestChild = currentChild } }) // Change element if child is larger if (isElementLargerThan(largestChild, element)) { - elements[index] = largestChild; + elements[index] = largestChild } }) - return elements; + return elements } /** @@ -881,13 +962,13 @@ function changeHintablesToLargestChild(elements: Element[]): Element[] { */ function isElementLargerThan(e1: Element, e2: Element): boolean { if (typeof e1.getBoundingClientRect !== "function") { - return false; + return false } else if (typeof e2.getBoundingClientRect !== "function") { - return true; + return true } - const e1BR = e1.getBoundingClientRect(); - const e2BR = e2.getBoundingClientRect(); - return e1BR.height > e2BR.height && e1BR.width > e2BR.width; + const e1BR = e1.getBoundingClientRect() + const e2BR = e2.getBoundingClientRect() + return e1BR.height > e2BR.height && e1BR.width > e2BR.width } /** Returns elements that point to a saveable resource @@ -908,7 +989,7 @@ export function hintableImages() { * text or RegExp rule * @hidden */ -export function hintByText(match: string|RegExp) { +export function hintByText(match: string | RegExp) { return DOM.getElemsBySelector(DOM.HINTTAGS_filter_by_text_selectors, [ DOM.isVisible, hint => { @@ -924,7 +1005,7 @@ export function hintByText(match: string|RegExp) { } else { return text.toUpperCase().includes(match.toUpperCase()) } - } + }, ]) } @@ -1008,9 +1089,16 @@ function focusRightHint() { /** @hidden */ export function parser(keys: KeyboardEvent[]) { - const parsed = keyseq.parse(keys, - keyseq.mapstrMapToKeyMap(new Map((Object.entries(config.get("hintmaps")) as any) - .filter(([key, value]) => value != "")))) + const parsed = keyseq.parse( + keys, + keyseq.mapstrMapToKeyMap( + new Map( + (Object.entries(config.get("hintmaps")) as any).filter( + ([key, value]) => value != "", + ), + ), + ), + ) if (parsed.isMatch === true) { return parsed } @@ -1018,7 +1106,10 @@ export function parser(keys: KeyboardEvent[]) { const simplekeys = keys.filter(key => !keyseq.hasModifiers(key)) let exstr if (simplekeys.length > 1) { - exstr = simplekeys.reduce((acc, key) => `hint.pushKey ${key.key};`, "composite ") + exstr = simplekeys.reduce( + (acc, key) => `hint.pushKey ${key.key};`, + "composite ", + ) } else if (simplekeys.length === 1) { exstr = `hint.pushKeyCodePoint ${simplekeys[0].key.codePointAt(0)}` } else { @@ -1042,5 +1133,5 @@ export function getHintCommands() { pushSpace, pushKeyCodePoint, popKey, - }; -}; + } +} diff --git a/src/excmds.ts b/src/excmds.ts index 4d7c00b7..1b4567cb 100644 --- a/src/excmds.ts +++ b/src/excmds.ts @@ -257,7 +257,7 @@ export function fillinput(selector: string, ...content: string[]) { let inputToFill = document.querySelector(selector) if (!inputToFill) inputToFill = DOM.getLastUsedInput() if ("value" in inputToFill) { - ; (inputToFill as HTMLInputElement).value = content.join(" ") + (inputToFill as HTMLInputElement).value = content.join(" ") } else { inputToFill.textContent = content.join(" ") } @@ -336,7 +336,7 @@ export async function editor() { let line = 0 let col = 0 wrap_input((t, start, end) => { - ; [text, line, col] = getLineAndColNumber(t, start, end) + [text, line, col] = getLineAndColNumber(t, start, end) return [null, null, null] })(elem) const file = (await Native.temp(text, document.location.hostname)).content @@ -444,16 +444,7 @@ export async function loadtheme(themename: string) { if (!(await Native.nativegate("0.1.9"))) return const separator = (await browserBg.runtime.getPlatformInfo()).os === "win" ? "\\" : "/" // remove the "tridactylrc" bit so that we're left with the directory - const path = - (await Native.getrcpath()) - .split(separator) - .slice(0, -1) - .join(separator) + - separator + - "themes" + - separator + - themename + - ".css" + const path = (await Native.getrcpath()).split(separator).slice(0, -1).join(separator) + separator + "themes" + separator + themename + ".css" const file = await Native.read(path) if (file.code !== 0) throw new Error("Couldn't read theme " + path) return set("customthemes." + themename, file.content) @@ -967,7 +958,7 @@ export function addJump() { JUMPED = false return } - const {scrollX, scrollY} = window + const { scrollX, scrollY } = window // Prevent pending jump from being registered clearTimeout(JUMP_TIMEOUTID) // Schedule the registering of the current jump @@ -992,7 +983,7 @@ export function addJump() { } //#content_helper -document.addEventListener("scroll", addJump, {passive: true}) +document.addEventListener("scroll", addJump, { passive: true }) // Try to restore the previous jump position every time a page is loaded //#content_helper @@ -2186,34 +2177,35 @@ export async function tabopen(...addressarr: string[]) { export function tabqueue(...addresses: string[]) { // addresses[0] is a string when called with `tabopen a b c` but an array // when called from `composite hint -qpipe a href | tabqueue`. - addresses = addresses.flat(Infinity); + addresses = addresses.flat(Infinity) if (addresses.length === 0) { - return Promise.resolve(); + return Promise.resolve() } - return tabopen("-b", addresses[0]).then(tab => - new Promise ((resolve, reject) => { - function openNextTab(activeInfo) { - if (activeInfo.tabId === tab.id) { - resolve(tabqueue(...(addresses.slice(1)))); - removeTabqueueListeners(tab.id); + return tabopen("-b", addresses[0]).then( + tab => + new Promise((resolve, reject) => { + function openNextTab(activeInfo) { + if (activeInfo.tabId === tab.id) { + resolve(tabqueue(...addresses.slice(1))) + removeTabqueueListeners(tab.id) + } } - } - function removeTabqueueListeners(tabId) { - if (tabId === tab.id) { - browser.tabs.onActivated.removeListener(openNextTab); - browser.tabs.onRemoved.removeListener(removeTabqueueListeners); - // FIXME: This should actually be `reject(tab)` to - // interrupt pipelines, but this results in an impossible - // to debug `Error: undefined` message being printed on the - // command line. So we silently resolve the promise and - // hope for the best. - resolve(tab); + function removeTabqueueListeners(tabId) { + if (tabId === tab.id) { + browser.tabs.onActivated.removeListener(openNextTab) + browser.tabs.onRemoved.removeListener(removeTabqueueListeners) + // FIXME: This should actually be `reject(tab)` to + // interrupt pipelines, but this results in an impossible + // to debug `Error: undefined` message being printed on the + // command line. So we silently resolve the promise and + // hope for the best. + resolve(tab) + } } - } - browser.tabs.onActivated.addListener(openNextTab); - browser.tabs.onRemoved.addListener(removeTabqueueListeners); - }) - ); + browser.tabs.onActivated.addListener(openNextTab) + browser.tabs.onRemoved.addListener(removeTabqueueListeners) + }), + ) } /** Resolve a tab index to the tab id of the corresponding tab in this window. @@ -2246,10 +2238,12 @@ async function idFromIndex(index?: number | "%" | "#" | string): Promise index = (index - 1).mod((await browser.tabs.query({ currentWindow: true })).length) + 1 // Return id of tab with that index. - return (await browser.tabs.query({ - currentWindow: true, - index: index - 1, - }))[0].id + return ( + await browser.tabs.query({ + currentWindow: true, + index: index - 1, + }) + )[0].id } else { return activeTabId() } @@ -2336,7 +2330,7 @@ export async function tabclose(...indexes: string[]) { */ //#background export async function tabcloseallto(side: string) { - if (!(["left", "right"].includes(side))) { + if (!["left", "right"].includes(side)) { throw "side argument must be left or right" } const tabs = await browser.tabs.query({ @@ -2692,11 +2686,7 @@ export async function viewcontainers() { // # and white space don't agree with FF's JSON viewer. // Probably other symbols too. const containers = await browserBg.contextualIdentities.query({}) // Can't access src/lib/containers.ts from a content script. - window.location.href = - "data:application/json," + - JSON.stringify(containers) - .replace(/#/g, "%23") - .replace(/ /g, "%20") + window.location.href = "data:application/json," + JSON.stringify(containers).replace(/#/g, "%23").replace(/ /g, "%20") } /** Opens the current tab in another container. @@ -2849,30 +2839,27 @@ export async function composite(...cmds: string[]) { // For each pipeline, wait for previous pipeline to finish, then // execute each cmd in pipeline in order, passing the result of the // previous cmd as the last argument to the next command. - .reduce( - async (prev_pipeline, cmd) => { - await prev_pipeline - const cmds = cmd.split("|") + .reduce(async (prev_pipeline, cmd) => { + await prev_pipeline + const cmds = cmd.split("|") - // Compute the first piped value. - // - // We could invoke controller.acceptExCmd, but - // that would cause our pipeline section to be - // stored as the last executed command for the - // purposes of :repeat, which would be - // nonsense. So we copy-paste the important - // parts of the body of that function instead. - const [fn, args] = excmd_parser.parser(cmds[0], ALL_EXCMDS) - const first_value = fn.call({}, ...args) + // Compute the first piped value. + // + // We could invoke controller.acceptExCmd, but + // that would cause our pipeline section to be + // stored as the last executed command for the + // purposes of :repeat, which would be + // nonsense. So we copy-paste the important + // parts of the body of that function instead. + const [fn, args] = excmd_parser.parser(cmds[0], ALL_EXCMDS) + const first_value = fn.call({}, ...args) - // Exec the rest of the pipe in sequence. - return cmds.slice(1).reduce(async (pipedValue, cmd) => { - const [fn, args] = excmd_parser.parser(cmd, ALL_EXCMDS) - return fn.call({}, ...args, await pipedValue) - }, first_value) - }, - null as any, - ) + // Exec the rest of the pipe in sequence. + return cmds.slice(1).reduce(async (pipedValue, cmd) => { + const [fn, args] = excmd_parser.parser(cmd, ALL_EXCMDS) + return fn.call({}, ...args, await pipedValue) + }, first_value) + }, null as any) ) } catch (e) { logger.error(e) @@ -3722,31 +3709,14 @@ export function get(...keys: string[]) { export function viewconfig(key?: string) { // # and white space don't agree with FF's JSON viewer. // Probably other symbols too. - if (!key) - window.location.href = - "data:application/json," + - JSON.stringify(config.get()) - .replace(/#/g, "%23") - .replace(/ /g, "%20") + if (!key) window.location.href = "data:application/json," + JSON.stringify(config.get()).replace(/#/g, "%23").replace(/ /g, "%20") // I think JS casts key to the string "undefined" if it isn't given. else if (key === "--default") { - window.location.href = - "data:application/json," + - JSON.stringify(config.o(new config.default_config())) - .replace(/#/g, "%23") - .replace(/ /g, "%20") + window.location.href = "data:application/json," + JSON.stringify(config.o(new config.default_config())).replace(/#/g, "%23").replace(/ /g, "%20") } else if (key === "--user") { - window.location.href = - "data:application/json," + - JSON.stringify(config.USERCONFIG) - .replace(/#/g, "%23") - .replace(/ /g, "%20") + window.location.href = "data:application/json," + JSON.stringify(config.USERCONFIG).replace(/#/g, "%23").replace(/ /g, "%20") } - window.location.href = - "data:application/json," + - JSON.stringify(config.getDynamic(key)) - .replace(/#/g, "%23") - .replace(/ /g, "%20") + window.location.href = "data:application/json," + JSON.stringify(config.getDynamic(key)).replace(/#/g, "%23").replace(/ /g, "%20") // base 64 encoding is a cleverer way of doing this, but it doesn't seem to work for the whole config. //window.location.href = "data:application/json;base64," + btoa(JSON.stringify(config.get())) } @@ -4030,12 +4000,7 @@ export async function hint(option?: string, selectors?: string, ...rest: string[ break case "-pipe": - selectHints = hinting.pipe( - selectors, - elem => elem[rest.join(" ")], - rapid, - jshints, - ) + selectHints = hinting.pipe(selectors, elem => elem[rest.join(" ")], rapid, jshints) break case "-i": @@ -4497,8 +4462,7 @@ async function js_helper(str: string[]) { done = true break } - if (!done) - str.shift() + if (!done) str.shift() } if (doSource) { @@ -4509,8 +4473,7 @@ async function js_helper(str: string[]) { sourcePath = [...rcPath, sourcePath].join(sep) } const file = await Native.read(sourcePath) - if (file.code !== 0) - throw new Error("Couldn't read js file " + sourcePath) + if (file.code !== 0) throw new Error("Couldn't read js file " + sourcePath) jsContent = file.content } else { jsContent = str.join(" ") diff --git a/src/lib/config.ts b/src/lib/config.ts index d6c07e2b..2ea6436a 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -26,8 +26,8 @@ const removeNull = R.when( R.is(Object), R.pipe( R.reject(val => val === null), - R.map(a => removeNull(a)) - ) + R.map(a => removeNull(a)), + ), ) /** @hidden */ @@ -276,7 +276,7 @@ export class default_config { ";y": "hint -y", ";p": "hint -p", ";h": "hint -h", - "v": "hint -h", // Easiest way of entering visual mode for now. Expect this bind to change + v: "hint -h", // Easiest way of entering visual mode for now. Expect this bind to change ";P": "hint -P", ";r": "hint -r", ";s": "hint -s", @@ -339,23 +339,32 @@ export class default_config { } vmaps = { - "": "composite js document.getSelection().empty(); mode normal; hidecmdline", - "": "composite js document.getSelection().empty(); mode normal ; hidecmdline", - "y": "composite js document.getSelection().toString() | clipboard yank", - "s": "composite js document.getSelection().toString() | fillcmdline open search", - "S": "composite js document.getSelection().toString() | fillcmdline tabopen search", - "l": 'js document.getSelection().modify("extend","forward","character")', - "h": 'js document.getSelection().modify("extend","backward","character")', - "e": 'js document.getSelection().modify("extend","forward","word")', - "w": 'js document.getSelection().modify("extend","forward","word"); document.getSelection().modify("extend","forward","character")', - "b": 'js document.getSelection().modify("extend","backward","character"); document.getSelection().modify("extend","backward","word"); document.getSelection().modify("extend","forward","character")', - "j": 'js document.getSelection().modify("extend","forward","line")', + "": + "composite js document.getSelection().empty(); mode normal; hidecmdline", + "": + "composite js document.getSelection().empty(); mode normal ; hidecmdline", + y: "composite js document.getSelection().toString() | clipboard yank", + s: + "composite js document.getSelection().toString() | fillcmdline open search", + S: + "composite js document.getSelection().toString() | fillcmdline tabopen search", + l: 'js document.getSelection().modify("extend","forward","character")', + h: 'js document.getSelection().modify("extend","backward","character")', + e: 'js document.getSelection().modify("extend","forward","word")', + w: + 'js document.getSelection().modify("extend","forward","word"); document.getSelection().modify("extend","forward","character")', + b: + 'js document.getSelection().modify("extend","backward","character"); document.getSelection().modify("extend","backward","word"); document.getSelection().modify("extend","forward","character")', + j: 'js document.getSelection().modify("extend","forward","line")', // "j": 'js document.getSelection().modify("extend","forward","paragraph")', // not implemented in Firefox - "k": 'js document.getSelection().modify("extend","backward","line")', - "$": 'js document.getSelection().modify("extend","forward","lineboundary")', - "0": 'js document.getSelection().modify("extend","backward","lineboundary")', - "=": "js let n = document.getSelection().anchorNode.parentNode; let s = window.getSelection(); let r = document.createRange(); s.removeAllRanges(); r.selectNodeContents(n); s.addRange(r)", - "o": "js tri.visual.reverseSelection(document.getSelection())", + k: 'js document.getSelection().modify("extend","backward","line")', + $: + 'js document.getSelection().modify("extend","forward","lineboundary")', + "0": + 'js document.getSelection().modify("extend","backward","lineboundary")', + "=": + "js let n = document.getSelection().anchorNode.parentNode; let s = window.getSelection(); let r = document.createRange(); s.removeAllRanges(); r.selectNodeContents(n); s.addRange(r)", + o: "js tri.visual.reverseSelection(document.getSelection())", "🕷🕷INHERITS🕷🕷": "nmaps", } @@ -572,14 +581,15 @@ export class default_config { mkt: "mktridactylrc", "mkt!": "mktridactylrc -f", "mktridactylrc!": "mktridactylrc -f", - mpvsafe: "js -p tri.excmds.shellescape(JS_ARG).then(url => tri.excmds.exclaim_quiet('mpv ' + url))", + mpvsafe: + "js -p tri.excmds.shellescape(JS_ARG).then(url => tri.excmds.exclaim_quiet('mpv ' + url))", exto: "extoptions", extpreferences: "extoptions", extp: "extpreferences", prefset: "setpref", prefremove: "removepref", tabclosealltoright: "tabcloseallto right", - tabclosealltoleft: "tabcloseallto left" + tabclosealltoleft: "tabcloseallto left", } /** @@ -897,7 +907,7 @@ export class default_config { * * Replaces %WINTAG with "-Tag $TRI_VERSION", similarly to [[nativeinstallcmd]]. */ - win_nativeinstallcmd = `powershell -NoProfile -InputFormat None -Command "Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/cmcaine/tridactyl/master/native/win_install.ps1'))"` + win_nativeinstallcmd = `powershell -NoProfile -InputFormat None -Command "Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/cmcaine/tridactyl/master/native/win_install.ps1'))"` /** * Used by :updatecheck and related built-in functionality to automatically check for updates and prompt users to upgrade. @@ -1056,10 +1066,13 @@ export const DEFAULTS = o(new default_config()) */ function getDeepProperty(obj, target: string[]) { if (obj !== undefined && obj !== null && target.length) { - if (obj["🕷🕷INHERITS🕷🕷"] === undefined) { + if (obj["🕷🕷INHERITS🕷🕷"] === undefined) { return getDeepProperty(obj[target[0]], target.slice(1)) } else { - return getDeepProperty(mergeDeepCull(get(obj["🕷🕷INHERITS🕷🕷"]), obj)[target[0]], target.slice(1)) + return getDeepProperty( + mergeDeepCull(get(obj["🕷🕷INHERITS🕷🕷"]), obj)[target[0]], + target.slice(1), + ) } } else { if (obj === undefined || obj === null) return obj @@ -1102,7 +1115,11 @@ export function mergeDeep(o1, o2) { .filter( key => typeof o1[key] === "object" && typeof o2[key] === "object", ) - .forEach(key => r[key] == null ? null : Object.assign(r[key], mergeDeep(o1[key], o2[key]))) + .forEach(key => + r[key] == null + ? null + : Object.assign(r[key], mergeDeep(o1[key], o2[key])), + ) return r } @@ -1134,18 +1151,15 @@ export function getURL(url: string, target: string[]) { (conf.subconfigs[k2].priority || 10), ) // Merge their corresponding value if they're objects, otherwise return the last value - .reduce( - (acc, curKey) => { - const curVal = getDeepProperty( - conf.subconfigs[curKey], - target, - ) - if (acc instanceof Object && curVal instanceof Object) - return mergeDeep(acc, curVal) - return curVal - }, - undefined as any, - ) + .reduce((acc, curKey) => { + const curVal = getDeepProperty( + conf.subconfigs[curKey], + target, + ) + if (acc instanceof Object && curVal instanceof Object) + return mergeDeep(acc, curVal) + return curVal + }, undefined as any) ) } const user = _getURL(USERCONFIG, url, target) @@ -1266,9 +1280,13 @@ export async function set(...args) { setDeepProperty(USERCONFIG, value, target) - if (target.length === 1 && target[0] === "storageloc" && previousValue !== value) { - // ensure storageloc is saved locally before switching - await save(previousValue) + if ( + target.length === 1 && + target[0] === "storageloc" && + previousValue !== value + ) { + // ensure storageloc is saved locally before switching + await save(previousValue) } return save() } else { @@ -1381,7 +1399,7 @@ export async function update() { set("configversion", "1.2") } case "1.2": { - ; ["ignoremaps", "inputmaps", "imaps", "nmaps"] + ["ignoremaps", "inputmaps", "imaps", "nmaps"] .map(mapname => [ mapname, getDeepProperty(USERCONFIG, [mapname]), @@ -1413,7 +1431,7 @@ export async function update() { set("configversion", "1.3") } case "1.3": { - ; [ + [ "priority", "hintdelay", "scrollduration", @@ -1426,7 +1444,7 @@ export async function update() { set("configversion", "1.4") } case "1.4": { - ; (getDeepProperty(USERCONFIG, ["noiframeon"]) || []).forEach( + (getDeepProperty(USERCONFIG, ["noiframeon"]) || []).forEach( site => { setURL(site, "noiframe", "true") }, @@ -1444,7 +1462,7 @@ export async function update() { mapObj[""] = mapObj[" "] delete mapObj[" "] } - ; [ + [ "", "", "", @@ -1464,18 +1482,22 @@ export async function update() { }) return mapObj } - ; ["nmaps", "exmaps", "imaps", "inputmaps", "ignoremaps"].forEach( - settingName => updateAll([settingName], updateSetting), - ) + ;[ + "nmaps", + "exmaps", + "imaps", + "inputmaps", + "ignoremaps", + ].forEach(settingName => updateAll([settingName], updateSetting)) set("configversion", "1.7") } case "1.7": { const autocontain = getDeepProperty(USERCONFIG, ["autocontain"]) unset("autocontain") if (autocontain !== undefined) { - Object.entries(autocontain).forEach(([domain, container]) => { - set("autocontain", `^https?://[^/]*${domain}/`, container) - }) + Object.entries(autocontain).forEach(([domain, container]) => { + set("autocontain", `^https?://[^/]*${domain}/`, container) + }) } set("configversion", "1.8") } @@ -1487,9 +1509,15 @@ export async function update() { return val }, mapObj) } - ; ["nmaps", "exmaps", "imaps", "inputmaps", "ignoremaps", "hintmaps", "vmaps"].forEach( - settingName => updateAll([settingName], updateSetting), - ) + ;[ + "nmaps", + "exmaps", + "imaps", + "inputmaps", + "ignoremaps", + "hintmaps", + "vmaps", + ].forEach(settingName => updateAll([settingName], updateSetting)) set("configversion", "1.9") updated = true // NB: when adding a new updater, move this line to the end of it } @@ -1508,7 +1536,7 @@ async function init() { if (localConfig === undefined || localConfig.storageloc !== "local") { const syncConfig = await browser.storage.sync.get(CONFIGNAME) if (syncConfig !== undefined) { - schlepp(syncConfig[CONFIGNAME]) + schlepp(syncConfig[CONFIGNAME]) } } else { // These could be merged instead, but the current design does not allow for that @@ -1516,8 +1544,7 @@ async function init() { } const configUpdated = await update() - if (configUpdated) - await save() + if (configUpdated) await save() INITIALISED = true for (const waiter of WAITERS) { @@ -1606,21 +1633,22 @@ export function parseConfig(): string { const ftdetect = `" For syntax highlighting see https://github.com/tridactyl/vim-tridactyl\n" vim: set filetype=tridactyl` - return `${s.general}${s.binds}${s.subconfigs}${s.aliases}${s.aucmds}${ - s.aucons - }${s.logging}${s.nulls}${ftdetect}` + return `${s.general}${s.binds}${s.subconfigs}${s.aliases}${s.aucmds}${s.aucons}${s.logging}${s.nulls}${ftdetect}` } -const parseConfigHelper = (pconf, parseobj, prefix= []) => { +const parseConfigHelper = (pconf, parseobj, prefix = []) => { for (const i of Object.keys(pconf)) { if (typeof pconf[i] !== "object") { if (prefix[0] === "subconfigs") { prefix.shift() const pattern = prefix.shift() - parseobj.subconfigs.push(`seturl ${pattern} ${[...prefix, i].join(".")} ${pconf[i]}`) + parseobj.subconfigs.push( + `seturl ${pattern} ${[...prefix, i].join(".")} ${pconf[i]}`, + ) } else { parseobj.conf.push( - `set ${[...prefix, i].join(".")} ${pconf[i]}`) + `set ${[...prefix, i].join(".")} ${pconf[i]}`, + ) } } else if (pconf[i] === null) { parseobj.nulls.push(`setnull ${[...prefix, i].join(".")}`) @@ -1647,7 +1675,7 @@ const parseConfigHelper = (pconf, parseobj, prefix= []) => { parseobj.binds.push(`un${cmd} ${e}`) } } else if (pconf[i][e] === null) { - parseobj.nulls.push(`setnull ${i}.${e}`) + parseobj.nulls.push(`setnull ${i}.${e}`) } else if (i === "exaliases") { // Only really useful if mapping the entire config and not just pconf. if (e === "alias") { @@ -1701,33 +1729,28 @@ browser.storage.onChanged.addListener((changes, areaname) => { // storageloc=local means ignoring changes that aren't set by us } else if (newValue !== undefined) { if (areaname === "sync") { - // prevent storageloc from being set remotely - delete old.storageloc - delete newValue.storageloc + // prevent storageloc from being set remotely + delete old.storageloc + delete newValue.storageloc } // A key has been :unset if it exists in USERCONFIG and doesn't in changes and if its value in USERCONFIG is different from the one it has in default_config const unsetKeys = Object.keys(old).filter( k => newValue[k] === undefined && - JSON.stringify(old[k]) !== - JSON.stringify(DEFAULTS[k]), + JSON.stringify(old[k]) !== JSON.stringify(DEFAULTS[k]), ) // A key has changed if it is defined in USERCONFIG and its value in USERCONFIG is different from the one in `changes` or if the value in defaultConf is different from the one in `changes` - const changedKeys = Object.keys( - newValue, - ).filter( + const changedKeys = Object.keys(newValue).filter( k => JSON.stringify( - old[k] !== undefined - ? old[k] - : DEFAULTS[k], + old[k] !== undefined ? old[k] : DEFAULTS[k], ) !== JSON.stringify(newValue[k]), ) // TODO: this should be a deep comparison but this is better than nothing - changedKeys.forEach(key => USERCONFIG[key] = newValue[key]) + changedKeys.forEach(key => (USERCONFIG[key] = newValue[key])) unsetKeys.forEach(key => delete USERCONFIG[key]) // Trigger listeners diff --git a/src/lib/html-tagged-template.js b/src/lib/html-tagged-template.js index cc003f75..de8f02be 100644 --- a/src/lib/html-tagged-template.js +++ b/src/lib/html-tagged-template.js @@ -1,10 +1,10 @@ -;(function(window) { +(function(window) { "use strict" // test for es6 support of needed functionality try { // spread operator and template strings support - ;(function testSpreadOpAndTemplate() { + (function testSpreadOpAndTemplate() { const tag = function tag(strings, ...values) { return } @@ -541,7 +541,7 @@ (node._replacedWith && node.childNodes.length === 0) || (parentNode && parentNode.childNodes.length === 0) ) { - ;(parentNode || node).remove() + (parentNode || node).remove() } // -------------------------------------------------- From d72016f10f9f51185492dc9e6c5a4ff159a0637c Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 13:02:43 +0100 Subject: [PATCH 02/11] Re-enable `guard-for-in` --- .eslintrc.js | 2 +- src/excmds.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 59afd2b1..946c5b28 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -174,7 +174,7 @@ module.exports = { "off", "always" ], - "guard-for-in": "off", //"error", + "guard-for-in": "error", "id-blacklist": "off", "id-match": "off", "import/order": "off", diff --git a/src/excmds.ts b/src/excmds.ts index 1b4567cb..2093514f 100644 --- a/src/excmds.ts +++ b/src/excmds.ts @@ -3625,7 +3625,8 @@ export async function sanitise(...args: string[]) { */ } if (args.find(x => x === "all") !== undefined) { - for (const attr in dts) dts[attr] = true + for (const attr in dts) + if (Object.prototype.hasOwnProperty.call(dts, attr)) dts[attr] = true } else { // We bother checking if dts[x] is false because // browser.browsingData.remove() is very strict on the format of the From db8f0e21ad1585e3ae2ff42b9f626b9f72f9de85 Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 13:05:31 +0100 Subject: [PATCH 03/11] Re-enable `brace-style` --- .eslintrc.js | 2 +- src/lib/html-tagged-template.js | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 946c5b28..4e3a056e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -161,7 +161,7 @@ module.exports = { "always" ], "brace-style": [ - "off", //"error", + "error", "1tbs" ], "camelcase": "off", diff --git a/src/lib/html-tagged-template.js b/src/lib/html-tagged-template.js index de8f02be..ca90673b 100644 --- a/src/lib/html-tagged-template.js +++ b/src/lib/html-tagged-template.js @@ -311,14 +311,13 @@ // use insertBefore() instead of replaceChild() so that the node Iterator // doesn't think the new tag should be the next node node.parentNode.insertBefore(tag, node) - } // special case for script tags: // using innerHTML with a string that contains a script tag causes the script // tag to not be executed when added to the DOM. We'll need to create a script // tag and append its contents which will make it execute correctly. // @see http://stackoverflow.com/questions/1197575/can-scripts-be-inserted-with-innerhtml - else if (node.nodeName === "SCRIPT") { + } else if (node.nodeName === "SCRIPT") { const script = document.createElement("script") tag = script @@ -420,12 +419,11 @@ ) { substitutionValue = '"' + substitutionValue + '"' - } // contextual auto-escaping: // if the attribute is a uri attribute then we need to uri encode it and // remove bad protocols - else if ( + } else if ( URI_ATTRIBUTES.indexOf(name) !== -1 || CUSTOM_URI_ATTRIBUTES_REGEX.test(name) ) { @@ -438,10 +436,9 @@ substitutionValue = encodeURIComponent( substitutionValue, ) - } // entity encode if value is part of the URL - else { + } else { substitutionValue = encodeURI( encodeURIEntities( substitutionValue, @@ -479,12 +476,11 @@ } } } - } // contextual auto-escaping: // HTML encode attribute value if it is not a URL or URI to prevent // DOM Level 0 event handlers from executing xss code - else if ( + } else if ( typeof substitutionValue === "string" ) { substitutionValue = encodeAttributeHTMLEntities( From a6ca46d147362eb3b5327a46c298c7f863af9942 Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 13:08:23 +0100 Subject: [PATCH 04/11] Re-enable `arrow-body-style` --- .eslintrc.js | 2 +- src/completions.ts | 4 +--- src/completions/Bindings.ts | 18 ++++++------------ src/content/hinting.ts | 18 +++++------------- src/excmds.ts | 18 +++++------------- src/lib/autocontainers.ts | 8 ++------ src/lib/commandline_cmds.ts | 8 ++------ src/lib/containers.ts | 4 +--- src/lib/dom.ts | 4 +--- src/lib/editor.ts | 38 ++++++++++++------------------------- src/lib/url_util.ts | 4 +--- 11 files changed, 37 insertions(+), 89 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 4e3a056e..201edee3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -155,7 +155,7 @@ module.exports = { "@typescript-eslint/type-annotation-spacing": "error", "@typescript-eslint/unbound-method": "off", //"error", "@typescript-eslint/unified-signatures": "off", //"error", - "arrow-body-style": "off", //"error", + "arrow-body-style": "error", "arrow-parens": [ "off", "always" diff --git a/src/completions.ts b/src/completions.ts index b41be6ac..1359a214 100644 --- a/src/completions.ts +++ b/src/completions.ts @@ -239,9 +239,7 @@ export abstract class CompletionSourceFuse extends CompletionSource { /** Rtn sorted array of {option, score} */ scoredOptions(query: string, options = this.options): ScoredOption[] { - const searchThis = this.options.map((elem, index) => { - return { index, fuseKeys: elem.fuseKeys } - }) + const searchThis = this.options.map((elem, index) => ({ index, fuseKeys: elem.fuseKeys })) this.fuse = new Fuse(searchThis, this.fuseOptions) return this.fuse.search(query).map(result => { // console.log(result, result.item, query) diff --git a/src/completions/Bindings.ts b/src/completions/Bindings.ts index d2657d95..4c41d09d 100644 --- a/src/completions/Bindings.ts +++ b/src/completions/Bindings.ts @@ -64,14 +64,12 @@ export class BindingsCompletionSource extends Completions.CompletionSourceFuse { this.options = Object.keys(patterns) .filter(pattern => pattern.startsWith(urlPattern)) .sort() - .map(pattern => { - return new BindingsCompletionOption( + .map(pattern => new BindingsCompletionOption( pattern, { name: pattern, value: "", mode: "URL Pattern", - }) - }) + })) return this.updateChain() } @@ -84,14 +82,12 @@ export class BindingsCompletionSource extends Completions.CompletionSourceFuse { const modeStr = margs.length > 1 ? margs[1] : "" this.options = Binding.modes .filter(k => k.startsWith(modeStr)) - .map(name => { - return new BindingsCompletionOption( + .map(name => new BindingsCompletionOption( options + "--mode=" + name, { name, value: "", mode: "Mode Name", - }) - }) + })) return this.updateChain() } } @@ -124,14 +120,12 @@ export class BindingsCompletionSource extends Completions.CompletionSourceFuse { this.options = Object.keys(bindings) .filter(x => x.toLowerCase().startsWith(query) ) .sort() - .map(keystr => { - return new BindingsCompletionOption( + .map(keystr => new BindingsCompletionOption( options + keystr + " " + bindings[keystr], { name: keystr, value: JSON.stringify(bindings[keystr]), mode: `${configName} (${modeName})`, - }) - }) + })) return this.updateChain() } diff --git a/src/content/hinting.ts b/src/content/hinting.ts index d1c75e61..54570c07 100644 --- a/src/content/hinting.ts +++ b/src/content/hinting.ts @@ -428,25 +428,19 @@ export function hintPage( const firstTarget = modeState.hints[0].target - const firstTargetIsSelectable = (): boolean => { - return ( + const firstTargetIsSelectable = (): boolean => ( firstTarget instanceof HTMLAnchorElement && firstTarget.href !== "" && !firstTarget.href.startsWith("javascript:") ) - } - const allTargetsAreEqual = (): boolean => { - return ( + const allTargetsAreEqual = (): boolean => ( undefined === - modeState.hints.find(h => { - return ( + modeState.hints.find(h => ( !(h.target instanceof HTMLAnchorElement) || h.target.href !== (firstTarget as HTMLAnchorElement).href - ) - }) + )) ) - } if ( modeState.hints.length == 1 || @@ -551,9 +545,7 @@ function* hintnames_uniform( // And return first n permutations yield* map( islice(permutationsWithReplacement(hintchars, taglen), n), - perm => { - return perm.join("") - }, + perm => perm.join(""), ) } } diff --git a/src/excmds.ts b/src/excmds.ts index 2093514f..24f6f0bb 100644 --- a/src/excmds.ts +++ b/src/excmds.ts @@ -2620,13 +2620,9 @@ export async function qall() { //#background export async function containerclose(name: string) { const containerId = await Container.getId(name) - return browser.tabs.query({ cookieStoreId: containerId }).then(tabs => { - return browser.tabs.remove( - tabs.map(tab => { - return tab.id - }), - ) - }) + return browser.tabs.query({ cookieStoreId: containerId }).then(tabs => browser.tabs.remove( + tabs.map(tab => tab.id), + )) } /** Creates a new container. Note that container names must be unique and that the checks are case-insensitive. @@ -2761,12 +2757,8 @@ async function getnexttabs(tabid: number, n?: number) { const tabs: browser.tabs.Tab[] = await browser.tabs.query({ currentWindow: true, }) - const indexFilter = ((tab: browser.tabs.Tab) => { - return curIndex <= tab.index && (n ? tab.index < curIndex + Number(n) : true) - }).bind(n) - return tabs.filter(indexFilter).map((tab: browser.tabs.Tab) => { - return tab.id - }) + const indexFilter = ((tab: browser.tabs.Tab) => curIndex <= tab.index && (n ? tab.index < curIndex + Number(n) : true)).bind(n) + return tabs.filter(indexFilter).map((tab: browser.tabs.Tab) => tab.id) } // Moderately slow; should load in results as they arrive, perhaps diff --git a/src/lib/autocontainers.ts b/src/lib/autocontainers.ts index 633b2fa0..7b6aa9ce 100644 --- a/src/lib/autocontainers.ts +++ b/src/lib/autocontainers.ts @@ -180,9 +180,7 @@ export class AutoContain implements IAutoContain { }, 2000) } - getCancelledRequest = (tabId: number): ICancelledRequest => { - return this.cancelledRequests[tabId] - } + getCancelledRequest = (tabId: number): ICancelledRequest => this.cancelledRequests[tabId] // Clear the cancelled requests. clearCancelledRequests = (tabId: number): void => { @@ -311,7 +309,5 @@ export class AutoContain implements IAutoContain { // Parses autocontain directives and returns valid cookieStoreIds or errors. getAuconForDetails = async ( details: browser.webRequest.IDetails, - ): Promise => { - return this.getAuconForUrl(details.url) - } + ): Promise => this.getAuconForUrl(details.url) } diff --git a/src/lib/commandline_cmds.ts b/src/lib/commandline_cmds.ts index 454366f7..c68805f3 100644 --- a/src/lib/commandline_cmds.ts +++ b/src/lib/commandline_cmds.ts @@ -93,16 +93,12 @@ export function getCommandlineFns(cmdline_state) { /** * Selects the next history line. */ - "next_history": () => { - return cmdline_state.history(1) - }, + "next_history": () => cmdline_state.history(1), /** * Selects the prev history line. */ - "prev_history": () => { - return cmdline_state.history(-1) - }, + "prev_history": () => cmdline_state.history(-1), /** * Execute the content of the command line and hide it. **/ diff --git a/src/lib/containers.ts b/src/lib/containers.ts index d29569c6..34c259b1 100644 --- a/src/lib/containers.ts +++ b/src/lib/containers.ts @@ -122,9 +122,7 @@ export async function exists(cname: string): Promise { let exists = false try { const containers = await getAll() - const res = containers.filter(c => { - return c.name.toLowerCase() === cname.toLowerCase() - }) + const res = containers.filter(c => c.name.toLowerCase() === cname.toLowerCase()) if (res.length > 0) { exists = true } diff --git a/src/lib/dom.ts b/src/lib/dom.ts index 597d04fc..35dc9904 100644 --- a/src/lib/dom.ts +++ b/src/lib/dom.ts @@ -122,9 +122,7 @@ export function mouseEvent( export function elementsWithText() { return getElemsBySelector("*", [ isVisible, - hint => { - return hint.textContent !== "" - }, + hint => hint.textContent !== "", ]) } diff --git a/src/lib/editor.ts b/src/lib/editor.ts index 4ffe64c7..f48af93c 100644 --- a/src/lib/editor.ts +++ b/src/lib/editor.ts @@ -164,36 +164,30 @@ export const transpose_words = wrap_input( * Behaves like readline's [upcase_word](http://web.mit.edu/gnu/doc/html/rlman_1.html#SEC14). Makes the word the caret is in uppercase. **/ export const upcase_word = wrap_input( - needs_text((text, selectionStart, selectionEnd) => { - return applyWord(text, selectionStart, selectionEnd, word => + needs_text((text, selectionStart, selectionEnd) => applyWord(text, selectionStart, selectionEnd, word => word.toUpperCase(), - ) - }), + )), ) /** * Behaves like readline's [downcase_word](http://web.mit.edu/gnu/doc/html/rlman_1.html#SEC14). Makes the word the caret is in lowercase. **/ export const downcase_word = wrap_input( - needs_text((text, selectionStart, selectionEnd) => { - return applyWord(text, selectionStart, selectionEnd, word => + needs_text((text, selectionStart, selectionEnd) => applyWord(text, selectionStart, selectionEnd, word => word.toLowerCase(), - ) - }), + )), ) /** * Behaves like readline's [capitalize_word](http://web.mit.edu/gnu/doc/html/rlman_1.html#SEC14). Makes the initial character of the word the caret is in uppercase. **/ export const capitalize_word = wrap_input( - needs_text((text, selectionStart, selectionEnd) => { - return applyWord( + needs_text((text, selectionStart, selectionEnd) => applyWord( text, selectionStart, selectionEnd, word => word[0].toUpperCase() + word.substring(1), - ) - }), + )), ) /** @@ -339,17 +333,13 @@ export const end_of_line = wrap_input( /** * Behaves like readline's [forward_char](http://web.mit.edu/gnu/doc/html/rlman_1.html#SEC12). Moves the caret one character to the right. **/ -export const forward_char = wrap_input((text, selectionStart, selectionEnd) => { - return [null, selectionStart + 1, null] -}) +export const forward_char = wrap_input((text, selectionStart, selectionEnd) => [null, selectionStart + 1, null]) /** * Behaves like readline's [backward_char](http://web.mit.edu/gnu/doc/html/rlman_1.html#SEC12). Moves the caret one character to the left. **/ export const backward_char = wrap_input( - (text, selectionStart, selectionEnd) => { - return [null, selectionStart - 1, null] - }, + (text, selectionStart, selectionEnd) => [null, selectionStart - 1, null], ) /** @@ -383,21 +373,17 @@ export const backward_word = wrap_input( * Insert text in the current input. **/ export const insert_text = wrap_input( - (text, selectionStart, selectionEnd, arg) => { - return [ + (text, selectionStart, selectionEnd, arg) => [ text.slice(0, selectionStart) + arg + text.slice(selectionEnd), selectionStart + arg.length, null, - ] - }, + ], ) export const rot13 = wrap_input( - (text, selectionStart, selectionEnd) => { - return [ + (text, selectionStart, selectionEnd) => [ rot13_helper(text.slice(0, selectionStart) + text.slice(selectionEnd)), selectionStart, null, - ] - }, + ], ) diff --git a/src/lib/url_util.ts b/src/lib/url_util.ts index 93831706..76cf16f0 100644 --- a/src/lib/url_util.ts +++ b/src/lib/url_util.ts @@ -254,9 +254,7 @@ export function deleteQuery(url: URL, matchQuery: string): URL { const qys = getUrlQueries(url) - const new_qys = qys.filter(q => { - return q.split("=")[0] !== matchQuery - }) + const new_qys = qys.filter(q => q.split("=")[0] !== matchQuery) setUrlQueries(newUrl, new_qys) From beebb6ffe5ec5677e4c8cf406f0f65f9ae89d32c Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 13:11:03 +0100 Subject: [PATCH 05/11] Re-enable `unified-signatures` --- .eslintrc.js | 2 +- src/tridactyl.d.ts | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 201edee3..0471ce29 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -154,7 +154,7 @@ module.exports = { ], "@typescript-eslint/type-annotation-spacing": "error", "@typescript-eslint/unbound-method": "off", //"error", - "@typescript-eslint/unified-signatures": "off", //"error", + "@typescript-eslint/unified-signatures": "error", "arrow-body-style": "error", "arrow-parens": [ "off", diff --git a/src/tridactyl.d.ts b/src/tridactyl.d.ts index 43add7b2..3eb066fd 100644 --- a/src/tridactyl.d.ts +++ b/src/tridactyl.d.ts @@ -48,9 +48,7 @@ interface findResult { interface HTMLElement { // Let's be future proof: // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus - focus(options: any): void - // Let's also implement the current function signature. - focus(): void + focus(options?: any): void } /* eslint-disable @typescript-eslint/ban-types */ @@ -67,9 +65,10 @@ declare namespace browser.find { function find(query, object): any } -// setZoom has an optional first argument of tabId. Unclear how first argument can be optional. declare namespace browser.tabs { function setZoom(zoomFactor: number): Promise + // setZoom has an optional first argument of tabId: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/setZoom#Parameters + // eslint-disable-next-line @typescript-eslint/unified-signatures function setZoom(tabId: number, zoomFactor: number): Promise function toggleReaderMode(tabId?: number): Promise } From 3155301bb9ab8e094f082e932f8f85d028a5b2f4 Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 13:31:00 +0100 Subject: [PATCH 06/11] Re-enable `unbound-method` --- .eslintrc.js | 2 +- src/content/controller_content.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 0471ce29..dd119142 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -153,7 +153,7 @@ module.exports = { } ], "@typescript-eslint/type-annotation-spacing": "error", - "@typescript-eslint/unbound-method": "off", //"error", + "@typescript-eslint/unbound-method": "error", "@typescript-eslint/unified-signatures": "error", "arrow-body-style": "error", "arrow-parens": [ diff --git a/src/content/controller_content.ts b/src/content/controller_content.ts index f081e55d..a33ab995 100644 --- a/src/content/controller_content.ts +++ b/src/content/controller_content.ts @@ -62,12 +62,12 @@ class KeyCanceller { this.keyUp.push(ke) } - cancelKeyPress(ke: KeyboardEvent) { + public cancelKeyPress = (ke: KeyboardEvent) => { if (!ke.isTrusted) return this.cancelKey(ke, this.keyPress) } - cancelKeyUp(ke: KeyboardEvent) { + public cancelKeyUp = (ke: KeyboardEvent) => { if (!ke.isTrusted) return this.cancelKey(ke, this.keyUp) } From ab13c700eee40999b70aaaa4447f6e89bc84906f Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 13:34:25 +0100 Subject: [PATCH 07/11] Update comments on linting rules --- .eslintrc.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index dd119142..1e9ed816 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -138,8 +138,8 @@ module.exports = { } ], "@typescript-eslint/require-await": "off", //"error", - "@typescript-eslint/restrict-plus-operands": "off", //"error", - "@typescript-eslint/restrict-template-expressions": "off", //"error", + "@typescript-eslint/restrict-plus-operands": "off", //"error", // We use this a lot - fixing it is a problem for a rainy day + "@typescript-eslint/restrict-template-expressions": "off", "@typescript-eslint/semi": [ "off", null From dee3b7e6c125b005f488c31d6bfab1fd3f3a0082 Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 13:48:22 +0100 Subject: [PATCH 08/11] Re-enable `require-await` --- .eslintrc.js | 17 +++++----- src/background/omnibox.ts | 9 +++--- src/excmds.ts | 9 ++---- src/lib/containers.ts | 10 +++--- src/lib/native.ts | 65 +++++++++++++++++++++------------------ src/lib/webext.ts | 32 +++++++++++-------- 6 files changed, 78 insertions(+), 64 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 1e9ed816..f8a0cac1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -137,7 +137,7 @@ module.exports = { "avoidEscape": true } ], - "@typescript-eslint/require-await": "off", //"error", + "@typescript-eslint/require-await": "error", "@typescript-eslint/restrict-plus-operands": "off", //"error", // We use this a lot - fixing it is a problem for a rainy day "@typescript-eslint/restrict-template-expressions": "off", "@typescript-eslint/semi": [ @@ -252,11 +252,12 @@ module.exports = { "use-isnan": "error", "valid-typeof": "off" }, - // // We ultimately didn't need this but I thought I should document it anyway - // "overrides": [{ - // "files": ["src/completions/*.ts",], - // "rules": { - // "@typescript-eslint/no-empty-function": "off", - // }, - // }], + "overrides": [{ + "files": ["src/completions/*.ts", "src/excmds.ts"], + "rules": { + // We have methods that must be async in some classes but not in others + // In src/excmds anything that crosses between content<->background must be async even if it looks like it isn't + "@typescript-eslint/require-await": "off", + }, + }], }; diff --git a/src/background/omnibox.ts b/src/background/omnibox.ts index 68d57db1..70a94432 100644 --- a/src/background/omnibox.ts +++ b/src/background/omnibox.ts @@ -4,13 +4,14 @@ */ import * as controller from "@src/lib/controller" -export async function inputEnteredListener( - input: string, disposition: - browser.omnibox.OnInputEnteredDisposition) { +export function inputEnteredListener( + input: string, + disposition: browser.omnibox.OnInputEnteredDisposition, +) { controller.acceptExCmd(input) } -export async function init() { +export function init() { browser.omnibox.onInputEntered.addListener(inputEnteredListener) browser.omnibox.setDefaultSuggestion({ description: `Execute a Tridactyl exstr (for example, "tabopen -c container www.google.com")`, diff --git a/src/excmds.ts b/src/excmds.ts index 24f6f0bb..24f93f31 100644 --- a/src/excmds.ts +++ b/src/excmds.ts @@ -2620,9 +2620,7 @@ export async function qall() { //#background export async function containerclose(name: string) { const containerId = await Container.getId(name) - return browser.tabs.query({ cookieStoreId: containerId }).then(tabs => browser.tabs.remove( - tabs.map(tab => tab.id), - )) + return browser.tabs.query({ cookieStoreId: containerId }).then(tabs => browser.tabs.remove(tabs.map(tab => tab.id))) } /** Creates a new container. Note that container names must be unique and that the checks are case-insensitive. @@ -2669,7 +2667,7 @@ export async function containerupdate(name: string, uname: string, ucolor: strin logger.debug("containerupdate parameters: " + name + ", " + uname + ", " + ucolor + ", " + uicon) const containerId = await Container.fuzzyMatch(name) const containerObj = Container.fromString(uname, ucolor, uicon) - await Container.update(containerId, containerObj) + Container.update(containerId, containerObj) } /** Shows a list of the current containers in Firefox's native JSON viewer in the current tab. @@ -3617,8 +3615,7 @@ export async function sanitise(...args: string[]) { */ } if (args.find(x => x === "all") !== undefined) { - for (const attr in dts) - if (Object.prototype.hasOwnProperty.call(dts, attr)) dts[attr] = true + for (const attr in dts) if (Object.prototype.hasOwnProperty.call(dts, attr)) dts[attr] = true } else { // We bother checking if dts[x] is false because // browser.browsingData.remove() is very strict on the format of the diff --git a/src/lib/containers.ts b/src/lib/containers.ts index 34c259b1..094d6dcc 100644 --- a/src/lib/containers.ts +++ b/src/lib/containers.ts @@ -80,7 +80,7 @@ export async function remove(name: string) { @param color the new color of the container @param icon the new icon of the container */ -export async function update( +export function update( containerId: string, updateObj: { name: string @@ -88,7 +88,7 @@ export async function update( icon: browser.contextualIdentities.IdentityIcon }, ) { - const {name, color, icon} = updateObj + const { name, color, icon } = updateObj if (!isValidColor(color)) { logger.debug(updateObj) throw new Error("[Container.update] invalid container color: " + color) @@ -97,7 +97,7 @@ export async function update( logger.debug(updateObj) throw new Error("[Container.update] invalid container icon: " + icon) } - browser.contextualIdentities.update(containerId, {name, color, icon}) + browser.contextualIdentities.update(containerId, { name, color, icon }) } /** Gets a container object from a supplied container id string. If no container corresponds to containerId, returns a default empty container. @@ -122,7 +122,9 @@ export async function exists(cname: string): Promise { let exists = false try { const containers = await getAll() - const res = containers.filter(c => c.name.toLowerCase() === cname.toLowerCase()) + const res = containers.filter( + c => c.name.toLowerCase() === cname.toLowerCase(), + ) if (res.length > 0) { exists = true } diff --git a/src/lib/native.ts b/src/lib/native.ts index 704f143a..30970bf1 100644 --- a/src/lib/native.ts +++ b/src/lib/native.ts @@ -102,7 +102,8 @@ export async function getBestEditor(): Promise { const vim_positioning_arg = ` ${arg_quote}+normal!%lGzv%c|${arg_quote}` if (os === "mac") { gui_candidates = [ - "/Applications/MacVim.app/Contents/bin/mvim -f" + vim_positioning_arg, + "/Applications/MacVim.app/Contents/bin/mvim -f" + + vim_positioning_arg, "/usr/local/bin/vimr --wait --nvim +only", ] // if anyone knows of any "sensible" terminals that let you send them commands to run, @@ -149,7 +150,12 @@ export async function getBestEditor(): Promise { ] } - tui_editors = ["vim" + vim_positioning_arg, "nvim" + vim_positioning_arg, "nano %f", "emacs -nw %f"] + tui_editors = [ + "vim" + vim_positioning_arg, + "nvim" + vim_positioning_arg, + "nano %f", + "emacs -nw %f", + ] // Consider GUI editors let cmd = await firstinpath(gui_candidates) @@ -246,12 +252,17 @@ export async function firstinpath(cmdarray) { return cmd } -export async function editor(file: string, line: number, col: number, content?: string) { +export async function editor( + file: string, + line: number, + col: number, + content?: string, +) { if (content !== undefined) await write(file, content) - const editorcmd = - (config.get("editorcmd") === "auto" - ? await getBestEditor() - : config.get("editorcmd")) + const editorcmd = (config.get("editorcmd") === "auto" + ? await getBestEditor() + : config.get("editorcmd") + ) .replace(/%l/, line) .replace(/%c/, col) let exec @@ -260,8 +271,7 @@ export async function editor(file: string, line: number, col: number, content?: } else { exec = await run(editorcmd + " " + file) } - if (exec.code != 0) - return exec + if (exec.code != 0) return exec return read(file) } @@ -371,9 +381,7 @@ export async function clipboard( const result = await run(`${clipcmd} -i`, str) if (result.code !== 0) throw new Error( - `External command failed with code ${ - result.code - }: ${clipcmd}`, + `External command failed with code ${result.code}: ${clipcmd}`, ) return "" } else { @@ -448,9 +456,7 @@ export async function parseProfilesIni(content: string, basePath: string) { } else if (profile.IsRelative === "0") { if (profile.Path.substring(0, basePath.length) !== basePath) { throw new Error( - `Error parsing profiles ini: basePath "${basePath}" doesn't match profile path ${ - profile.Path - }`, + `Error parsing profiles ini: basePath "${basePath}" doesn't match profile path ${profile.Path}`, ) } profile.relativePath = profile.Path.substring(basePath.length) @@ -509,8 +515,7 @@ export async function getProfileUncached() { // Then, try to find a profile path in the arguments given to Firefox const cmdline = await ff_cmdline().catch(e => "") let profile = cmdline.indexOf("--profile") - if (profile === -1) - profile = cmdline.indexOf("-profile") + if (profile === -1) profile = cmdline.indexOf("-profile") if (profile >= 0 && profile < cmdline.length - 1) { const profilePath = cmdline[profile + 1] if (iniSucceeded) { @@ -545,9 +550,7 @@ export async function getProfileUncached() { } } throw new Error( - `native.ts:getProfile() : '${ - cmdline[p] - }' found in command line arguments but no matching profile name found in "${iniPath}"`, + `native.ts:getProfile() : '${cmdline[p]}' found in command line arguments but no matching profile name found in "${iniPath}"`, ) } } @@ -562,10 +565,7 @@ export async function getProfileUncached() { profilecmd.content = profilecmd.content.trim() // If there's only one profile in use, use that to find the right profile if (profilecmd.content.split("\n").length === 1) { - const path = profilecmd.content - .split("/") - .slice(0, -1) - .join("/") + const path = profilecmd.content.split("/").slice(0, -1).join("/") if (iniSucceeded) { for (const profileName of Object.keys(iniObject)) { const profile = iniObject[profileName] @@ -602,8 +602,7 @@ export async function getProfileUncached() { // Disk operations are extremely slow on windows, let's cache our profile info let cachedProfile export async function getProfile() { - if (cachedProfile === undefined) - cachedProfile = await getProfileUncached() + if (cachedProfile === undefined) cachedProfile = await getProfileUncached() return cachedProfile } // It makes sense to pre-fetch this value in the background script because it's @@ -627,7 +626,7 @@ export async function getProfileDir() { return getProfile().then(p => p.absolutePath) } -export async function parsePrefs(prefFileContent: string) { +export function parsePrefs(prefFileContent: string) { // This RegExp currently only deals with " but for correctness it should // also deal with ' and ` // We could also just give up on parsing and eval() the whole thing @@ -790,17 +789,23 @@ export async function unfixamo() { const tridactylPref2 = "tridactyl.unfixedamo_removed" const restricted = "extensions.webextensions.restrictedDomains" const amoblocker = "privacy.resistFingerprinting.block_mozAddonManager" - const restrictedDomains = '"accounts-static.cdn.mozilla.net,accounts.firefox.com,addons.cdn.mozilla.net,addons.mozilla.org,api.accounts.firefox.com,content.cdn.mozilla.net,discovery.addons.mozilla.org,install.mozilla.org,oauth.accounts.firefox.com,profile.accounts.firefox.com,support.mozilla.org,sync.services.mozilla.com"' + const restrictedDomains = + '"accounts-static.cdn.mozilla.net,accounts.firefox.com,addons.cdn.mozilla.net,addons.mozilla.org,api.accounts.firefox.com,content.cdn.mozilla.net,discovery.addons.mozilla.org,install.mozilla.org,oauth.accounts.firefox.com,profile.accounts.firefox.com,support.mozilla.org,sync.services.mozilla.com"' // Exit if we've already run this once if (userjs[tridactylPref2] === "true") return - if (userjs[restricted] === "" || userjs[restricted] === restrictedDomains) { + if ( + userjs[restricted] === "" || + userjs[restricted] === restrictedDomains + ) { await removePref(tridactylPref) // Clean up after first attempt if it exists await removePref(restricted) await removePref(amoblocker) await writePref(tridactylPref2, "true") - browserBg.tabs.create({url: browserBg.runtime.getURL("static/unfixamo.html")}) + browserBg.tabs.create({ + url: browserBg.runtime.getURL("static/unfixamo.html"), + }) } return diff --git a/src/lib/webext.ts b/src/lib/webext.ts index 59a32ea8..832fb83e 100644 --- a/src/lib/webext.ts +++ b/src/lib/webext.ts @@ -39,10 +39,12 @@ export const browserBg = inContentScript() ? browserProxy : browser * */ export async function activeTab() { - return (await browserBg.tabs.query({ - active: true, - currentWindow: true, - }))[0] + return ( + await browserBg.tabs.query({ + active: true, + currentWindow: true, + }) + )[0] } export async function activeTabId() { @@ -122,9 +124,11 @@ export async function openInNewTab( break case "last": // Infinity can't be serialised, apparently. - options.index = (await browserBg.tabs.query({ - currentWindow: true, - })).length + options.index = ( + await browserBg.tabs.query({ + currentWindow: true, + }) + ).length break case "related": if (await firefoxVersionAtLeast(57)) { @@ -135,16 +139,20 @@ export async function openInNewTab( break } - if (kwargs.active === false) { // load in background + if (kwargs.active === false) { + // load in background return browserBg.tabs.create(options) - } else { // load in background and then activate, per issue #1993 - return browserBg.tabs.create(options).then(newtab => browserBg.tabs.update(newtab.id, { active: true })) + } else { + // load in background and then activate, per issue #1993 + return browserBg.tabs + .create(options) + .then(newtab => browserBg.tabs.update(newtab.id, { active: true })) } } // lazily copied from excmds.ts' winopen - forceURI really ought to be moved to lib/webext // Should consider changing interface of this to match openInNewTab or vice versa -export async function openInNewWindow(createData = {}) { +export function openInNewWindow(createData = {}) { browserBg.windows.create(createData) } @@ -254,5 +262,5 @@ export async function openInTab(tab, opts = {}, strarr: string[]) { // No search engine has been defined in Tridactyl, let's use firefox's default search engine browserBg.search.search({ tabId: tab.id, query: queryString }) - return tab; + return tab } From ff5c0d7323e46263973da98df5a13d2faec8ce5c Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 13:55:22 +0100 Subject: [PATCH 09/11] Re-enable `quotes` --- .eslintrc.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index f8a0cac1..acf0210e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -131,11 +131,12 @@ module.exports = { "@typescript-eslint/prefer-namespace-keyword": "error", "@typescript-eslint/prefer-regexp-exec": "off", //"error", "@typescript-eslint/quotes": [ - "off", //"error", + "error", "double", { - "avoidEscape": true - } + "avoidEscape": true, + "allowTemplateLiterals": true, + }, ], "@typescript-eslint/require-await": "error", "@typescript-eslint/restrict-plus-operands": "off", //"error", // We use this a lot - fixing it is a problem for a rainy day From d5192f6daccf55cf23e5dd0e0821a3aae8ed0a54 Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 15:19:46 +0100 Subject: [PATCH 10/11] Re-enable `prefer-regexp-exec` --- .eslintrc.js | 2 +- src/background.ts | 30 ++++++++++------------ src/completions/Tab.ts | 57 ++++++++++++++++++++++------------------- src/excmds.ts | 16 ++++++------ src/lib/dom.ts | 12 ++++----- src/lib/editor_utils.ts | 36 ++++++++++++-------------- src/lib/native.ts | 6 ++--- src/perf.ts | 9 ++++--- 8 files changed, 84 insertions(+), 84 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index acf0210e..a489b3bc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -129,7 +129,7 @@ module.exports = { "@typescript-eslint/prefer-for-of": "error", "@typescript-eslint/prefer-function-type": "error", "@typescript-eslint/prefer-namespace-keyword": "error", - "@typescript-eslint/prefer-regexp-exec": "off", //"error", + "@typescript-eslint/prefer-regexp-exec": "error", "@typescript-eslint/quotes": [ "error", "double", diff --git a/src/background.ts b/src/background.ts index 5aebb33f..9607d3ab 100644 --- a/src/background.ts +++ b/src/background.ts @@ -27,7 +27,7 @@ import * as omnibox from "@src/background/omnibox" import * as R from "ramda" // Add various useful modules to the window for debugging -; (window as any).tri = Object.assign(Object.create(null), { +;(window as any).tri = Object.assign(Object.create(null), { messaging, excmds: excmds_background, convert, @@ -54,9 +54,9 @@ import { HintingCmds } from "@src/background/hinting" // here. controller.setExCmds({ "": excmds_background, - "ex": CmdlineCmds, - "text": EditorCmds, - "hint": HintingCmds + ex: CmdlineCmds, + text: EditorCmds, + hint: HintingCmds, }) // {{{ tri.contentLocation @@ -78,13 +78,11 @@ browser.tabs.onActivated.addListener(ev => { }) }) // Update on navigation too (but remember that sometimes people open tabs in the background :) ) -browser.webNavigation.onDOMContentLoaded.addListener( - () => { - browser.tabs.query({ currentWindow: true, active: true }).then(t => { - (window as any).tri.contentLocation = new URL(t[0].url) - }) - }, -) +browser.webNavigation.onDOMContentLoaded.addListener(() => { + browser.tabs.query({ currentWindow: true, active: true }).then(t => { + (window as any).tri.contentLocation = new URL(t[0].url) + }) +}) // Prevent Tridactyl from being updated while it is running in the hope of fixing #290 browser.runtime.onUpdateAvailable.addListener(_ => undefined) @@ -98,7 +96,7 @@ browser.runtime.onStartup.addListener(_ => { } else { native.run("hostname").then(hostname => { for (const host of hosts) { - if (hostname.content.match(host)) { + if (new RegExp(host).exec(hostname.content)) { controller.acceptExCmd(aucmds[host]) } } @@ -164,9 +162,7 @@ browser.webRequest.onBeforeRequest.addListener( ["blocking"], ) -browser.tabs.onCreated.addListener( - aucon.tabCreatedListener, -) +browser.tabs.onCreated.addListener(aucon.tabCreatedListener) // }}} @@ -182,7 +178,7 @@ const messages = { downloadUrl: download_background.downloadUrl, downloadUrlAs: download_background.downloadUrlAs, }, - browser_proxy_background: {shim: proxy_background.shim} + browser_proxy_background: { shim: proxy_background.shim }, } export type Messages = typeof messages @@ -211,6 +207,6 @@ omnibox.init() // {{{ Obey Mozilla's orders https://github.com/tridactyl/tridactyl/issues/1800 -native.unfixamo(); +native.unfixamo() /// }}} diff --git a/src/completions/Tab.ts b/src/completions/Tab.ts index f6c5d873..0135e61f 100644 --- a/src/completions/Tab.ts +++ b/src/completions/Tab.ts @@ -38,18 +38,17 @@ class BufferCompletionOption extends Completions.CompletionOptionHTML const favIconUrl = tab.favIconUrl ? tab.favIconUrl : Completions.DEFAULT_FAVICON - this.html = html` - ${pre.padEnd(2)} - - - ${tab.index + 1}: ${tab.title} - - ${tab.url} - - ` + this.html = html` + ${pre.padEnd(2)} + + + ${tab.index + 1}: ${tab.title} + + ${tab.url} + + ` } } @@ -126,15 +125,17 @@ export class BufferCompletionSource extends Completions.CompletionSourceFuse { /** Return the scoredOption[] result for the nth tab */ private nthTabscoredOptions( n: number, - options: BufferCompletionOption[] + options: BufferCompletionOption[], ): Completions.ScoredOption[] { for (const [index, option] of enumerate(options)) { if (option.tabIndex === n) { - return [{ - index, - option, - score: 0, - }, ] + return [ + { + index, + option, + score: 0, + }, + ] } } } @@ -142,10 +143,10 @@ export class BufferCompletionSource extends Completions.CompletionSourceFuse { /** Return the scoredOption[] result for the tab index startswith n */ private TabscoredOptionsStartsWithN( n: number, - options: BufferCompletionOption[] + options: BufferCompletionOption[], ): Completions.ScoredOption[] { const nstr = (n + 1).toString() - const res = []; + const res = [] for (const [index, option] of enumerate(options)) { if ((option.tabIndex + 1).toString().startsWith(nstr)) { res.push({ @@ -158,7 +159,7 @@ export class BufferCompletionSource extends Completions.CompletionSourceFuse { // old input will change order: 12 => 123 => 12 res.sort((a, b) => a.option.tabIndex - b.option.tabIndex) - return res; + return res } private async fillOptions() { @@ -167,17 +168,19 @@ export class BufferCompletionSource extends Completions.CompletionSourceFuse { }) const options = [] // Get alternative tab, defined as last accessed tab. - tabs.sort((a, b) => (b.lastAccessed - a.lastAccessed)) + tabs.sort((a, b) => b.lastAccessed - a.lastAccessed) const alt = tabs[1] - const useMruTabOrder = (config.get("tabsort") === "mru") + const useMruTabOrder = config.get("tabsort") === "mru" if (!useMruTabOrder) { - tabs.sort((a, b) => (a.index - b.index)) + tabs.sort((a, b) => a.index - b.index) } const container_all = await browserBg.contextualIdentities.query({}) const container_map = new Map() - container_all.forEach(elem => container_map.set(elem.cookieStoreId, elem)) + container_all.forEach(elem => + container_map.set(elem.cookieStoreId, elem), + ) // firefox-default is not in contextualIdenetities container_map.set("firefox-default", Containers.DefaultContainer) @@ -191,7 +194,7 @@ export class BufferCompletionSource extends Completions.CompletionSourceFuse { (tab.index + 1).toString(), tab, tab === alt, - tab_container + tab_container, ), ) } @@ -219,7 +222,7 @@ export class BufferCompletionSource extends Completions.CompletionSourceFuse { // When the user is asking for tabmove completions, don't autoselect if the query looks like a relative move https://github.com/tridactyl/tridactyl/issues/825 this.shouldSetStateFromScore = !( - prefix === "tabmove " && query.match("^[+-][0-9]+$") + prefix === "tabmove " && /^[+-][0-9]+$/.exec(query) ) if (!this.options) { diff --git a/src/excmds.ts b/src/excmds.ts index 24f93f31..4b65d79b 100644 --- a/src/excmds.ts +++ b/src/excmds.ts @@ -1019,7 +1019,7 @@ export async function scrollpx(a: number, b: number) { */ //#content export function scrollto(a: number | string, b: number | "x" | "y" = "y") { - if (typeof a === "string" && a.match(/c$/i)) { + if (typeof a === "string" && /c$/i.exec(a)) { a = (Number(a.replace(/c$/, "")) * 100) / (2 * Math.PI) } a = Number(a) @@ -1199,10 +1199,10 @@ export async function open(...urlarr: string[]) { const url = urlarr.join(" ") // Setting window.location to about:blank results in a page we can't access, tabs.update works. - if (!ABOUT_WHITELIST.includes(url) && url.match(/^(about|file):.*/)) { + if (!ABOUT_WHITELIST.includes(url) && /^(about|file):.*/.exec(url)) { // Open URLs that firefox won't let us by running `firefox ` on the command line return nativeopen(url) - } else if (url.match(/^javascript:/)) { + } else if (/^javascript:/.exec(url)) { const bookmarklet = url.replace(/^javascript:/, "") document.body.append( html` @@ -1236,7 +1236,7 @@ export async function bmarks(opt: string, ...urlarr: string[]) { export async function open_quiet(...urlarr: string[]) { const url = urlarr.join(" ") - if (!ABOUT_WHITELIST.includes(url) && url.match(/^(about|file):.*/)) { + if (!ABOUT_WHITELIST.includes(url) && /^(about|file):.*/.exec(url)) { return nativeopen(url) } @@ -2134,7 +2134,7 @@ export async function tabopen(...addressarr: string[]) { const query = await argParse(addressarr) const address = query.join(" ") - if (!ABOUT_WHITELIST.includes(address) && address.match(/^(about|file):.*/)) { + if (!ABOUT_WHITELIST.includes(address) && /^(about|file):.*/.exec(address)) { return nativeopen(address) } @@ -2579,7 +2579,7 @@ export async function winopen(...args: string[]) { } const address = args.join(" ") - if (!ABOUT_WHITELIST.includes(address) && address.match(/^(about|file):.*/)) { + if (!ABOUT_WHITELIST.includes(address) && /^(about|file):.*/.exec(address)) { return nativeopen(firefoxArgs, address) } @@ -3099,7 +3099,7 @@ export async function tab(index: number | "#") { //#background export async function taball(id: string) { const windows = (await browser.windows.getAll()).map(w => w.id).sort((a, b) => a - b) - if (id === null || id === undefined || !id.match(/\d+\.\d+/)) { + if (id === null || id === undefined || /\d+\.\d+/.exec(id)) { const tab = await activeTab() const prevId = id id = windows.indexOf(tab.windowId) + "." + (tab.index + 1) @@ -3567,7 +3567,7 @@ export async function sanitise(...args: string[]) { // If the -t flag has been given and there is an arg after it if (flagpos > -1) { if (flagpos < args.length - 1) { - const match = args[flagpos + 1].match("^([0-9])+(m|h|d|w)$") + const match = /^([0-9])+(m|h|d|w)$/.exec(args[flagpos + 1]) // If the arg of the flag matches Pentadactyl's sanitisetimespan format if (match !== null && match.length === 3) { // Compute the timespan in milliseconds and get a Date object diff --git a/src/lib/dom.ts b/src/lib/dom.ts index 35dc9904..d3b07465 100644 --- a/src/lib/dom.ts +++ b/src/lib/dom.ts @@ -120,10 +120,7 @@ export function mouseEvent( } export function elementsWithText() { - return getElemsBySelector("*", [ - isVisible, - hint => hint.textContent !== "", - ]) + return getElemsBySelector("*", [isVisible, hint => hint.textContent !== ""]) } /** Iterable of elements that match xpath. @@ -304,7 +301,7 @@ export function getAllDocumentFrames(doc = document) { export function getSelector(e: HTMLElement) { function uniqueSelector(e: HTMLElement) { // Only matching alphanumeric selectors because others chars might have special meaning in CSS - if (e.id && e.id.match("^[a-zA-Z0-9]+$")) return "#" + e.id + if (e.id && /^[a-zA-Z0-9]+$/.exec(e.id)) return "#" + e.id // If we reached the top of the document if (!e.parentElement) return "HTML" // Compute the position of the element @@ -537,7 +534,10 @@ function onPageFocus(elem: HTMLElement, args: any[]): boolean { async function setInput(el) { const tab = await activeTabId() // store maximum of 10 elements to stop this getting bonkers huge - const arr = (await State.getAsync("prevInputs")).concat({ tab, inputId: el.id }) + const arr = (await State.getAsync("prevInputs")).concat({ + tab, + inputId: el.id, + }) state.prevInputs = arr.slice(Math.max(arr.length - 10, 0)) } diff --git a/src/lib/editor_utils.ts b/src/lib/editor_utils.ts index 660d60cf..1a9f8c06 100644 --- a/src/lib/editor_utils.ts +++ b/src/lib/editor_utils.ts @@ -1,4 +1,3 @@ - // We have a single dependency on config: getting the value of the WORDPATTERN setting // Perhaps we could find a way to get rid of it? import * as config from "@src/lib/config" @@ -165,7 +164,11 @@ export function needs_text(fn: editor_function, arg?: any): editor_function { /** * Returns line and column number. */ -export function getLineAndColNumber(text: string, start: number, end: number): [string, number, number] { +export function getLineAndColNumber( + text: string, + start: number, + end: number, +): [string, number, number] { const lines = text.split("\n") let totalChars = 0 for (let i = 0; i < lines.length; ++i) { @@ -188,21 +191,18 @@ export function getWordBoundaries( ): [number, number] { if (position < 0 || position > text.length) throw new Error( - `getWordBoundaries: position (${position}) should be within text ("${text}") boundaries (0, ${ - text.length - })`, + `getWordBoundaries: position (${position}) should be within text ("${text}") boundaries (0, ${text.length})`, ) const pattern = new RegExp(config.get("wordpattern"), "g") let boundary1 = position < text.length ? position : text.length - 1 const direction = before ? -1 : 1 // if the caret is not in a word, try to find the word before or after it // For `before`, we should check the char before the caret - if (before && boundary1 > 0) - boundary1 -= 1 + if (before && boundary1 > 0) boundary1 -= 1 while ( boundary1 >= 0 && boundary1 < text.length && - !text[boundary1].match(pattern) + !pattern.exec(text[boundary1]) ) { boundary1 += direction } @@ -214,7 +214,7 @@ export function getWordBoundaries( while ( boundary1 >= 0 && boundary1 < text.length && - !text[boundary1].match(pattern) + !pattern.exec(text[boundary1]) ) { boundary1 -= direction } @@ -222,12 +222,10 @@ export function getWordBoundaries( if (boundary1 < 0) boundary1 = 0 else if (boundary1 >= text.length) boundary1 = text.length - 1 - if (!text[boundary1].match(pattern)) { + if (!pattern.exec(text[boundary1])) { // there is no word in text throw new Error( - `getWordBoundaries: no characters matching wordpattern (${ - pattern.source - }) in text (${text})`, + `getWordBoundaries: no characters matching wordpattern (${pattern.source}) in text (${text})`, ) } @@ -235,7 +233,7 @@ export function getWordBoundaries( while ( boundary1 >= 0 && boundary1 < text.length && - !!text[boundary1].match(pattern) + !!pattern.exec(text[boundary1]) ) { boundary1 += direction } @@ -247,7 +245,7 @@ export function getWordBoundaries( while ( boundary2 >= 0 && boundary2 < text.length && - !!text[boundary2].match(pattern) + !!pattern.exec(text[boundary2]) ) { boundary2 -= direction } @@ -268,10 +266,10 @@ export function wordAfterPos(text: string, position: number) { throw new Error(`wordAfterPos: position (${position}) is less that 0`) const pattern = new RegExp(config.get("wordpattern"), "g") // move position out of the current word - while (position < text.length && !!text[position].match(pattern)) + while (position < text.length && !!pattern.exec(text[position])) position += 1 // try to find characters that match wordpattern - while (position < text.length && !text[position].match(pattern)) + while (position < text.length && !pattern.exec(text[position])) position += 1 if (position >= text.length) return -1 return position @@ -289,8 +287,8 @@ export const rot13_helper = (s: string, n: number = 13): string => { export const charesar = (c: string, n: number = 13): string => { const cn = c.charCodeAt(0) if (cn >= 65 && cn <= 90) - return String.fromCharCode((((cn - 65) + n) % 26) + 65) + return String.fromCharCode(((cn - 65 + n) % 26) + 65) if (cn >= 97 && cn <= 122) - return String.fromCharCode((((cn - 97) + n) % 26) + 97) + return String.fromCharCode(((cn - 97 + n) % 26) + 97) return c } diff --git a/src/lib/native.ts b/src/lib/native.ts index 30970bf1..e9653fad 100644 --- a/src/lib/native.ts +++ b/src/lib/native.ts @@ -426,12 +426,12 @@ export async function parseProfilesIni(content: string, basePath: string) { let current = "General" const result = {} for (const line of lines) { - let match = line.match(/^\[([^\]]+)\]$/) + let match = /^\[([^\]]+)\]$/.exec(line) if (match !== null) { current = match[1] result[current] = {} } else { - match = line.match(/^([^=]+)=([^=]+)$/) + match = /^([^=]+)=([^=]+)$/.exec(line) if (match !== null) { result[current][match[1]] = match[2] } @@ -635,7 +635,7 @@ export function parsePrefs(prefFileContent: string) { ) // Fragile parsing return prefFileContent.split("\n").reduce((prefs, line) => { - const matches = line.match(regex) + const matches = regex.exec(line) if (!matches) { return prefs } diff --git a/src/perf.ts b/src/perf.ts index 7c70855e..0f4dd000 100644 --- a/src/perf.ts +++ b/src/perf.ts @@ -278,7 +278,6 @@ export class StatsLogger { private incrementIdx() { this.idx = (this.idx + 1) % this.buffersize } - } /** @@ -388,7 +387,7 @@ const extractRegExp = new RegExp( // sample itself. ) function extractMetricName(counterName: string): MetricNameInfo { - const matchresult = counterName.match(extractRegExp) + const matchresult = extractRegExp.exec(counterName) if (!matchresult) return const [ownerName, functionName, uniqueSuffix] = matchresult.slice(1) @@ -416,5 +415,9 @@ class MetricName { } function sendStats(list: PerformanceEntryList) { - messaging.message("performance_background", "receiveStatsJson", JSON.stringify(list)) + messaging.message( + "performance_background", + "receiveStatsJson", + JSON.stringify(list), + ) } From 1457219c2336d16c2f2c90f30391b29fe07736a9 Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 15:31:23 +0100 Subject: [PATCH 11/11] Fix missing brackets --- src/background.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/background.ts b/src/background.ts index 9607d3ab..942ac778 100644 --- a/src/background.ts +++ b/src/background.ts @@ -96,7 +96,7 @@ browser.runtime.onStartup.addListener(_ => { } else { native.run("hostname").then(hostname => { for (const host of hosts) { - if (new RegExp(host).exec(hostname.content)) { + if ((new RegExp(host)).exec(hostname.content)) { controller.acceptExCmd(aucmds[host]) } }