Add support for restoring the selection after using scanSelectedText (#1631)

This commit is contained in:
toasted-nutbread 2021-04-26 21:05:46 -04:00 committed by GitHub
parent 59f788be39
commit 6f5ad490fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 3 deletions

View File

@ -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;
}

View File

@ -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
}
}
}
}