diff options
| -rw-r--r-- | ext/css/settings.css | 13 | ||||
| -rw-r--r-- | ext/data/schemas/options-schema.json | 42 | ||||
| -rw-r--r-- | ext/js/data/options-util.js | 16 | ||||
| -rw-r--r-- | ext/js/display/display.js | 7 | ||||
| -rw-r--r-- | ext/js/language/text-scanner.js | 145 | ||||
| -rw-r--r-- | ext/js/pages/settings/scan-inputs-controller.js | 7 | ||||
| -rw-r--r-- | ext/settings.html | 36 | ||||
| -rw-r--r-- | test/test-options-util.js | 21 | 
8 files changed, 216 insertions, 71 deletions
| diff --git a/ext/css/settings.css b/ext/css/settings.css index dc8132be..6f1afa00 100644 --- a/ext/css/settings.css +++ b/ext/css/settings.css @@ -1714,9 +1714,12 @@ code.anki-field-marker {  .scan-input-prefix-cell[data-property=search-options] {      grid-area: 4/2/5/3;  } -.scan-input-prefix-cell[data-property=touch-pen-options] { +.scan-input-prefix-cell[data-property=touch-options] {      grid-area: 5/2/6/3;  } +.scan-input-prefix-cell[data-property=pen-options] { +    grid-area: 6/2/7/3; +}  .scan-input-content-cell[data-property=include] {      grid-area: 1/3/2/4;  } @@ -1735,12 +1738,18 @@ code.anki-field-marker {      flex-flow: row wrap;      align-items: center;  } -.scan-input-content-cell[data-property=touch-pen-options] { +.scan-input-content-cell[data-property=touch-options] {      grid-area: 5/3/6/4;      display: flex;      flex-flow: column nowrap;      align-items: flex-start;  } +.scan-input-content-cell[data-property=pen-options] { +    grid-area: 6/3/7/4; +    display: flex; +    flex-flow: column nowrap; +    align-items: flex-start; +}  .scan-input-options-cell {      padding: 0.25em 0;      align-self: start; diff --git a/ext/data/schemas/options-schema.json b/ext/data/schemas/options-schema.json index 279be153..d7e3b5f4 100644 --- a/ext/data/schemas/options-schema.json +++ b/ext/data/schemas/options-schema.json @@ -457,10 +457,15 @@                                                      "searchTerms": true,                                                      "searchKanji": true,                                                      "scanOnTouchMove": true, +                                                    "scanOnTouchPress": true, +                                                    "scanOnTouchRelease": false, +                                                    "scanOnPenMove": true,                                                      "scanOnPenHover": true, +                                                    "scanOnPenReleaseHover": false,                                                      "scanOnPenPress": true,                                                      "scanOnPenRelease": false, -                                                    "preventTouchScrolling": false +                                                    "preventTouchScrolling": false, +                                                    "preventPenScrolling": false                                                  }                                              },                                              { @@ -476,10 +481,15 @@                                                      "searchTerms": true,                                                      "searchKanji": true,                                                      "scanOnTouchMove": true, +                                                    "scanOnTouchPress": true, +                                                    "scanOnTouchRelease": false, +                                                    "scanOnPenMove": true,                                                      "scanOnPenHover": true, +                                                    "scanOnPenReleaseHover": false,                                                      "scanOnPenPress": true,                                                      "scanOnPenRelease": false, -                                                    "preventTouchScrolling": true +                                                    "preventTouchScrolling": true, +                                                    "preventPenScrolling": true                                                  }                                              }                                          ], @@ -528,10 +538,12 @@                                                          "searchTerms",                                                          "searchKanji",                                                          "scanOnTouchMove", +                                                        "scanOnTouchPress", +                                                        "scanOnPenMove",                                                          "scanOnPenHover", -                                                        "scanOnPenPress", -                                                        "scanOnPenRelease", -                                                        "preventTouchScrolling" +                                                        "scanOnPenReleaseHover", +                                                        "preventTouchScrolling", +                                                        "preventPenScrolling"                                                      ],                                                      "properties": {                                                          "showAdvanced": { @@ -550,10 +562,26 @@                                                              "type": "boolean",                                                              "default": true                                                          }, +                                                        "scanOnTouchPress": { +                                                            "type": "boolean", +                                                            "default": true +                                                        }, +                                                        "scanOnTouchRelease": { +                                                            "type": "boolean", +                                                            "default": false +                                                        }, +                                                        "scanOnPenMove": { +                                                            "type": "boolean", +                                                            "default": true +                                                        },                                                          "scanOnPenHover": {                                                              "type": "boolean",                                                              "default": true                                                          }, +                                                        "scanOnPenReleaseHover": { +                                                            "type": "boolean", +                                                            "default": false +                                                        },                                                          "scanOnPenPress": {                                                              "type": "boolean",                                                              "default": true @@ -565,6 +593,10 @@                                                          "preventTouchScrolling": {                                                              "type": "boolean",                                                              "default": true +                                                        }, +                                                        "preventPenScrolling": { +                                                            "type": "boolean", +                                                            "default": true                                                          }                                                      }                                                  } diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js index f19094df..a163580f 100644 --- a/ext/js/data/options-util.js +++ b/ext/js/data/options-util.js @@ -953,9 +953,25 @@ class OptionsUtil {          // Version 19 changes:          //  Added anki.noteGuiMode.          //  Added anki.apiKey. +        //  Renamed scanning.inputs[].options.scanOnPenPress to scanOnPenMove. +        //  Renamed scanning.inputs[].options.scanOnPenRelease to scanOnPenReleaseHover. +        //  Added scanning.inputs[].options.scanOnTouchPress. +        //  Added scanning.inputs[].options.scanOnTouchRelease. +        //  Added scanning.inputs[].options.scanOnPenPress. +        //  Added scanning.inputs[].options.scanOnPenRelease. +        //  Added scanning.inputs[].options.preventPenScrolling.          for (const profile of options.profiles) {              profile.options.anki.noteGuiMode = 'browse';              profile.options.anki.apiKey = ''; +            for (const input of profile.options.scanning.inputs) { +                input.options.scanOnPenMove = input.options.scanOnPenPress; +                input.options.scanOnPenReleaseHover = input.options.scanOnPenRelease; +                input.options.scanOnTouchPress = true; +                input.options.scanOnTouchRelease = false; +                input.options.scanOnPenPress = input.options.scanOnPenMove; +                input.options.scanOnPenRelease = false; +                input.options.preventPenScrolling = input.options.preventTouchScrolling; +            }          }          return options;      } diff --git a/ext/js/display/display.js b/ext/js/display/display.js index f9153420..923c9dd2 100644 --- a/ext/js/display/display.js +++ b/ext/js/display/display.js @@ -1516,10 +1516,15 @@ class Display extends EventDispatcher {                      searchTerms: true,                      searchKanji: true,                      scanOnTouchMove: false, +                    scanOnTouchPress: false, +                    scanOnTouchRelease: false, +                    scanOnPenMove: false,                      scanOnPenHover: false, +                    scanOnPenReleaseHover: false,                      scanOnPenPress: false,                      scanOnPenRelease: false, -                    preventTouchScrolling: false +                    preventTouchScrolling: false, +                    preventPenScrolling: false                  }              }],              deepContentScan: scanningOptions.deepDomScan, diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js index 36091805..978f3d36 100644 --- a/ext/js/language/text-scanner.js +++ b/ext/js/language/text-scanner.js @@ -83,8 +83,7 @@ class TextScanner extends EventDispatcher {          this._preventNextMouseDown = false;          this._preventNextClick = false;          this._preventScroll = false; -        this._penPointerPressed = false; -        this._penPointerReleased = false; +        this._penPointerState = 0; // 0 = not active; 1 = hovering; 2 = touching; 3 = hovering after touching          this._pointerIdTypeMap = new Map();          this._canClearSelection = true; @@ -135,8 +134,7 @@ class TextScanner extends EventDispatcher {          this._preventNextMouseDown = false;          this._preventNextClick = false;          this._preventScroll = false; -        this._penPointerPressed = false; -        this._penPointerReleased = false; +        this._penPointerState = 0;          this._pointerIdTypeMap.clear();          this._enabledValue = value; @@ -168,10 +166,15 @@ class TextScanner extends EventDispatcher {                      searchTerms,                      searchKanji,                      scanOnTouchMove, +                    scanOnTouchPress, +                    scanOnTouchRelease, +                    scanOnPenMove,                      scanOnPenHover, +                    scanOnPenReleaseHover,                      scanOnPenPress,                      scanOnPenRelease, -                    preventTouchScrolling +                    preventTouchScrolling, +                    preventPenScrolling                  }              }) => ({                  include: this._getInputArray(include), @@ -181,10 +184,15 @@ class TextScanner extends EventDispatcher {                      searchTerms,                      searchKanji,                      scanOnTouchMove, +                    scanOnTouchPress, +                    scanOnTouchRelease, +                    scanOnPenMove,                      scanOnPenHover, +                    scanOnPenReleaseHover,                      scanOnPenPress,                      scanOnPenRelease, -                    preventTouchScrolling +                    preventTouchScrolling, +                    preventPenScrolling                  }              }));          } @@ -515,41 +523,60 @@ class TextScanner extends EventDispatcher {          this._primaryTouchIdentifier = identifier; -        this._searchAtFromTouchStart(e, x, y); +        if (this._pendingLookup) { return; } + +        const inputInfo = this._getMatchingInputGroupFromEvent('touch', 'touchStart', e); +        if (inputInfo === null || !inputInfo.input.options.scanOnTouchPress) { return; } + +        this._searchAtFromTouchStart(x, y, inputInfo);      }      _onTouchEnd(e) { -        if ( -            this._primaryTouchIdentifier === null || -            this._getTouch(e.changedTouches, this._primaryTouchIdentifier) === null -        ) { -            return; -        } +        if (this._primaryTouchIdentifier === null) { return; } + +        const primaryTouch = this._getTouch(e.changedTouches, this._primaryTouchIdentifier); +        if (primaryTouch === null) { return; } -        this._onPrimaryTouchEnd(); +        const {clientX, clientY} = primaryTouch; +        this._onPrimaryTouchEnd(e, clientX, clientY, true);      } -    _onPrimaryTouchEnd() { +    _onPrimaryTouchEnd(e, x, y, allowSearch) {          this._primaryTouchIdentifier = null;          this._preventScroll = false;          this._preventNextClick = false;          // Don't revert context menu and mouse down prevention, since these events can occur after the touch has ended.          // I.e. this._preventNextContextMenu and this._preventNextMouseDown should not be assigned to false. + +        if (!allowSearch) { return; } + +        const inputInfo = this._getMatchingInputGroupFromEvent('touch', 'touchEnd', e); +        if (inputInfo === null || !inputInfo.input.options.scanOnTouchRelease) { return; } + +        this._searchAtFromTouchEnd(x, y, inputInfo);      }      _onTouchCancel(e) { -        this._onTouchEnd(e); +        if (this._primaryTouchIdentifier === null) { return; } + +        const primaryTouch = this._getTouch(e.changedTouches, this._primaryTouchIdentifier); +        if (primaryTouch === null) { return; } + +        this._onPrimaryTouchEnd(e, 0, 0, false);      }      _onTouchMove(e) { -        if (!this._preventScroll || !e.cancelable || this._primaryTouchIdentifier === null) { +        if (this._primaryTouchIdentifier === null) { return; } + +        if (!e.cancelable) { +            this._onPrimaryTouchEnd(e, 0, 0, false);              return;          } +        if (!this._preventScroll) { return; } +          const primaryTouch = this._getTouch(e.changedTouches, this._primaryTouchIdentifier); -        if (primaryTouch === null) { -            return; -        } +        if (primaryTouch === null) { return; }          const inputInfo = this._getMatchingInputGroupFromEvent('touch', 'touchMove', e);          if (inputInfo === null) { return; } @@ -652,7 +679,7 @@ class TextScanner extends EventDispatcher {      _onTouchPointerDown(e) {          const {clientX, clientY, pointerId} = e; -        return this._onPrimaryTouchStart(e, clientX, clientY, pointerId); +        this._onPrimaryTouchStart(e, clientX, clientY, pointerId);      }      _onTouchPointerMove(e) { @@ -666,12 +693,13 @@ class TextScanner extends EventDispatcher {          this._searchAt(e.clientX, e.clientY, inputInfo);      } -    _onTouchPointerUp() { -        return this._onPrimaryTouchEnd(); +    _onTouchPointerUp(e) { +        const {clientX, clientY} = e; +        return this._onPrimaryTouchEnd(e, clientX, clientY, true);      } -    _onTouchPointerCancel() { -        return this._onPrimaryTouchEnd(); +    _onTouchPointerCancel(e) { +        return this._onPrimaryTouchEnd(e, 0, 0, false);      }      _onTouchPointerOut() { @@ -689,25 +717,24 @@ class TextScanner extends EventDispatcher {      }      _onPenPointerOver(e) { -        this._penPointerPressed = false; -        this._penPointerReleased = false; -        this._searchAtFromPen(e, e.clientX, e.clientY, 'pointerOver', false); +        this._penPointerState = 1; +        this._searchAtFromPen(e, 'pointerOver', false);      }      _onPenPointerDown(e) { -        this._penPointerPressed = true; -        this._searchAtFromPen(e, e.clientX, e.clientY, 'pointerDown', true); +        this._penPointerState = 2; +        this._searchAtFromPen(e, 'pointerDown', true);      }      _onPenPointerMove(e) { -        if (this._penPointerPressed && (!this._preventScroll || !e.cancelable)) { return; } -        this._searchAtFromPen(e, e.clientX, e.clientY, 'pointerMove', true); +        if (this._penPointerState === 2 && (!this._preventScroll || !e.cancelable)) { return; } +        this._searchAtFromPen(e, 'pointerMove', true);      } -    _onPenPointerUp() { -        this._penPointerPressed = false; -        this._penPointerReleased = true; +    _onPenPointerUp(e) { +        this._penPointerState = 3;          this._preventScroll = false; +        this._searchAtFromPen(e, 'pointerUp', false);      }      _onPenPointerCancel(e) { @@ -715,8 +742,7 @@ class TextScanner extends EventDispatcher {      }      _onPenPointerOut() { -        this._penPointerPressed = false; -        this._penPointerReleased = false; +        this._penPointerState = 0;          this._preventScroll = false;          this._preventNextContextMenu = false;          this._preventNextMouseDown = false; @@ -953,12 +979,7 @@ class TextScanner extends EventDispatcher {          await this._searchAt(x, y, inputInfo);      } -    async _searchAtFromTouchStart(e, x, y) { -        if (this._pendingLookup) { return; } - -        const inputInfo = this._getMatchingInputGroupFromEvent('touch', 'touchStart', e); -        if (inputInfo === null) { return; } - +    async _searchAtFromTouchStart(x, y, inputInfo) {          const textSourceCurrentPrevious = this._textSourceCurrent !== null ? this._textSourceCurrent.clone() : null;          const preventScroll = inputInfo.input.options.preventTouchScrolling; @@ -974,23 +995,22 @@ class TextScanner extends EventDispatcher {          }      } -    async _searchAtFromPen(e, x, y, eventType, prevent) { +    async _searchAtFromTouchEnd(x, y, inputInfo) { +        await this._searchAt(x, y, inputInfo); +    } + +    async _searchAtFromPen(e, eventType, prevent) {          if (this._pendingLookup) { return; }          const inputInfo = this._getMatchingInputGroupFromEvent('pen', eventType, e);          if (inputInfo === null) { return; } -        const {input: {options}} = inputInfo; -        if ( -            (!options.scanOnPenRelease && this._penPointerReleased) || -            !(this._penPointerPressed ? options.scanOnPenPress : options.scanOnPenHover) -        ) { -            return; -        } +        const {options} = inputInfo.input; +        if (!this._isPenEventSupported(eventType, options)) { return; } -        const preventScroll = inputInfo.input.options.preventTouchScrolling; +        const preventScroll = options.preventPenScrolling; -        await this._searchAt(x, y, inputInfo); +        await this._searchAt(e.clientX, e.clientY, inputInfo);          if (              prevent && @@ -1003,6 +1023,25 @@ class TextScanner extends EventDispatcher {          }      } +    _isPenEventSupported(eventType, options) { +        switch (eventType) { +            case 'pointerDown': +                return options.scanOnPenPress; +            case 'pointerUp': +                return options.scanOnPenRelease; +        } +        switch (this._penPointerState) { +            case 1: // hovering +                return options.scanOnPenHover; +            case 2: // touching +                return options.scanOnPenMove; +            case 3: // hovering after touching +                return options.scanOnPenReleaseHover; +            default: // not active +                return false; +        } +    } +      _getMatchingInputGroupFromEvent(pointerType, eventType, event) {          const modifiers = DocumentUtil.getActiveModifiersAndButtons(event);          const modifierKeys = DocumentUtil.getActiveModifiers(event); diff --git a/ext/js/pages/settings/scan-inputs-controller.js b/ext/js/pages/settings/scan-inputs-controller.js index 7b363b9a..855ccf9a 100644 --- a/ext/js/pages/settings/scan-inputs-controller.js +++ b/ext/js/pages/settings/scan-inputs-controller.js @@ -150,10 +150,15 @@ class ScanInputsController {                  searchTerms: true,                  searchKanji: true,                  scanOnTouchMove: true, +                scanOnTouchPress: true, +                scanOnTouchRelease: false, +                scanOnPenMove: true,                  scanOnPenHover: true, +                scanOnPenReleaseHover: false,                  scanOnPenPress: true,                  scanOnPenRelease: false, -                preventTouchScrolling: true +                preventTouchScrolling: true, +                preventPenScrolling: true              }          };      } diff --git a/ext/settings.html b/ext/settings.html index 64246fd6..ec9dd34b 100644 --- a/ext/settings.html +++ b/ext/settings.html @@ -2934,16 +2934,28 @@              </label>          </div> -        <div class="scan-input-prefix-cell scan-input-options-cell scan-input-advanced-only" data-property="touch-pen-options"><span>Touch & pen:</span></div> -        <div class="scan-input-content-cell scan-input-options-cell scan-input-advanced-only" data-property="touch-pen-options"> +        <div class="scan-input-prefix-cell scan-input-options-cell scan-input-advanced-only" data-property="touch-options"><span>Touch options:</span></div> +        <div class="scan-input-content-cell scan-input-options-cell scan-input-advanced-only" data-property="touch-options"> +            <label class="scan-input-checkbox-item"> +                <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.scanOnTouchPress"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> +                <span>Scan on touch press</span> +            </label> +            <label class="scan-input-checkbox-item"> +                <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.scanOnTouchRelease"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> +                <span>Scan on touch release</span> +            </label>              <label class="scan-input-checkbox-item">                  <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.scanOnTouchMove"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label>                  <span>Scan on touch move</span>              </label>              <label class="scan-input-checkbox-item"> -                <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.scanOnPenHover"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> -                <span>Scan on pen hover</span> +                <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.preventTouchScrolling"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> +                <span>Prevent touch scrolling</span>              </label> +        </div> + +        <div class="scan-input-prefix-cell scan-input-options-cell scan-input-advanced-only" data-property="pen-options"><span>Pen options:</span></div> +        <div class="scan-input-content-cell scan-input-options-cell scan-input-advanced-only" data-property="pen-options">              <label class="scan-input-checkbox-item">                  <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.scanOnPenPress"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label>                  <span>Scan on pen press</span> @@ -2953,8 +2965,20 @@                  <span>Scan on pen release</span>              </label>              <label class="scan-input-checkbox-item"> -                <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.preventTouchScrolling"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> -                <span>Prevent touch/pen scrolling</span> +                <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.scanOnPenMove"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> +                <span>Scan on pen move (while touched)</span> +            </label> +            <label class="scan-input-checkbox-item"> +                <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.scanOnPenHover"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> +                <span>Scan on pen hover (before touched)</span> +            </label> +            <label class="scan-input-checkbox-item"> +                <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.scanOnPenReleaseHover"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> +                <span>Scan on pen hover (after touched)</span> +            </label> +            <label class="scan-input-checkbox-item"> +                <label class="checkbox"><input type="checkbox" class="scan-input-settings-checkbox" data-property="options.preventPenScrolling"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> +                <span>Prevent pen scrolling</span>              </label>          </div>      </div> diff --git a/test/test-options-util.js b/test/test-options-util.js index c4f9a3a9..16660fd0 100644 --- a/test/test-options-util.js +++ b/test/test-options-util.js @@ -367,10 +367,15 @@ function createProfileOptionsUpdatedTestData1() {                          searchTerms: true,                          searchKanji: true,                          scanOnTouchMove: true, +                        scanOnTouchPress: true, +                        scanOnTouchRelease: false, +                        scanOnPenMove: true,                          scanOnPenHover: true, +                        scanOnPenReleaseHover: false,                          scanOnPenPress: true,                          scanOnPenRelease: false, -                        preventTouchScrolling: true +                        preventTouchScrolling: true, +                        preventPenScrolling: true                      }                  },                  { @@ -386,10 +391,15 @@ function createProfileOptionsUpdatedTestData1() {                          searchTerms: true,                          searchKanji: true,                          scanOnTouchMove: true, +                        scanOnTouchPress: true, +                        scanOnTouchRelease: false, +                        scanOnPenMove: true,                          scanOnPenHover: true, +                        scanOnPenReleaseHover: false,                          scanOnPenPress: true,                          scanOnPenRelease: false, -                        preventTouchScrolling: true +                        preventTouchScrolling: true, +                        preventPenScrolling: true                      }                  },                  { @@ -405,10 +415,15 @@ function createProfileOptionsUpdatedTestData1() {                          searchTerms: true,                          searchKanji: true,                          scanOnTouchMove: true, +                        scanOnTouchPress: true, +                        scanOnTouchRelease: false, +                        scanOnPenMove: true,                          scanOnPenHover: true, +                        scanOnPenReleaseHover: false,                          scanOnPenPress: true,                          scanOnPenRelease: false, -                        preventTouchScrolling: true +                        preventTouchScrolling: true, +                        preventPenScrolling: true                      }                  }              ] |