diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/bg/js/search-query-parser.js | 1 | ||||
| -rw-r--r-- | ext/bg/js/settings/popup-preview-frame.js | 9 | ||||
| -rw-r--r-- | ext/fg/js/frontend.js | 94 | ||||
| -rw-r--r-- | ext/mixed/js/text-scanner.js | 22 | 
4 files changed, 77 insertions, 49 deletions
| diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index 3215f8e4..137234e8 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -86,6 +86,7 @@ class QueryParser extends TextScanner {      setOptions(options) {          super.setOptions(options); +        super.setEnabled(true);          this.queryParser.dataset.termSpacing = `${options.parsing.termSpacing}`;      } diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index e73c04a0..cb548ed7 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -66,12 +66,10 @@ class SettingsPopupPreview {          this.popup.setCustomOuterCss = this.popupSetCustomOuterCss.bind(this);          this.frontend = new Frontend(this.popup); -          this.frontend.getOptionsContext = async () => this.optionsContext; -        this.frontend.setEnabled = () => {}; -        this.frontend.clearSelection = () => {}; -          await this.frontend.prepare(); +        this.frontend.setDisabledOverride(true); +        this.frontend.canClearSelection = false;          // Update search          this.updateSearch(); @@ -169,8 +167,7 @@ class SettingsPopupPreview {          const source = new TextSourceRange(range, range.toString(), null, null);          try { -            await this.frontend.onSearchSource(source, 'script'); -            this.frontend.setCurrentTextSource(source); +            await this.frontend.setTextSource(source);          } finally {              source.cleanup();          } diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 50f52724..76ad27e0 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -25,14 +25,8 @@   * docSentenceExtract   */ -class Frontend extends TextScanner { +class Frontend {      constructor(popup, getUrl=null) { -        super( -            window, -            () => this.popup.isProxy() ? [] : [this.popup.getContainer()], -            [(x, y) => this.popup.containsPoint(x, y)] -        ); -          this._id = yomichan.generateId(16);          this.popup = popup; @@ -41,15 +35,23 @@ class Frontend extends TextScanner {          this._disabledOverride = false; -        this.options = null; +        this._options = null;          this._pageZoomFactor = 1.0;          this._contentScale = 1.0;          this._orphaned = false;          this._lastShowPromise = Promise.resolve(); +        this._enabledEventListeners = new EventListenerCollection(); +        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._windowMessageHandlers = new Map([ -            ['popupClose', () => this.clearSelection(false)], +            ['popupClose', () => this._textScanner.clearSelection(false)],              ['selectionCopy', () => document.execCommand('copy')]          ]); @@ -60,6 +62,14 @@ class Frontend extends TextScanner {          ]);      } +    get canClearSelection() { +        return this._textScanner.canClearSelection; +    } + +    set canClearSelection(value) { +        this._textScanner.canClearSelection = value; +    } +      async prepare() {          try {              await this.updateOptions(); @@ -79,7 +89,7 @@ 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._textScanner.on('clearSelection', this.onClearSelection.bind(this));              this._updateContentScale();              this._broadcastRootPopupInformation(); @@ -129,44 +139,45 @@ class Frontend extends TextScanner {          this._updateContentScale();      } -    getMouseEventListeners() { -        return [ -            ...super.getMouseEventListeners(), -            [window, 'message', this.onWindowMessage.bind(this)] -        ]; -    } -      setDisabledOverride(disabled) {          this._disabledOverride = disabled; -        this.setEnabled(this.options.general.enable, this._canEnable()); +        this._updateTextScannerEnabled();      }      async setPopup(popup) { -        this.clearSelection(true); +        this._textScanner.clearSelection(true);          this.popup = popup;          await popup.setOptionsContext(await this.getOptionsContext(), this._id);      }      async updateOptions() {          const optionsContext = await this.getOptionsContext(); -        this.options = await apiOptionsGet(optionsContext); -        this.setOptions(this.options, this._canEnable()); +        this._options = await apiOptionsGet(optionsContext); +        this._textScanner.setOptions(this._options); +        this._updateTextScannerEnabled();          const ignoreNodes = ['.scan-disable', '.scan-disable *']; -        if (!this.options.scanning.enableOnPopupExpressions) { +        if (!this._options.scanning.enableOnPopupExpressions) {              ignoreNodes.push('.source-text', '.source-text *');          } -        this.ignoreNodes = ignoreNodes.join(','); +        this._textScanner.ignoreNodes = ignoreNodes.join(',');          await this.popup.setOptionsContext(optionsContext, this._id);          this._updateContentScale(); -        if (this.textSourceCurrent !== null && this.causeCurrent !== null) { -            await this.onSearchSource(this.textSourceCurrent, this.causeCurrent); +        const textSourceCurrent = this._textScanner.getCurrentTextSource(); +        const causeCurrent = this._textScanner.causeCurrent; +        if (textSourceCurrent !== null && causeCurrent !== null) { +            await this.onSearchSource(textSourceCurrent, causeCurrent);          }      } +    async setTextSource(textSource) { +        await this.onSearchSource(textSource, 'script'); +        this._textScanner.setCurrentTextSource(textSource); +    } +      async onSearchSource(textSource, cause) {          let results = null; @@ -184,15 +195,15 @@ class Frontend extends TextScanner {              }          } catch (e) {              if (this._orphaned) { -                if (textSource !== null && this.options.scanning.modifier !== 'none') { +                if (textSource !== null && this._options.scanning.modifier !== 'none') {                      this._showPopupContent(textSource, await this.getOptionsContext(), 'orphaned');                  }              } else {                  yomichan.logError(e);              }          } finally { -            if (results === null && this.options.scanning.autoHideResults) { -                this.clearSelection(false); +            if (results === null && this._options.scanning.autoHideResults) { +                this._textScanner.clearSelection(false);              }          } @@ -201,7 +212,7 @@ class Frontend extends TextScanner {      showContent(textSource, focus, definitions, type, optionsContext) {          const {url} = optionsContext; -        const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt); +        const sentence = docSentenceExtract(textSource, this._options.anki.sentenceExt);          this._showPopupContent(              textSource,              optionsContext, @@ -215,7 +226,7 @@ class Frontend extends TextScanner {      }      async findTerms(textSource, optionsContext) { -        this.setTextSourceScanLength(textSource, this.options.scanning.length); +        this._textScanner.setTextSourceScanLength(textSource, this._options.scanning.length);          const searchText = textSource.text();          if (searchText.length === 0) { return null; } @@ -229,7 +240,7 @@ class Frontend extends TextScanner {      }      async findKanji(textSource, optionsContext) { -        this.setTextSourceScanLength(textSource, 1); +        this._textScanner.setTextSourceScanLength(textSource, 1);          const searchText = textSource.text();          if (searchText.length === 0) { return null; } @@ -263,8 +274,21 @@ class Frontend extends TextScanner {          return this._lastShowPromise;      } +    _updateTextScannerEnabled() { +        const enabled = ( +            this._options.general.enable && +            this.popup.depth <= this._options.scanning.popupNestingMaxDepth && +            !this._disabledOverride +        ); +        this._enabledEventListeners.removeAllEventListeners(); +        this._textScanner.setEnabled(enabled); +        if (enabled) { +            this._enabledEventListeners.addEventListener(window, 'message', this.onWindowMessage.bind(this)); +        } +    } +      _updateContentScale() { -        const {popupScalingFactor, popupScaleRelativeToPageZoom, popupScaleRelativeToVisualViewport} = this.options.general; +        const {popupScalingFactor, popupScaleRelativeToPageZoom, popupScaleRelativeToVisualViewport} = this._options.general;          let contentScale = popupScalingFactor;          if (popupScaleRelativeToPageZoom) {              contentScale /= this._pageZoomFactor; @@ -295,12 +319,8 @@ class Frontend extends TextScanner {          });      } -    _canEnable() { -        return this.popup.depth <= this.options.scanning.popupNestingMaxDepth && !this._disabledOverride; -    } -      async _updatePopupPosition() { -        const textSource = this.getCurrentTextSource(); +        const textSource = this._textScanner.getCurrentTextSource();          if (textSource !== null && await this.popup.isVisible()) {              this._showPopupContent(textSource, await this.getOptionsContext());          } diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index c582ccd8..774eef44 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -45,6 +45,16 @@ class TextScanner extends EventDispatcher {          this.preventNextMouseDown = false;          this.preventNextClick = false;          this.preventScroll = false; + +        this._canClearSelection = true; +    } + +    get canClearSelection() { +        return this._canClearSelection; +    } + +    set canClearSelection(value) { +        this._canClearSelection = value;      }      onMouseOver(e) { @@ -222,9 +232,9 @@ class TextScanner extends EventDispatcher {          }      } -    setEnabled(enabled, canEnable) { +    setEnabled(enabled) {          this.eventListeners.removeAllEventListeners(); -        this.enabled = enabled && canEnable; +        this.enabled = enabled;          if (this.enabled) {              this.hookEvents();          } else { @@ -233,9 +243,9 @@ class TextScanner extends EventDispatcher {      }      hookEvents() { -        let eventListenerInfos = this.getMouseEventListeners(); +        const eventListenerInfos = this.getMouseEventListeners();          if (this.options.scanning.touchInputEnabled) { -            eventListenerInfos = eventListenerInfos.concat(this.getTouchEventListeners()); +            eventListenerInfos.push(...this.getTouchEventListeners());          }          for (const [node, type, listener, options] of eventListenerInfos) { @@ -264,9 +274,8 @@ class TextScanner extends EventDispatcher {          ];      } -    setOptions(options, canEnable=true) { +    setOptions(options) {          this.options = options; -        this.setEnabled(this.options.general.enable, canEnable);      }      async searchAt(x, y, cause) { @@ -324,6 +333,7 @@ class TextScanner extends EventDispatcher {      }      clearSelection(passive) { +        if (!this._canClearSelection) { return; }          if (this.textSourceCurrent !== null) {              if (this.textSourceCurrentSelected) {                  this.textSourceCurrent.deselect(); |