diff --git a/ext/bg/js/search.js b/ext/bg/js/search-display-controller.js
similarity index 84%
rename from ext/bg/js/search.js
rename to ext/bg/js/search-display-controller.js
index a786b0bf..b8ad2d52 100644
--- a/ext/bg/js/search.js
+++ b/ext/bg/js/search-display-controller.js
@@ -17,22 +17,23 @@
/* global
* ClipboardMonitor
- * Display
* api
* wanakana
*/
-class DisplaySearch extends Display {
- constructor(tabId, frameId, japaneseUtil, documentFocusController, hotkeyHandler) {
- super(tabId, frameId, 'search', japaneseUtil, documentFocusController, hotkeyHandler);
+class SearchDisplayController {
+ constructor(tabId, frameId, display, japaneseUtil) {
+ this._tabId = tabId;
+ this._frameId = frameId;
+ this._display = display;
this._searchButton = document.querySelector('#search-button');
this._queryInput = document.querySelector('#search-textbox');
this._introElement = document.querySelector('#intro');
this._clipboardMonitorEnableCheckbox = document.querySelector('#clipboard-monitor-enable');
this._wanakanaEnableCheckbox = document.querySelector('#wanakana-enable');
this._queryInputEvents = new EventListenerCollection();
+ this._queryInputEventsSetup = false;
this._wanakanaEnabled = false;
- this._isPrepared = false;
this._introVisible = true;
this._introAnimationTimer = null;
this._clipboardMonitorEnabled = false;
@@ -42,57 +43,38 @@ class DisplaySearch extends Display {
getText: async () => (await api.clipboardGet())
}
});
- this.autoPlayAudioDelay = 0;
-
- this.hotkeyHandler.registerActions([
- ['focusSearchBox', this._onActionFocusSearchBox.bind(this)]
- ]);
}
async prepare() {
- await super.prepare();
- await this.updateOptions();
+ await this._display.updateOptions();
+
yomichan.on('optionsUpdated', this._onOptionsUpdated.bind(this));
- this.on('optionsUpdated', this._onDisplayOptionsUpdated.bind(this));
- this.on('contentUpdating', this._onContentUpdating.bind(this));
- this.on('modeChange', this._onModeChange.bind(this));
+ this._display.on('optionsUpdated', this._onDisplayOptionsUpdated.bind(this));
+ this._display.on('contentUpdating', this._onContentUpdating.bind(this));
+ this._display.on('modeChange', this._onModeChange.bind(this));
- this.registerMessageHandlers([
+ this._display.hotkeyHandler.registerActions([
+ ['focusSearchBox', this._onActionFocusSearchBox.bind(this)]
+ ]);
+ this._display.registerMessageHandlers([
['updateSearchQuery', {async: false, handler: this._onExternalSearchUpdate.bind(this)}]
]);
- this.queryParserVisible = true;
- this.setHistorySettings({useBrowserHistory: true});
-
- const enableWanakana = !!this.getOptions().general.enableWanakana;
- this._wanakanaEnableCheckbox.checked = enableWanakana;
- this._setWanakanaEnabled(enableWanakana);
+ this._display.autoPlayAudioDelay = 0;
+ this._display.queryParserVisible = true;
+ this._display.setHistorySettings({useBrowserHistory: true});
+ this._display.setQueryPostProcessor(this._postProcessQuery.bind(this));
this._searchButton.addEventListener('click', this._onSearch.bind(this), false);
this._wanakanaEnableCheckbox.addEventListener('change', this._onWanakanaEnableChange.bind(this));
window.addEventListener('copy', this._onCopy.bind(this));
this._clipboardMonitor.on('change', this._onExternalSearchUpdate.bind(this));
this._clipboardMonitorEnableCheckbox.addEventListener('change', this._onClipboardMonitorEnableChange.bind(this));
- this.hotkeyHandler.on('keydownNonHotkey', this._onKeyDown.bind(this));
+ this._display.hotkeyHandler.on('keydownNonHotkey', this._onKeyDown.bind(this));
this._onModeChange();
- this._onDisplayOptionsUpdated({options: this.getOptions()});
-
- this.initializeState();
-
- this._isPrepared = true;
- }
-
- postProcessQuery(query) {
- if (this._wanakanaEnabled) {
- try {
- query = this._japaneseUtil.convertToKana(query);
- } catch (e) {
- // NOP
- }
- }
- return query;
+ this._onDisplayOptionsUpdated({options: this._display.getOptions()});
}
// Actions
@@ -118,16 +100,20 @@ class DisplaySearch extends Display {
}
async _onOptionsUpdated() {
- await this.updateOptions();
+ await this._display.updateOptions();
const query = this._queryInput.value;
if (query) {
- this.searchLast();
+ this._display.searchLast();
}
}
_onDisplayOptionsUpdated({options}) {
this._clipboardMonitorEnabled = options.clipboard.enableSearchPageMonitor;
this._updateClipboardMonitorEnabled();
+
+ const enableWanakana = !!this._display.getOptions().general.enableWanakana;
+ this._wanakanaEnableCheckbox.checked = enableWanakana;
+ this._setWanakanaEnabled(enableWanakana);
}
_onContentUpdating({type, content, source}) {
@@ -138,7 +124,7 @@ class DisplaySearch extends Display {
case 'kanji':
animate = !!content.animate;
valid = (typeof source === 'string' && source.length > 0);
- this.blurElement(this._queryInput);
+ this._display.blurElement(this._queryInput);
break;
case 'clear':
valid = false;
@@ -167,7 +153,7 @@ class DisplaySearch extends Display {
// Search
e.preventDefault();
e.stopImmediatePropagation();
- this.blurElement(e.currentTarget);
+ this._display.blurElement(e.currentTarget);
this._search(true, true, true);
}
@@ -182,7 +168,7 @@ class DisplaySearch extends Display {
}
_onExternalSearchUpdate({text, animate=true}) {
- const {clipboard: {autoSearchContent, maximumSearchLength}} = this.getOptions();
+ const {clipboard: {autoSearchContent, maximumSearchLength}} = this._display.getOptions();
if (text.length > maximumSearchLength) {
text = text.substring(0, maximumSearchLength);
}
@@ -199,7 +185,7 @@ class DisplaySearch extends Display {
path: 'general.enableWanakana',
value,
scope: 'profile',
- optionsContext: this.getOptionsContext()
+ optionsContext: this._display.getOptionsContext()
}], 'search');
}
@@ -209,28 +195,28 @@ class DisplaySearch extends Display {
}
_onModeChange() {
- let mode = this.mode;
+ let mode = this._display.mode;
if (mode === null) { mode = ''; }
document.documentElement.dataset.searchMode = mode;
this._updateClipboardMonitorEnabled();
}
_setWanakanaEnabled(enabled) {
+ if (this._queryInputEventsSetup && this._wanakanaEnabled === enabled) { return; }
+
const input = this._queryInput;
this._queryInputEvents.removeAllEventListeners();
-
this._queryInputEvents.addEventListener(input, 'keydown', this._onSearchKeydown.bind(this), false);
- if (this._wanakanaEnabled !== enabled) {
- this._wanakanaEnabled = enabled;
- if (enabled) {
- wanakana.bind(input);
- } else {
- wanakana.unbind(input);
- }
+ this._wanakanaEnabled = enabled;
+ if (enabled) {
+ wanakana.bind(input);
+ } else {
+ wanakana.unbind(input);
}
this._queryInputEvents.addEventListener(input, 'input', this._onSearchInput.bind(this), false);
+ this._queryInputEventsSetup = true;
}
_setIntroVisible(visible, animate) {
@@ -306,12 +292,12 @@ class DisplaySearch extends Display {
path: 'clipboard.enableSearchPageMonitor',
value,
scope: 'profile',
- optionsContext: this.getOptionsContext()
+ optionsContext: this._display.getOptionsContext()
}], 'search');
}
_updateClipboardMonitorEnabled() {
- const mode = this.mode;
+ const mode = this._display.mode;
const enabled = this._clipboardMonitorEnabled;
this._clipboardMonitorEnableCheckbox.checked = enabled;
if (enabled && mode !== 'popup') {
@@ -335,7 +321,7 @@ class DisplaySearch extends Display {
_search(animate, history, lookup) {
const query = this._queryInput.value;
- const depth = this.depth;
+ const depth = this._display.depth;
const url = window.location.href;
const documentTitle = document.title;
const details = {
@@ -361,7 +347,7 @@ class DisplaySearch extends Display {
}
};
if (!lookup) { details.params.lookup = 'false'; }
- this.setContent(details);
+ this._display.setContent(details);
}
_updateSearchHeight(shrink) {
@@ -375,4 +361,15 @@ class DisplaySearch extends Display {
node.style.height = `${scrollHeight}px`;
}
}
+
+ _postProcessQuery(query) {
+ if (this._wanakanaEnabled) {
+ try {
+ query = this._japaneseUtil.convertToKana(query);
+ } catch (e) {
+ // NOP
+ }
+ }
+ return query;
+ }
}
diff --git a/ext/bg/js/search-main.js b/ext/bg/js/search-main.js
index f6abdfc8..c7ec595a 100644
--- a/ext/bg/js/search-main.js
+++ b/ext/bg/js/search-main.js
@@ -16,10 +16,11 @@
*/
/* global
- * DisplaySearch
+ * Display
* DocumentFocusController
* HotkeyHandler
* JapaneseUtil
+ * SearchDisplayController
* api
* wanakana
*/
@@ -39,10 +40,16 @@
const hotkeyHandler = new HotkeyHandler();
hotkeyHandler.prepare();
- const displaySearch = new DisplaySearch(tabId, frameId, japaneseUtil, documentFocusController, hotkeyHandler);
- await displaySearch.prepare();
+ const display = new Display(tabId, frameId, 'search', japaneseUtil, documentFocusController, hotkeyHandler);
+ await display.prepare();
+
+ const searchDisplayController = new SearchDisplayController(tabId, frameId, display, japaneseUtil);
+ await searchDisplayController.prepare();
+
+ display.initializeState();
document.documentElement.dataset.loaded = 'true';
+
yomichan.ready();
} catch (e) {
yomichan.logError(e);
diff --git a/ext/bg/search.html b/ext/bg/search.html
index 40c1ef45..e5690c8d 100644
--- a/ext/bg/search.html
+++ b/ext/bg/search.html
@@ -109,7 +109,7 @@
-
+
diff --git a/ext/fg/js/float-main.js b/ext/fg/js/float-main.js
index efc012d7..7c048b62 100644
--- a/ext/fg/js/float-main.js
+++ b/ext/fg/js/float-main.js
@@ -41,10 +41,14 @@
const display = new Display(tabId, frameId, 'popup', japaneseUtil, documentFocusController, hotkeyHandler);
await display.prepare();
+
const displayProfileSelection = new DisplayProfileSelection(display);
displayProfileSelection.prepare();
+
display.initializeState();
+ document.documentElement.dataset.loaded = 'true';
+
yomichan.ready();
} catch (e) {
yomichan.logError(e);
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js
index c8b7b14b..2acc0d3f 100644
--- a/ext/mixed/js/display.js
+++ b/ext/mixed/js/display.js
@@ -117,6 +117,7 @@ class Display extends EventDispatcher {
this._displayAudio = new DisplayAudio(this);
this._ankiNoteNotification = null;
this._ankiNoteNotificationEventListeners = null;
+ this._queryPostProcessor = null;
this._hotkeyHandler.registerActions([
['close', () => { this._onHotkeyClose(); }],
@@ -405,8 +406,8 @@ class Display extends EventDispatcher {
return data.data;
}
- postProcessQuery(query) {
- return query;
+ setQueryPostProcessor(func) {
+ this._queryPostProcessor = func;
}
close() {
@@ -573,10 +574,10 @@ class Display extends EventDispatcher {
this._query = query;
clear = false;
const isTerms = (type === 'terms');
- query = this.postProcessQuery(query);
+ query = this._postProcessQuery(query);
this._rawQuery = query;
let queryFull = urlSearchParams.get('full');
- queryFull = (queryFull !== null ? this.postProcessQuery(queryFull) : query);
+ queryFull = (queryFull !== null ? this._postProcessQuery(queryFull) : query);
const wildcardsEnabled = (urlSearchParams.get('wildcards') !== 'off');
const lookup = (urlSearchParams.get('lookup') !== 'false');
await this._setContentTermsOrKanji(token, isTerms, query, queryFull, lookup, wildcardsEnabled, eventArgs);
@@ -1930,4 +1931,9 @@ class Display extends EventDispatcher {
}
return false;
}
+
+ _postProcessQuery(query) {
+ const queryPostProcessor = this._queryPostProcessor;
+ return typeof queryPostProcessor === 'function' ? queryPostProcessor(query) : query;
+ }
}