Chrome Extension Helpers

Jonathan Raphaelson
2016-04-29T16:39:29Z

1.dispatch.md

dispatch helpers

createMessageDispatcher creates a message listener which will call a method on the handler argument, based on the contents of the message that's passed from elsewhere. It does this by injecting the (potentially error causing) method into a promise chain, by sticking it inside a custom thenable, which gives us much nicer error handling.

example

const handler = {
  methodA() {
    console.log("called methodA", arguments);
    return 42;
  }
}

createMessageDispatcher("handlerid", handler);

elsewhere...

dispatchExtMessage("handlerid", "methodA", 1, 2, 3).then((resp) => console.log(resp))

// in THIS context
//# { state: "resolved", value: 42 }

// in the OTHER context
//# called method A [1, 2, 3]

2.dispatch.js

| export function createMessageDispatcher(identity, handler) {
| chrome.runtime.onMessage.addListener((msg, sender, respond) => {
| if (!Array.isArray(msg)) { return; }
| if (msg[0] === identity) {
| var method = msg[1];
| var args = msg.slice(2);
| var thunk = (res) => res(handler[method].apply(handler, args));
|
| // call the method, but do it via a thunk that's injected into a promise chain
| // that way, all errors are handled the same way, and we can use the normal response methods
| // this includes non-existant methods, bad arguments, etc.
| Promise.resolve({ then: thunk })
| .then((value) => ({ state: "resolved", value }))
| .catch((error) => ({ state: "rejected", error }))
| .then(respond);
|
| return true;
| }
| });
| }
|
| export function dispatchTabMessage(to, method, ...args) {
| return new Promise((resolve, reject) => {
| chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
| chrome.tabs.sendMessage(tabs[0].id, [to, method, ...args], (response) => {
| if (response === undefined) { return reject(chrome.runtime.lastError); }
| if (response.state === "rejected") { return reject(response.error); }
| if (response.state === "resolved") { return resolve(response.value); }
|
| console.log("Weird message response:", response);
| return reject("Unknown response object.");
| });
| });
| });
| }
|
| export function dispatchExtMessage(to, method, ...args) {
| return new Promise((resolve, reject) => {
| chrome.runtime.sendMessage([to, method, ...args], (response) => {
| if (response === undefined) { return reject(chrome.runtime.lastError); }
| if (response.state === "rejected") { return reject(response.error); }
| if (response.state === "resolved") { return resolve(response.value); }
|
| console.log("Weird message response:", response);
| return reject("Unknown response object.");
| });
| });
| }