webextension-messages 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/README.md +89 -0
- package/dist/webextension-messages.js +77 -112
- package/package.json +7 -4
- package/src/index.js +18 -14
- package/webpack.config.js +3 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2026 Morozov Igor (ismorozs)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Webextension Messages
|
|
2
|
+
Easily and neatly describe all communication instances between the background process and tabs in one place. Wait for the result from the message sent in the same instruction flow.
|
|
3
|
+
|
|
4
|
+
## How to install and prepare
|
|
5
|
+
Install the library through
|
|
6
|
+
```sh
|
|
7
|
+
npm install webextension-messages
|
|
8
|
+
```
|
|
9
|
+
then import with
|
|
10
|
+
```js
|
|
11
|
+
import WebextensionMessages from 'webextension-messages'
|
|
12
|
+
```
|
|
13
|
+
in your script file.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
Library has only one method ```setup```, which creates all message-sending functions and sets up listeners.
|
|
17
|
+
With such a signature:
|
|
18
|
+
```js
|
|
19
|
+
WebextensionMessages.setup (
|
|
20
|
+
MessageHandlersMap {
|
|
21
|
+
MessageSenderFunctionName1: MessageHandler1 (...MessageParameters1) => ResultToSendBack1
|
|
22
|
+
MessageSenderFunctionName2: MessageHandler2 (...MessageParameters2) => ResultToSendBack2
|
|
23
|
+
MessageSenderFunctionName3: MessageHandler3 (...MessageParameters3) => ResultToSendBack3
|
|
24
|
+
...
|
|
25
|
+
},
|
|
26
|
+
CommunicationId
|
|
27
|
+
) =>
|
|
28
|
+
MessageSendersMap {
|
|
29
|
+
MessageSenderFunctionName1: (...MessageParameters1) => PromiseWithResult1
|
|
30
|
+
MessageSenderFunctionName2: (...MessageParameters2) => PromiseWithResult2
|
|
31
|
+
MessageSenderFunctionName3: (...MessageParameters3) => PromiseWithResult3
|
|
32
|
+
...
|
|
33
|
+
stopCommunication ()
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
Where:
|
|
37
|
+
```MessageHandlersMap``` - map linking sender and handler function on the receiving end
|
|
38
|
+
```MessageSendersMap``` - map of sender functions
|
|
39
|
+
|
|
40
|
+
```MessageSenderFunctionName``` - name of the function that will send the message
|
|
41
|
+
```MessageHandler``` - function that will handle the message on the receiving end
|
|
42
|
+
```MessageParameters``` - payload to the sender function and parameters for the handler function
|
|
43
|
+
```ResultToSendBack``` - return value of the handler function that will be sent back to the sender
|
|
44
|
+
```PromiseWithResult``` - return value of the sender function, a promise that will be resolved to ```ResultToSendBack``` from the receiver
|
|
45
|
+
|
|
46
|
+
```CommunicationId``` (optional) - string identifying the declared communication, used only for removing listeners
|
|
47
|
+
```stopCommunication ()``` - special predefined method for stopping messaging and removing listeners, works only if ```CommunicationId``` is given
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
**Important: the exact same ```setup``` method with the exact same arguments must run on both sides to ensure their proper communication!**
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
Basic usage:
|
|
56
|
+
```js
|
|
57
|
+
// shared.js =>
|
|
58
|
+
// code that must be shared between the background and page scripts
|
|
59
|
+
import WebextensionMessages from 'webextension-messages'
|
|
60
|
+
const { sum } = WebextensionMessages.setup({
|
|
61
|
+
sum: (x, y) => x + y,
|
|
62
|
+
})
|
|
63
|
+
export { sum };
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
// background-script.js =>
|
|
67
|
+
// if there's no sender functions for one of the ends, just import the file to set up listeners
|
|
68
|
+
import from "./shared.js"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
// content-script.js =>
|
|
72
|
+
import { sum } from "./shared.js"; // import sender function
|
|
73
|
+
const result = await sum(1, 2); // send a message to the background and wait for the response
|
|
74
|
+
console.log(result);
|
|
75
|
+
// 3
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Stop messaging and remove listeners:
|
|
79
|
+
```js
|
|
80
|
+
// setting up communication
|
|
81
|
+
cosnt { stopCommunication } = WebextensionMessages.setup({
|
|
82
|
+
sum: (x, y) => x + y,
|
|
83
|
+
}, "Math correspondence");
|
|
84
|
+
// give the communication an identifier for both sides to know what set of functions is under discussion
|
|
85
|
+
|
|
86
|
+
// stopping it somewhere lower in the code
|
|
87
|
+
stopCommunication();
|
|
88
|
+
// no more listening for sum() message
|
|
89
|
+
```
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
|
+
if(typeof exports === 'object' && typeof module === 'object')
|
|
3
|
+
module.exports = factory();
|
|
4
|
+
else if(typeof define === 'function' && define.amd)
|
|
5
|
+
define([], factory);
|
|
6
|
+
else if(typeof exports === 'object')
|
|
7
|
+
exports["WMessages"] = factory();
|
|
8
|
+
else
|
|
9
|
+
root["WMessages"] = factory();
|
|
10
|
+
})(this, () => {
|
|
11
|
+
return /******/ (() => { // webpackBootstrap
|
|
2
12
|
/******/ var __webpack_modules__ = ({
|
|
3
13
|
|
|
4
14
|
/***/ "./node_modules/webextension-polyfill/dist/browser-polyfill.js"
|
|
@@ -1230,118 +1240,27 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
|
1230
1240
|
//# sourceMappingURL=browser-polyfill.js.map
|
|
1231
1241
|
|
|
1232
1242
|
|
|
1233
|
-
/***/ }
|
|
1243
|
+
/***/ },
|
|
1234
1244
|
|
|
1235
|
-
|
|
1236
|
-
/************************************************************************/
|
|
1237
|
-
/******/ // The module cache
|
|
1238
|
-
/******/ const __webpack_module_cache__ = {};
|
|
1239
|
-
/******/
|
|
1240
|
-
/******/ // The require function
|
|
1241
|
-
/******/ function __webpack_require__(moduleId) {
|
|
1242
|
-
/******/ // Check if module is in cache
|
|
1243
|
-
/******/ const cachedModule = __webpack_module_cache__[moduleId];
|
|
1244
|
-
/******/ if (cachedModule !== undefined) {
|
|
1245
|
-
/******/ return cachedModule.exports;
|
|
1246
|
-
/******/ }
|
|
1247
|
-
/******/ // Create a new module (and put it into the cache)
|
|
1248
|
-
/******/ const module = __webpack_module_cache__[moduleId] = {
|
|
1249
|
-
/******/ // no module.id needed
|
|
1250
|
-
/******/ // no module.loaded needed
|
|
1251
|
-
/******/ exports: {}
|
|
1252
|
-
/******/ };
|
|
1253
|
-
/******/
|
|
1254
|
-
/******/ // Execute the module function
|
|
1255
|
-
/******/ if (!(moduleId in __webpack_modules__)) {
|
|
1256
|
-
/******/ delete __webpack_module_cache__[moduleId];
|
|
1257
|
-
/******/ const e = new Error("Cannot find module '" + moduleId + "'");
|
|
1258
|
-
/******/ e.code = 'MODULE_NOT_FOUND';
|
|
1259
|
-
/******/ throw e;
|
|
1260
|
-
/******/ }
|
|
1261
|
-
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
1262
|
-
/******/
|
|
1263
|
-
/******/ // Return the exports of the module
|
|
1264
|
-
/******/ return module.exports;
|
|
1265
|
-
/******/ }
|
|
1266
|
-
/******/
|
|
1267
|
-
/************************************************************************/
|
|
1268
|
-
/******/ /* webpack/runtime/define property getters */
|
|
1269
|
-
/******/ (() => {
|
|
1270
|
-
/******/ // define getter/value functions for harmony exports
|
|
1271
|
-
/******/ __webpack_require__.d = (exports, definition) => {
|
|
1272
|
-
/******/ if(Array.isArray(definition)) {
|
|
1273
|
-
/******/ var i = 0;
|
|
1274
|
-
/******/ while(i < definition.length) {
|
|
1275
|
-
/******/ var key = definition[i++];
|
|
1276
|
-
/******/ var binding = definition[i++];
|
|
1277
|
-
/******/ if(!__webpack_require__.o(exports, key)) {
|
|
1278
|
-
/******/ if(binding === 0) {
|
|
1279
|
-
/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
|
|
1280
|
-
/******/ } else {
|
|
1281
|
-
/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
|
|
1282
|
-
/******/ }
|
|
1283
|
-
/******/ } else if(binding === 0) { i++; }
|
|
1284
|
-
/******/ }
|
|
1285
|
-
/******/ } else {
|
|
1286
|
-
/******/ for(var key in definition) {
|
|
1287
|
-
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
1288
|
-
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
1289
|
-
/******/ }
|
|
1290
|
-
/******/ }
|
|
1291
|
-
/******/ }
|
|
1292
|
-
/******/ };
|
|
1293
|
-
/******/ })();
|
|
1294
|
-
/******/
|
|
1295
|
-
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
1296
|
-
/******/ (() => {
|
|
1297
|
-
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
1298
|
-
/******/ })();
|
|
1299
|
-
/******/
|
|
1300
|
-
/******/ /* webpack/runtime/make namespace object */
|
|
1301
|
-
/******/ (() => {
|
|
1302
|
-
/******/ // define __esModule on exports
|
|
1303
|
-
/******/ __webpack_require__.r = (exports) => {
|
|
1304
|
-
/******/ if(Symbol.toStringTag) {
|
|
1305
|
-
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
1306
|
-
/******/ }
|
|
1307
|
-
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
1308
|
-
/******/ };
|
|
1309
|
-
/******/ })();
|
|
1310
|
-
/******/
|
|
1311
|
-
/******/ /* webpack/runtime/set anonymous default export name */
|
|
1312
|
-
/******/ (() => {
|
|
1313
|
-
/******/ // set .name for anonymous default exports per ES spec
|
|
1314
|
-
/******/ __webpack_require__.dn = (x) => {
|
|
1315
|
-
/******/ (Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true });
|
|
1316
|
-
/******/ };
|
|
1317
|
-
/******/ })();
|
|
1318
|
-
/******/
|
|
1319
|
-
/************************************************************************/
|
|
1320
|
-
let __webpack_exports__ = {};
|
|
1321
|
-
// This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
|
|
1322
|
-
(() => {
|
|
1323
|
-
"use strict";
|
|
1245
|
+
/***/ "./src/index.js"
|
|
1324
1246
|
/*!**********************!*\
|
|
1325
1247
|
!*** ./src/index.js ***!
|
|
1326
1248
|
\**********************/
|
|
1327
|
-
__webpack_require__
|
|
1328
|
-
|
|
1329
|
-
/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)
|
|
1330
|
-
/* harmony export */ });
|
|
1331
|
-
__webpack_require__.dn(__WEBPACK_DEFAULT_EXPORT__);
|
|
1249
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
1250
|
+
|
|
1332
1251
|
const browser = __webpack_require__(/*! webextension-polyfill */ "./node_modules/webextension-polyfill/dist/browser-polyfill.js");
|
|
1333
1252
|
|
|
1334
|
-
const
|
|
1253
|
+
const STOP_ACTION = `WEBEXTENSION_MESSAGES_STOP_COMMUNICATION`;
|
|
1335
1254
|
const RESULT_PROMISES = {};
|
|
1336
1255
|
const ACTIONS = {};
|
|
1337
1256
|
|
|
1338
1257
|
browser.runtime.onMessage.addListener((message) => {
|
|
1339
|
-
if (message.action ===
|
|
1340
|
-
|
|
1258
|
+
if (message.action === STOP_ACTION) {
|
|
1259
|
+
stopCommunication(message.payload);
|
|
1341
1260
|
}
|
|
1342
1261
|
});
|
|
1343
1262
|
|
|
1344
|
-
|
|
1263
|
+
function setupCommunication (actions, messagesId = generateId()) {
|
|
1345
1264
|
const messages = Object.fromEntries(
|
|
1346
1265
|
Object.entries(actions).map(([action]) => [
|
|
1347
1266
|
action,
|
|
@@ -1355,11 +1274,11 @@ browser.runtime.onMessage.addListener((message) => {
|
|
|
1355
1274
|
|
|
1356
1275
|
return {
|
|
1357
1276
|
...messages,
|
|
1358
|
-
|
|
1277
|
+
stopCommunication: () => stopCommunication(messagesId, true),
|
|
1359
1278
|
};
|
|
1360
1279
|
}
|
|
1361
1280
|
|
|
1362
|
-
async function onMessage(message, actions = {}) {
|
|
1281
|
+
async function onMessage (message, actions = {}) {
|
|
1363
1282
|
if (RESULT_PROMISES[message.resultId]) {
|
|
1364
1283
|
RESULT_PROMISES[message.resultId](message.payload);
|
|
1365
1284
|
delete RESULT_PROMISES[message.resultId];
|
|
@@ -1372,13 +1291,13 @@ async function onMessage(message, actions = {}) {
|
|
|
1372
1291
|
}
|
|
1373
1292
|
}
|
|
1374
1293
|
|
|
1375
|
-
function sendMessageForResult(action, payload) {
|
|
1294
|
+
function sendMessageForResult (action, payload) {
|
|
1376
1295
|
const { resultId, promise } = createResultPromise();
|
|
1377
1296
|
sendMessage(action, payload, resultId);
|
|
1378
1297
|
return promise;
|
|
1379
1298
|
}
|
|
1380
1299
|
|
|
1381
|
-
function sendMessage(action, payload, resultId) {
|
|
1300
|
+
function sendMessage (action, payload, resultId) {
|
|
1382
1301
|
const message = { action, payload, resultId };
|
|
1383
1302
|
|
|
1384
1303
|
if (isBackgroundScript()) {
|
|
@@ -1388,7 +1307,7 @@ function sendMessage(action, payload, resultId) {
|
|
|
1388
1307
|
}
|
|
1389
1308
|
}
|
|
1390
1309
|
|
|
1391
|
-
function createResultPromise() {
|
|
1310
|
+
function createResultPromise () {
|
|
1392
1311
|
const resultId = generateId();
|
|
1393
1312
|
|
|
1394
1313
|
return {
|
|
@@ -1397,31 +1316,77 @@ function createResultPromise() {
|
|
|
1397
1316
|
};
|
|
1398
1317
|
}
|
|
1399
1318
|
|
|
1400
|
-
function isBackgroundScript() {
|
|
1319
|
+
function isBackgroundScript () {
|
|
1401
1320
|
return (
|
|
1402
1321
|
window.location.protocol === "chrome-extension:" ||
|
|
1403
1322
|
window.location.protocol === "moz-extension:"
|
|
1404
1323
|
);
|
|
1405
1324
|
}
|
|
1406
1325
|
|
|
1407
|
-
function generateId() {
|
|
1326
|
+
function generateId () {
|
|
1408
1327
|
return `${Date.now()}-${Math.random()}`;
|
|
1409
1328
|
}
|
|
1410
1329
|
|
|
1411
|
-
function getCurrentTab() {
|
|
1330
|
+
function getCurrentTab () {
|
|
1412
1331
|
return browser.tabs.query({ active: true, currentWindow: true });
|
|
1413
1332
|
}
|
|
1414
1333
|
|
|
1415
|
-
function
|
|
1334
|
+
function stopCommunication (messagesId, sendToReceiver) {
|
|
1416
1335
|
browser.runtime.onMessage.removeListener(ACTIONS[messagesId]);
|
|
1417
1336
|
delete ACTIONS[messagesId];
|
|
1418
1337
|
|
|
1419
1338
|
if (sendToReceiver) {
|
|
1420
|
-
sendMessage(
|
|
1339
|
+
sendMessage(STOP_ACTION, messagesId);
|
|
1421
1340
|
}
|
|
1422
1341
|
}
|
|
1342
|
+
|
|
1343
|
+
module.exports = {
|
|
1344
|
+
setup: setupCommunication,
|
|
1345
|
+
};
|
|
1423
1346
|
|
|
1424
|
-
})();
|
|
1425
1347
|
|
|
1348
|
+
/***/ }
|
|
1349
|
+
|
|
1350
|
+
/******/ });
|
|
1351
|
+
/************************************************************************/
|
|
1352
|
+
/******/ // The module cache
|
|
1353
|
+
/******/ const __webpack_module_cache__ = {};
|
|
1354
|
+
/******/
|
|
1355
|
+
/******/ // The require function
|
|
1356
|
+
/******/ function __webpack_require__(moduleId) {
|
|
1357
|
+
/******/ // Check if module is in cache
|
|
1358
|
+
/******/ const cachedModule = __webpack_module_cache__[moduleId];
|
|
1359
|
+
/******/ if (cachedModule !== undefined) {
|
|
1360
|
+
/******/ return cachedModule.exports;
|
|
1361
|
+
/******/ }
|
|
1362
|
+
/******/ // Create a new module (and put it into the cache)
|
|
1363
|
+
/******/ const module = __webpack_module_cache__[moduleId] = {
|
|
1364
|
+
/******/ // no module.id needed
|
|
1365
|
+
/******/ // no module.loaded needed
|
|
1366
|
+
/******/ exports: {}
|
|
1367
|
+
/******/ };
|
|
1368
|
+
/******/
|
|
1369
|
+
/******/ // Execute the module function
|
|
1370
|
+
/******/ if (!(moduleId in __webpack_modules__)) {
|
|
1371
|
+
/******/ delete __webpack_module_cache__[moduleId];
|
|
1372
|
+
/******/ const e = new Error("Cannot find module '" + moduleId + "'");
|
|
1373
|
+
/******/ e.code = 'MODULE_NOT_FOUND';
|
|
1374
|
+
/******/ throw e;
|
|
1375
|
+
/******/ }
|
|
1376
|
+
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
1377
|
+
/******/
|
|
1378
|
+
/******/ // Return the exports of the module
|
|
1379
|
+
/******/ return module.exports;
|
|
1380
|
+
/******/ }
|
|
1381
|
+
/******/
|
|
1382
|
+
/************************************************************************/
|
|
1383
|
+
/******/
|
|
1384
|
+
/******/ // startup
|
|
1385
|
+
/******/ // Load entry module and return exports
|
|
1386
|
+
/******/ // This entry module is referenced by other modules so it can't be inlined
|
|
1387
|
+
/******/ let __webpack_exports__ = __webpack_require__("./src/index.js");
|
|
1388
|
+
/******/
|
|
1389
|
+
/******/ return __webpack_exports__;
|
|
1426
1390
|
/******/ })()
|
|
1427
|
-
;
|
|
1391
|
+
;
|
|
1392
|
+
});
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webextension-messages",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Package simplifying the exchange of messages between the background and tabs",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "Package simplifying the exchange of messages between the background process and tabs of the browser",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"author": "Igor Morozov",
|
|
6
|
+
"author": "Igor Morozov <ismorozs@gmail.com>",
|
|
7
7
|
"main": "./dist/webextension-messages.js",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"start": "webpack"
|
|
@@ -12,5 +12,8 @@
|
|
|
12
12
|
"webextension-polyfill": "0.12.0",
|
|
13
13
|
"webpack": "5.108.4",
|
|
14
14
|
"webpack-cli": "7.2.1"
|
|
15
|
-
}
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/ismorozs/webextension-messages",
|
|
17
|
+
"repository": "https://github.com/ismorozs/webextension-messages.git",
|
|
18
|
+
"bugs": "https://github.com/ismorozs/webextension-messages/issues"
|
|
16
19
|
}
|
package/src/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
const browser = require("webextension-polyfill");
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const STOP_ACTION = `WEBEXTENSION_MESSAGES_STOP_COMMUNICATION`;
|
|
4
4
|
const RESULT_PROMISES = {};
|
|
5
5
|
const ACTIONS = {};
|
|
6
6
|
|
|
7
7
|
browser.runtime.onMessage.addListener((message) => {
|
|
8
|
-
if (message.action ===
|
|
9
|
-
|
|
8
|
+
if (message.action === STOP_ACTION) {
|
|
9
|
+
stopCommunication(message.payload);
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
function setupCommunication (actions, messagesId = generateId()) {
|
|
14
14
|
const messages = Object.fromEntries(
|
|
15
15
|
Object.entries(actions).map(([action]) => [
|
|
16
16
|
action,
|
|
@@ -24,11 +24,11 @@ export default function (actions, messagesId = generateId()) {
|
|
|
24
24
|
|
|
25
25
|
return {
|
|
26
26
|
...messages,
|
|
27
|
-
|
|
27
|
+
stopCommunication: () => stopCommunication(messagesId, true),
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
async function onMessage(message, actions = {}) {
|
|
31
|
+
async function onMessage (message, actions = {}) {
|
|
32
32
|
if (RESULT_PROMISES[message.resultId]) {
|
|
33
33
|
RESULT_PROMISES[message.resultId](message.payload);
|
|
34
34
|
delete RESULT_PROMISES[message.resultId];
|
|
@@ -41,13 +41,13 @@ async function onMessage(message, actions = {}) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function sendMessageForResult(action, payload) {
|
|
44
|
+
function sendMessageForResult (action, payload) {
|
|
45
45
|
const { resultId, promise } = createResultPromise();
|
|
46
46
|
sendMessage(action, payload, resultId);
|
|
47
47
|
return promise;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
function sendMessage(action, payload, resultId) {
|
|
50
|
+
function sendMessage (action, payload, resultId) {
|
|
51
51
|
const message = { action, payload, resultId };
|
|
52
52
|
|
|
53
53
|
if (isBackgroundScript()) {
|
|
@@ -57,7 +57,7 @@ function sendMessage(action, payload, resultId) {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
function createResultPromise() {
|
|
60
|
+
function createResultPromise () {
|
|
61
61
|
const resultId = generateId();
|
|
62
62
|
|
|
63
63
|
return {
|
|
@@ -66,26 +66,30 @@ function createResultPromise() {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function isBackgroundScript() {
|
|
69
|
+
function isBackgroundScript () {
|
|
70
70
|
return (
|
|
71
71
|
window.location.protocol === "chrome-extension:" ||
|
|
72
72
|
window.location.protocol === "moz-extension:"
|
|
73
73
|
);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function generateId() {
|
|
76
|
+
function generateId () {
|
|
77
77
|
return `${Date.now()}-${Math.random()}`;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
function getCurrentTab() {
|
|
80
|
+
function getCurrentTab () {
|
|
81
81
|
return browser.tabs.query({ active: true, currentWindow: true });
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
function
|
|
84
|
+
function stopCommunication (messagesId, sendToReceiver) {
|
|
85
85
|
browser.runtime.onMessage.removeListener(ACTIONS[messagesId]);
|
|
86
86
|
delete ACTIONS[messagesId];
|
|
87
87
|
|
|
88
88
|
if (sendToReceiver) {
|
|
89
|
-
sendMessage(
|
|
89
|
+
sendMessage(STOP_ACTION, messagesId);
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
+
|
|
93
|
+
module.exports = {
|
|
94
|
+
setup: setupCommunication,
|
|
95
|
+
};
|