Query parser text scanner options refactor (#717)

* Add _setSelectedParser helper

* Update TextScanner internal options representation

* Update QueryParser internal options representation
This commit is contained in:
toasted-nutbread 2020-08-09 13:19:42 -04:00 committed by GitHub
parent b3eb2cb1ef
commit e87cc5c37d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 108 additions and 44 deletions

View File

@ -25,9 +25,12 @@
class QueryParser extends EventDispatcher { class QueryParser extends EventDispatcher {
constructor({getOptionsContext, setSpinnerVisible}) { constructor({getOptionsContext, setSpinnerVisible}) {
super(); super();
this._options = null;
this._getOptionsContext = getOptionsContext; this._getOptionsContext = getOptionsContext;
this._setSpinnerVisible = setSpinnerVisible; this._setSpinnerVisible = setSpinnerVisible;
this._selectedParser = null;
this._scanLength = 1;
this._sentenceExtent = 1;
this._layoutAwareScan = false;
this._parseResults = []; this._parseResults = [];
this._queryParser = document.querySelector('#query-parser-content'); this._queryParser = document.querySelector('#query-parser-content');
this._queryParserSelect = document.querySelector('#query-parser-select-container'); this._queryParserSelect = document.querySelector('#query-parser-select-container');
@ -46,11 +49,26 @@ class QueryParser extends EventDispatcher {
this._queryParser.addEventListener('click', this._onClick.bind(this)); this._queryParser.addEventListener('click', this._onClick.bind(this));
} }
setOptions(options) { setOptions({selectedParser, scanLength, sentenceExtent, layoutAwareScan, termSpacing, scanning}) {
this._options = options; if (selectedParser === null || typeof selectedParser === 'string') {
this._textScanner.setOptions(options); this._selectedParser = selectedParser;
}
if (typeof scanLength === 'number') {
this._scanLength = scanLength;
}
if (typeof sentenceExtent === 'number') {
this._sentenceExtent = sentenceExtent;
}
if (typeof layoutAwareScan === 'boolean') {
this._layoutAwareScan = layoutAwareScan;
}
if (typeof termSpacing === 'boolean') {
this._queryParser.dataset.termSpacing = `${termSpacing}`;
}
if (scanning !== null && typeof scanning === 'object') {
this._textScanner.setOptions(scanning);
}
this._textScanner.setEnabled(true); this._textScanner.setEnabled(true);
this._queryParser.dataset.termSpacing = `${options.parsing.termSpacing}`;
} }
async setText(text) { async setText(text) {
@ -76,7 +94,9 @@ class QueryParser extends EventDispatcher {
async _search(textSource, cause) { async _search(textSource, cause) {
if (textSource === null) { return null; } if (textSource === null) { return null; }
const {length: scanLength, layoutAwareScan} = this._options.scanning; const scanLength = this._scanLength;
const sentenceExtent = this._sentenceExtent;
const layoutAwareScan = this._layoutAwareScan;
const searchText = this._textScanner.getTextSourceContent(textSource, scanLength, layoutAwareScan); const searchText = this._textScanner.getTextSourceContent(textSource, scanLength, layoutAwareScan);
if (searchText.length === 0) { return null; } if (searchText.length === 0) { return null; }
@ -84,7 +104,6 @@ class QueryParser extends EventDispatcher {
const {definitions, length} = await api.termsFind(searchText, {}, optionsContext); const {definitions, length} = await api.termsFind(searchText, {}, optionsContext);
if (definitions.length === 0) { return null; } if (definitions.length === 0) { return null; }
const sentenceExtent = this._options.anki.sentenceExt;
const sentence = docSentenceExtract(textSource, sentenceExtent, layoutAwareScan); const sentence = docSentenceExtract(textSource, sentenceExtent, layoutAwareScan);
textSource.setEndOffset(length, layoutAwareScan); textSource.setEndOffset(length, layoutAwareScan);
@ -103,32 +122,29 @@ class QueryParser extends EventDispatcher {
_onParserChange(e) { _onParserChange(e) {
const value = e.target.value; const value = e.target.value;
api.modifySettings([{ this._setSelectedParser(value);
action: 'set',
path: 'parsing.selectedParser',
value,
scope: 'profile',
optionsContext: this._getOptionsContext()
}], 'search');
} }
_refreshSelectedParser() { _refreshSelectedParser() {
if (this._parseResults.length > 0) { if (this._parseResults.length > 0 && !this._getParseResult()) {
if (!this._getParseResult()) {
const value = this._parseResults[0].id; const value = this._parseResults[0].id;
this._setSelectedParser(value);
}
}
_setSelectedParser(value) {
const optionsContext = this._getOptionsContext();
api.modifySettings([{ api.modifySettings([{
action: 'set', action: 'set',
path: 'parsing.selectedParser', path: 'parsing.selectedParser',
value, value,
scope: 'profile', scope: 'profile',
optionsContext: this._getOptionsContext() optionsContext
}], 'search'); }], 'search');
} }
}
}
_getParseResult() { _getParseResult() {
const {selectedParser} = this._options.parsing; const selectedParser = this._selectedParser;
return this._parseResults.find((r) => r.id === selectedParser); return this._parseResults.find((r) => r.id === selectedParser);
} }
@ -145,7 +161,7 @@ class QueryParser extends EventDispatcher {
_renderParserSelect() { _renderParserSelect() {
this._queryParserSelect.textContent = ''; this._queryParserSelect.textContent = '';
if (this._parseResults.length > 1) { if (this._parseResults.length > 1) {
const {selectedParser} = this._options.parsing; const selectedParser = this._selectedParser;
const select = this._queryParserGenerator.createParserSelect(this._parseResults, selectedParser); const select = this._queryParserGenerator.createParserSelect(this._parseResults, selectedParser);
select.addEventListener('change', this._onParserChange.bind(this)); select.addEventListener('change', this._onParserChange.bind(this));
this._queryParserSelect.appendChild(select); this._queryParserSelect.appendChild(select);

View File

@ -233,11 +233,20 @@ class Frontend {
async _updateOptionsInternal() { async _updateOptionsInternal() {
const optionsContext = await this.getOptionsContext(); const optionsContext = await this.getOptionsContext();
this._options = await api.optionsGet(optionsContext); const options = await api.optionsGet(optionsContext);
const scanningOptions = options.scanning;
this._options = options;
await this._updatePopup(); await this._updatePopup();
this._textScanner.setOptions(this._options); this._textScanner.setOptions({
deepContentScan: scanningOptions.deepDomScan,
selectText: scanningOptions.selectText,
modifier: scanningOptions.modifier,
useMiddleMouse: scanningOptions.middleMouse,
delay: scanningOptions.delay,
touchInputEnabled: scanningOptions.touchInputEnabled
});
this._updateTextScannerEnabled(); this._updateTextScannerEnabled();
const ignoreNodes = ['.scan-disable', '.scan-disable *']; const ignoreNodes = ['.scan-disable', '.scan-disable *'];

View File

@ -218,11 +218,29 @@ class Display extends EventDispatcher {
} }
async updateOptions() { async updateOptions() {
this._options = await api.optionsGet(this.getOptionsContext()); const options = await api.optionsGet(this.getOptionsContext());
this._updateDocumentOptions(this._options); const scanning = options.scanning;
this._updateTheme(this._options.general.popupTheme); this._options = options;
this.setCustomCss(this._options.general.customPopupCss);
this._queryParser.setOptions(this._options); this._updateDocumentOptions(options);
this._updateTheme(options.general.popupTheme);
this.setCustomCss(options.general.customPopupCss);
this._queryParser.setOptions({
selectedParser: options.parsing.selectedParser,
scanLength: scanning.length,
sentenceExtent: options.anki.sentenceExt,
layoutAwareScan: scanning.layoutAwareScan,
termSpacing: options.parsing.termSpacing,
scanning: {
deepContentScan: scanning.deepDomScan,
selectText: scanning.selectText,
modifier: scanning.modifier,
useMiddleMouse: scanning.middleMouse,
delay: scanning.delay,
touchInputEnabled: scanning.touchInputEnabled
}
});
} }
addMultipleEventListeners(selector, type, listener, options) { addMultipleEventListeners(selector, type, listener, options) {

View File

@ -36,7 +36,13 @@ class TextScanner extends EventDispatcher {
this._textSourceCurrent = null; this._textSourceCurrent = null;
this._textSourceCurrentSelected = false; this._textSourceCurrentSelected = false;
this._pendingLookup = false; this._pendingLookup = false;
this._options = null;
this._deepContentScan = false;
this._selectText = false;
this._modifier = 'none';
this._useMiddleMouse = false;
this._delay = 0;
this._touchInputEnabled = false;
this._enabled = false; this._enabled = false;
this._eventListeners = new EventListenerCollection(); this._eventListeners = new EventListenerCollection();
@ -85,8 +91,25 @@ class TextScanner extends EventDispatcher {
} }
} }
setOptions(options) { setOptions({deepContentScan, selectText, modifier, useMiddleMouse, delay, touchInputEnabled}) {
this._options = options; if (typeof deepContentScan === 'boolean') {
this._deepContentScan = deepContentScan;
}
if (typeof selectText === 'boolean') {
this._selectText = selectText;
}
if (typeof modifier === 'string') {
this._modifier = modifier;
}
if (typeof useMiddleMouse === 'boolean') {
this._useMiddleMouse = useMiddleMouse;
}
if (typeof delay === 'number') {
this._delay = delay;
}
if (typeof touchInputEnabled === 'boolean') {
this._touchInputEnabled = false;
}
} }
async searchAt(x, y, cause) { async searchAt(x, y, cause) {
@ -101,7 +124,7 @@ class TextScanner extends EventDispatcher {
return; return;
} }
const textSource = docRangeFromPoint(x, y, this._options.scanning.deepDomScan); const textSource = docRangeFromPoint(x, y, this._deepContentScan);
try { try {
if (this._textSourceCurrent !== null && this._textSourceCurrent.equals(textSource)) { if (this._textSourceCurrent !== null && this._textSourceCurrent.equals(textSource)) {
return; return;
@ -162,7 +185,7 @@ class TextScanner extends EventDispatcher {
setCurrentTextSource(textSource) { setCurrentTextSource(textSource) {
this._textSourceCurrent = textSource; this._textSourceCurrent = textSource;
if (this._options.scanning.selectText) { if (this._selectText) {
this._textSourceCurrent.select(); this._textSourceCurrent.select();
this._textSourceCurrentSelected = true; this._textSourceCurrentSelected = true;
} else { } else {
@ -188,17 +211,15 @@ class TextScanner extends EventDispatcher {
const modifiers = DOM.getActiveModifiers(e); const modifiers = DOM.getActiveModifiers(e);
this.trigger('activeModifiersChanged', {modifiers}); this.trigger('activeModifiersChanged', {modifiers});
const scanningOptions = this._options.scanning;
const scanningModifier = scanningOptions.modifier;
if (!( if (!(
this._isScanningModifierPressed(scanningModifier, e) || this._isScanningModifierPressed(this._modifier, e) ||
(scanningOptions.middleMouse && DOM.isMouseButtonDown(e, 'auxiliary')) (this._useMiddleMouse && DOM.isMouseButtonDown(e, 'auxiliary'))
)) { )) {
return; return;
} }
const search = async () => { const search = async () => {
if (scanningModifier === 'none') { if (this._modifier === 'none') {
if (!await this._scanTimerWait()) { if (!await this._scanTimerWait()) {
// Aborted // Aborted
return; return;
@ -325,7 +346,7 @@ class TextScanner extends EventDispatcher {
} }
async _scanTimerWait() { async _scanTimerWait() {
const delay = this._options.scanning.delay; const delay = this._delay;
const promise = promiseTimeout(delay, true); const promise = promiseTimeout(delay, true);
this._scanTimerPromise = promise; this._scanTimerPromise = promise;
try { try {
@ -346,7 +367,7 @@ class TextScanner extends EventDispatcher {
_hookEvents() { _hookEvents() {
const eventListenerInfos = this._getMouseEventListeners(); const eventListenerInfos = this._getMouseEventListeners();
if (this._options.scanning.touchInputEnabled) { if (this._touchInputEnabled) {
eventListenerInfos.push(...this._getTouchEventListeners()); eventListenerInfos.push(...this._getTouchEventListeners());
} }