update readme
[dotfiles/.git] / .config / BraveSoftware / Brave-Browser / Default / Extensions / cimiefiiaegbelhefglklhhakcgmhkai / 1.7.6_0 / extension-utils.js
1 /*
2     Copyright (C) 2017 Kai Uwe Broulik <kde@privat.broulik.de>
3
4     This program is free software; you can redistribute it and/or
5     modify it under the terms of the GNU General Public License as
6     published by the Free Software Foundation; either version 3 of
7     the License, or (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 var port;
19
20 var callbacks = {}; // TODO rename to "portCallbacks"?
21 var runtimeCallbacks = {};
22
23 let currentMessageSerial = 0;
24 let pendingMessageReplyResolvers = {};
25
26 // Callback is called with following arguments (in that order);
27 // - The actual message data/payload
28 // - The name of the action triggered
29 function addCallback(subsystem, action, callback) // TODO rename to "addPortCallbacks"?
30 {
31     if (Array.isArray(action)) {
32         action.forEach(function(item) {
33             addCallback(subsystem, item, callback);
34         });
35         return;
36     }
37
38     if (!callbacks[subsystem]) {
39         callbacks[subsystem] = {};
40     }
41     callbacks[subsystem][action] = callback;
42 }
43
44 function sendPortMessage(subsystem, event, payload)
45 {
46     // why do we put stuff on root level here but otherwise have a "payload"? :(
47     var message = payload || {}
48     message.subsystem = subsystem;
49     message.event = event;
50
51     port.postMessage(message);
52 }
53
54 function sendPortMessageWithReply(subsystem, event, payload)
55 {
56     return new Promise((resolve, reject) => {
57         let message = payload || {};
58         message.subsystem = subsystem;
59         message.event = event;
60         ++currentMessageSerial;
61         if (currentMessageSerial >= Math.pow(2, 31) - 1) { // INT_MAX
62             currentMessageSerial = 0;
63         }
64         message.serial = currentMessageSerial;
65
66         port.postMessage(message);
67
68         pendingMessageReplyResolvers[message.serial] = resolve;
69     });
70 }
71
72 // Callback is called with following arguments (in that order);
73 // - The actual message data/payload
74 // - Information about the sender of the message (including tab and frameId)
75 // - The name of the action triggered
76 // Return a Promise from the callback if you wish to send a reply to the sender
77 function addRuntimeCallback(subsystem, action, callback)
78 {
79     if (action.constructor === Array) {
80         action.forEach(function(item) {
81             addRuntimeCallback(subsystem, item, callback);
82         });
83         return;
84     }
85
86     if (!runtimeCallbacks[subsystem]) {
87         runtimeCallbacks[subsystem] = {};
88     }
89     runtimeCallbacks[subsystem][action] = callback;
90 }
91
92 // returns an Object which only contains values for keys in allowedKeys
93 function filterObject(obj, allowedKeys) {
94     var newObj = {}
95
96     // I bet this can be done in a more efficient way
97     for (key in obj) {
98         if (obj.hasOwnProperty(key) && allowedKeys.indexOf(key) > -1) {
99             newObj[key] = obj[key];
100         }
101     }
102
103     return newObj;
104 }
105
106 // filters objects within an array so they only contain values for keys in allowedKeys
107 function filterArrayObjects(arr, allowedKeys) {
108     return arr.map(function (item) {
109         return filterObject(item, allowedKeys);
110     });
111 }
112
113 chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
114     // TODO check sender for privilege
115
116     var subsystem = message.subsystem;
117     var action = message.action;
118
119     if (!subsystem || !action) {
120         return false;
121     }
122
123     if (runtimeCallbacks[subsystem] && runtimeCallbacks[subsystem][action]) {
124         let result = runtimeCallbacks[subsystem][action](message.payload, sender, action);
125
126         // Not a promise
127         if (typeof result !== "object" || typeof result.then !== "function") {
128             return false;
129         }
130
131         result.then((response) => {
132             sendResponse(response);
133         }, (err) => {
134             sendResponse({
135                 rejected: true,
136                 message: err
137             });
138         });
139
140         return true;
141     }
142
143     console.warn("Don't know what to do with runtime message", subsystem, action);
144     return false;
145 });