diff options
-rw-r--r-- | ext/js/app/frontend.js | 18 | ||||
-rw-r--r-- | ext/js/app/popup-factory.js | 30 | ||||
-rw-r--r-- | ext/js/background/backend.js | 100 | ||||
-rw-r--r-- | ext/js/background/offscreen.js | 32 | ||||
-rw-r--r-- | ext/js/comm/cross-frame-api.js | 2 | ||||
-rw-r--r-- | ext/js/comm/frame-ancestry-handler.js | 4 | ||||
-rw-r--r-- | ext/js/comm/frame-offset-forwarder.js | 2 | ||||
-rw-r--r-- | ext/js/core.js | 11 | ||||
-rw-r--r-- | ext/js/display/display-audio.js | 2 | ||||
-rw-r--r-- | ext/js/display/display.js | 33 | ||||
-rw-r--r-- | ext/js/display/search-display-controller.js | 8 | ||||
-rw-r--r-- | ext/js/input/hotkey-handler.js | 2 | ||||
-rw-r--r-- | ext/js/templates/sandbox/template-renderer-frame-api.js | 14 | ||||
-rw-r--r-- | ext/js/yomitan.js | 14 | ||||
-rw-r--r-- | types/ext/backend.d.ts | 8 | ||||
-rw-r--r-- | types/ext/core.d.ts | 26 | ||||
-rw-r--r-- | types/ext/offscreen.d.ts | 6 |
17 files changed, 138 insertions, 174 deletions
diff --git a/ext/js/app/frontend.js b/ext/js/app/frontend.js index a1bbb217..8c11775a 100644 --- a/ext/js/app/frontend.js +++ b/ext/js/app/frontend.js @@ -108,10 +108,10 @@ export class Frontend { /* eslint-disable no-multi-spaces */ /** @type {import('core').MessageHandlerMap} */ - this._runtimeMessageHandlers = new Map(/** @type {import('core').MessageHandlerArray} */ ([ - ['Frontend.requestReadyBroadcast', {async: false, handler: this._onMessageRequestFrontendReadyBroadcast.bind(this)}], - ['Frontend.setAllVisibleOverride', {async: true, handler: this._onApiSetAllVisibleOverride.bind(this)}], - ['Frontend.clearAllVisibleOverride', {async: true, handler: this._onApiClearAllVisibleOverride.bind(this)}] + this._runtimeMessageHandlers = new Map(/** @type {import('core').MessageHandlerMapInit} */ ([ + ['Frontend.requestReadyBroadcast', this._onMessageRequestFrontendReadyBroadcast.bind(this)], + ['Frontend.setAllVisibleOverride', this._onApiSetAllVisibleOverride.bind(this)], + ['Frontend.clearAllVisibleOverride', this._onApiClearAllVisibleOverride.bind(this)] ])); this._hotkeyHandler.registerActions([ @@ -178,11 +178,11 @@ export class Frontend { /* eslint-disable no-multi-spaces */ yomitan.crossFrame.registerHandlers([ - ['Frontend.closePopup', {async: false, handler: this._onApiClosePopup.bind(this)}], - ['Frontend.copySelection', {async: false, handler: this._onApiCopySelection.bind(this)}], - ['Frontend.getSelectionText', {async: false, handler: this._onApiGetSelectionText.bind(this)}], - ['Frontend.getPopupInfo', {async: false, handler: this._onApiGetPopupInfo.bind(this)}], - ['Frontend.getPageInfo', {async: false, handler: this._onApiGetPageInfo.bind(this)}] + ['Frontend.closePopup', this._onApiClosePopup.bind(this)], + ['Frontend.copySelection', this._onApiCopySelection.bind(this)], + ['Frontend.getSelectionText', this._onApiGetSelectionText.bind(this)], + ['Frontend.getPopupInfo', this._onApiGetPopupInfo.bind(this)], + ['Frontend.getPageInfo', this._onApiGetPageInfo.bind(this)] ]); /* eslint-enable no-multi-spaces */ diff --git a/ext/js/app/popup-factory.js b/ext/js/app/popup-factory.js index 41984841..184a55ca 100644 --- a/ext/js/app/popup-factory.js +++ b/ext/js/app/popup-factory.js @@ -49,21 +49,21 @@ export class PopupFactory { this._frameOffsetForwarder.prepare(); /* eslint-disable no-multi-spaces */ yomitan.crossFrame.registerHandlers([ - ['PopupFactory.getOrCreatePopup', {async: true, handler: this._onApiGetOrCreatePopup.bind(this)}], - ['PopupFactory.setOptionsContext', {async: true, handler: this._onApiSetOptionsContext.bind(this)}], - ['PopupFactory.hide', {async: true, handler: this._onApiHide.bind(this)}], - ['PopupFactory.isVisible', {async: true, handler: this._onApiIsVisibleAsync.bind(this)}], - ['PopupFactory.setVisibleOverride', {async: true, handler: this._onApiSetVisibleOverride.bind(this)}], - ['PopupFactory.clearVisibleOverride', {async: true, handler: this._onApiClearVisibleOverride.bind(this)}], - ['PopupFactory.containsPoint', {async: true, handler: this._onApiContainsPoint.bind(this)}], - ['PopupFactory.showContent', {async: true, handler: this._onApiShowContent.bind(this)}], - ['PopupFactory.setCustomCss', {async: true, handler: this._onApiSetCustomCss.bind(this)}], - ['PopupFactory.clearAutoPlayTimer', {async: true, handler: this._onApiClearAutoPlayTimer.bind(this)}], - ['PopupFactory.setContentScale', {async: true, handler: this._onApiSetContentScale.bind(this)}], - ['PopupFactory.updateTheme', {async: true, handler: this._onApiUpdateTheme.bind(this)}], - ['PopupFactory.setCustomOuterCss', {async: true, handler: this._onApiSetCustomOuterCss.bind(this)}], - ['PopupFactory.getFrameSize', {async: true, handler: this._onApiGetFrameSize.bind(this)}], - ['PopupFactory.setFrameSize', {async: true, handler: this._onApiSetFrameSize.bind(this)}] + ['PopupFactory.getOrCreatePopup', this._onApiGetOrCreatePopup.bind(this)], + ['PopupFactory.setOptionsContext', this._onApiSetOptionsContext.bind(this)], + ['PopupFactory.hide', this._onApiHide.bind(this)], + ['PopupFactory.isVisible', this._onApiIsVisibleAsync.bind(this)], + ['PopupFactory.setVisibleOverride', this._onApiSetVisibleOverride.bind(this)], + ['PopupFactory.clearVisibleOverride', this._onApiClearVisibleOverride.bind(this)], + ['PopupFactory.containsPoint', this._onApiContainsPoint.bind(this)], + ['PopupFactory.showContent', this._onApiShowContent.bind(this)], + ['PopupFactory.setCustomCss', this._onApiSetCustomCss.bind(this)], + ['PopupFactory.clearAutoPlayTimer', this._onApiClearAutoPlayTimer.bind(this)], + ['PopupFactory.setContentScale', this._onApiSetContentScale.bind(this)], + ['PopupFactory.updateTheme', this._onApiUpdateTheme.bind(this)], + ['PopupFactory.setCustomOuterCss', this._onApiSetCustomOuterCss.bind(this)], + ['PopupFactory.getFrameSize', this._onApiGetFrameSize.bind(this)], + ['PopupFactory.setFrameSize', this._onApiSetFrameSize.bind(this)] ]); /* eslint-enable no-multi-spaces */ } diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index 09edbd6e..c3de6fc7 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -149,51 +149,51 @@ export class Backend { this._permissionsUtil = new PermissionsUtil(); /* eslint-disable no-multi-spaces */ - /** @type {import('backend').MessageHandlerMap} */ - this._messageHandlers = new Map(/** @type {import('backend').MessageHandlerMapInit} */ ([ - ['requestBackendReadySignal', {async: false, contentScript: true, handler: this._onApiRequestBackendReadySignal.bind(this)}], - ['optionsGet', {async: false, contentScript: true, handler: this._onApiOptionsGet.bind(this)}], - ['optionsGetFull', {async: false, contentScript: true, handler: this._onApiOptionsGetFull.bind(this)}], - ['kanjiFind', {async: true, contentScript: true, handler: this._onApiKanjiFind.bind(this)}], - ['termsFind', {async: true, contentScript: true, handler: this._onApiTermsFind.bind(this)}], - ['parseText', {async: true, contentScript: true, handler: this._onApiParseText.bind(this)}], - ['getAnkiConnectVersion', {async: true, contentScript: true, handler: this._onApiGetAnkiConnectVersion.bind(this)}], - ['isAnkiConnected', {async: true, contentScript: true, handler: this._onApiIsAnkiConnected.bind(this)}], - ['addAnkiNote', {async: true, contentScript: true, handler: this._onApiAddAnkiNote.bind(this)}], - ['getAnkiNoteInfo', {async: true, contentScript: true, handler: this._onApiGetAnkiNoteInfo.bind(this)}], - ['injectAnkiNoteMedia', {async: true, contentScript: true, handler: this._onApiInjectAnkiNoteMedia.bind(this)}], - ['noteView', {async: true, contentScript: true, handler: this._onApiNoteView.bind(this)}], - ['suspendAnkiCardsForNote', {async: true, contentScript: true, handler: this._onApiSuspendAnkiCardsForNote.bind(this)}], - ['commandExec', {async: false, contentScript: true, handler: this._onApiCommandExec.bind(this)}], - ['getTermAudioInfoList', {async: true, contentScript: true, handler: this._onApiGetTermAudioInfoList.bind(this)}], - ['sendMessageToFrame', {async: false, contentScript: true, handler: this._onApiSendMessageToFrame.bind(this)}], - ['broadcastTab', {async: false, contentScript: true, handler: this._onApiBroadcastTab.bind(this)}], - ['frameInformationGet', {async: true, contentScript: true, handler: this._onApiFrameInformationGet.bind(this)}], - ['injectStylesheet', {async: true, contentScript: true, handler: this._onApiInjectStylesheet.bind(this)}], - ['getStylesheetContent', {async: true, contentScript: true, handler: this._onApiGetStylesheetContent.bind(this)}], - ['getEnvironmentInfo', {async: false, contentScript: true, handler: this._onApiGetEnvironmentInfo.bind(this)}], - ['clipboardGet', {async: true, contentScript: true, handler: this._onApiClipboardGet.bind(this)}], - ['getDisplayTemplatesHtml', {async: true, contentScript: true, handler: this._onApiGetDisplayTemplatesHtml.bind(this)}], - ['getZoom', {async: true, contentScript: true, handler: this._onApiGetZoom.bind(this)}], - ['getDefaultAnkiFieldTemplates', {async: false, contentScript: true, handler: this._onApiGetDefaultAnkiFieldTemplates.bind(this)}], - ['getDictionaryInfo', {async: true, contentScript: true, handler: this._onApiGetDictionaryInfo.bind(this)}], - ['purgeDatabase', {async: true, contentScript: false, handler: this._onApiPurgeDatabase.bind(this)}], - ['getMedia', {async: true, contentScript: true, handler: this._onApiGetMedia.bind(this)}], - ['log', {async: false, contentScript: true, handler: this._onApiLog.bind(this)}], - ['logIndicatorClear', {async: false, contentScript: true, handler: this._onApiLogIndicatorClear.bind(this)}], - ['createActionPort', {async: false, contentScript: true, handler: this._onApiCreateActionPort.bind(this)}], - ['modifySettings', {async: true, contentScript: true, handler: this._onApiModifySettings.bind(this)}], - ['getSettings', {async: false, contentScript: true, handler: this._onApiGetSettings.bind(this)}], - ['setAllSettings', {async: true, contentScript: false, handler: this._onApiSetAllSettings.bind(this)}], - ['getOrCreateSearchPopup', {async: true, contentScript: true, handler: this._onApiGetOrCreateSearchPopup.bind(this)}], - ['isTabSearchPopup', {async: true, contentScript: true, handler: this._onApiIsTabSearchPopup.bind(this)}], - ['triggerDatabaseUpdated', {async: false, contentScript: true, handler: this._onApiTriggerDatabaseUpdated.bind(this)}], - ['testMecab', {async: true, contentScript: true, handler: this._onApiTestMecab.bind(this)}], - ['textHasJapaneseCharacters', {async: false, contentScript: true, handler: this._onApiTextHasJapaneseCharacters.bind(this)}], - ['getTermFrequencies', {async: true, contentScript: true, handler: this._onApiGetTermFrequencies.bind(this)}], - ['findAnkiNotes', {async: true, contentScript: true, handler: this._onApiFindAnkiNotes.bind(this)}], - ['loadExtensionScripts', {async: true, contentScript: true, handler: this._onApiLoadExtensionScripts.bind(this)}], - ['openCrossFramePort', {async: false, contentScript: true, handler: this._onApiOpenCrossFramePort.bind(this)}] + /** @type {import('core').MessageHandlerMap} */ + this._messageHandlers = new Map(/** @type {import('core').MessageHandlerMapInit} */ ([ + ['requestBackendReadySignal', this._onApiRequestBackendReadySignal.bind(this)], + ['optionsGet', this._onApiOptionsGet.bind(this)], + ['optionsGetFull', this._onApiOptionsGetFull.bind(this)], + ['kanjiFind', this._onApiKanjiFind.bind(this)], + ['termsFind', this._onApiTermsFind.bind(this)], + ['parseText', this._onApiParseText.bind(this)], + ['getAnkiConnectVersion', this._onApiGetAnkiConnectVersion.bind(this)], + ['isAnkiConnected', this._onApiIsAnkiConnected.bind(this)], + ['addAnkiNote', this._onApiAddAnkiNote.bind(this)], + ['getAnkiNoteInfo', this._onApiGetAnkiNoteInfo.bind(this)], + ['injectAnkiNoteMedia', this._onApiInjectAnkiNoteMedia.bind(this)], + ['noteView', this._onApiNoteView.bind(this)], + ['suspendAnkiCardsForNote', this._onApiSuspendAnkiCardsForNote.bind(this)], + ['commandExec', this._onApiCommandExec.bind(this)], + ['getTermAudioInfoList', this._onApiGetTermAudioInfoList.bind(this)], + ['sendMessageToFrame', this._onApiSendMessageToFrame.bind(this)], + ['broadcastTab', this._onApiBroadcastTab.bind(this)], + ['frameInformationGet', this._onApiFrameInformationGet.bind(this)], + ['injectStylesheet', this._onApiInjectStylesheet.bind(this)], + ['getStylesheetContent', this._onApiGetStylesheetContent.bind(this)], + ['getEnvironmentInfo', this._onApiGetEnvironmentInfo.bind(this)], + ['clipboardGet', this._onApiClipboardGet.bind(this)], + ['getDisplayTemplatesHtml', this._onApiGetDisplayTemplatesHtml.bind(this)], + ['getZoom', this._onApiGetZoom.bind(this)], + ['getDefaultAnkiFieldTemplates', this._onApiGetDefaultAnkiFieldTemplates.bind(this)], + ['getDictionaryInfo', this._onApiGetDictionaryInfo.bind(this)], + ['purgeDatabase', this._onApiPurgeDatabase.bind(this)], + ['getMedia', this._onApiGetMedia.bind(this)], + ['log', this._onApiLog.bind(this)], + ['logIndicatorClear', this._onApiLogIndicatorClear.bind(this)], + ['createActionPort', this._onApiCreateActionPort.bind(this)], + ['modifySettings', this._onApiModifySettings.bind(this)], + ['getSettings', this._onApiGetSettings.bind(this)], + ['setAllSettings', this._onApiSetAllSettings.bind(this)], + ['getOrCreateSearchPopup', this._onApiGetOrCreateSearchPopup.bind(this)], + ['isTabSearchPopup', this._onApiIsTabSearchPopup.bind(this)], + ['triggerDatabaseUpdated', this._onApiTriggerDatabaseUpdated.bind(this)], + ['testMecab', this._onApiTestMecab.bind(this)], + ['textHasJapaneseCharacters', this._onApiTextHasJapaneseCharacters.bind(this)], + ['getTermFrequencies', this._onApiGetTermFrequencies.bind(this)], + ['findAnkiNotes', this._onApiFindAnkiNotes.bind(this)], + ['loadExtensionScripts', this._onApiLoadExtensionScripts.bind(this)], + ['openCrossFramePort', this._onApiOpenCrossFramePort.bind(this)] ])); /* eslint-enable no-multi-spaces */ /** @type {import('backend').MessageHandlerWithProgressMap} */ @@ -408,16 +408,6 @@ export class Backend { _onMessage({action, params}, sender, callback) { const messageHandler = this._messageHandlers.get(action); if (typeof messageHandler === 'undefined') { return false; } - - if (!messageHandler.contentScript) { - try { - this._validatePrivilegedMessageSender(sender); - } catch (error) { - callback({error: ExtensionError.serialize(error)}); - return false; - } - } - return invokeMessageHandler(messageHandler, params, callback, sender); } diff --git a/ext/js/background/offscreen.js b/ext/js/background/offscreen.js index 85b6847b..bcbcda6b 100644 --- a/ext/js/background/offscreen.js +++ b/ext/js/background/offscreen.js @@ -52,23 +52,21 @@ export class Offscreen { /* eslint-disable no-multi-spaces */ /** @type {import('offscreen').MessageHandlerMap} */ - const messageHandlers = new Map([ - ['clipboardGetTextOffscreen', {async: true, handler: this._getTextHandler.bind(this)}], - ['clipboardGetImageOffscreen', {async: true, handler: this._getImageHandler.bind(this)}], - ['clipboardSetBrowserOffscreen', {async: false, handler: this._setClipboardBrowser.bind(this)}], - ['databasePrepareOffscreen', {async: true, handler: this._prepareDatabaseHandler.bind(this)}], - ['getDictionaryInfoOffscreen', {async: true, handler: this._getDictionaryInfoHandler.bind(this)}], - ['databasePurgeOffscreen', {async: true, handler: this._purgeDatabaseHandler.bind(this)}], - ['databaseGetMediaOffscreen', {async: true, handler: this._getMediaHandler.bind(this)}], - ['translatorPrepareOffscreen', {async: false, handler: this._prepareTranslatorHandler.bind(this)}], - ['findKanjiOffscreen', {async: true, handler: this._findKanjiHandler.bind(this)}], - ['findTermsOffscreen', {async: true, handler: this._findTermsHandler.bind(this)}], - ['getTermFrequenciesOffscreen', {async: true, handler: this._getTermFrequenciesHandler.bind(this)}], - ['clearDatabaseCachesOffscreen', {async: false, handler: this._clearDatabaseCachesHandler.bind(this)}] - ]); + this._messageHandlers = new Map(/** @type {import('offscreen').MessageHandlerMapInit} */ ([ + ['clipboardGetTextOffscreen', this._getTextHandler.bind(this)], + ['clipboardGetImageOffscreen', this._getImageHandler.bind(this)], + ['clipboardSetBrowserOffscreen', this._setClipboardBrowser.bind(this)], + ['databasePrepareOffscreen', this._prepareDatabaseHandler.bind(this)], + ['getDictionaryInfoOffscreen', this._getDictionaryInfoHandler.bind(this)], + ['databasePurgeOffscreen', this._purgeDatabaseHandler.bind(this)], + ['databaseGetMediaOffscreen', this._getMediaHandler.bind(this)], + ['translatorPrepareOffscreen', this._prepareTranslatorHandler.bind(this)], + ['findKanjiOffscreen', this._findKanjiHandler.bind(this)], + ['findTermsOffscreen', this._findTermsHandler.bind(this)], + ['getTermFrequenciesOffscreen', this._getTermFrequenciesHandler.bind(this)], + ['clearDatabaseCachesOffscreen', this._clearDatabaseCachesHandler.bind(this)] + ])); /* eslint-enable no-multi-spaces */ - /** @type {import('offscreen').MessageHandlerMap<string>} */ - this._messageHandlers = messageHandlers; const onMessage = this._onMessage.bind(this); chrome.runtime.onMessage.addListener(onMessage); @@ -172,7 +170,7 @@ export class Offscreen { /** @type {import('extension').ChromeRuntimeOnMessageCallback} */ _onMessage({action, params}, sender, callback) { - const messageHandler = this._messageHandlers.get(action); + const messageHandler = this._messageHandlers.get(/** @type {import('offscreen').MessageType} */ (action)); if (typeof messageHandler === 'undefined') { return false; } return invokeMessageHandler(messageHandler, params, callback, sender); } diff --git a/ext/js/comm/cross-frame-api.js b/ext/js/comm/cross-frame-api.js index 0d3f3275..023ca18e 100644 --- a/ext/js/comm/cross-frame-api.js +++ b/ext/js/comm/cross-frame-api.js @@ -351,7 +351,7 @@ export class CrossFrameAPI { } /** - * @param {import('core').MessageHandlerArray} messageHandlers + * @param {import('core').MessageHandlerMapInit} messageHandlers * @throws {Error} */ registerHandlers(messageHandlers) { diff --git a/ext/js/comm/frame-ancestry-handler.js b/ext/js/comm/frame-ancestry-handler.js index b91046bc..261ea943 100644 --- a/ext/js/comm/frame-ancestry-handler.js +++ b/ext/js/comm/frame-ancestry-handler.js @@ -164,7 +164,9 @@ export class FrameAncestryHandler { }; // Start - yomitan.crossFrame.registerHandlers([[responseMessageId, {async: false, handler: onMessage}]]); + yomitan.crossFrame.registerHandlers([ + [responseMessageId, onMessage] + ]); resetTimeout(); const frameId = this._frameId; this._requestFrameInfo(targetWindow, frameId, frameId, uniqueId, nonce); diff --git a/ext/js/comm/frame-offset-forwarder.js b/ext/js/comm/frame-offset-forwarder.js index af9bd268..afa6a5e6 100644 --- a/ext/js/comm/frame-offset-forwarder.js +++ b/ext/js/comm/frame-offset-forwarder.js @@ -36,7 +36,7 @@ export class FrameOffsetForwarder { prepare() { this._frameAncestryHandler.prepare(); yomitan.crossFrame.registerHandlers([ - ['FrameOffsetForwarder.getChildFrameRect', {async: false, handler: this._onMessageGetChildFrameRect.bind(this)}] + ['FrameOffsetForwarder.getChildFrameRect', this._onMessageGetChildFrameRect.bind(this)] ]); } diff --git a/ext/js/core.js b/ext/js/core.js index d2372352..9995ee5b 100644 --- a/ext/js/core.js +++ b/ext/js/core.js @@ -324,7 +324,7 @@ export function promiseAnimationFrame(timeout) { * Invokes a standard message handler. This function is used to react and respond * to communication messages within the extension. * @template {import('core').SafeAny} TParams - * @param {import('core').MessageHandlerDetails} details Details about how to handle messages. + * @param {import('core').MessageHandler} handler The message handler function. * @param {TParams} params Information which was passed with the original message. * @param {(response: import('core').Response) => void} callback A callback function which is invoked after the handler has completed. The value passed * to the function is in the format: @@ -333,13 +333,10 @@ export function promiseAnimationFrame(timeout) { * @param {...*} extraArgs Additional arguments which are passed to the `handler` function. * @returns {boolean} `true` if the function is invoked asynchronously, `false` otherwise. */ -export function invokeMessageHandler({handler, async}, params, callback, ...extraArgs) { +export function invokeMessageHandler(handler, params, callback, ...extraArgs) { try { - let promiseOrResult = handler(params, ...extraArgs); - if (async === 'dynamic') { - ({async, result: promiseOrResult} = promiseOrResult); - } - if (async) { + const promiseOrResult = handler(params, ...extraArgs); + if (promiseOrResult instanceof Promise) { /** @type {Promise<any>} */ (promiseOrResult).then( (result) => { callback({result}); }, (error) => { callback({error: ExtensionError.serialize(error)}); } diff --git a/ext/js/display/display-audio.js b/ext/js/display/display-audio.js index 8cd1ccc3..30cf2b92 100644 --- a/ext/js/display/display-audio.js +++ b/ext/js/display/display-audio.js @@ -89,7 +89,7 @@ export class DisplayAudio { ['playAudioFromSource', this._onHotkeyActionPlayAudioFromSource.bind(this)] ]); this._display.registerDirectMessageHandlers([ - ['Display.clearAutoPlayTimer', {async: false, handler: this._onMessageClearAutoPlayTimer.bind(this)}] + ['Display.clearAutoPlayTimer', this._onMessageClearAutoPlayTimer.bind(this)] ]); /* eslint-enable no-multi-spaces */ this._display.on('optionsUpdated', this._onOptionsUpdated.bind(this)); diff --git a/ext/js/display/display.js b/ext/js/display/display.js index d7b8f898..79cf79a8 100644 --- a/ext/js/display/display.js +++ b/ext/js/display/display.js @@ -207,15 +207,15 @@ export class Display extends EventDispatcher { ['previousEntryDifferentDictionary', () => { this._focusEntryWithDifferentDictionary(-1, true); }] ]); this.registerDirectMessageHandlers([ - ['Display.setOptionsContext', {async: true, handler: this._onMessageSetOptionsContext.bind(this)}], - ['Display.setContent', {async: false, handler: this._onMessageSetContent.bind(this)}], - ['Display.setCustomCss', {async: false, handler: this._onMessageSetCustomCss.bind(this)}], - ['Display.setContentScale', {async: false, handler: this._onMessageSetContentScale.bind(this)}], - ['Display.configure', {async: true, handler: this._onMessageConfigure.bind(this)}], - ['Display.visibilityChanged', {async: false, handler: this._onMessageVisibilityChanged.bind(this)}] + ['Display.setOptionsContext', this._onMessageSetOptionsContext.bind(this)], + ['Display.setContent', this._onMessageSetContent.bind(this)], + ['Display.setCustomCss', this._onMessageSetCustomCss.bind(this)], + ['Display.setContentScale', this._onMessageSetContentScale.bind(this)], + ['Display.configure', this._onMessageConfigure.bind(this)], + ['Display.visibilityChanged', this._onMessageVisibilityChanged.bind(this)] ]); this.registerWindowMessageHandlers([ - ['Display.extensionUnloaded', {async: false, handler: this._onMessageExtensionUnloaded.bind(this)}] + ['Display.extensionUnloaded', this._onMessageExtensionUnloaded.bind(this)] ]); /* eslint-enable no-multi-spaces */ } @@ -328,7 +328,7 @@ export class Display extends EventDispatcher { this._progressIndicatorVisible.on('change', this._onProgressIndicatorVisibleChanged.bind(this)); yomitan.on('extensionUnloaded', this._onExtensionUnloaded.bind(this)); yomitan.crossFrame.registerHandlers([ - ['popupMessage', {async: 'dynamic', handler: this._onDirectMessage.bind(this)}] + ['popupMessage', this._onDirectMessage.bind(this)] ]); window.addEventListener('message', this._onWindowMessage.bind(this), false); @@ -506,7 +506,7 @@ export class Display extends EventDispatcher { } /** - * @param {import('core').MessageHandlerArray} handlers + * @param {import('core').MessageHandlerMapInit} handlers */ registerDirectMessageHandlers(handlers) { for (const [name, handlerInfo] of handlers) { @@ -515,7 +515,7 @@ export class Display extends EventDispatcher { } /** - * @param {import('core').MessageHandlerArray} handlers + * @param {import('core').MessageHandlerMapInit} handlers */ registerWindowMessageHandlers(handlers) { for (const [name, handlerInfo] of handlers) { @@ -638,22 +638,17 @@ export class Display extends EventDispatcher { /** * @param {import('frame-client').Message<import('display').MessageDetails>} data - * @returns {import('core').MessageHandlerAsyncResult} + * @returns {import('core').MessageHandlerResult} * @throws {Error} */ _onDirectMessage(data) { const {action, params} = this._authenticateMessageData(data); - const handlerInfo = this._directMessageHandlers.get(action); - if (typeof handlerInfo === 'undefined') { + const handler = this._directMessageHandlers.get(action); + if (typeof handler === 'undefined') { throw new Error(`Invalid action: ${action}`); } - const {async, handler} = handlerInfo; - const result = handler(params); - return { - async: typeof async === 'boolean' && async, - result - }; + return handler(params); } /** diff --git a/ext/js/display/search-display-controller.js b/ext/js/display/search-display-controller.js index 44850cbb..4dd41736 100644 --- a/ext/js/display/search-display-controller.js +++ b/ext/js/display/search-display-controller.js @@ -96,9 +96,9 @@ export class SearchDisplayController { ]); /* eslint-disable no-multi-spaces */ this._registerMessageHandlers([ - ['SearchDisplayController.getMode', {async: false, handler: this._onMessageGetMode.bind(this)}], - ['SearchDisplayController.setMode', {async: false, handler: this._onMessageSetMode.bind(this)}], - ['SearchDisplayController.updateSearchQuery', {async: false, handler: this._onExternalSearchUpdate.bind(this)}] + ['SearchDisplayController.getMode', this._onMessageGetMode.bind(this)], + ['SearchDisplayController.setMode', this._onMessageSetMode.bind(this)], + ['SearchDisplayController.updateSearchQuery', this._onExternalSearchUpdate.bind(this)] ]); /* eslint-enable no-multi-spaces */ @@ -549,7 +549,7 @@ export class SearchDisplayController { } /** - * @param {import('core').MessageHandlerArray} handlers + * @param {import('core').MessageHandlerMapInit} handlers */ _registerMessageHandlers(handlers) { for (const [name, handlerInfo] of handlers) { diff --git a/ext/js/input/hotkey-handler.js b/ext/js/input/hotkey-handler.js index f1512b8f..da763662 100644 --- a/ext/js/input/hotkey-handler.js +++ b/ext/js/input/hotkey-handler.js @@ -51,7 +51,7 @@ export class HotkeyHandler extends EventDispatcher { this._isPrepared = true; this._updateEventHandlers(); yomitan.crossFrame.registerHandlers([ - ['HotkeyHandler.forwardHotkey', {async: false, handler: this._onMessageForwardHotkey.bind(this)}] + ['HotkeyHandler.forwardHotkey', this._onMessageForwardHotkey.bind(this)] ]); } diff --git a/ext/js/templates/sandbox/template-renderer-frame-api.js b/ext/js/templates/sandbox/template-renderer-frame-api.js index 388401f2..56cedb97 100644 --- a/ext/js/templates/sandbox/template-renderer-frame-api.js +++ b/ext/js/templates/sandbox/template-renderer-frame-api.js @@ -27,10 +27,10 @@ export class TemplateRendererFrameApi { /** @type {import('./template-renderer.js').TemplateRenderer} */ this._templateRenderer = templateRenderer; /** @type {import('core').MessageHandlerMap} */ - this._windowMessageHandlers = new Map(/** @type {import('core').MessageHandlerArray} */ ([ - ['render', {async: false, handler: this._onRender.bind(this)}], - ['renderMulti', {async: false, handler: this._onRenderMulti.bind(this)}], - ['getModifiedData', {async: false, handler: this._onGetModifiedData.bind(this)}] + this._windowMessageHandlers = new Map(/** @type {import('core').MessageHandlerMapInit} */ ([ + ['render', this._onRender.bind(this)], + ['renderMulti', this._onRenderMulti.bind(this)], + ['getModifiedData', this._onGetModifiedData.bind(this)] ])); } @@ -56,17 +56,17 @@ export class TemplateRendererFrameApi { } /** - * @param {import('core').MessageHandlerDetails} handlerItem + * @param {import('core').MessageHandler} handler * @param {string} action * @param {import('core').SerializableObject} params * @param {Window} source * @param {?string} id */ - async _onWindowMessageInner({handler, async}, action, params, source, id) { + async _onWindowMessageInner(handler, action, params, source, id) { let response; try { let result = handler(params); - if (async) { + if (result instanceof Promise) { result = await result; } response = {result}; diff --git a/ext/js/yomitan.js b/ext/js/yomitan.js index 37455d00..1d6f7644 100644 --- a/ext/js/yomitan.js +++ b/ext/js/yomitan.js @@ -90,13 +90,13 @@ export class Yomitan extends EventDispatcher { /* eslint-disable no-multi-spaces */ /** @type {import('core').MessageHandlerMap} */ - this._messageHandlers = new Map(/** @type {import('core').MessageHandlerArray} */ ([ - ['Yomitan.isReady', {async: false, handler: this._onMessageIsReady.bind(this)}], - ['Yomitan.backendReady', {async: false, handler: this._onMessageBackendReady.bind(this)}], - ['Yomitan.getUrl', {async: false, handler: this._onMessageGetUrl.bind(this)}], - ['Yomitan.optionsUpdated', {async: false, handler: this._onMessageOptionsUpdated.bind(this)}], - ['Yomitan.databaseUpdated', {async: false, handler: this._onMessageDatabaseUpdated.bind(this)}], - ['Yomitan.zoomChanged', {async: false, handler: this._onMessageZoomChanged.bind(this)}] + this._messageHandlers = new Map(/** @type {import('core').MessageHandlerMapInit} */ ([ + ['Yomitan.isReady', this._onMessageIsReady.bind(this)], + ['Yomitan.backendReady', this._onMessageBackendReady.bind(this)], + ['Yomitan.getUrl', this._onMessageGetUrl.bind(this)], + ['Yomitan.optionsUpdated', this._onMessageOptionsUpdated.bind(this)], + ['Yomitan.databaseUpdated', this._onMessageDatabaseUpdated.bind(this)], + ['Yomitan.zoomChanged', this._onMessageZoomChanged.bind(this)] ])); /* eslint-enable no-multi-spaces */ } diff --git a/types/ext/backend.d.ts b/types/ext/backend.d.ts index 08cbf4b0..6cbe7938 100644 --- a/types/ext/backend.d.ts +++ b/types/ext/backend.d.ts @@ -18,14 +18,6 @@ import type * as Api from './api'; import type * as Core from './core'; -export type MessageHandlerDetails = { - async: boolean; - contentScript: boolean; - handler: (params: Core.SerializableObject | undefined, sender: chrome.runtime.MessageSender) => unknown; -}; -export type MessageHandlerMap = Map<string, MessageHandlerDetails>; -export type MessageHandlerMapInit = [key: string, handlerDetails: MessageHandlerDetails][]; - export type MessageHandlerWithProgressDetails = { async: boolean; contentScript: boolean; diff --git a/types/ext/core.d.ts b/types/ext/core.d.ts index d1a4ef8f..c71a8ec4 100644 --- a/types/ext/core.d.ts +++ b/types/ext/core.d.ts @@ -75,30 +75,16 @@ export type ResponseError = { export type Response<T = unknown> = ResponseSuccess<T> | ResponseError; export type MessageHandler = (params: SafeAny, ...extraArgs: SafeAny[]) => ( - SafeAny | - Promise<SafeAny> | - MessageHandlerAsyncResult + MessageHandlerResult | + Promise<MessageHandlerResult> ); -export type MessageHandlerAsyncResult = { - async: boolean; - result: SafeAny | Promise<SafeAny>; -}; +export type MessageHandlerResult = SafeAny; -export type MessageHandlerDetails = { - /** - * 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}`. - */ - async: boolean | 'dynamic'; - /** - * A handler function which is passed `params` and `...extraArgs` as arguments. - */ - handler: MessageHandler; -}; +export type MessageHandlerMap = Map<string, MessageHandler>; -export type MessageHandlerMap = Map<string, MessageHandlerDetails>; +export type MessageHandlerMapInit = MessageHandlerMapInitItem[]; -export type MessageHandlerArray = [key: string, handlerDetails: MessageHandlerDetails][]; +export type MessageHandlerMapInitItem = [key: string, handlerDetails: MessageHandler]; export type Timeout = number | NodeJS.Timeout; diff --git a/types/ext/offscreen.d.ts b/types/ext/offscreen.d.ts index 85bce1ff..c741ac99 100644 --- a/types/ext/offscreen.d.ts +++ b/types/ext/offscreen.d.ts @@ -110,4 +110,8 @@ export type MessageHandler< details: MessageDetailsMap[TMessage], ) => (TIsAsync extends true ? Promise<MessageReturn<TMessage>> : MessageReturn<TMessage>); -export type MessageHandlerMap<T = MessageType> = Map<T, Core.MessageHandlerDetails>; +export type MessageHandlerMap = Map<MessageType, Core.MessageHandler>; + +export type MessageHandlerMapInit = MessageHandlerMapInitItem[]; + +export type MessageHandlerMapInitItem = [messageType: MessageType, handler: Core.MessageHandler]; |