summaryrefslogtreecommitdiff
path: root/ext/js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-04-26 21:05:46 -0400
committerGitHub <noreply@github.com>2021-04-26 21:05:46 -0400
commit6f5ad490fb54b4d0431d56cc644c76d62213abd7 (patch)
tree162c22275eb2444d36d0f0ba206ac3dcecb3d89e /ext/js
parent59f788be395145a5a350bb361cc70a90830f1f5f (diff)
Add support for restoring the selection after using scanSelectedText (#1631)
Diffstat (limited to 'ext/js')
-rw-r--r--ext/js/app/frontend.js2
-rw-r--r--ext/js/language/text-scanner.js46
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
+ }
+ }
+ }
}