diff options
Diffstat (limited to 'ext/bg/js/search-query-parser.js')
-rw-r--r-- | ext/bg/js/search-query-parser.js | 97 |
1 files changed, 89 insertions, 8 deletions
diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index debe53b4..c3a3900b 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -23,22 +23,103 @@ class QueryParser { this.queryParser = document.querySelector('#query-parser'); - // TODO also enable for mouseover scanning - this.queryParser.addEventListener('click', (e) => this.onTermLookup(e)); + this.queryParser.addEventListener('click', (e) => this.onClick(e)); + this.queryParser.addEventListener('mousemove', (e) => this.onMouseMove(e)); } onError(error) { logError(error, false); } - async onTermLookup(e) { - const {textSource} = await this.search.onTermLookup(e, {isQueryParser: true}); - if (textSource) { - textSource.select(); + onClick(e) { + this.onTermLookup(e, {disableScroll: true, selectText: true}); + } + + async onMouseMove(e) { + if ( + (e.buttons & 0x1) !== 0x0 // Left mouse button + ) { + return; + } + + const scanningOptions = this.search.options.scanning; + const scanningModifier = scanningOptions.modifier; + if (!( + QueryParser.isScanningModifierPressed(scanningModifier, e) || + (scanningOptions.middleMouse && (e.buttons & 0x4) !== 0x0) // Middle mouse button + )) { + return; } + + await this.onTermLookup(e, {disableScroll: true, selectText: true, disableHistory: true}) + } + + onTermLookup(e, params) { + this.search.onTermLookup(e, params); } - setText(text) { - this.queryParser.innerText = text; + async setText(text) { + this.search.setSpinnerVisible(true); + + const results = await apiTextParse(text, this.search.getOptionsContext()); + + const tempContainer = document.createElement('div'); + for (const {text, furigana} of results) { + if (furigana) { + const rubyElement = document.createElement('ruby'); + const furiganaElement = document.createElement('rt'); + furiganaElement.innerText = furigana; + rubyElement.appendChild(document.createTextNode(text)); + rubyElement.appendChild(furiganaElement); + tempContainer.appendChild(rubyElement); + } else { + tempContainer.appendChild(document.createTextNode(text)); + } + } + this.queryParser.innerHTML = ''; + this.queryParser.appendChild(tempContainer); + + this.search.setSpinnerVisible(false); + } + + async parseText(text) { + const results = []; + while (text) { + const {definitions, length} = await apiTermsFind(text, {}, this.search.getOptionsContext()); + if (length) { + results.push(definitions); + text = text.slice(length); + } else { + results.push(text[0]); + text = text.slice(1); + } + } + return results; + } + + popupTimerSet(callback) { + const delay = this.options.scanning.delay; + if (delay > 0) { + this.popupTimer = window.setTimeout(callback, delay); + } else { + Promise.resolve().then(callback); + } + } + + popupTimerClear() { + if (this.popupTimer !== null) { + window.clearTimeout(this.popupTimer); + this.popupTimer = null; + } + } + + static isScanningModifierPressed(scanningModifier, mouseEvent) { + switch (scanningModifier) { + case 'alt': return mouseEvent.altKey; + case 'ctrl': return mouseEvent.ctrlKey; + case 'shift': return mouseEvent.shiftKey; + case 'none': return true; + default: return false; + } } } |