diff options
Diffstat (limited to 'ext/js')
| -rw-r--r-- | ext/js/app/frontend.js | 2 | ||||
| -rw-r--r-- | ext/js/language/text-scanner.js | 46 | 
2 files changed, 45 insertions, 3 deletions
| diff --git a/ext/js/app/frontend.js b/ext/js/app/frontend.js index c7e8c9d8..e1b531d4 100644 --- a/ext/js/app/frontend.js +++ b/ext/js/app/frontend.js @@ -683,7 +683,7 @@ class Frontend {          const range = this._getFirstNonEmptySelectionRange();          if (range === null) { return false; }          const source = new TextSourceRange(range, range.toString(), null, null); -        await this._textScanner.search(source, {focus: true}); +        await this._textScanner.search(source, {focus: true, restoreSelection: true});          return true;      } diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js index b571435b..a49627f8 100644 --- a/ext/js/language/text-scanner.js +++ b/ext/js/language/text-scanner.js @@ -52,6 +52,7 @@ class TextScanner extends EventDispatcher {          this._textSourceCurrent = null;          this._textSourceCurrentSelected = false;          this._pendingLookup = false; +        this._selectionRestoreInfo = null;          this._deepContentScan = false;          this._selectText = false; @@ -258,6 +259,10 @@ class TextScanner extends EventDispatcher {          if (this._textSourceCurrent !== null) {              if (this._textSourceCurrentSelected) {                  this._textSourceCurrent.deselect(); +                if (this._selectionRestoreInfo !== null) { +                    this._restoreSelection(this._selectionRestoreInfo); +                    this._selectionRestoreInfo = null; +                }              }              this._textSourceCurrent = null;              this._textSourceCurrentSelected = false; @@ -313,6 +318,13 @@ class TextScanner extends EventDispatcher {          let detail = null;          try { +            const inputInfoDetail = inputInfo.detail; +            const selectionRestoreInfo = ( +                (isObject(inputInfoDetail) && inputInfoDetail.restoreSelection) ? +                (this._inputInfoCurrent === null ? this._createSelectionRestoreInfo() : void 0) : +                null +            ); +              if (this._textSourceCurrent !== null && this._textSourceCurrent.hasSameStart(textSource)) {                  return null;              } @@ -322,17 +334,24 @@ class TextScanner extends EventDispatcher {              searched = true; +            let valid = false;              const result = await this._findDictionaryEntries(textSource, searchTerms, searchKanji, optionsContext);              if (result !== null) {                  ({dictionaryEntries, sentence, type} = result); -                this._inputInfoCurrent = inputInfo; -                this.setCurrentTextSource(textSource); +                valid = true;              } else if (textSource instanceof TextSourceElement && await this._hasJapanese(textSource.fullContent)) {                  dictionaryEntries = [];                  sentence = {sentence: '', offset: 0};                  type = 'terms'; +                valid = true; +            } + +            if (valid) {                  this._inputInfoCurrent = inputInfo;                  this.setCurrentTextSource(textSource); +                if (typeof selectionRestoreInfo !== 'undefined') { +                    this._selectionRestoreInfo = selectionRestoreInfo; +                }              }          } catch (e) {              error = e; @@ -1054,4 +1073,27 @@ class TextScanner extends EventDispatcher {              return false;          }      } + +    _createSelectionRestoreInfo() { +        const ranges = []; +        const selection = window.getSelection(); +        for (let i = 0, ii = selection.rangeCount; i < ii; ++i) { +            const range = selection.getRangeAt(i); +            ranges.push(range.cloneRange()); +        } +        return {ranges}; +    } + +    _restoreSelection(selectionRestoreInfo) { +        const {ranges} = selectionRestoreInfo; +        const selection = window.getSelection(); +        selection.removeAllRanges(); +        for (const range of ranges) { +            try { +                selection.addRange(range); +            } catch (e) { +                // NOP +            } +        } +    }  } |