Content script ready checks (#670)

* Move ready checkout of Display

* Add function to wait until if a tab's content script is ready
This commit is contained in:
toasted-nutbread 2020-07-18 14:18:10 -04:00 committed by GitHub
parent ffc0b6588e
commit c6c0126394
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 1 deletions

View File

@ -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);
}
});
}
}

View File

@ -23,6 +23,7 @@
(async () => {
try {
api.forwardLogsToBackend();
await yomichan.ready();
const display = new DisplayFloat();
await display.prepare();

View File

@ -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));
}

View File

@ -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();