K41F4r
K41F4r

Reputation: 1551

Chrome Extension - Receiving requests in the content script

Is there a better way to pass commands between the content script and the popup/background? Right now I'm doing something like this (and it's not maintainable or robust....)

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request) {
      switch (request.command) {
        case "command1":
            //do stuff
            break;
        case "command2":
            //do stuff
            break;

This is in the content script

Upvotes: 1

Views: 802

Answers (1)

woxxom
woxxom

Reputation: 73586

content.js

const API = new Proxy({}, {
  get(target, command) {
    return data => browser.runtime.sendMessage({command, data});
  },
});

Using with a Promise:

API.foo(123).then(console.log);

Using with async/await:

async function doSomething() {
  const result = await API.bar(456);
  console.log(result);
}

background.js

class Commands extends null {
  static foo(data, sender) {
    return data * 2;
  }
  async static bar(data, sender) {
    return (await fetch('https://example.org/json')).json();
  }
}

browser.runtime.onMessage.addListener(async ({command, data}, sender) => {
  const handler = Commands.hasOwnProperty(command) && Commands[command];
  return typeof handler === 'function'
         ? handler(data, sender)
         : Promise.reject();
});

That was a simplified barebones example without error handling. The same may be applied to extension->content route and you can put this into a separate js that's loaded both in the content script and an extension page. There could be existing js libraries that implement this approach.

Upvotes: 1

Related Questions