mirror of
https://github.com/vale981/tridactyl
synced 2025-03-06 10:01:39 -05:00
commit
3a80fd03cb
16 changed files with 154 additions and 104 deletions
37
.eslintrc.js
37
.eslintrc.js
|
@ -37,7 +37,7 @@ module.exports = {
|
||||||
"rules": {
|
"rules": {
|
||||||
"sonarjs/cognitive-complexity": "off", //"error",
|
"sonarjs/cognitive-complexity": "off", //"error",
|
||||||
"sonarjs/no-duplicate-string": "off",
|
"sonarjs/no-duplicate-string": "off",
|
||||||
"sonarjs/no-unused-collection": "off", //"error",
|
"sonarjs/no-unused-collection": "off", //"error", // There seems to be a bug with this rule - exported collections are assumed unused
|
||||||
"@typescript-eslint/adjacent-overload-signatures": "error",
|
"@typescript-eslint/adjacent-overload-signatures": "error",
|
||||||
"@typescript-eslint/array-type": [
|
"@typescript-eslint/array-type": [
|
||||||
"error",
|
"error",
|
||||||
|
@ -82,7 +82,7 @@ module.exports = {
|
||||||
"accessibility": "explicit"
|
"accessibility": "explicit"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"@typescript-eslint/explicit-module-boundary-types": "off", //"warn",
|
"@typescript-eslint/explicit-module-boundary-types": "off", //"warn", // This is another hard one to enable
|
||||||
"@typescript-eslint/indent": "off",
|
"@typescript-eslint/indent": "off",
|
||||||
"@typescript-eslint/interface-name-prefix": "off",
|
"@typescript-eslint/interface-name-prefix": "off",
|
||||||
"@typescript-eslint/member-delimiter-style": [
|
"@typescript-eslint/member-delimiter-style": [
|
||||||
|
@ -104,25 +104,40 @@ module.exports = {
|
||||||
"@typescript-eslint/no-empty-interface": "error",
|
"@typescript-eslint/no-empty-interface": "error",
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
"@typescript-eslint/no-extra-non-null-assertion": "error",
|
"@typescript-eslint/no-extra-non-null-assertion": "error",
|
||||||
"@typescript-eslint/no-extra-semi": "off", //"error",
|
"@typescript-eslint/no-extra-semi": "error",
|
||||||
"@typescript-eslint/no-floating-promises": "off", //"error",
|
"@typescript-eslint/no-floating-promises": "off", //"error", // We should turn this on eventually but it will take a while to fix
|
||||||
"@typescript-eslint/no-for-in-array": "error",
|
"@typescript-eslint/no-for-in-array": "error",
|
||||||
"@typescript-eslint/no-implied-eval": "error",
|
"@typescript-eslint/no-implied-eval": "error",
|
||||||
"@typescript-eslint/no-inferrable-types": "off", //"error",
|
"@typescript-eslint/no-inferrable-types": "error",
|
||||||
"@typescript-eslint/no-misused-new": "error",
|
"@typescript-eslint/no-misused-new": "error",
|
||||||
"@typescript-eslint/no-misused-promises": "off", //"error",
|
"@typescript-eslint/no-misused-promises": ["error",
|
||||||
|
{
|
||||||
|
"checksVoidReturn": false,
|
||||||
|
},
|
||||||
|
],
|
||||||
"@typescript-eslint/no-namespace": "error",
|
"@typescript-eslint/no-namespace": "error",
|
||||||
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
|
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
|
||||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||||
"@typescript-eslint/no-parameter-properties": "off",
|
"@typescript-eslint/no-parameter-properties": "off",
|
||||||
"@typescript-eslint/no-this-alias": "error",
|
"@typescript-eslint/no-this-alias": "error",
|
||||||
"@typescript-eslint/no-unnecessary-type-assertion": "off", //"error",
|
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
||||||
"@typescript-eslint/no-unsafe-assignment": "off", //"error",
|
"@typescript-eslint/no-unsafe-assignment": "off", //"error",
|
||||||
"@typescript-eslint/no-unsafe-call": "off", //"error",
|
"@typescript-eslint/no-unsafe-call": "off", //"error",
|
||||||
"@typescript-eslint/no-unsafe-member-access": "off", //"error",
|
"@typescript-eslint/no-unsafe-member-access": "off", //"error", // We've done this a lot, but it would be a good idea to fix it
|
||||||
"@typescript-eslint/no-unsafe-return": "off", //"error",
|
"@typescript-eslint/no-unsafe-return": "off", //"error", // We've done this a lot, but it would be a good idea to fix it
|
||||||
"@typescript-eslint/no-unused-expressions": "off", //"error",
|
"@typescript-eslint/no-unused-expressions": [
|
||||||
"@typescript-eslint/no-unused-vars": "off", //"warn",
|
"error",
|
||||||
|
{
|
||||||
|
"allowShortCircuit": true,
|
||||||
|
"allowTernary": true,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@typescript-eslint/no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"args": "none",
|
||||||
|
}
|
||||||
|
],
|
||||||
"@typescript-eslint/no-use-before-define": "off",
|
"@typescript-eslint/no-use-before-define": "off",
|
||||||
"@typescript-eslint/no-var-requires": "error",
|
"@typescript-eslint/no-var-requires": "error",
|
||||||
"@typescript-eslint/prefer-as-const": "error",
|
"@typescript-eslint/prefer-as-const": "error",
|
||||||
|
|
|
@ -37,7 +37,7 @@ export class BindingsCompletionSource extends Completions.CompletionSourceFuse {
|
||||||
let options = ""
|
let options = ""
|
||||||
let [prefix, query] = this.splitOnPrefix(exstr)
|
let [prefix, query] = this.splitOnPrefix(exstr)
|
||||||
const args = query ? query.split(/\s+/) : []
|
const args = query ? query.split(/\s+/) : []
|
||||||
let configName: string = "nmaps"
|
let configName = "nmaps"
|
||||||
let modeName = "normal"
|
let modeName = "normal"
|
||||||
let urlPattern: string = null
|
let urlPattern: string = null
|
||||||
|
|
||||||
|
@ -64,12 +64,14 @@ export class BindingsCompletionSource extends Completions.CompletionSourceFuse {
|
||||||
this.options = Object.keys(patterns)
|
this.options = Object.keys(patterns)
|
||||||
.filter(pattern => pattern.startsWith(urlPattern))
|
.filter(pattern => pattern.startsWith(urlPattern))
|
||||||
.sort()
|
.sort()
|
||||||
.map(pattern => new BindingsCompletionOption(
|
.map(
|
||||||
pattern, {
|
pattern =>
|
||||||
|
new BindingsCompletionOption(pattern, {
|
||||||
name: pattern,
|
name: pattern,
|
||||||
value: "",
|
value: "",
|
||||||
mode: "URL Pattern",
|
mode: "URL Pattern",
|
||||||
}))
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
return this.updateChain()
|
return this.updateChain()
|
||||||
}
|
}
|
||||||
|
@ -82,12 +84,17 @@ export class BindingsCompletionSource extends Completions.CompletionSourceFuse {
|
||||||
const modeStr = margs.length > 1 ? margs[1] : ""
|
const modeStr = margs.length > 1 ? margs[1] : ""
|
||||||
this.options = Binding.modes
|
this.options = Binding.modes
|
||||||
.filter(k => k.startsWith(modeStr))
|
.filter(k => k.startsWith(modeStr))
|
||||||
.map(name => new BindingsCompletionOption(
|
.map(
|
||||||
options + "--mode=" + name, {
|
name =>
|
||||||
|
new BindingsCompletionOption(
|
||||||
|
options + "--mode=" + name,
|
||||||
|
{
|
||||||
name,
|
name,
|
||||||
value: "",
|
value: "",
|
||||||
mode: "Mode Name",
|
mode: "Mode Name",
|
||||||
}))
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
return this.updateChain()
|
return this.updateChain()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +116,9 @@ export class BindingsCompletionSource extends Completions.CompletionSourceFuse {
|
||||||
return this.updateChain()
|
return this.updateChain()
|
||||||
}
|
}
|
||||||
|
|
||||||
const bindings = urlPattern ? config.getURL(urlPattern, [configName]) : config.get(configName as any)
|
const bindings = urlPattern
|
||||||
|
? config.getURL(urlPattern, [configName])
|
||||||
|
: config.get(configName as any)
|
||||||
|
|
||||||
if (bindings === undefined) {
|
if (bindings === undefined) {
|
||||||
this.options = []
|
this.options = []
|
||||||
|
@ -118,14 +127,19 @@ export class BindingsCompletionSource extends Completions.CompletionSourceFuse {
|
||||||
|
|
||||||
query = args.join(" ").toLowerCase()
|
query = args.join(" ").toLowerCase()
|
||||||
this.options = Object.keys(bindings)
|
this.options = Object.keys(bindings)
|
||||||
.filter(x => x.toLowerCase().startsWith(query) )
|
.filter(x => x.toLowerCase().startsWith(query))
|
||||||
.sort()
|
.sort()
|
||||||
.map(keystr => new BindingsCompletionOption(
|
.map(
|
||||||
options + keystr + " " + bindings[keystr], {
|
keystr =>
|
||||||
|
new BindingsCompletionOption(
|
||||||
|
options + keystr + " " + bindings[keystr],
|
||||||
|
{
|
||||||
name: keystr,
|
name: keystr,
|
||||||
value: JSON.stringify(bindings[keystr]),
|
value: JSON.stringify(bindings[keystr]),
|
||||||
mode: `${configName} (${modeName})`,
|
mode: `${configName} (${modeName})`,
|
||||||
}))
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
return this.updateChain()
|
return this.updateChain()
|
||||||
}
|
}
|
||||||
|
@ -137,6 +151,4 @@ export class BindingsCompletionSource extends Completions.CompletionSourceFuse {
|
||||||
// Call concrete class
|
// Call concrete class
|
||||||
return this.updateDisplay()
|
return this.updateDisplay()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ export async function jumpToMatch(searchQuery, reverse) {
|
||||||
)
|
)
|
||||||
if (!focused) {
|
if (!focused) {
|
||||||
selected = 0
|
selected = 0
|
||||||
/* tslint:disable:no-useless-cast */
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
;(lastHighlights[selected] as any).focus()
|
;(lastHighlights[selected] as any).focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,9 +170,9 @@ export async function jumpToNextMatch(n: number) {
|
||||||
removeHighlighting()
|
removeHighlighting()
|
||||||
throw new Error("Pattern not found: " + lastSearchQuery)
|
throw new Error("Pattern not found: " + lastSearchQuery)
|
||||||
}
|
}
|
||||||
/* tslint:disable:no-useless-cast */
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
(lastHighlights[selected] as any).unfocus()
|
(lastHighlights[selected] as any).unfocus()
|
||||||
selected = (selected + n + lastHighlights.length) % lastHighlights.length
|
selected = (selected + n + lastHighlights.length) % lastHighlights.length
|
||||||
/* tslint:disable:no-useless-cast */
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
;(lastHighlights[selected] as any).focus()
|
;(lastHighlights[selected] as any).focus()
|
||||||
}
|
}
|
||||||
|
|
|
@ -428,18 +428,17 @@ export function hintPage(
|
||||||
|
|
||||||
const firstTarget = modeState.hints[0].target
|
const firstTarget = modeState.hints[0].target
|
||||||
|
|
||||||
const firstTargetIsSelectable = (): boolean => (
|
const firstTargetIsSelectable = (): boolean =>
|
||||||
firstTarget instanceof HTMLAnchorElement &&
|
firstTarget instanceof HTMLAnchorElement &&
|
||||||
firstTarget.href !== "" &&
|
firstTarget.href !== "" &&
|
||||||
!firstTarget.href.startsWith("javascript:")
|
!firstTarget.href.startsWith("javascript:")
|
||||||
)
|
|
||||||
|
|
||||||
const allTargetsAreEqual = (): boolean => (
|
const allTargetsAreEqual = (): boolean =>
|
||||||
undefined ===
|
undefined ===
|
||||||
modeState.hints.find(h => (
|
modeState.hints.find(
|
||||||
|
h =>
|
||||||
!(h.target instanceof HTMLAnchorElement) ||
|
!(h.target instanceof HTMLAnchorElement) ||
|
||||||
h.target.href !== (firstTarget as HTMLAnchorElement).href
|
h.target.href !== (firstTarget as HTMLAnchorElement).href,
|
||||||
))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -987,7 +986,7 @@ export function hintByText(match: string | RegExp) {
|
||||||
hint => {
|
hint => {
|
||||||
let text
|
let text
|
||||||
if (hint instanceof HTMLInputElement) {
|
if (hint instanceof HTMLInputElement) {
|
||||||
// tslint:disable-next-line:no-useless-cast
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
text = (hint as HTMLInputElement).value
|
text = (hint as HTMLInputElement).value
|
||||||
} else {
|
} else {
|
||||||
text = hint.textContent
|
text = hint.textContent
|
||||||
|
|
|
@ -70,10 +70,15 @@ class ScrollingData {
|
||||||
const elapsed: number = performance.now() - this.startTime
|
const elapsed: number = performance.now() - this.startTime
|
||||||
|
|
||||||
// If the animation should be done, return the position the element should have
|
// If the animation should be done, return the position the element should have
|
||||||
if (elapsed >= this.duration || this.elem[this.scrollDirection] === this.endPos)
|
if (
|
||||||
|
elapsed >= this.duration ||
|
||||||
|
this.elem[this.scrollDirection] === this.endPos
|
||||||
|
)
|
||||||
return this.endPos
|
return this.endPos
|
||||||
|
|
||||||
let pixelToScrollTo: number = this.startPos + (((this.endPos - this.startPos) * elapsed) / this.duration)
|
let pixelToScrollTo: number =
|
||||||
|
this.startPos +
|
||||||
|
((this.endPos - this.startPos) * elapsed) / this.duration
|
||||||
if (this.startPos < this.endPos) {
|
if (this.startPos < this.endPos) {
|
||||||
// We need to ceil() because only highdpi screens have a decimal this.elem[this.pos]
|
// We need to ceil() because only highdpi screens have a decimal this.elem[this.pos]
|
||||||
pixelToScrollTo = Math.ceil(pixelToScrollTo)
|
pixelToScrollTo = Math.ceil(pixelToScrollTo)
|
||||||
|
@ -104,7 +109,6 @@ class ScrollingData {
|
||||||
this.scrollStep() ? this.scheduleStep() : (this.scrolling = false),
|
this.scrollStep() ? this.scheduleStep() : (this.scrolling = false),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stores elements that are currently being horizontally scrolled
|
// Stores elements that are currently being horizontally scrolled
|
||||||
|
@ -116,8 +120,8 @@ const verticallyScrolling = new Map<Node, ScrollingData>()
|
||||||
* last duration milliseconds
|
* last duration milliseconds
|
||||||
*/
|
*/
|
||||||
export async function scroll(
|
export async function scroll(
|
||||||
xDistance: number = 0,
|
xDistance = 0,
|
||||||
yDistance: number = 0,
|
yDistance = 0,
|
||||||
e: Node,
|
e: Node,
|
||||||
duration?: number,
|
duration?: number,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
|
@ -189,15 +193,15 @@ export async function recursiveScroll(
|
||||||
startingFromCached = true
|
startingFromCached = true
|
||||||
node = lastRecursiveScrolled
|
node = lastRecursiveScrolled
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Try scrolling the active node or one of its parent elements
|
// Try scrolling the active node or one of its parent elements
|
||||||
|
|
||||||
// If nothing has been given focus explicitly use the activeElement
|
// If nothing has been given focus explicitly use the activeElement
|
||||||
if (!currentFocused || currentFocused.nodeName == "#document") currentFocused = document.activeElement
|
if (!currentFocused || currentFocused.nodeName == "#document")
|
||||||
|
currentFocused = document.activeElement
|
||||||
|
|
||||||
node = currentFocused
|
node = currentFocused
|
||||||
while (true) {
|
while (true) {
|
||||||
if ((await scroll(xDistance, yDistance, node))) return true
|
if (await scroll(xDistance, yDistance, node)) return true
|
||||||
node = node.parentElement
|
node = node.parentElement
|
||||||
if (!node) break
|
if (!node) break
|
||||||
}
|
}
|
||||||
|
@ -215,7 +219,9 @@ export async function recursiveScroll(
|
||||||
if (
|
if (
|
||||||
(await scroll(xDistance, yDistance, treeWalker.currentNode)) ||
|
(await scroll(xDistance, yDistance, treeWalker.currentNode)) ||
|
||||||
((treeWalker.currentNode as any).contentDocument &&
|
((treeWalker.currentNode as any).contentDocument &&
|
||||||
!(treeWalker.currentNode as any).src.startsWith("moz-extension://") &&
|
!(treeWalker.currentNode as any).src.startsWith(
|
||||||
|
"moz-extension://",
|
||||||
|
) &&
|
||||||
(await recursiveScroll(
|
(await recursiveScroll(
|
||||||
xDistance,
|
xDistance,
|
||||||
yDistance,
|
yDistance,
|
||||||
|
|
|
@ -19,10 +19,14 @@ export class PrevInput {
|
||||||
|
|
||||||
class ContentState {
|
class ContentState {
|
||||||
mode: ModeName = "normal"
|
mode: ModeName = "normal"
|
||||||
suffix: string = ""
|
suffix = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ContentStateProperty = "mode" | "cmdHistory" | "prevInputs" | "suffix"
|
export type ContentStateProperty =
|
||||||
|
| "mode"
|
||||||
|
| "cmdHistory"
|
||||||
|
| "prevInputs"
|
||||||
|
| "suffix"
|
||||||
|
|
||||||
export type ContentStateChangedCallback = (
|
export type ContentStateChangedCallback = (
|
||||||
property: ContentStateProperty,
|
property: ContentStateProperty,
|
||||||
|
|
|
@ -1528,7 +1528,7 @@ export function snow_mouse_mode() {
|
||||||
//#content_helper
|
//#content_helper
|
||||||
function findRelLink(pattern: RegExp): HTMLAnchorElement | null {
|
function findRelLink(pattern: RegExp): HTMLAnchorElement | null {
|
||||||
// querySelectorAll returns a "non-live NodeList" which is just a shit array without working reverse() or find() calls, so convert it.
|
// querySelectorAll returns a "non-live NodeList" which is just a shit array without working reverse() or find() calls, so convert it.
|
||||||
/* tslint:disable:no-useless-cast */
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
const links = Array.from(document.querySelectorAll("a[href]") as NodeListOf<HTMLAnchorElement>)
|
const links = Array.from(document.querySelectorAll("a[href]") as NodeListOf<HTMLAnchorElement>)
|
||||||
|
|
||||||
// Find the last link that matches the test
|
// Find the last link that matches the test
|
||||||
|
@ -1544,7 +1544,7 @@ function findRelLink(pattern: RegExp): HTMLAnchorElement | null {
|
||||||
// Return the last element in the document matching the supplied selector,
|
// Return the last element in the document matching the supplied selector,
|
||||||
// or null if there are no matches.
|
// or null if there are no matches.
|
||||||
function selectLast(selector: string): HTMLElement | null {
|
function selectLast(selector: string): HTMLElement | null {
|
||||||
/* tslint:disable:no-useless-cast */
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
const nodes = document.querySelectorAll(selector) as NodeListOf<HTMLElement>
|
const nodes = document.querySelectorAll(selector) as NodeListOf<HTMLElement>
|
||||||
return nodes.length ? nodes[nodes.length - 1] : null
|
return nodes.length ? nodes[nodes.length - 1] : null
|
||||||
}
|
}
|
||||||
|
@ -4439,6 +4439,8 @@ async function js_helper(str: string[]) {
|
||||||
switch (str[0]) {
|
switch (str[0]) {
|
||||||
case "-p":
|
case "-p":
|
||||||
// arg of -p comes from the end of str[]
|
// arg of -p comes from the end of str[]
|
||||||
|
// and we don't know if the user will use it or not
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
JS_ARG = str.pop()
|
JS_ARG = str.pop()
|
||||||
break
|
break
|
||||||
case "-s":
|
case "-s":
|
||||||
|
|
|
@ -1031,7 +1031,7 @@ export class default_config {
|
||||||
* statistics, so somewhere around 10k samples.
|
* statistics, so somewhere around 10k samples.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
perfsamples: string = "10000"
|
perfsamples = "10000"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show (partial) command in the mode indicator.
|
* Show (partial) command in the mode indicator.
|
||||||
|
|
|
@ -144,12 +144,7 @@ export async function exists(cname: string): Promise<boolean> {
|
||||||
@param color
|
@param color
|
||||||
@param icon
|
@param icon
|
||||||
*/
|
*/
|
||||||
export function fromString(
|
export function fromString(name: string, color: string, icon: string, id = "") {
|
||||||
name: string,
|
|
||||||
color: string,
|
|
||||||
icon: string,
|
|
||||||
id: string = "",
|
|
||||||
) {
|
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
color: color as browser.contextualIdentities.IdentityColor,
|
color: color as browser.contextualIdentities.IdentityColor,
|
||||||
|
|
|
@ -278,13 +278,13 @@ export function wordAfterPos(text: string, position: number) {
|
||||||
/** @hidden
|
/** @hidden
|
||||||
* Rots by 13.
|
* Rots by 13.
|
||||||
*/
|
*/
|
||||||
export const rot13_helper = (s: string, n: number = 13): string => {
|
export const rot13_helper = (s: string, n = 13): string => {
|
||||||
let sa = s.split("")
|
let sa = s.split("")
|
||||||
sa = sa.map(x => charesar(x, n))
|
sa = sa.map(x => charesar(x, n))
|
||||||
return sa.join("")
|
return sa.join("")
|
||||||
}
|
}
|
||||||
|
|
||||||
export const charesar = (c: string, n: number = 13): string => {
|
export const charesar = (c: string, n = 13): string => {
|
||||||
const cn = c.charCodeAt(0)
|
const cn = c.charCodeAt(0)
|
||||||
if (cn >= 65 && cn <= 90)
|
if (cn >= 65 && cn <= 90)
|
||||||
return String.fromCharCode(((cn - 65 + n) % 26) + 65)
|
return String.fromCharCode(((cn - 65 + n) % 26) + 65)
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
const tag = function tag(strings, ...values) {
|
const tag = function tag(strings, ...values) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// We don't need this value - we're just checking if its attempted creation causes any errors
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||||
tag`test`
|
tag`test`
|
||||||
})()
|
})()
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ export function* islice(iterable, start: number, stop?: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip elements until start
|
// Skip elements until start
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
for (const _ of range(start)) {
|
for (const _ of range(start)) {
|
||||||
const res = iter.next()
|
const res = iter.next()
|
||||||
if (res.done) return
|
if (res.done) return
|
||||||
|
@ -131,6 +132,7 @@ export function* permutationsWithReplacement(arr, n) {
|
||||||
const len = arr.length
|
const len = arr.length
|
||||||
const counters = zeros(n)
|
const counters = zeros(n)
|
||||||
let index = 1
|
let index = 1
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
for (const _ of range(Math.pow(len, n))) {
|
for (const _ of range(Math.pow(len, n))) {
|
||||||
yield counters.map(i => arr[i])
|
yield counters.map(i => arr[i])
|
||||||
for (const i of range(counters.length)) {
|
for (const i of range(counters.length)) {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import { FunctionType } from "../../compiler/types/AllTypes"
|
import { FunctionType } from "../../compiler/types/AllTypes"
|
||||||
import { everything as metadata } from "@src/.metadata.generated"
|
import { everything as metadata } from "@src/.metadata.generated"
|
||||||
import * as convert from "@src/lib/convert"
|
|
||||||
import * as aliases from "@src/lib/aliases"
|
import * as aliases from "@src/lib/aliases"
|
||||||
import * as Logging from "@src/lib/logging"
|
import * as Logging from "@src/lib/logging"
|
||||||
|
|
||||||
|
@ -10,7 +9,11 @@ const logger = new Logging.Logger("exmode")
|
||||||
|
|
||||||
function convertArgs(types, argv) {
|
function convertArgs(types, argv) {
|
||||||
const typedArgs = []
|
const typedArgs = []
|
||||||
for (let itypes = 0, iargv = 0; itypes < types.length && iargv < argv.length; ++itypes && ++iargv) {
|
for (
|
||||||
|
let itypes = 0, iargv = 0;
|
||||||
|
itypes < types.length && iargv < argv.length;
|
||||||
|
++itypes && ++iargv
|
||||||
|
) {
|
||||||
const curType = types[itypes]
|
const curType = types[itypes]
|
||||||
const curArg = argv[iargv]
|
const curArg = argv[iargv]
|
||||||
// Special casing arrays because that's why the previous arg conversion code did
|
// Special casing arrays because that's why the previous arg conversion code did
|
||||||
|
@ -38,7 +41,7 @@ export function parser(exstr: string, all_excmds: any): any[] {
|
||||||
const excmds = all_excmds[namespce]
|
const excmds = all_excmds[namespce]
|
||||||
|
|
||||||
if (excmds === undefined) {
|
if (excmds === undefined) {
|
||||||
throw new Error(`Unknown namespace: ${namespce}.`);
|
throw new Error(`Unknown namespace: ${namespce}.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert arguments, but only for ex commands
|
// Convert arguments, but only for ex commands
|
||||||
|
@ -46,11 +49,8 @@ export function parser(exstr: string, all_excmds: any): any[] {
|
||||||
if (namespce == "" && args.length > 0) {
|
if (namespce == "" && args.length > 0) {
|
||||||
let types
|
let types
|
||||||
try {
|
try {
|
||||||
types = (metadata
|
types = (metadata.getFile("src/excmds.ts").getFunction(funcName)
|
||||||
.getFile("src/excmds.ts")
|
.type as FunctionType).args
|
||||||
.getFunction(funcName)
|
|
||||||
.type as FunctionType)
|
|
||||||
.args
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// user defined functions?
|
// user defined functions?
|
||||||
types = null
|
types = null
|
||||||
|
|
|
@ -16,7 +16,7 @@ let modeState: NModeState
|
||||||
|
|
||||||
/** Init n [mode] mode. After parsing the defined number of commands, execute
|
/** Init n [mode] mode. After parsing the defined number of commands, execute
|
||||||
`endCmd`. `Escape` cancels the mode and executes `endCmd`. */
|
`endCmd`. `Escape` cancels the mode and executes `endCmd`. */
|
||||||
export function init(endCommand: string, mode = "normal", numCommands: number = 1) {
|
export function init(endCommand: string, mode = "normal", numCommands = 1) {
|
||||||
contentState.mode = "nmode"
|
contentState.mode = "nmode"
|
||||||
modeState = new NModeState()
|
modeState = new NModeState()
|
||||||
modeState.endCommand = endCommand
|
modeState.endCommand = endCommand
|
||||||
|
@ -40,10 +40,13 @@ export function parser(keys: KeyboardEvent[]) {
|
||||||
}
|
}
|
||||||
const response = keyseq.parse(keys, maps)
|
const response = keyseq.parse(keys, maps)
|
||||||
|
|
||||||
if ((response.exstr !== undefined && response.isMatch) || !response.isMatch) modeState.curCommands += 1
|
if ((response.exstr !== undefined && response.isMatch) || !response.isMatch)
|
||||||
|
modeState.curCommands += 1
|
||||||
if (modeState.curCommands >= modeState.numCommands) {
|
if (modeState.curCommands >= modeState.numCommands) {
|
||||||
const prefix =
|
const prefix =
|
||||||
(response.exstr === undefined) ? "" : ("composite " + response.exstr + "; ")
|
response.exstr === undefined
|
||||||
|
? ""
|
||||||
|
: "composite " + response.exstr + "; "
|
||||||
response.exstr = prefix + modeState.endCommand // NB: this probably breaks any `js` binds
|
response.exstr = prefix + modeState.endCommand // NB: this probably breaks any `js` binds
|
||||||
modeState = undefined
|
modeState = undefined
|
||||||
}
|
}
|
||||||
|
|
12
src/perf.ts
12
src/perf.ts
|
@ -192,9 +192,9 @@ export class StatsLogger {
|
||||||
// mapped symbol instead of the name so we're storing more like 50
|
// mapped symbol instead of the name so we're storing more like 50
|
||||||
// bytes per sample instead of 130 @_@
|
// bytes per sample instead of 130 @_@
|
||||||
public buffer: PerformanceEntry[] = []
|
public buffer: PerformanceEntry[] = []
|
||||||
private idx: number = 0
|
private idx = 0
|
||||||
private buffersize: number = 10000
|
private buffersize = 10000
|
||||||
private lastError: number = 0
|
private lastError = 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Target for receiving stats entries from other threads - there
|
* Target for receiving stats entries from other threads - there
|
||||||
|
@ -301,8 +301,8 @@ export class StatsLogger {
|
||||||
*/
|
*/
|
||||||
export function renderStatsHistogram(
|
export function renderStatsHistogram(
|
||||||
samples: PerformanceEntry[],
|
samples: PerformanceEntry[],
|
||||||
buckets: number = 15,
|
buckets = 15,
|
||||||
width: number = 80,
|
width = 80,
|
||||||
): string {
|
): string {
|
||||||
const durs: number[] = samples.map(sample => sample.duration)
|
const durs: number[] = samples.map(sample => sample.duration)
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ export class StatsFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const TRI_PERFORMANCE_NAME_PREFIX: string = "tri"
|
const TRI_PERFORMANCE_NAME_PREFIX = "tri"
|
||||||
|
|
||||||
function performanceApiAvailable(): boolean {
|
function performanceApiAvailable(): boolean {
|
||||||
return performance.mark !== undefined
|
return performance.mark !== undefined
|
||||||
|
|
26
src/state.ts
26
src/state.ts
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
import Logger from "@src/lib/logging"
|
import Logger from "@src/lib/logging"
|
||||||
import * as messaging from "@src/lib/messaging"
|
import * as messaging from "@src/lib/messaging"
|
||||||
import {notBackground} from "@src/lib/webext"
|
import { notBackground } from "@src/lib/webext"
|
||||||
|
|
||||||
const logger = new Logger("state")
|
const logger = new Logger("state")
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class State {
|
||||||
jumppos: undefined,
|
jumppos: undefined,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
last_ex_str: string = "echo"
|
last_ex_str = "echo"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't change these from const or you risk breaking the Proxy below.
|
// Don't change these from const or you risk breaking the Proxy below.
|
||||||
|
@ -43,10 +43,11 @@ browser.storage.local
|
||||||
})
|
})
|
||||||
.catch((...args) => logger.error(...args))
|
.catch((...args) => logger.error(...args))
|
||||||
|
|
||||||
const state = (new Proxy(overlay, {
|
const state = new Proxy(overlay, {
|
||||||
/** Give defaults if overlay doesn't have the key */
|
/** Give defaults if overlay doesn't have the key */
|
||||||
get(target, property) {
|
get(target, property) {
|
||||||
if (notBackground()) throw "State object must be accessed with getAsync in content"
|
if (notBackground())
|
||||||
|
throw "State object must be accessed with getAsync in content"
|
||||||
if (property in target) {
|
if (property in target) {
|
||||||
return target[property]
|
return target[property]
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,7 +62,11 @@ const state = (new Proxy(overlay, {
|
||||||
|
|
||||||
logger.debug("State changed!", property, value)
|
logger.debug("State changed!", property, value)
|
||||||
if (notBackground()) {
|
if (notBackground()) {
|
||||||
browser.runtime.sendMessage({type: "state", command: "stateUpdate", args: {property, value}})
|
browser.runtime.sendMessage({
|
||||||
|
type: "state",
|
||||||
|
command: "stateUpdate",
|
||||||
|
args: { property, value },
|
||||||
|
})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Do we need a global storage lock?
|
// Do we need a global storage lock?
|
||||||
|
@ -69,10 +74,15 @@ const state = (new Proxy(overlay, {
|
||||||
browser.storage.local.set({ state: target } as any)
|
browser.storage.local.set({ state: target } as any)
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
}))
|
})
|
||||||
|
|
||||||
export async function getAsync(property) {
|
export async function getAsync(property) {
|
||||||
if (notBackground()) return browser.runtime.sendMessage({type: "state", command: "stateGet", args: [{prop: property}]})
|
if (notBackground())
|
||||||
|
return browser.runtime.sendMessage({
|
||||||
|
type: "state",
|
||||||
|
command: "stateGet",
|
||||||
|
args: [{ prop: property }],
|
||||||
|
})
|
||||||
else return state[property]
|
else return state[property]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +95,7 @@ messaging.addListener("state", (message, sender, sendResponse) => {
|
||||||
overlay[property] = value
|
overlay[property] = value
|
||||||
} else if (message.command == "stateGet") {
|
} else if (message.command == "stateGet") {
|
||||||
sendResponse(state[message.args[0].prop])
|
sendResponse(state[message.args[0].prop])
|
||||||
} else throw("Unsupported message to state, type " + message.command)
|
} else throw "Unsupported message to state, type " + message.command
|
||||||
})
|
})
|
||||||
|
|
||||||
export { state as default }
|
export { state as default }
|
||||||
|
|
Loading…
Add table
Reference in a new issue