diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-09-09 16:59:03 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-09 16:59:03 -0400 | 
| commit | 0d00f7e1cf8a0fa1e2b1aa2732bceaae39f4e23c (patch) | |
| tree | 92b0a2e72ef2cecb31e8cc70da354ee43b87e2b4 /ext/mixed | |
| parent | acb7ad32f39c40b879400c9daa4bc8cd25585ba7 (diff) | |
Scanning input generalization (#789)
* Add inputs to options.scanning
* Update CSS for mouse buttons
* Update list counters
* Set up HTML/CSS
* Add input controller
* Use new inputs
* Include mouse buttons
* Update how button inputs are detected
* Add index/empty fields to the input details object
* Update none check for scanning modifier
* Remove old settings
* Remove unused global
Diffstat (limited to 'ext/mixed')
| -rw-r--r-- | ext/mixed/js/display.js | 3 | ||||
| -rw-r--r-- | ext/mixed/js/document-util.js | 25 | ||||
| -rw-r--r-- | ext/mixed/js/text-scanner.js | 88 | 
3 files changed, 79 insertions, 37 deletions
| diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 70b3895a..ea6b52c0 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -239,10 +239,9 @@ class Display extends EventDispatcher {              selectedParser: options.parsing.selectedParser,              termSpacing: options.parsing.termSpacing,              scanning: { +                inputs: scanning.inputs,                  deepContentScan: scanning.deepDomScan,                  selectText: scanning.selectText, -                modifier: scanning.modifier, -                useMiddleMouse: scanning.middleMouse,                  delay: scanning.delay,                  touchInputEnabled: scanning.touchInputEnabled,                  scanLength: scanning.length, diff --git a/ext/mixed/js/document-util.js b/ext/mixed/js/document-util.js index 0b72ff9a..58b0c759 100644 --- a/ext/mixed/js/document-util.js +++ b/ext/mixed/js/document-util.js @@ -188,6 +188,18 @@ class DocumentUtil {          return modifiers;      } +    static getActiveModifiersAndButtons(event) { +        const modifiers = this.getActiveModifiers(event); +        this._getActiveButtons(event, modifiers); +        return modifiers; +    } + +    static getActiveButtons(event) { +        const buttons = new Set(); +        this._getActiveButtons(event, buttons); +        return buttons; +    } +      static getKeyFromEvent(event) {          const key = event.key;          return (typeof key === 'string' ? (key.length === 1 ? key.toUpperCase() : key) : ''); @@ -299,6 +311,19 @@ class DocumentUtil {          return !(browser === 'firefox' || browser === 'firefox-mobile') || os === 'mac';      } +    static _getActiveButtons(event, set) { +        const {buttons} = event; +        if (typeof buttons === 'number') { +            for (let i = 0; i < 6; ++i) { +                const buttonFlag = (1 << i); +                if ((buttons & buttonFlag) !== 0) { +                    set.add(`mouse${i}`); +                } +            } +        } +        return set; +    } +      // Private      _setImposterStyle(style, propertyName, value) { diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index f3e99577..6eafc82c 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -43,13 +43,12 @@ class TextScanner extends EventDispatcher {          this._deepContentScan = false;          this._selectText = false; -        this._modifier = 'none'; -        this._useMiddleMouse = false;          this._delay = 0;          this._touchInputEnabled = false;          this._scanLength = 1;          this._sentenceExtent = 1;          this._layoutAwareScan = false; +        this._inputs = [];          this._enabled = false;          this._eventListeners = new EventListenerCollection(); @@ -94,19 +93,19 @@ class TextScanner extends EventDispatcher {          }      } -    setOptions({deepContentScan, selectText, modifier, useMiddleMouse, delay, touchInputEnabled, scanLength, sentenceExtent, layoutAwareScan}) { +    setOptions({inputs, deepContentScan, selectText, delay, touchInputEnabled, scanLength, sentenceExtent, layoutAwareScan}) { +        if (Array.isArray(inputs)) { +            this._inputs = inputs.map(({include, exclude}) => ({ +                include: this._getInputArray(include), +                exclude: this._getInputArray(exclude) +            })); +        }          if (typeof deepContentScan === 'boolean') {              this._deepContentScan = deepContentScan;          }          if (typeof selectText === 'boolean') {              this._selectText = selectText;          } -        if (typeof modifier === 'string') { -            this._modifier = modifier; -        } -        if (typeof useMiddleMouse === 'boolean') { -            this._useMiddleMouse = useMiddleMouse; -        }          if (typeof delay === 'number') {              this._delay = delay;          } @@ -184,7 +183,7 @@ class TextScanner extends EventDispatcher {      }      async search(textSource) { -        return await this._search(textSource, {cause: 'script'}); +        return await this._search(textSource, {cause: 'script', index: -1, empty: false});      }      // Private @@ -242,17 +241,14 @@ class TextScanner extends EventDispatcher {              return;          } -        const modifiers = DocumentUtil.getActiveModifiers(e); +        const modifiers = DocumentUtil.getActiveModifiersAndButtons(e);          this.trigger('activeModifiersChanged', {modifiers}); -        if (!( -            this._isScanningModifierPressed(this._modifier, e) || -            (this._useMiddleMouse && DocumentUtil.isMouseButtonDown(e, 'auxiliary')) -        )) { -            return; -        } +        const inputInfo = this._getMatchingInputGroup(modifiers); +        if (inputInfo === null) { return; } -        this._searchAtFromMouse(e.clientX, e.clientY); +        const {index, empty} = inputInfo; +        this._searchAtFromMouse(e.clientX, e.clientY, index, empty);      }      _onMouseDown(e) { @@ -276,7 +272,7 @@ class TextScanner extends EventDispatcher {      _onClick(e) {          if (this._searchOnClick) { -            this._searchAt(e.clientX, e.clientY, {cause: 'click'}); +            this._searchAt(e.clientX, e.clientY, {cause: 'click', index: -1, empty: false});          }          if (this._preventNextClick) { @@ -349,7 +345,7 @@ class TextScanner extends EventDispatcher {              return;          } -        this._searchAt(primaryTouch.clientX, primaryTouch.clientY, {cause: 'touchMove'}); +        this._searchAt(primaryTouch.clientX, primaryTouch.clientY, {cause: 'touchMove', index: -1, empty: false});          e.preventDefault(); // Disable scroll      } @@ -406,17 +402,6 @@ class TextScanner extends EventDispatcher {          ];      } -    _isScanningModifierPressed(scanningModifier, mouseEvent) { -        switch (scanningModifier) { -            case 'alt': return mouseEvent.altKey; -            case 'ctrl': return mouseEvent.ctrlKey; -            case 'shift': return mouseEvent.shiftKey; -            case 'meta': return mouseEvent.metaKey; -            case 'none': return true; -            default: return false; -        } -    } -      _getTouch(touchList, identifier) {          for (const touch of touchList) {              if (touch.identifier === identifier) { @@ -498,17 +483,17 @@ class TextScanner extends EventDispatcher {          }      } -    async _searchAtFromMouse(x, y) { +    async _searchAtFromMouse(x, y, inputIndex, inputEmpty) {          if (this._pendingLookup) { return; } -        if (this._modifier === 'none') { +        if (inputEmpty) {              if (!await this._scanTimerWait()) {                  // Aborted                  return;              }          } -        await this._searchAt(x, y, {cause: 'mouse'}); +        await this._searchAt(x, y, {cause: 'mouse', index: inputIndex, empty: inputEmpty});      }      async _searchAtFromTouchStart(x, y) { @@ -516,7 +501,7 @@ class TextScanner extends EventDispatcher {          const textSourceCurrentPrevious = this._textSourceCurrent !== null ? this._textSourceCurrent.clone() : null; -        await this._searchAt(x, y, {cause: 'touchStart'}); +        await this._searchAt(x, y, {cause: 'touchStart', index: -1, empty: false});          if (              this._textSourceCurrent !== null && @@ -527,4 +512,37 @@ class TextScanner extends EventDispatcher {              this._preventNextMouseDown = true;          }      } + +    _getMatchingInputGroup(modifiers) { +        let fallback = null; +        for (let i = 0, ii = this._inputs.length; i < ii; ++i) { +            const input = this._inputs[i]; +            const {include, exclude} = input; +            if (this._setHasAll(modifiers, include) && (exclude.length === 0 || !this._setHasAll(modifiers, exclude))) { +                if (include.length > 0) { +                    return {index: i, empty: false, input}; +                } else if (fallback === null) { +                    fallback = {index: i, empty: true, input}; +                } +            } +        } +        return fallback; +    } + +    _setHasAll(set, values) { +        for (const value of values) { +            if (!set.has(value)) { +                return false; +            } +        } +        return true; +    } + +    _getInputArray(value) { +        return ( +            typeof value === 'string' ? +            value.split(/[,;\s]+/).map((v) => v.trim().toLowerCase()).filter((v) => v.length > 0) : +            [] +        ); +    }  } |