diff options
Diffstat (limited to 'ext/mixed/js/text-scanner.js')
| -rw-r--r-- | ext/mixed/js/text-scanner.js | 203 | 
1 files changed, 100 insertions, 103 deletions
| diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index 2ed6c3b9..b8688b08 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -22,11 +22,12 @@   */  class TextScanner extends EventDispatcher { -    constructor(node, ignoreElements, ignorePoints) { +    constructor({node, ignoreElements, ignorePoint, search}) {          super();          this._node = node;          this._ignoreElements = ignoreElements; -        this._ignorePoints = ignorePoints; +        this._ignorePoint = ignorePoint; +        this._search = search;          this._ignoreNodes = null; @@ -69,6 +70,103 @@ class TextScanner extends EventDispatcher {          return this._causeCurrent;      } +    setEnabled(enabled) { +        this._eventListeners.removeAllEventListeners(); +        this._enabled = enabled; +        if (this._enabled) { +            this._hookEvents(); +        } else { +            this.clearSelection(true); +        } +    } + +    setOptions(options) { +        this._options = options; +    } + +    async searchAt(x, y, cause) { +        try { +            this._scanTimerClear(); + +            if (this._pendingLookup) { +                return; +            } + +            if (typeof this._ignorePoint === 'function' && await this._ignorePoint(x, y)) { +                return; +            } + +            const textSource = docRangeFromPoint(x, y, this._options.scanning.deepDomScan); +            try { +                if (this._textSourceCurrent !== null && this._textSourceCurrent.equals(textSource)) { +                    return; +                } + +                this._pendingLookup = true; +                const result = await this._search(textSource, cause); +                if (result !== null) { +                    this._causeCurrent = cause; +                    this.setCurrentTextSource(textSource); +                } +                this._pendingLookup = false; +            } finally { +                if (textSource !== null) { +                    textSource.cleanup(); +                } +            } +        } catch (e) { +            yomichan.logError(e); +        } +    } + +    getTextSourceContent(textSource, length) { +        const clonedTextSource = textSource.clone(); + +        clonedTextSource.setEndOffset(length); + +        if (this._ignoreNodes !== null && clonedTextSource.range) { +            length = clonedTextSource.text().length; +            while (clonedTextSource.range && length > 0) { +                const nodes = TextSourceRange.getNodesInRange(clonedTextSource.range); +                if (!TextSourceRange.anyNodeMatchesSelector(nodes, this._ignoreNodes)) { +                    break; +                } +                --length; +                clonedTextSource.setEndOffset(length); +            } +        } + +        return clonedTextSource.text(); +    } + +    clearSelection(passive) { +        if (!this._canClearSelection) { return; } +        if (this._textSourceCurrent !== null) { +            if (this._textSourceCurrentSelected) { +                this._textSourceCurrent.deselect(); +            } +            this._textSourceCurrent = null; +            this._textSourceCurrentSelected = false; +        } +        this.trigger('clearSelection', {passive}); +    } + +    getCurrentTextSource() { +        return this._textSourceCurrent; +    } + +    setCurrentTextSource(textSource) { +        this._textSourceCurrent = textSource; +        if (this._options.scanning.selectText) { +            this._textSourceCurrent.select(); +            this._textSourceCurrentSelected = true; +        } else { +            this._textSourceCurrentSelected = false; +        } +    } + +    // Private +      _onMouseOver(e) {          if (this._ignoreElements().includes(e.target)) {              this._scanTimerClear(); @@ -221,10 +319,6 @@ class TextScanner extends EventDispatcher {          e.preventDefault(); // Disable scroll      } -    async onSearchSource(_textSource, _cause) { -        throw new Error('Override me'); -    } -      async _scanTimerWait() {          const delay = this._options.scanning.delay;          const promise = promiseTimeout(delay, true); @@ -245,16 +339,6 @@ class TextScanner extends EventDispatcher {          }      } -    setEnabled(enabled) { -        this._eventListeners.removeAllEventListeners(); -        this._enabled = enabled; -        if (this._enabled) { -            this._hookEvents(); -        } else { -            this.clearSelection(true); -        } -    } -      _hookEvents() {          const eventListenerInfos = this._getMouseEventListeners();          if (this._options.scanning.touchInputEnabled) { @@ -287,93 +371,6 @@ class TextScanner extends EventDispatcher {          ];      } -    setOptions(options) { -        this._options = options; -    } - -    async searchAt(x, y, cause) { -        try { -            this._scanTimerClear(); - -            if (this._pendingLookup) { -                return; -            } - -            for (const ignorePointFn of this._ignorePoints) { -                if (await ignorePointFn(x, y)) { -                    return; -                } -            } - -            const textSource = docRangeFromPoint(x, y, this._options.scanning.deepDomScan); -            try { -                if (this._textSourceCurrent !== null && this._textSourceCurrent.equals(textSource)) { -                    return; -                } - -                this._pendingLookup = true; -                const result = await this.onSearchSource(textSource, cause); -                if (result !== null) { -                    this._causeCurrent = cause; -                    this.setCurrentTextSource(textSource); -                } -                this._pendingLookup = false; -            } finally { -                if (textSource !== null) { -                    textSource.cleanup(); -                } -            } -        } catch (e) { -            yomichan.logError(e); -        } -    } - -    getTextSourceContent(textSource, length) { -        const clonedTextSource = textSource.clone(); - -        clonedTextSource.setEndOffset(length); - -        if (this._ignoreNodes !== null && clonedTextSource.range) { -            length = clonedTextSource.text().length; -            while (clonedTextSource.range && length > 0) { -                const nodes = TextSourceRange.getNodesInRange(clonedTextSource.range); -                if (!TextSourceRange.anyNodeMatchesSelector(nodes, this._ignoreNodes)) { -                    break; -                } -                --length; -                clonedTextSource.setEndOffset(length); -            } -        } - -        return clonedTextSource.text(); -    } - -    clearSelection(passive) { -        if (!this._canClearSelection) { return; } -        if (this._textSourceCurrent !== null) { -            if (this._textSourceCurrentSelected) { -                this._textSourceCurrent.deselect(); -            } -            this._textSourceCurrent = null; -            this._textSourceCurrentSelected = false; -        } -        this.trigger('clearSelection', {passive}); -    } - -    getCurrentTextSource() { -        return this._textSourceCurrent; -    } - -    setCurrentTextSource(textSource) { -        this._textSourceCurrent = textSource; -        if (this._options.scanning.selectText) { -            this._textSourceCurrent.select(); -            this._textSourceCurrentSelected = true; -        } else { -            this._textSourceCurrentSelected = false; -        } -    } -      _isScanningModifierPressed(scanningModifier, mouseEvent) {          switch (scanningModifier) {              case 'alt': return mouseEvent.altKey; |