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:
parent
b3eb2cb1ef
commit
e87cc5c37d
@ -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;
|
||||||
|
this._setSelectedParser(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
_refreshSelectedParser() {
|
||||||
|
if (this._parseResults.length > 0 && !this._getParseResult()) {
|
||||||
|
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');
|
||||||
}
|
}
|
||||||
|
|
||||||
_refreshSelectedParser() {
|
|
||||||
if (this._parseResults.length > 0) {
|
|
||||||
if (!this._getParseResult()) {
|
|
||||||
const value = this._parseResults[0].id;
|
|
||||||
api.modifySettings([{
|
|
||||||
action: 'set',
|
|
||||||
path: 'parsing.selectedParser',
|
|
||||||
value,
|
|
||||||
scope: 'profile',
|
|
||||||
optionsContext: this._getOptionsContext()
|
|
||||||
}], '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);
|
||||||
|
@ -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 *'];
|
||||||
|
@ -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) {
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user