diff options
Diffstat (limited to 'ext/mixed')
| -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};          } |