diff options
Diffstat (limited to 'ext/mixed/js')
-rw-r--r-- | ext/mixed/js/core.js | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index fd762e97..db7fc69b 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -278,11 +278,16 @@ const yomichan = (() => { constructor() { super(); - this._isBackendPreparedResolve = null; - this._isBackendPreparedPromise = new Promise((resolve) => (this._isBackendPreparedResolve = resolve)); + this._isBackendPreparedPromise = this.getTemporaryListenerResult( + chrome.runtime.onMessage, + ({action}, {resolve}) => { + if (action === 'backendPrepared') { + 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)] @@ -312,6 +317,42 @@ const yomichan = (() => { this.trigger('orphaned', {error}); } + getTemporaryListenerResult(eventHandler, userCallback, timeout=null) { + if (!( + typeof eventHandler.addListener === 'function' && + typeof eventHandler.removeListener === 'function' + )) { + throw new Error('Event handler type not supported'); + } + + return new Promise((resolve, reject) => { + const runtimeMessageCallback = ({action, params}, sender, sendResponse) => { + let timeoutId = null; + if (timeout !== null) { + timeoutId = window.setTimeout(() => { + timeoutId = null; + eventHandler.removeListener(runtimeMessageCallback); + reject(new Error(`Listener timed out in ${timeout} ms`)); + }, timeout); + } + + const cleanupResolve = (value) => { + if (timeoutId !== null) { + window.clearTimeout(timeoutId); + timeoutId = null; + } + eventHandler.removeListener(runtimeMessageCallback); + sendResponse(); + resolve(value); + }; + + userCallback({action, params}, {resolve: cleanupResolve, sender}); + }; + + eventHandler.addListener(runtimeMessageCallback); + }); + } + // Private _onMessage({action, params}, sender, callback) { @@ -323,10 +364,6 @@ const yomichan = (() => { return false; } - _onBackendPrepared() { - this._isBackendPreparedResolve(); - } - _onMessageGetUrl() { return {url: window.location.href}; } |