diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2024-02-18 09:27:16 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-18 14:27:16 +0000 |
commit | 65fa65fc7765bc9a6557d3ce6f8bdcef5b5e0cf7 (patch) | |
tree | 4e91bc8ec3e0dadbabe3e3d4c6c92d2b6f9fd2a5 /ext/js/application.js | |
parent | cfc65c31313731dfa0d36c2eceaca35e9d50992f (diff) |
Application main updates (#708)
* Move waitForBackendReady
* Add option to wait for DOM before running main
* Move script load to be earlier
Diffstat (limited to 'ext/js/application.js')
-rw-r--r-- | ext/js/application.js | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/ext/js/application.js b/ext/js/application.js index 350a4210..ec5c7e02 100644 --- a/ext/js/application.js +++ b/ext/js/application.js @@ -52,6 +52,41 @@ if (checkChromeNotAvailable()) { } /** + * @param {WebExtension} webExtension + */ +async function waitForBackendReady(webExtension) { + const {promise, resolve} = /** @type {import('core').DeferredPromiseDetails<void>} */ (deferPromise()); + /** @type {import('application').ApiMap} */ + const apiMap = createApiMap([['applicationBackendReady', () => { resolve(); }]]); + /** @type {import('extension').ChromeRuntimeOnMessageCallback<import('application').ApiMessageAny>} */ + const onMessage = ({action, params}, _sender, callback) => invokeApiMapHandler(apiMap, action, params, [], callback); + chrome.runtime.onMessage.addListener(onMessage); + try { + await webExtension.sendMessagePromise({action: 'requestBackendReadySignal'}); + await promise; + } finally { + chrome.runtime.onMessage.removeListener(onMessage); + } +} + +/** + * @returns {Promise<void>} + */ +function waitForDomContentLoaded() { + return new Promise((resolve) => { + if (document.readyState !== 'loading') { + resolve(); + return; + } + const onDomContentLoaded = () => { + document.removeEventListener('DOMContentLoaded', onDomContentLoaded); + resolve(); + }; + document.addEventListener('DOMContentLoaded', onDomContentLoaded); + }); +} + +/** * The Yomitan class is a core component through which various APIs are handled and invoked. * @augments EventDispatcher<import('application').Events> */ @@ -151,18 +186,20 @@ export class Application extends EventDispatcher { } /** + * @param {boolean} waitForDom * @param {(application: Application) => (Promise<void>)} mainFunction */ - static async main(mainFunction) { + static async main(waitForDom, mainFunction) { const webExtension = new WebExtension(); log.configure(webExtension.extensionName); const api = new API(webExtension); - await this.waitForBackendReady(webExtension); + await waitForBackendReady(webExtension); const {tabId, frameId} = await api.frameInformationGet(); const crossFrameApi = new CrossFrameAPI(api, tabId, frameId); crossFrameApi.prepare(); const application = new Application(api, crossFrameApi); application.prepare(); + if (waitForDom) { await waitForDomContentLoaded(); } try { await mainFunction(application); } catch (error) { @@ -172,24 +209,6 @@ export class Application extends EventDispatcher { } } - /** - * @param {WebExtension} webExtension - */ - static async waitForBackendReady(webExtension) { - const {promise, resolve} = /** @type {import('core').DeferredPromiseDetails<void>} */ (deferPromise()); - /** @type {import('application').ApiMap} */ - const apiMap = createApiMap([['applicationBackendReady', () => { resolve(); }]]); - /** @type {import('extension').ChromeRuntimeOnMessageCallback<import('application').ApiMessageAny>} */ - const onMessage = ({action, params}, _sender, callback) => invokeApiMapHandler(apiMap, action, params, [], callback); - chrome.runtime.onMessage.addListener(onMessage); - try { - await webExtension.sendMessagePromise({action: 'requestBackendReadySignal'}); - await promise; - } finally { - chrome.runtime.onMessage.removeListener(onMessage); - } - } - // Private /** |