aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlessio Vanni <vannilla@firemail.cc>2019-06-23 02:43:40 +0200
committerAlessio Vanni <vannilla@firemail.cc>2019-06-23 02:43:40 +0200
commit6458ec333511fe07101dd3afffbefed7b4fead07 (patch)
tree2c769d4fbc8ff3da5ad55700a9e08604a81f3cf0
parentd9858f22244f58eb2a305aa2e42439c77acdb861 (diff)
downloadematrix-6458ec333511fe07101dd3afffbefed7b4fead07.tar.lz
ematrix-6458ec333511fe07101dd3afffbefed7b4fead07.tar.xz
ematrix-6458ec333511fe07101dd3afffbefed7b4fead07.zip
Make CallbackWrapper a module
In theory this way it can be used anywhere else if needed, but right now it's simply because it has to be placed somewhere and a module seems the best place for an object definition (constructor, etc.)
-rw-r--r--CallbackWrapper.jsm90
-rw-r--r--Makefile2
-rw-r--r--js/vapi-background.js66
-rw-r--r--js/vapi-messaging.js2
4 files changed, 93 insertions, 67 deletions
diff --git a/CallbackWrapper.jsm b/CallbackWrapper.jsm
new file mode 100644
index 0000000..71237c4
--- /dev/null
+++ b/CallbackWrapper.jsm
@@ -0,0 +1,90 @@
+/*******************************************************************************
+
+ ηMatrix - a browser extension to black/white list requests.
+ Copyright (C) 2014-2019 The uMatrix/uBlock Origin authors
+ Copyright (C) 2019 Alessio Vanni
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see {http://www.gnu.org/licenses/}.
+
+ Home: https://gitlab.com/vannilla/ematrix
+ uMatrix Home: https://github.com/gorhill/uMatrix
+*/
+
+var EXPORTED_SYMBOLS = ['CallbackWrapper'];
+
+var junkyard = [];
+
+var CallbackWrapper = function (messageManager, channelName,
+ listenerId, requestId) {
+ // This allows to avoid creating a closure for every single
+ // message which expects an answer. Having a closure created
+ // each time a message is processed has been always bothering
+ // me. Another benefit of the implementation here is to reuse
+ // the callback proxy object, so less memory churning.
+ //
+ // https://developers.google.com/speed/articles/optimizing-javascript
+ // "Creating a closure is significantly slower then creating
+ // an inner function without a closure, and much slower than
+ // reusing a static function"
+ //
+ // http://hacksoflife.blogspot.ca/2015/01/the-four-horsemen-of-performance.html
+ // "the dreaded 'uniformly slow code' case where every
+ // function takes 1% of CPU and you have to make one hundred
+ // separate performance optimizations to improve performance
+ // at all"
+ //
+ // http://jsperf.com/closure-no-closure/2
+ this.callback = this.proxy.bind(this); // bind once
+ this.init(messageManager, channelName, listenerId, requestId);
+};
+
+CallbackWrapper.factory = function (messageManager, channelName,
+ listenerId, requestId) {
+ let wrapper = junkyard.pop();
+ if (wrapper) {
+ wrapper.init(messageManager, channelName, listenerId, requestId);
+ return wrapper;
+ }
+
+ return new CallbackWrapper(messageManager, channelName,
+ listenerId, requestId);
+};
+
+CallbackWrapper.prototype.init = function (messageManager, channelName,
+ listenerId, requestId) {
+ this.messageManager = messageManager;
+ this.channelName = channelName;
+ this.listenerId = listenerId;
+ this.requestId = requestId;
+};
+
+CallbackWrapper.prototype.proxy = function (response) {
+ let message = JSON.stringify({
+ requestId: this.requestId,
+ channelName: this.channelName,
+ msg: response !== undefined ? response : null
+ });
+
+ if (this.messageManager.sendAsyncMessage) {
+ this.messageManager.sendAsyncMessage(this.listenerId, message);
+ } else {
+ this.messageManager.broadcastAsyncMessage(this.listenerId, message);
+ }
+
+ // Mark for reuse
+ this.messageManager = this.channelName =
+ this.requestId = this.listenerId = null;
+
+ junkyard.push(this);
+};
diff --git a/Makefile b/Makefile
index 754f0b3..87c1320 100644
--- a/Makefile
+++ b/Makefile
@@ -119,7 +119,7 @@ JS2 := js/httpsb.js js/i18n.js js/liquid-dict.js js/logger.js \
# vapi-popup.js is apparently not needed on UXP
# TODO: investigate wether or not it can be removed
JS3 := js/tab.js js/traffic.js js/udom.js js/uritools.js js/user-rules.js \
- js/usersettings.js js/utils.js js/xal.js
+ js/usersettings.js js/utils.js js/xal.js CallbackWrapper.jsm
JS4 := js/vapi-client.js js/vapi-common.js js/vapi-background.js \
js/vapi-popup.js js/vapi-tabs.js js/vapi-window.js \
diff --git a/js/vapi-background.js b/js/vapi-background.js
index 6c874f3..0da0638 100644
--- a/js/vapi-background.js
+++ b/js/vapi-background.js
@@ -69,72 +69,6 @@
}
};
- let CallbackWrapper = function (messageManager, channelName,
- listenerId, requestId) {
- // This allows to avoid creating a closure for every single
- // message which expects an answer. Having a closure created
- // each time a message is processed has been always bothering
- // me. Another benefit of the implementation here is to reuse
- // the callback proxy object, so less memory churning.
- //
- // https://developers.google.com/speed/articles/optimizing-javascript
- // "Creating a closure is significantly slower then creating
- // an inner function without a closure, and much slower than
- // reusing a static function"
- //
- // http://hacksoflife.blogspot.ca/2015/01/the-four-horsemen-of-performance.html
- // "the dreaded 'uniformly slow code' case where every
- // function takes 1% of CPU and you have to make one hundred
- // separate performance optimizations to improve performance
- // at all"
- //
- // http://jsperf.com/closure-no-closure/2
- this.callback = this.proxy.bind(this); // bind once
- this.init(messageManager, channelName, listenerId, requestId);
- };
-
- CallbackWrapper.junkyard = [];
-
- CallbackWrapper.factory = function (messageManager, channelName,
- listenerId, requestId) {
- let wrapper = CallbackWrapper.junkyard.pop();
- if (wrapper) {
- wrapper.init(messageManager, channelName, listenerId, requestId);
- return wrapper;
- }
-
- return new CallbackWrapper(messageManager, channelName,
- listenerId, requestId);
- };
-
- CallbackWrapper.prototype.init = function (messageManager, channelName,
- listenerId, requestId) {
- this.messageManager = messageManager;
- this.channelName = channelName;
- this.listenerId = listenerId;
- this.requestId = requestId;
- };
-
- CallbackWrapper.prototype.proxy = function (response) {
- let message = JSON.stringify({
- requestId: this.requestId,
- channelName: this.channelName,
- msg: response !== undefined ? response : null
- });
-
- if (this.messageManager.sendAsyncMessage) {
- this.messageManager.sendAsyncMessage(this.listenerId, message);
- } else {
- this.messageManager.broadcastAsyncMessage(this.listenerId, message);
- }
-
- // Mark for reuse
- this.messageManager = this.channelName =
- this.requestId = this.listenerId = null;
-
- CallbackWrapper.junkyard.push(this);
- };
-
let httpRequestHeadersFactory = function (channel) {
let entry = httpRequestHeadersFactory.junkyard.pop();
if (entry) {
diff --git a/js/vapi-messaging.js b/js/vapi-messaging.js
index abed913..b00c054 100644
--- a/js/vapi-messaging.js
+++ b/js/vapi-messaging.js
@@ -32,6 +32,8 @@
(function () {
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const {Services} = Cu.import('resource://gre/modules/Services.jsm', null);
+ const {CallbackWrapper} =
+ Cu.import('chrome://ematrix/content/CallbackWrapper.jsm', null);
let vAPI = self.vAPI; // Guaranteed to be initialized by vapi-background.js