diff options
| -rw-r--r-- | ext/bg/js/backend.js | 55 | ||||
| -rw-r--r-- | ext/fg/js/float-main.js | 1 | ||||
| -rw-r--r-- | ext/mixed/js/display.js | 1 | ||||
| -rw-r--r-- | ext/mixed/js/yomichan.js | 7 | 
4 files changed, 63 insertions, 1 deletions
| diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index f17e8897..301fe135 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -1383,4 +1383,59 @@ class Backend {              // Edge throws exception for no reason here.          }      } + +    _waitUntilTabFrameIsReady(tabId, frameId, timeout=null) { +        return new Promise((resolve, reject) => { +            let timer = null; +            let onMessage = (message, sender) => { +                if ( +                    !sender.tab || +                    sender.tab.id !== tabId || +                    sender.frameId !== frameId || +                    !isObject(message) || +                    message.action !== 'yomichanCoreReady' +                ) { +                    return; +                } + +                cleanup(); +                resolve(); +            }; +            const cleanup = () => { +                if (timer !== null) { +                    clearTimeout(timer); +                    timer = null; +                } +                if (onMessage !== null) { +                    chrome.runtime.onMessage.removeListener(onMessage); +                    onMessage = null; +                } +            }; + +            chrome.runtime.onMessage.addListener(onMessage); + +            chrome.tabs.sendMessage(tabId, {action: 'isReady'}, {frameId}, (response) => { +                const error = chrome.runtime.lastError; +                if (error) { return; } + +                try { +                    const value = yomichan.getMessageResponseResult(response); +                    if (!value) { return; } + +                    cleanup(); +                    resolve(); +                } catch (e) { +                    // NOP +                } +            }); + +            if (timeout !== null) { +                timer = setTimeout(() => { +                    timer = null; +                    cleanup(); +                    reject(new Error('Timeout')); +                }, timeout); +            } +        }); +    }  } diff --git a/ext/fg/js/float-main.js b/ext/fg/js/float-main.js index 3bedfe58..d31d5050 100644 --- a/ext/fg/js/float-main.js +++ b/ext/fg/js/float-main.js @@ -23,6 +23,7 @@  (async () => {      try {          api.forwardLogsToBackend(); +        await yomichan.ready();          const display = new DisplayFloat();          await display.prepare(); diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index bf3e3eae..82e77353 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -95,7 +95,6 @@ class Display {      async prepare() {          this._setInteractive(true); -        await yomichan.ready();          await this._displayGenerator.prepare();          yomichan.on('extensionUnloaded', this._onExtensionUnloaded.bind(this));      } diff --git a/ext/mixed/js/yomichan.js b/ext/mixed/js/yomichan.js index 33870658..3ae905c3 100644 --- a/ext/mixed/js/yomichan.js +++ b/ext/mixed/js/yomichan.js @@ -48,12 +48,14 @@ const yomichan = (() => {              }              this._isExtensionUnloaded = false; +            this._isReady = false;              const {promise, resolve} = deferPromise();              this._isBackendPreparedPromise = promise;              this._isBackendPreparedPromiseResolve = resolve;              this._messageHandlers = new Map([ +                ['isReady',         {async: false, handler: this._onMessageIsReady.bind(this)}],                  ['backendPrepared', {async: false, handler: this._onMessageBackendPrepared.bind(this)}],                  ['getUrl',          {async: false, handler: this._onMessageGetUrl.bind(this)}],                  ['optionsUpdated',  {async: false, handler: this._onMessageOptionsUpdated.bind(this)}], @@ -72,6 +74,7 @@ const yomichan = (() => {          }          ready() { +            this._isReady = true;              this.sendMessage({action: 'yomichanCoreReady'});              return this._isBackendPreparedPromise;          } @@ -268,6 +271,10 @@ const yomichan = (() => {              return this.invokeMessageHandler(messageHandler, params, callback, sender);          } +        _onMessageIsReady() { +            return this._isReady; +        } +          _onMessageBackendPrepared() {              if (this._isBackendPreparedPromiseResolve === null) { return; }              this._isBackendPreparedPromiseResolve(); |