Merge pull request #2534 from tridactyl/hint_discrimination

Hint discrimination
This commit is contained in:
Oliver Blanthorn 2020-06-25 16:20:06 +01:00 committed by GitHub
commit 5834f83d55
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 30 deletions

View file

@ -36,6 +36,7 @@ import {
import { contentState } from "@src/content/state_content"
import * as config from "@src/lib/config"
import Logger from "@src/lib/logging"
import * as R from "ramda"
/** @hidden */
const logger = new Logger("hinting")
@ -375,11 +376,16 @@ class HintState {
/** @hidden*/
let modeState: HintState
interface Hintables {
elements: Element[]
hintclasses?: string[]
}
/** For each hintable element, add a hint
* @hidden
* */
export function hintPage(
hintableElements: Element[],
hintableElements: Hintables[],
onSelect: HintSelectedCallback,
resolve = () => {}, // eslint-disable-line @typescript-eslint/no-empty-function
reject = () => {}, // eslint-disable-line @typescript-eslint/no-empty-function
@ -391,23 +397,27 @@ export function hintPage(
modeState = new HintState(filterHints, resolve, reject, rapid)
if (!rapid) {
buildHints(hintableElements, hint => {
modeState.cleanUpHints()
hint.result = onSelect(hint.target)
modeState.selectedHints.push(hint)
reset()
})
for (const hints of hintableElements) {
buildHints(hints, hint => {
modeState.cleanUpHints()
hint.result = onSelect(hint.target)
modeState.selectedHints.push(hint)
reset()
})
}
} else {
buildHints(hintableElements, hint => {
hint.result = onSelect(hint.target)
modeState.selectedHints.push(hint)
if (
modeState.selectedHints.length > 1 &&
config.get("hintshift") === "true"
) {
modeState.shiftHints()
}
})
for (const hints of hintableElements) {
buildHints(hints, hint => {
hint.result = onSelect(hint.target)
modeState.selectedHints.push(hint)
if (
modeState.selectedHints.length > 1 &&
config.get("hintshift") === "true"
) {
modeState.shiftHints()
}
})
}
}
if (!modeState.hints.length) {
@ -585,6 +595,7 @@ class Hint {
public name: string,
public readonly filterData: any,
private readonly onSelect: HintSelectedCallback,
private readonly classes?: string[],
) {
// We need to compute the offset for elements that are in an iframe
let offsetTop = 0
@ -624,6 +635,7 @@ class Hint {
this.flag.classList.add("TridactylHintUppercase")
}
this.flag.classList.add("TridactylHint" + target.tagName)
classes?.forEach(f => this.flag.classList.add(f))
const top = rect.top > 0 ? this.rect.top : offsetTop + pad
const left = rect.left > 0 ? this.rect.left : offsetLeft + pad
@ -668,15 +680,24 @@ class Hint {
}
/** @hidden */
type HintBuilder = (els: Element[], onSelect: HintSelectedCallback) => void
type HintBuilder = (
hintables: Hintables,
onSelect: HintSelectedCallback,
) => void
/** @hidden */
function buildHintsSimple(els: Element[], onSelect: HintSelectedCallback) {
function buildHintsSimple(
hintables: Hintables,
onSelect: HintSelectedCallback,
) {
const els = hintables.elements
const names = hintnames(els.length)
for (const [el, name] of izip(els, names)) {
logger.debug({ el, name })
modeState.hintchars += name
modeState.hints.push(new Hint(el, name, null, onSelect))
modeState.hints.push(
new Hint(el, name, null, onSelect, hintables.hintclasses),
)
}
}
@ -714,14 +735,20 @@ export const vimpHelper = {
}
/** @hidden */
function buildHintsVimperator(els: Element[], onSelect: HintSelectedCallback) {
function buildHintsVimperator(
hintables: Hintables,
onSelect: HintSelectedCallback,
) {
const els = hintables.elements
const names = hintnames(els.length)
for (const [el, name] of izip(els, names)) {
let ft = elementFilterableText(el)
ft = vimpHelper.sanitiseHintText(ft)
logger.debug({ el, name, ft })
modeState.hintchars += name + ft
modeState.hints.push(new Hint(el, name, ft, onSelect))
modeState.hints.push(
new Hint(el, name, ft, onSelect, hintables.hintclasses),
)
}
}
@ -911,13 +938,24 @@ function pushSpace() {
@hidden
*/
export function hintables(selectors = DOM.HINTTAGS_selectors, withjs = false) {
let elems = DOM.getElemsBySelector(selectors, [])
const elems = R.pipe(
DOM.getElemsBySelector,
R.filter(DOM.isVisible),
changeHintablesToLargestChild,
)(selectors, [])
const hintables: Hintables[] = [{ elements: elems }]
if (withjs) {
const elemSet = new Set([...elems, ...DOM.hintworthy_js_elems])
elems = [...elemSet]
hintables.push({
elements: R.pipe(
Array.from,
R.filter(DOM.isVisible),
R.without(elems),
changeHintablesToLargestChild,
)(DOM.hintworthy_js_elems),
hintclasses: ["TridactylJSHint"],
})
}
elems = elems.filter(DOM.isVisible)
return changeHintablesToLargestChild(elems)
return hintables
}
/**
@ -1032,7 +1070,7 @@ export function pipe_elements(
rapid = false,
): Promise<[Element, number]> {
return new Promise((resolve, reject) => {
hintPage(elements, action, resolve, reject, rapid)
hintPage([{ elements }], action, resolve, reject, rapid)
})
}

View file

@ -42,3 +42,7 @@ span.TridactylHintUppercase {
div.TridactylHintHost {
position: static !important !important;
}
span.TridactylJSHint {
background-color: var(--tridactyl-hintspan-js-background) !important;
}

View file

@ -6,7 +6,7 @@
--tridactyl-small-font-size: 12px;
--tridactyl-bg: white;
--tridactyl-fg: black;
--tridactyl-logo: url('data:image/png;base64,REPLACE_ME_WITH_BASE64_TRIDACTYL_LOGO');
--tridactyl-logo: url("data:image/png;base64,REPLACE_ME_WITH_BASE64_TRIDACTYL_LOGO");
/* Mode indicator */
--tridactyl-status-font-family: var(--tridactyl-font-family);
@ -30,6 +30,7 @@
--tridactyl-hintspan-border-color: ButtonShadow;
--tridactyl-hintspan-border-width: 0px;
--tridactyl-hintspan-border-style: solid;
--tridactyl-hintspan-js-background: hsla(0, 0%, 65%);
/* Element highlights */
--tridactyl-hint-active-fg: var(--tridactyl-fg);
@ -126,5 +127,4 @@
--tridactyl-container-color-purple: #af51f5;
--tridactyl-externaledit-bg: var(--tridactyl-logo) no-repeat center;
}