Message handler refactor (#660)
* Refactor searchQueryUpdate action * Use standard message handler style * Use name "promiseOrResult" for consistency * Use standard message handler convention for Yomichan message handlers * Use common message handler invoker
This commit is contained in:
parent
8389cd8ba2
commit
ec42a7e4d6
@ -294,30 +294,18 @@ class Backend {
|
|||||||
const messageHandler = this._messageHandlers.get(action);
|
const messageHandler = this._messageHandlers.get(action);
|
||||||
if (typeof messageHandler === 'undefined') { return false; }
|
if (typeof messageHandler === 'undefined') { return false; }
|
||||||
|
|
||||||
const {handler, async, contentScript} = messageHandler;
|
if (!messageHandler.contentScript) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!contentScript) {
|
|
||||||
this._validatePrivilegedMessageSender(sender);
|
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});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
callback({error: errorToJson(error)});
|
callback({error: errorToJson(error)});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return yomichan.invokeMessageHandler(messageHandler, params, callback, sender);
|
||||||
|
}
|
||||||
|
|
||||||
_onConnect(port) {
|
_onConnect(port) {
|
||||||
try {
|
try {
|
||||||
const match = /^background-cross-frame-communication-port-(\d+)$/.exec(`${port.name}`);
|
const match = /^background-cross-frame-communication-port-(\d+)$/.exec(`${port.name}`);
|
||||||
@ -814,11 +802,7 @@ class Backend {
|
|||||||
if (tab !== null) {
|
if (tab !== null) {
|
||||||
await this._focusTab(tab);
|
await this._focusTab(tab);
|
||||||
if (queryParams.query) {
|
if (queryParams.query) {
|
||||||
await new Promise((resolve) => chrome.tabs.sendMessage(
|
await this._updateSearchQuery(tab.id, queryParams.query);
|
||||||
tab.id,
|
|
||||||
{action: 'searchQueryUpdate', params: {text: queryParams.query}},
|
|
||||||
resolve
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -882,6 +866,21 @@ class Backend {
|
|||||||
|
|
||||||
// Utilities
|
// 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={}) {
|
_sendMessageAllTabs(action, params={}) {
|
||||||
const callback = () => this._checkLastError(chrome.runtime.lastError);
|
const callback = () => this._checkLastError(chrome.runtime.lastError);
|
||||||
chrome.tabs.query({}, (tabs) => {
|
chrome.tabs.query({}, (tabs) => {
|
||||||
@ -1286,11 +1285,10 @@ class Backend {
|
|||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
chrome.tabs.sendMessage(tab.id, {action: 'getUrl'}, {frameId: 0}, (response) => {
|
chrome.tabs.sendMessage(tab.id, {action: 'getUrl'}, {frameId: 0}, (response) => {
|
||||||
let url = null;
|
let url = null;
|
||||||
if (!chrome.runtime.lastError) {
|
try {
|
||||||
url = (response !== null && typeof response === 'object' && !Array.isArray(response) ? response.url : null);
|
url = yomichan.getMessageResponseResult(response);
|
||||||
if (url !== null && typeof url !== 'string') {
|
} catch (error) {
|
||||||
url = null;
|
// NOP
|
||||||
}
|
|
||||||
}
|
}
|
||||||
resolve({tab, url});
|
resolve({tab, url});
|
||||||
});
|
});
|
||||||
|
@ -61,7 +61,7 @@ class DisplaySearch extends Display {
|
|||||||
['Shift', new Set()]
|
['Shift', new Set()]
|
||||||
]);
|
]);
|
||||||
this._runtimeMessageHandlers = new Map([
|
this._runtimeMessageHandlers = new Map([
|
||||||
['searchQueryUpdate', this._onExternalSearchUpdate.bind(this)]
|
['updateSearchQuery', {async: false, handler: this._onExternalSearchUpdate.bind(this)}]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.setOptionsContext({
|
this.setOptionsContext({
|
||||||
@ -206,12 +206,9 @@ class DisplaySearch extends Display {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onRuntimeMessage({action, params}, sender, callback) {
|
_onRuntimeMessage({action, params}, sender, callback) {
|
||||||
const handler = this._runtimeMessageHandlers.get(action);
|
const messageHandler = this._runtimeMessageHandlers.get(action);
|
||||||
if (typeof handler !== 'function') { return false; }
|
if (typeof messageHandler === 'undefined') { return false; }
|
||||||
|
return yomichan.invokeMessageHandler(messageHandler, params, callback, sender);
|
||||||
const result = handler(params, sender);
|
|
||||||
callback(result);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCopy() {
|
_onCopy() {
|
||||||
|
@ -211,25 +211,7 @@ class Frontend {
|
|||||||
_onRuntimeMessage({action, params}, sender, callback) {
|
_onRuntimeMessage({action, params}, sender, callback) {
|
||||||
const messageHandler = this._runtimeMessageHandlers.get(action);
|
const messageHandler = this._runtimeMessageHandlers.get(action);
|
||||||
if (typeof messageHandler === 'undefined') { return false; }
|
if (typeof messageHandler === 'undefined') { return false; }
|
||||||
|
return yomichan.invokeMessageHandler(messageHandler, params, callback, sender);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onZoomChanged({newZoomFactor}) {
|
_onZoomChanged({newZoomFactor}) {
|
||||||
|
@ -166,31 +166,14 @@ class CrossFrameAPIPort extends EventDispatcher {
|
|||||||
// Invocation
|
// Invocation
|
||||||
|
|
||||||
_onInvoke(id, {action, params}) {
|
_onInvoke(id, {action, params}) {
|
||||||
|
const callback = (response) => this._sendResponse({type: 'result', id, data: response});
|
||||||
const messageHandler = this._messageHandlers.get(action);
|
const messageHandler = this._messageHandlers.get(action);
|
||||||
if (typeof messageHandler === 'undefined') {
|
if (typeof messageHandler === 'undefined') {
|
||||||
this._sendError(id, new Error(`Unknown action: ${action}`));
|
callback({error: new Error(`Unknown action: ${action}`)});
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {handler, async} = messageHandler;
|
|
||||||
|
|
||||||
this._sendAck(id);
|
this._sendAck(id);
|
||||||
try {
|
return yomichan.invokeMessageHandler(messageHandler, params, callback);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_sendResponse(data) {
|
_sendResponse(data) {
|
||||||
|
@ -54,10 +54,10 @@ const yomichan = (() => {
|
|||||||
this._isBackendPreparedPromiseResolve = resolve;
|
this._isBackendPreparedPromiseResolve = resolve;
|
||||||
|
|
||||||
this._messageHandlers = new Map([
|
this._messageHandlers = new Map([
|
||||||
['backendPrepared', this._onMessageBackendPrepared.bind(this)],
|
['backendPrepared', {async: false, handler: this._onMessageBackendPrepared.bind(this)}],
|
||||||
['getUrl', this._onMessageGetUrl.bind(this)],
|
['getUrl', {async: false, handler: this._onMessageGetUrl.bind(this)}],
|
||||||
['optionsUpdated', this._onMessageOptionsUpdated.bind(this)],
|
['optionsUpdated', {async: false, handler: this._onMessageOptionsUpdated.bind(this)}],
|
||||||
['zoomChanged', this._onMessageZoomChanged.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
|
// Private
|
||||||
|
|
||||||
_onExtensionUnloaded(error) {
|
_onExtensionUnloaded(error) {
|
||||||
@ -222,16 +259,13 @@ const yomichan = (() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_getLogContext() {
|
_getLogContext() {
|
||||||
return {url: this._getUrl()};
|
return this._getUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMessage({action, params}, sender, callback) {
|
_onMessage({action, params}, sender, callback) {
|
||||||
const handler = this._messageHandlers.get(action);
|
const messageHandler = this._messageHandlers.get(action);
|
||||||
if (typeof handler !== 'function') { return false; }
|
if (typeof messageHandler === 'undefined') { return false; }
|
||||||
|
return this.invokeMessageHandler(messageHandler, params, callback, sender);
|
||||||
const result = handler(params, sender);
|
|
||||||
callback(result);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMessageBackendPrepared() {
|
_onMessageBackendPrepared() {
|
||||||
|
Loading…
Reference in New Issue
Block a user