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.
This commit is contained in:
Oliver Blanthorn 2020-06-19 12:56:18 +01:00
parent f2cd6a7988
commit 96f763e42e
No known key found for this signature in database
GPG key ID: 2BB8C36BB504BFF3
8 changed files with 379 additions and 273 deletions

View file

@ -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",

View file

@ -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"

View file

@ -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(),
})

View file

@ -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()
}

View file

@ -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,
};
};
}
}

View file

@ -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<number>
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(" ")

View file

@ -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 = {
"<Escape>": "composite js document.getSelection().empty(); mode normal; hidecmdline",
"<C-[>": "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")',
"<Escape>":
"composite js document.getSelection().empty(); mode normal; hidecmdline",
"<C-[>":
"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["<Space>"] = mapObj[" "]
delete mapObj[" "]
}
; [
[
"<A- >",
"<C- >",
"<M- >",
@ -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

View file

@ -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()
}
// --------------------------------------------------