simplify with inheritance

This commit is contained in:
siikamiika 2019-12-06 21:39:29 +02:00
parent 595636c40b
commit f6d0503604
2 changed files with 65 additions and 107 deletions

View File

@ -17,17 +17,16 @@
*/ */
class Frontend { class Frontend extends TextScanner {
constructor(popup, ignoreNodes) { constructor(popup, ignoreNodes) {
this.popup = popup; super(
this.textScanner = new TextScanner(
window, window,
ignoreNodes, ignoreNodes,
[this.popup.container], [popup.container],
[(x, y) => this.popup.containsPoint(x, y)] [(x, y) => this.popup.containsPoint(x, y)]
); );
this.textScanner.subscribe('textSearch', ({textSource, cause}) => this.searchSource(textSource, cause));
this.textScanner.subscribe('searchClear', () => this.searchClear(true)); this.popup = popup;
this.options = null; this.options = null;
this.optionsContext = { this.optionsContext = {
@ -35,9 +34,6 @@ class Frontend {
url: popup.url url: popup.url
}; };
this.enabled = false;
this.eventListeners = [];
this.isPreparedPromiseResolve = null; this.isPreparedPromiseResolve = null;
this.isPreparedPromise = new Promise((resolve) => { this.isPreparedPromiseResolve = resolve; }); this.isPreparedPromise = new Promise((resolve) => { this.isPreparedPromiseResolve = resolve; });
@ -70,7 +66,7 @@ class Frontend {
} }
async onResize() { async onResize() {
const textSource = this.textScanner.getCurrentTextSource(); const textSource = this.textSourceCurrent;
if (textSource !== null && await this.popup.isVisibleAsync()) { if (textSource !== null && await this.popup.isVisibleAsync()) {
this.lastShowPromise = this.popup.showContent( this.lastShowPromise = this.popup.showContent(
textSource.getRect(), textSource.getRect(),
@ -97,51 +93,21 @@ class Frontend {
} }
} }
onError(error) { getMouseEventListeners() {
logError(error, false); return [
} ...super.getMouseEventListeners(),
[window, 'message', this.onWindowMessage.bind(this)],
setEnabled(enabled) { [window, 'resize', this.onResize.bind(this)]
this.textScanner.setEnabled(enabled); ];
if (enabled) {
if (!this.enabled) {
this.hookEvents();
this.enabled = true;
}
} else {
if (this.enabled) {
this.clearEventListeners();
this.enabled = false;
}
this.searchClear(false);
}
}
hookEvents() {
this.addEventListener(window, 'message', this.onWindowMessage.bind(this));
this.addEventListener(window, 'resize', this.onResize.bind(this));
}
addEventListener(node, type, listener, options) {
node.addEventListener(type, listener, options);
this.eventListeners.push([node, type, listener, options]);
}
clearEventListeners() {
for (const [node, type, listener, options] of this.eventListeners) {
node.removeEventListener(type, listener, options);
}
this.eventListeners = [];
} }
async updateOptions() { async updateOptions() {
this.options = await apiOptionsGet(this.getOptionsContext()); this.options = await apiOptionsGet(this.getOptionsContext());
this.textScanner.setOptions(this.options);
await this.popup.setOptions(this.options); await this.popup.setOptions(this.options);
this.setEnabled(this.options.general.enable); this.setEnabled(this.options.general.enable);
} }
async searchSource(textSource, cause) { async onSearchSource(textSource, cause) {
let results = null; let results = null;
try { try {
@ -169,7 +135,7 @@ class Frontend {
} }
} finally { } finally {
if (results === null && this.options.scanning.autoHideResults) { if (results === null && this.options.scanning.autoHideResults) {
this.searchClear(true); this.onSearchClear(true);
} }
} }
@ -188,7 +154,7 @@ class Frontend {
} }
async findTerms(textSource) { async findTerms(textSource) {
this.textScanner.setTextSourceScanLength(textSource, this.options.scanning.length); this.setTextSourceScanLength(textSource, this.options.scanning.length);
const searchText = textSource.text(); const searchText = textSource.text();
if (searchText.length === 0) { return null; } if (searchText.length === 0) { return null; }
@ -202,7 +168,7 @@ class Frontend {
} }
async findKanji(textSource) { async findKanji(textSource) {
this.textScanner.setTextSourceScanLength(textSource, 1); this.setTextSourceScanLength(textSource, 1);
const searchText = textSource.text(); const searchText = textSource.text();
if (searchText.length === 0) { return null; } if (searchText.length === 0) { return null; }
@ -213,10 +179,10 @@ class Frontend {
return {definitions, type: 'kanji'}; return {definitions, type: 'kanji'};
} }
searchClear(changeFocus) { onSearchClear(changeFocus) {
this.popup.hide(changeFocus); this.popup.hide(changeFocus);
this.popup.clearAutoPlayTimer(); this.popup.clearAutoPlayTimer();
this.textScanner.searchClear(); super.onSearchClear(changeFocus);
} }
getOptionsContext() { getOptionsContext() {
@ -227,7 +193,7 @@ class Frontend {
Frontend.windowMessageHandlers = { Frontend.windowMessageHandlers = {
popupClose: (self) => { popupClose: (self) => {
self.searchClear(true); self.onSearchClear(true);
}, },
selectionCopy: () => { selectionCopy: () => {

View File

@ -31,10 +31,6 @@ class TextScanner {
this.enabled = false; this.enabled = false;
this.eventListeners = []; this.eventListeners = [];
this.subscribers = {
searchClear: [],
textSearch: []
};
this.primaryTouchIdentifier = null; this.primaryTouchIdentifier = null;
this.preventNextContextMenu = false; this.preventNextContextMenu = false;
@ -90,7 +86,7 @@ class TextScanner {
if (DOM.isMouseButtonDown(e, 'primary')) { if (DOM.isMouseButtonDown(e, 'primary')) {
this.scanTimerClear(); this.scanTimerClear();
this.onSearchClear(); this.onSearchClear(true);
} }
} }
@ -196,41 +192,14 @@ class TextScanner {
e.preventDefault(); // Disable scroll e.preventDefault(); // Disable scroll
} }
async onSearchClear() { async onSearchSource(_textSource, _cause) {
this.searchClear(); throw new Error('Override me');
await this.publish('searchClear', {});
}
async onTextSearch(textSource, cause) {
this.pendingLookup = true;
const results = await this.publish('textSearch', {textSource, cause});
if (results.some((r) => r)) {
this.textSourceCurrent = textSource;
if (this.options.scanning.selectText) {
textSource.select();
}
}
this.pendingLookup = false;
} }
onError(error) { onError(error) {
logError(error, false); logError(error, false);
} }
subscribe(eventName, subscriber) {
if (this.subscribers[eventName].includes(subscriber)) { return; }
this.subscribers[eventName].push(subscriber);
}
async publish(eventName, data) {
const results = [];
for (const subscriber of this.subscribers[eventName]) {
const result = await subscriber(data);
results.push(result);
}
return results;
}
async scanTimerWait() { async scanTimerWait() {
const delay = this.options.scanning.delay; const delay = this.options.scanning.delay;
const promise = promiseTimeout(delay, true); const promise = promiseTimeout(delay, true);
@ -262,35 +231,50 @@ class TextScanner {
this.clearEventListeners(); this.clearEventListeners();
this.enabled = false; this.enabled = false;
} }
this.onSearchClear(); this.onSearchClear(false);
} }
} }
hookEvents() { hookEvents() {
this.addEventListener('mousedown', this.onMouseDown.bind(this)); let eventListeners = this.getMouseEventListeners();
this.addEventListener('mousemove', this.onMouseMove.bind(this));
this.addEventListener('mouseover', this.onMouseOver.bind(this));
this.addEventListener('mouseout', this.onMouseOut.bind(this));
if (this.options.scanning.touchInputEnabled) { if (this.options.scanning.touchInputEnabled) {
this.addEventListener('click', this.onClick.bind(this)); eventListeners = eventListeners.concat(this.getTouchEventListeners());
this.addEventListener('auxclick', this.onAuxClick.bind(this)); }
this.addEventListener('touchstart', this.onTouchStart.bind(this));
this.addEventListener('touchend', this.onTouchEnd.bind(this)); for (const [node, type, listener, options] of eventListeners) {
this.addEventListener('touchcancel', this.onTouchCancel.bind(this)); this.addEventListener(node, type, listener, options);
this.addEventListener('touchmove', this.onTouchMove.bind(this), {passive: false});
this.addEventListener('contextmenu', this.onContextMenu.bind(this));
} }
} }
addEventListener(type, listener, options) { getMouseEventListeners() {
this.node.addEventListener(type, listener, options); return [
this.eventListeners.push([type, listener, options]); [this.node, 'mousedown', this.onMouseDown.bind(this)],
[this.node, 'mousemove', this.onMouseMove.bind(this)],
[this.node, 'mouseover', this.onMouseOver.bind(this)],
[this.node, 'mouseout', this.onMouseOut.bind(this)]
];
}
getTouchEventListeners() {
return [
[this.node, 'click', this.onClick.bind(this)],
[this.node, 'auxclick', this.onAuxClick.bind(this)],
[this.node, 'touchstart', this.onTouchStart.bind(this)],
[this.node, 'touchend', this.onTouchEnd.bind(this)],
[this.node, 'touchcancel', this.onTouchCancel.bind(this)],
[this.node, 'touchmove', this.onTouchMove.bind(this), {passive: false}],
[this.node, 'contextmenu', this.onContextMenu.bind(this)]
];
}
addEventListener(node, type, listener, options) {
node.addEventListener(type, listener, options);
this.eventListeners.push([node, type, listener, options]);
} }
clearEventListeners() { clearEventListeners() {
for (const [type, listener, options] of this.eventListeners) { for (const [node, type, listener, options] of this.eventListeners) {
this.node.removeEventListener(type, listener, options); node.removeEventListener(type, listener, options);
} }
this.eventListeners = []; this.eventListeners = [];
} }
@ -319,7 +303,15 @@ class TextScanner {
} }
try { try {
await this.onTextSearch(textSource, cause); this.pendingLookup = true;
const result = await this.onSearchSource(textSource, cause);
if (result !== null) {
this.textSourceCurrent = textSource;
if (this.options.scanning.selectText) {
textSource.select();
}
}
this.pendingLookup = false;
} finally { } finally {
if (textSource !== null) { if (textSource !== null) {
textSource.cleanup(); textSource.cleanup();
@ -347,7 +339,7 @@ class TextScanner {
} }
} }
searchClear() { onSearchClear(_) {
if (this.textSourceCurrent !== null) { if (this.textSourceCurrent !== null) {
if (this.options.scanning.selectText) { if (this.options.scanning.selectText) {
this.textSourceCurrent.deselect(); this.textSourceCurrent.deselect();