summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/bg/js/backend.js55
-rw-r--r--ext/fg/js/float-main.js1
-rw-r--r--ext/mixed/js/display.js1
-rw-r--r--ext/mixed/js/yomichan.js7
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();