diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index 0001c9ff..3215f8e4 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -44,12 +44,7 @@ class QueryParser extends TextScanner { await this.queryParserGenerator.prepare(); } - onError(error) { - yomichan.logError(error); - } - - onClick(e) { - super.onClick(e); + onClick2(e) { this.searchAt(e.clientX, e.clientY, 'click'); } @@ -84,22 +79,8 @@ class QueryParser extends TextScanner { getMouseEventListeners() { return [ - [this.node, 'click', this.onClick.bind(this)], - [this.node, 'mousedown', this.onMouseDown.bind(this)], - [this.node, 'mousemove', this.onMouseMove.bind(this)], - [this.node, 'mouseover', this.onMouseOver.bind(this)], - [this.node, 'mouseout', this.onMouseOut.bind(this)] - ]; - } - - getTouchEventListeners() { - return [ - [this.node, 'auxclick', this.onAuxClick.bind(this)], - [this.node, 'touchstart', this.onTouchStart.bind(this)], - [this.node, 'touchend', this.onTouchEnd.bind(this)], - [this.node, 'touchcancel', this.onTouchCancel.bind(this)], - [this.node, 'touchmove', this.onTouchMove.bind(this), {passive: false}], - [this.node, 'contextmenu', this.onContextMenu.bind(this)] + ...super.getMouseEventListeners(), + [this.node, 'click', this.onClick2.bind(this)] ]; } diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index cbd7b562..b7d2eed8 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -125,7 +125,7 @@ class DisplaySearch extends Display { yomichan.logError(error); } - onSearchClear() { + onEscape() { if (this.query === null) { return; } diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 05a2a41b..e73c04a0 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -69,7 +69,7 @@ class SettingsPopupPreview { this.frontend.getOptionsContext = async () => this.optionsContext; this.frontend.setEnabled = () => {}; - this.frontend.onSearchClear = () => {}; + this.frontend.clearSelection = () => {}; await this.frontend.prepare(); diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index fd3b92cc..294093cd 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -92,7 +92,7 @@ class DisplayFloat extends Display { this._orphaned = true; } - onSearchClear() { + onEscape() { window.parent.postMessage('popupClose', '*'); } diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 46921d36..50f52724 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -49,7 +49,7 @@ class Frontend extends TextScanner { this._lastShowPromise = Promise.resolve(); this._windowMessageHandlers = new Map([ - ['popupClose', () => this.onSearchClear(true)], + ['popupClose', () => this.clearSelection(false)], ['selectionCopy', () => document.execCommand('copy')] ]); @@ -79,10 +79,12 @@ class Frontend extends TextScanner { yomichan.on('zoomChanged', this.onZoomChanged.bind(this)); chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); + this.on('clearSelection', this.onClearSelection.bind(this)); + this._updateContentScale(); this._broadcastRootPopupInformation(); } catch (e) { - this.onError(e); + yomichan.logError(e); } } @@ -140,7 +142,7 @@ class Frontend extends TextScanner { } async setPopup(popup) { - this.onSearchClear(false); + this.clearSelection(true); this.popup = popup; await popup.setOptionsContext(await this.getOptionsContext(), this._id); } @@ -186,11 +188,11 @@ class Frontend extends TextScanner { this._showPopupContent(textSource, await this.getOptionsContext(), 'orphaned'); } } else { - this.onError(e); + yomichan.logError(e); } } finally { if (results === null && this.options.scanning.autoHideResults) { - this.onSearchClear(true); + this.clearSelection(false); } } @@ -238,10 +240,9 @@ class Frontend extends TextScanner { return {definitions, type: 'kanji'}; } - onSearchClear(changeFocus) { - this.popup.hide(changeFocus); + onClearSelection({passive}) { + this.popup.hide(!passive); this.popup.clearAutoPlayTimer(); - super.onSearchClear(changeFocus); } async getOptionsContext() { @@ -269,7 +270,9 @@ class Frontend extends TextScanner { contentScale /= this._pageZoomFactor; } if (popupScaleRelativeToVisualViewport) { - contentScale /= Frontend._getVisualViewportScale(); + const visualViewport = window.visualViewport; + const visualViewportScale = (visualViewport !== null && typeof visualViewport === 'object' ? visualViewport.scale : 1.0); + contentScale /= visualViewportScale; } if (contentScale === this._contentScale) { return; } @@ -302,9 +305,4 @@ class Frontend extends TextScanner { this._showPopupContent(textSource, await this.getOptionsContext()); } } - - static _getVisualViewportScale() { - const visualViewport = window.visualViewport; - return visualViewport !== null && typeof visualViewport === 'object' ? visualViewport.scale : 1.0; - } } diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 70b7fcd3..32081c70 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -69,7 +69,7 @@ class Display { this._onKeyDownHandlers = new Map([ ['Escape', () => { - this.onSearchClear(); + this.onEscape(); return true; }], ['PageUp', (e) => { @@ -183,7 +183,7 @@ class Display { throw new Error('Override me'); } - onSearchClear() { + onEscape() { throw new Error('Override me'); } diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index 1c32714b..c582ccd8 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -21,8 +21,9 @@ * docRangeFromPoint */ -class TextScanner { +class TextScanner extends EventDispatcher { constructor(node, ignoreElements, ignorePoints) { + super(); this.node = node; this.ignoreElements = ignoreElements; this.ignorePoints = ignorePoints; @@ -32,6 +33,7 @@ class TextScanner { this.scanTimerPromise = null; this.causeCurrent = null; this.textSourceCurrent = null; + this.textSourceCurrentSelected = false; this.pendingLookup = false; this.options = null; @@ -92,7 +94,7 @@ class TextScanner { if (DOM.isMouseButtonDown(e, 'primary')) { this.scanTimerClear(); - this.onSearchClear(true); + this.clearSelection(false); } } @@ -200,10 +202,6 @@ class TextScanner { throw new Error('Override me'); } - onError(error) { - yomichan.logError(error); - } - async scanTimerWait() { const delay = this.options.scanning.delay; const promise = promiseTimeout(delay, true); @@ -225,17 +223,12 @@ class TextScanner { } setEnabled(enabled, canEnable) { - if (enabled && canEnable) { - if (!this.enabled) { - this.hookEvents(); - this.enabled = true; - } + this.eventListeners.removeAllEventListeners(); + this.enabled = enabled && canEnable; + if (this.enabled) { + this.hookEvents(); } else { - if (this.enabled) { - this.eventListeners.removeAllEventListeners(); - this.enabled = false; - } - this.onSearchClear(false); + this.clearSelection(true); } } @@ -300,10 +293,7 @@ class TextScanner { const result = await this.onSearchSource(textSource, cause); if (result !== null) { this.causeCurrent = cause; - this.textSourceCurrent = textSource; - if (this.options.scanning.selectText) { - textSource.select(); - } + this.setCurrentTextSource(textSource); } this.pendingLookup = false; } finally { @@ -312,7 +302,7 @@ class TextScanner { } } } catch (e) { - this.onError(e); + yomichan.logError(e); } } @@ -333,13 +323,15 @@ class TextScanner { } } - onSearchClear(_) { + clearSelection(passive) { if (this.textSourceCurrent !== null) { - if (this.options.scanning.selectText) { + if (this.textSourceCurrentSelected) { this.textSourceCurrent.deselect(); } this.textSourceCurrent = null; + this.textSourceCurrentSelected = false; } + this.trigger('clearSelection', {passive}); } getCurrentTextSource() { @@ -347,7 +339,13 @@ class TextScanner { } setCurrentTextSource(textSource) { - return this.textSourceCurrent = textSource; + this.textSourceCurrent = textSource; + if (this.options.scanning.selectText) { + this.textSourceCurrent.select(); + this.textSourceCurrentSelected = true; + } else { + this.textSourceCurrentSelected = false; + } } static isScanningModifierPressed(scanningModifier, mouseEvent) {