aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/bg/js/backend.js54
-rw-r--r--ext/bg/js/search.js11
-rw-r--r--ext/fg/js/frontend.js20
-rw-r--r--ext/mixed/js/comm.js25
-rw-r--r--ext/mixed/js/yomichan.js56
5 files changed, 80 insertions, 86 deletions
diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js
index 6e594f9b..07c32fa2 100644
--- a/ext/bg/js/backend.js
+++ b/ext/bg/js/backend.js
@@ -294,28 +294,16 @@ class Backend {
const messageHandler = this._messageHandlers.get(action);
if (typeof messageHandler === 'undefined') { return false; }
- const {handler, async, contentScript} = messageHandler;
-
- try {
- if (!contentScript) {
+ if (!messageHandler.contentScript) {
+ try {
this._validatePrivilegedMessageSender(sender);
- }
-
- const promiseOrResult = handler(params, sender);
- if (async) {
- promiseOrResult.then(
- (result) => callback({result}),
- (error) => callback({error: errorToJson(error)})
- );
- return true;
- } else {
- callback({result: promiseOrResult});
+ } catch (error) {
+ callback({error: errorToJson(error)});
return false;
}
- } catch (error) {
- callback({error: errorToJson(error)});
- return false;
}
+
+ return yomichan.invokeMessageHandler(messageHandler, params, callback, sender);
}
_onConnect(port) {
@@ -814,11 +802,7 @@ class Backend {
if (tab !== null) {
await this._focusTab(tab);
if (queryParams.query) {
- await new Promise((resolve) => chrome.tabs.sendMessage(
- tab.id,
- {action: 'searchQueryUpdate', params: {text: queryParams.query}},
- resolve
- ));
+ await this._updateSearchQuery(tab.id, queryParams.query);
}
return true;
}
@@ -882,6 +866,21 @@ class Backend {
// Utilities
+ _updateSearchQuery(tabId, text) {
+ new Promise((resolve, reject) => {
+ const callback = (response) => {
+ try {
+ resolve(yomichan.getMessageResponseResult(response));
+ } catch (error) {
+ reject(error);
+ }
+ };
+
+ const message = {action: 'updateSearchQuery', params: {text}};
+ chrome.tabs.sendMessage(tabId, message, callback);
+ });
+ }
+
_sendMessageAllTabs(action, params={}) {
const callback = () => this._checkLastError(chrome.runtime.lastError);
chrome.tabs.query({}, (tabs) => {
@@ -1286,11 +1285,10 @@ class Backend {
return new Promise((resolve) => {
chrome.tabs.sendMessage(tab.id, {action: 'getUrl'}, {frameId: 0}, (response) => {
let url = null;
- if (!chrome.runtime.lastError) {
- url = (response !== null && typeof response === 'object' && !Array.isArray(response) ? response.url : null);
- if (url !== null && typeof url !== 'string') {
- url = null;
- }
+ try {
+ url = yomichan.getMessageResponseResult(response);
+ } catch (error) {
+ // NOP
}
resolve({tab, url});
});
diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js
index 9bbc66f2..52fc19f8 100644
--- a/ext/bg/js/search.js
+++ b/ext/bg/js/search.js
@@ -61,7 +61,7 @@ class DisplaySearch extends Display {
['Shift', new Set()]
]);
this._runtimeMessageHandlers = new Map([
- ['searchQueryUpdate', this._onExternalSearchUpdate.bind(this)]
+ ['updateSearchQuery', {async: false, handler: this._onExternalSearchUpdate.bind(this)}]
]);
this.setOptionsContext({
@@ -206,12 +206,9 @@ class DisplaySearch extends Display {
}
_onRuntimeMessage({action, params}, sender, callback) {
- const handler = this._runtimeMessageHandlers.get(action);
- if (typeof handler !== 'function') { return false; }
-
- const result = handler(params, sender);
- callback(result);
- return false;
+ const messageHandler = this._runtimeMessageHandlers.get(action);
+ if (typeof messageHandler === 'undefined') { return false; }
+ return yomichan.invokeMessageHandler(messageHandler, params, callback, sender);
}
_onCopy() {
diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js
index 1618fa12..aa03d4b5 100644
--- a/ext/fg/js/frontend.js
+++ b/ext/fg/js/frontend.js
@@ -211,25 +211,7 @@ class Frontend {
_onRuntimeMessage({action, params}, sender, callback) {
const messageHandler = this._runtimeMessageHandlers.get(action);
if (typeof messageHandler === 'undefined') { return false; }
-
- const {handler, async} = messageHandler;
-
- try {
- const promiseOrResult = handler(params, sender);
- if (async) {
- promiseOrResult.then(
- (result) => callback({result}),
- (error) => callback({error: errorToJson(error)})
- );
- return true;
- } else {
- callback({result: promiseOrResult});
- return false;
- }
- } catch (error) {
- callback({error: errorToJson(error)});
- return false;
- }
+ return yomichan.invokeMessageHandler(messageHandler, params, callback, sender);
}
_onZoomChanged({newZoomFactor}) {
diff --git a/ext/mixed/js/comm.js b/ext/mixed/js/comm.js
index 182400e3..1516a98f 100644
--- a/ext/mixed/js/comm.js
+++ b/ext/mixed/js/comm.js
@@ -166,31 +166,14 @@ class CrossFrameAPIPort extends EventDispatcher {
// Invocation
_onInvoke(id, {action, params}) {
+ const callback = (response) => this._sendResponse({type: 'result', id, data: response});
const messageHandler = this._messageHandlers.get(action);
if (typeof messageHandler === 'undefined') {
- this._sendError(id, new Error(`Unknown action: ${action}`));
- return;
+ callback({error: new Error(`Unknown action: ${action}`)});
+ return false;
}
-
- let {handler, async} = messageHandler;
-
this._sendAck(id);
- try {
- let result = handler(params);
- if (async === 'dynamic') {
- ({async, result} = result);
- }
- if (async) {
- result.then(
- (result2) => this._sendResult(id, result2),
- (error2) => this._sendError(id, error2)
- );
- } else {
- this._sendResult(id, result);
- }
- } catch (error) {
- this._sendError(id, error);
- }
+ return yomichan.invokeMessageHandler(messageHandler, params, callback);
}
_sendResponse(data) {
diff --git a/ext/mixed/js/yomichan.js b/ext/mixed/js/yomichan.js
index d921a5a2..7fffbaa6 100644
--- a/ext/mixed/js/yomichan.js
+++ b/ext/mixed/js/yomichan.js
@@ -54,10 +54,10 @@ const yomichan = (() => {
this._isBackendPreparedPromiseResolve = resolve;
this._messageHandlers = new Map([
- ['backendPrepared', this._onMessageBackendPrepared.bind(this)],
- ['getUrl', this._onMessageGetUrl.bind(this)],
- ['optionsUpdated', this._onMessageOptionsUpdated.bind(this)],
- ['zoomChanged', this._onMessageZoomChanged.bind(this)]
+ ['backendPrepared', {async: false, handler: this._onMessageBackendPrepared.bind(this)}],
+ ['getUrl', {async: false, handler: this._onMessageGetUrl.bind(this)}],
+ ['optionsUpdated', {async: false, handler: this._onMessageOptionsUpdated.bind(this)}],
+ ['zoomChanged', {async: false, handler: this._onMessageZoomChanged.bind(this)}]
]);
}
@@ -210,6 +210,43 @@ const yomichan = (() => {
}
}
+ 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 jsonToError(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: errorToJson(error)}); }
+ );
+ return true;
+ } else {
+ callback({result: promiseOrResult});
+ return false;
+ }
+ } catch (error) {
+ callback({error: errorToJson(error)});
+ return false;
+ }
+ }
+
// Private
_onExtensionUnloaded(error) {
@@ -222,16 +259,13 @@ const yomichan = (() => {
}
_getLogContext() {
- return {url: this._getUrl()};
+ return this._getUrl();
}
_onMessage({action, params}, sender, callback) {
- const handler = this._messageHandlers.get(action);
- if (typeof handler !== 'function') { return false; }
-
- const result = handler(params, sender);
- callback(result);
- return false;
+ const messageHandler = this._messageHandlers.get(action);
+ if (typeof messageHandler === 'undefined') { return false; }
+ return this.invokeMessageHandler(messageHandler, params, callback, sender);
}
_onMessageBackendPrepared() {