diff options
| -rw-r--r-- | ext/bg/js/search-query-parser.js | 16 | ||||
| -rw-r--r-- | ext/fg/js/frontend.js | 18 | ||||
| -rw-r--r-- | ext/mixed/js/text-scanner.js | 203 | 
3 files changed, 117 insertions, 120 deletions
| diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index caace34b..e1e37d1c 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -34,12 +34,12 @@ class QueryParser {          this._queryParser = document.querySelector('#query-parser-content');          this._queryParserSelect = document.querySelector('#query-parser-select-container');          this._queryParserGenerator = new QueryParserGenerator(); -        this._textScanner = new TextScanner( -            this._queryParser, -            () => [], -            [] -        ); -        this._textScanner.onSearchSource = this._onSearchSource.bind(this); +        this._textScanner = new TextScanner({ +            node: this._queryParser, +            ignoreElements: () => [], +            ignorePoint: null, +            search: this._search.bind(this) +        });      }      async prepare() { @@ -74,11 +74,11 @@ class QueryParser {          this._textScanner.searchAt(e.clientX, e.clientY, 'click');      } -    async _onSearchSource(textSource, cause) { +    async _search(textSource, cause) {          if (textSource === null) { return null; }          const searchText = this._textScanner.getTextSourceContent(textSource, this._options.scanning.length); -        if (searchText.length === 0) { return; } +        if (searchText.length === 0) { return null; }          const {definitions, length} = await apiTermsFind(searchText, {}, this._getOptionsContext());          if (definitions.length === 0) { return null; } diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 9de6597e..78440991 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -39,12 +39,12 @@ class Frontend {          this._enabledEventListeners = new EventListenerCollection();          this._activeModifiers = new Set();          this._optionsUpdatePending = false; -        this._textScanner = new TextScanner( -            window, -            () => this._popup.isProxy() ? [] : [this._popup.getContainer()], -            [(x, y) => this._popup.containsPoint(x, y)] -        ); -        this._textScanner.onSearchSource = this._onSearchSource.bind(this); +        this._textScanner = new TextScanner({ +            node: window, +            ignoreElements: () => this._popup.isProxy() ? [] : [this._popup.getContainer()], +            ignorePoint: (x, y) => this._popup.containsPoint(x, y), +            search: this._search.bind(this) +        });          this._windowMessageHandlers = new Map([              ['popupClose', () => this._textScanner.clearSelection(false)], @@ -107,7 +107,7 @@ class Frontend {      }      async setTextSource(textSource) { -        await this._onSearchSource(textSource, 'script'); +        await this._search(textSource, 'script');          this._textScanner.setCurrentTextSource(textSource);      } @@ -137,7 +137,7 @@ class Frontend {          const textSourceCurrent = this._textScanner.getCurrentTextSource();          const causeCurrent = this._textScanner.causeCurrent;          if (textSourceCurrent !== null && causeCurrent !== null) { -            await this._onSearchSource(textSourceCurrent, causeCurrent); +            await this._search(textSourceCurrent, causeCurrent);          }      } @@ -204,7 +204,7 @@ class Frontend {          await this.updateOptions();      } -    async _onSearchSource(textSource, cause) { +    async _search(textSource, cause) {          await this._updatePendingOptions();          let results = null; 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; |