message.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import browser from 'webextension-polyfill';
  2. import { objectHasKey } from './helper';
  3. const nameBuilder = (prefix, name) => (prefix ? `${prefix}--${name}` : name);
  4. const isFirefox = BROWSER_TYPE === 'firefox';
  5. /**
  6. *
  7. * @param {string=} name
  8. * @param {*=} data
  9. * @param {string=} prefix
  10. *
  11. * @returns {Promise<*>}
  12. */
  13. export function sendMessage(name = '', data = {}, prefix = '') {
  14. let payload = {
  15. name: nameBuilder(prefix, name),
  16. data,
  17. };
  18. if (isFirefox) {
  19. payload = JSON.stringify(payload);
  20. }
  21. return browser.runtime.sendMessage(payload);
  22. }
  23. export class MessageListener {
  24. static sendMessage = sendMessage;
  25. constructor(prefix = '') {
  26. this.listeners = {};
  27. this.prefix = prefix;
  28. this.listener = this.listener.bind(this);
  29. }
  30. on(name, listener) {
  31. if (objectHasKey(this.listeners, name)) {
  32. console.error(`You already added ${name}`);
  33. return this.on;
  34. }
  35. this.listeners[nameBuilder(this.prefix, name)] = listener;
  36. return this.on;
  37. }
  38. listener(message, sender) {
  39. try {
  40. if (isFirefox) message = JSON.parse(message);
  41. const listener = this.listeners[message.name];
  42. const response =
  43. listener && listener.call({ message, sender }, message.data, sender);
  44. if (!response) {
  45. return Promise.resolve();
  46. }
  47. if (!(response instanceof Promise)) {
  48. return Promise.resolve(response);
  49. }
  50. return response;
  51. } catch (err) {
  52. return Promise.reject(
  53. new Error(`Unhandled Background Error: ${String(err)}`)
  54. );
  55. }
  56. }
  57. /**
  58. *
  59. * @param {string} name
  60. * @param {*} data
  61. *
  62. * @returns {Promise<*>}
  63. */
  64. sendMessage(name, data) {
  65. return sendMessage(name, data, this.prefix);
  66. }
  67. }