diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2021-02-14 18:18:02 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-14 18:18:02 -0500 | 
| commit | 48b59375eb50a3c11ab1cbee659164e6991827ac (patch) | |
| tree | 160bfe321492839cf3211b27285490e43a7f130d /ext/js | |
| parent | 9279ced68660610764931da681f22c8b71bf1b6e (diff) | |
Cleanup yomichan api (#1394)
* Move invokeMessageHandler to core.js
* Move getMessageResponseResult to backghend.js
* Replace getTemporaryListenerResult
Diffstat (limited to 'ext/js')
| -rw-r--r-- | ext/js/app/frontend.js | 51 | ||||
| -rw-r--r-- | ext/js/background/backend.js | 19 | ||||
| -rw-r--r-- | ext/js/comm/cross-frame-api.js | 2 | ||||
| -rw-r--r-- | ext/js/core.js | 36 | ||||
| -rw-r--r-- | ext/js/display/display.js | 2 | ||||
| -rw-r--r-- | ext/js/display/search-display-controller.js | 2 | ||||
| -rw-r--r-- | ext/js/yomichan.js | 75 | 
7 files changed, 92 insertions, 95 deletions
| diff --git a/ext/js/app/frontend.js b/ext/js/app/frontend.js index 02707f41..92366d6e 100644 --- a/ext/js/app/frontend.js +++ b/ext/js/app/frontend.js @@ -238,7 +238,7 @@ class Frontend {      _onRuntimeMessage({action, params}, sender, callback) {          const messageHandler = this._runtimeMessageHandlers.get(action);          if (typeof messageHandler === 'undefined') { return false; } -        return yomichan.invokeMessageHandler(messageHandler, params, callback, sender); +        return invokeMessageHandler(messageHandler, params, callback, sender);      }      _onZoomChanged({newZoomFactor}) { @@ -455,7 +455,7 @@ class Frontend {      async _getIframeProxyPopup() {          const targetFrameId = 0; // Root frameId          try { -            await this._waitForFrontendReady(targetFrameId); +            await this._waitForFrontendReady(targetFrameId, 10000);          } catch (e) {              // Root frame not available              return await this._getDefaultPopup(); @@ -613,21 +613,40 @@ class Frontend {          }      } -    async _waitForFrontendReady(frameId) { -        const promise = yomichan.getTemporaryListenerResult( -            chrome.runtime.onMessage, -            ({action, params}, {resolve}) => { -                if ( -                    action === 'frontendReady' && -                    params.frameId === frameId -                ) { -                    resolve(); +    async _waitForFrontendReady(frameId, timeout) { +        return new Promise((resolve, reject) => { +            let timeoutId = null; + +            const cleanup = () => { +                if (timeoutId !== null) { +                    clearTimeout(timeoutId); +                    timeoutId = null;                  } -            }, -            10000 -        ); -        yomichan.api.broadcastTab('requestFrontendReadyBroadcast', {frameId: this._frameId}); -        await promise; +                chrome.runtime.onMessage.removeListener(onMessage); +            }; +            const onMessage = (message, sender, sendResponse) => { +                try { +                    const {action, params} = message; +                    if (action === 'frontendReady' && params.frameId === frameId) { +                        cleanup(); +                        resolve(); +                        sendResponse(); +                    } +                } catch (e) { +                    // NOP +                } +            }; + +            if (timeout !== null) { +                timeoutId = setTimeout(() => { +                    timeoutId = null; +                    cleanup(); +                    reject(new Error(`Wait for frontend ready timed out after ${timeout}ms`)); +                }, timeout); +            } + +            chrome.runtime.onMessage.addListener(onMessage); +        });      }      _getPreventMiddleMouseValueForPageType(preventMiddleMouseOptions) { diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index 698724fc..d88c5853 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -307,7 +307,7 @@ class Backend {              }          } -        return yomichan.invokeMessageHandler(messageHandler, params, callback, sender); +        return invokeMessageHandler(messageHandler, params, callback, sender);      }      _onConnect(port) { @@ -1563,7 +1563,7 @@ class Backend {          return new Promise((resolve, reject) => {              const callback = (response) => {                  try { -                    resolve(yomichan.getMessageResponseResult(response)); +                    resolve(this._getMessageResponseResult(response));                  } catch (error) {                      reject(error);                  } @@ -1573,6 +1573,21 @@ class Backend {          });      } +    _getMessageResponseResult(response) { +        let error = chrome.runtime.lastError; +        if (error) { +            throw new Error(error.message); +        } +        if (!isObject(response)) { +            throw new Error('Tab did not respond'); +        } +        error = response.error; +        if (error) { +            throw deserializeError(error); +        } +        return response.result; +    } +      async _checkTabUrl(tabId, urlPredicate) {          let tab;          try { diff --git a/ext/js/comm/cross-frame-api.js b/ext/js/comm/cross-frame-api.js index 7dbfb411..461ad45d 100644 --- a/ext/js/comm/cross-frame-api.js +++ b/ext/js/comm/cross-frame-api.js @@ -191,7 +191,7 @@ class CrossFrameAPIPort extends EventDispatcher {          }          const callback = (data) => this._sendResult(id, data); -        return yomichan.invokeMessageHandler(messageHandler, params, callback); +        return invokeMessageHandler(messageHandler, params, callback);      }      _sendResponse(data) { diff --git a/ext/js/core.js b/ext/js/core.js index 4384d9f0..9b95c407 100644 --- a/ext/js/core.js +++ b/ext/js/core.js @@ -342,6 +342,42 @@ function promiseAnimationFrame(timeout=null) {  }  /** + * Invokes a standard message handler. This function is used to react and respond + * to communication messages within the extension. + * @param handler A handler function which is passed `params` and `...extraArgs` as arguments. + * @param async Whether or not the handler is async or not. Values include `false`, `true`, or `'dynamic'`. + *   When the value is `'dynamic'`, the handler should return an object of the format `{async: boolean, result: any}`. + * @param params Information which was passed with the original message. + * @param callback A callback function which is invoked after the handler has completed. The value passed + *   to the function is in the format: + *   * `{result: any}` if the handler invoked successfully. + *   * `{error: object}` if the handler thew an error. The error is serialized. + * @param extraArgs Additional arguments which are passed to the `handler` function. + * @returns `true` if the function is invoked asynchronously, `false` otherwise. + */ +function invokeMessageHandler({handler, async}, params, callback, ...extraArgs) { +    try { +        let promiseOrResult = handler(params, ...extraArgs); +        if (async === 'dynamic') { +            ({async, result: promiseOrResult} = promiseOrResult); +        } +        if (async) { +            promiseOrResult.then( +                (result) => { callback({result}); }, +                (error) => { callback({error: serializeError(error)}); } +            ); +            return true; +        } else { +            callback({result: promiseOrResult}); +            return false; +        } +    } catch (error) { +        callback({error: serializeError(error)}); +        return false; +    } +} + +/**   * Base class controls basic event dispatching.   */  class EventDispatcher { diff --git a/ext/js/display/display.js b/ext/js/display/display.js index b7477bb8..a7c45f19 100644 --- a/ext/js/display/display.js +++ b/ext/js/display/display.js @@ -463,7 +463,7 @@ class Display extends EventDispatcher {          if (typeof messageHandler === 'undefined') { return; }          const callback = () => {}; // NOP -        yomichan.invokeMessageHandler(messageHandler, params, callback); +        invokeMessageHandler(messageHandler, params, callback);      }      _onMessageSetOptionsContext({optionsContext}) { diff --git a/ext/js/display/search-display-controller.js b/ext/js/display/search-display-controller.js index 3b48af44..d1a4593f 100644 --- a/ext/js/display/search-display-controller.js +++ b/ext/js/display/search-display-controller.js @@ -104,7 +104,7 @@ class SearchDisplayController {      _onMessage({action, params}, sender, callback) {          const messageHandler = this._messageHandlers.get(action);          if (typeof messageHandler === 'undefined') { return false; } -        return yomichan.invokeMessageHandler(messageHandler, params, callback, sender); +        return invokeMessageHandler(messageHandler, params, callback, sender);      }      _onKeyDown(e) { diff --git a/ext/js/yomichan.js b/ext/js/yomichan.js index 107694e9..1eae2d4d 100644 --- a/ext/js/yomichan.js +++ b/ext/js/yomichan.js @@ -120,42 +120,6 @@ class Yomichan extends EventDispatcher {          }      } -    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 = setTimeout(() => { -                        timeoutId = null; -                        eventHandler.removeListener(runtimeMessageCallback); -                        reject(new Error(`Listener timed out in ${timeout} ms`)); -                    }, timeout); -                } - -                const cleanupResolve = (value) => { -                    if (timeoutId !== null) { -                        clearTimeout(timeoutId); -                        timeoutId = null; -                    } -                    eventHandler.removeListener(runtimeMessageCallback); -                    sendResponse(); -                    resolve(value); -                }; - -                userCallback({action, params}, {resolve: cleanupResolve, sender}); -            }; - -            eventHandler.addListener(runtimeMessageCallback); -        }); -    } -      sendMessage(...args) {          try {              return chrome.runtime.sendMessage(...args); @@ -174,43 +138,6 @@ class Yomichan extends EventDispatcher {          }      } -    getMessageResponseResult(response) { -        let error = chrome.runtime.lastError; -        if (error) { -            throw new Error(error.message); -        } -        if (!isObject(response)) { -            throw new Error('Tab did not respond'); -        } -        error = response.error; -        if (error) { -            throw deserializeError(error); -        } -        return response.result; -    } - -    invokeMessageHandler({handler, async}, params, callback, ...extraArgs) { -        try { -            let promiseOrResult = handler(params, ...extraArgs); -            if (async === 'dynamic') { -                ({async, result: promiseOrResult} = promiseOrResult); -            } -            if (async) { -                promiseOrResult.then( -                    (result) => { callback({result}); }, -                    (error) => { callback({error: serializeError(error)}); } -                ); -                return true; -            } else { -                callback({result: promiseOrResult}); -                return false; -            } -        } catch (error) { -            callback({error: serializeError(error)}); -            return false; -        } -    } -      triggerExtensionUnloaded() {          this._isExtensionUnloaded = true;          if (this._isTriggeringExtensionUnloaded) { return; } @@ -235,7 +162,7 @@ class Yomichan extends EventDispatcher {      _onMessage({action, params}, sender, callback) {          const messageHandler = this._messageHandlers.get(action);          if (typeof messageHandler === 'undefined') { return false; } -        return this.invokeMessageHandler(messageHandler, params, callback, sender); +        return invokeMessageHandler(messageHandler, params, callback, sender);      }      _onMessageIsReady() { |