From 96f763e42ed2f05c6b6a4b1b60e6a0e38fdee8ba Mon Sep 17 00:00:00 2001 From: Oliver Blanthorn Date: Fri, 19 Jun 2020 12:56:18 +0100 Subject: [PATCH] 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() } // --------------------------------------------------