diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index e849bc69..81578462 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -48,7 +48,7 @@ class Backend { this.messageToken = yomichan.generateId(16); this._messageHandlers = new Map([ - ['isBackendReady', this._onApiIsBackendReady.bind(this)], + ['yomichanOnline', this._onApiYomichanOnline.bind(this)], ['optionsSchemaGet', this._onApiOptionsSchemaGet.bind(this)], ['optionsGet', this._onApiOptionsGet.bind(this)], ['optionsGetFull', this._onApiOptionsGetFull.bind(this)], @@ -114,17 +114,22 @@ class Backend { } this.clipboardMonitor.onClipboardText = this._onClipboardText.bind(this); + + this._sendMessageAllTabs('backendPrepared'); + } + + _sendMessageAllTabs(action, params={}) { + const callback = () => this.checkLastError(chrome.runtime.lastError); + chrome.tabs.query({}, (tabs) => { + for (const tab of tabs) { + chrome.tabs.sendMessage(tab.id, {action, params}, callback); + } + }); } onOptionsUpdated(source) { this.applyOptions(); - - const callback = () => this.checkLastError(chrome.runtime.lastError); - chrome.tabs.query({}, (tabs) => { - for (const tab of tabs) { - chrome.tabs.sendMessage(tab.id, {action: 'optionsUpdated', params: {source}}, callback); - } - }); + this._sendMessageAllTabs('optionsUpdated', {source}); } onMessage({action, params}, sender, callback) { @@ -268,8 +273,11 @@ class Backend { // Message handlers - async _onApiIsBackendReady() { - return true; + async _onApiYomichanOnline(_params, sender) { + const tabId = sender.tab.id; + return new Promise((resolve) => { + chrome.tabs.sendMessage(tabId, {action: 'backendPrepared'}, resolve); + }); } async _onApiOptionsSchemaGet() { diff --git a/ext/bg/js/search-frontend.js b/ext/bg/js/search-frontend.js index 509c4009..453a0b79 100644 --- a/ext/bg/js/search-frontend.js +++ b/ext/bg/js/search-frontend.js @@ -19,6 +19,8 @@ /*global apiOptionsGet*/ async function searchFrontendSetup() { + await yomichan.prepare(); + const optionsContext = { depth: 0, url: window.location.href diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 0a7a5fe1..f3cba7ae 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -68,9 +68,8 @@ class DisplaySearch extends Display { async prepare() { try { - const superPromise = super.prepare(); - const queryParserPromise = this.queryParser.prepare(); - await Promise.all([superPromise, queryParserPromise]); + await super.prepare(); + await this.queryParser.prepare(); const {queryParams: {query='', mode=''}} = parseUrl(window.location.href); diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 929ab56a..203366c3 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -52,6 +52,7 @@ class Frontend extends TextScanner { async prepare() { try { + await yomichan.prepare(); await this.updateOptions(); const {zoomFactor} = await apiGetZoom(); this._pageZoomFactor = zoomFactor; diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index fa61a1e2..26f4389d 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -122,30 +122,6 @@ function apiGetDefaultAnkiFieldTemplates() { } function _apiInvoke(action, params={}) { - if (!_isBackendReady) { - if (_isBackendReadyPromise === null) { - _isBackendReadyPromise = new Promise((resolve) => (_isBackendReadyResolve = resolve)); - const checkBackendReady = async () => { - try { - if (await _apiInvokeRaw('isBackendReady')) { - _isBackendReady = true; - _isBackendReadyResolve(); - } - } catch (e) { - // NOP - } - setTimeout(checkBackendReady, 100); // poll Backend until it responds - }; - checkBackendReady(); - } - return _isBackendReadyPromise.then( - () => _apiInvokeRaw(action, params) - ); - } - return _apiInvokeRaw(action, params); -} - -function _apiInvokeRaw(action, params={}) { const data = {action, params}; return new Promise((resolve, reject) => { try { @@ -172,7 +148,3 @@ function _apiInvokeRaw(action, params={}) { function _apiCheckLastError() { // NOP } - -let _isBackendReady = false; -let _isBackendReadyResolve = null; -let _isBackendReadyPromise = null; diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index 83813796..a3cb2459 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -269,17 +269,26 @@ const yomichan = (() => { constructor() { super(); + this._isBackendPreparedResolve = null; + this._isBackendPreparedPromise = new Promise((resolve) => (this._isBackendPreparedResolve = resolve)); + this._messageHandlers = new Map([ + ['backendPrepared', this._onBackendPrepared.bind(this)], ['getUrl', this._onMessageGetUrl.bind(this)], ['optionsUpdated', this._onMessageOptionsUpdated.bind(this)], ['zoomChanged', this._onMessageZoomChanged.bind(this)] ]); chrome.runtime.onMessage.addListener(this._onMessage.bind(this)); + chrome.runtime.sendMessage({action: 'yomichanOnline'}); } // Public + prepare() { + return this._isBackendPreparedPromise; + } + generateId(length) { const array = new Uint8Array(length); window.crypto.getRandomValues(array); @@ -305,6 +314,10 @@ const yomichan = (() => { return false; } + _onBackendPrepared() { + this._isBackendPreparedResolve(); + } + _onMessageGetUrl() { return {url: window.location.href}; } diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index e3e5e7df..6a762a65 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -153,6 +153,7 @@ class Display { } async prepare(options=null) { + await yomichan.prepare(); const displayGeneratorPromise = this.displayGenerator.prepare(); const updateOptionsPromise = this.updateOptions(options); await Promise.all([displayGeneratorPromise, updateOptionsPromise]);