| Index: ext/common.js | 
| =================================================================== | 
| --- a/ext/common.js | 
| +++ b/ext/common.js | 
| @@ -12,148 +12,72 @@ | 
| * GNU General Public License for more details. | 
| * | 
| * You should have received a copy of the GNU General Public License | 
| * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 
| */ | 
| (function(global) | 
| { | 
| - const Ci = Components.interfaces; | 
| - | 
| if (!global.ext) | 
| global.ext = {}; | 
| - var holder = { | 
| - get Page() | 
| - { | 
| - delete this.Page; | 
| - this.Page = (typeof require == "function" ? | 
| - require("ext_background").Page : | 
| - function() {}); | 
| - return this.Page; | 
| - } | 
| - }; | 
| + function wrapFrames(frames) | 
| + { | 
| + if (!frames.length) | 
| + return null; | 
| - var getSender = global.ext._getSender = function(origin) | 
| + // We have frames as an array, non-Firefox code expects url and parent | 
| + // properties however. | 
| + Object.defineProperty(frames, "url", { | 
| + enumerable: true, | 
| + get: () => new URL(frames[0].location) | 
| + }); | 
| + | 
| + Object.defineProperty(frames, "parent", { | 
| + enumerable: true, | 
| + get: () => wrapFrames(frames.slice(1)) | 
| + }); | 
| + | 
| + return frames; | 
| + } | 
| + | 
| + var EventTarget = global.ext._EventTarget = function(port, windowID) | 
| 
 
Thomas Greiner
2016/04/18 13:22:50
Detail: It looks a bit contradictory to export som
 
Wladimir Palant
2016/04/18 15:28:56
It's used internally by the ext layer, not meant f
 
 | 
| { | 
| - if (origin instanceof Ci.nsIDOMXULElement) | 
| - return origin.messageManager; | 
| - else if (origin instanceof Ci.nsIMessageSender) | 
| - return origin; | 
| - else | 
| - return null; | 
| - }; | 
| - | 
| - var MessageProxy = global.ext._MessageProxy = function(messageManager, messageTarget) | 
| - { | 
| - this._messageManager = messageManager; | 
| - this._messageTarget = messageTarget; | 
| - this._callbacks = new Map(); | 
| - this._responseCallbackCounter = 0; | 
| - | 
| - this._handleRequest = this._handleRequest.bind(this); | 
| - this._handleResponse = this._handleResponse.bind(this); | 
| - this._messageManager.addMessageListener("AdblockPlus:Message", this._handleRequest); | 
| - this._messageManager.addMessageListener("AdblockPlus:Response", this._handleResponse); | 
| - }; | 
| - MessageProxy.prototype = { | 
| - _disconnect: function() | 
| - { | 
| - this._messageManager.removeMessageListener("AdblockPlus:Message", this._handleRequest); | 
| - this._messageManager.removeMessageListener("AdblockPlus:Response", this._handleResponse); | 
| - }, | 
| - | 
| - _sendResponse: function(sender, callbackId, message) | 
| - { | 
| - var response = { | 
| - callbackId: callbackId | 
| - }; | 
| - if (typeof response != "undefined") | 
| - response.payload = message; | 
| - sender.sendAsyncMessage("AdblockPlus:Response", response); | 
| - }, | 
| - | 
| - _handleRequest: function(message) | 
| - { | 
| - var sender = getSender(message.target); | 
| - var request = message.data; | 
| - | 
| - var sent = false; | 
| - var sendResponse; | 
| - if (sender && "callbackId" in request) | 
| - { | 
| - sendResponse = function(message) | 
| - { | 
| - this._sendResponse(sender, request.callbackId, message); | 
| - sent = true; | 
| - }.bind(this); | 
| - } | 
| - else | 
| - sendResponse = function() {}; | 
| - | 
| - var results = this._messageTarget._dispatch(request.payload, { | 
| - page: new holder.Page(sender) | 
| - }, sendResponse); | 
| - if (!sent && results.indexOf(true) == -1) | 
| - sendResponse(undefined); | 
| - }, | 
| - | 
| - _handleResponse: function(message) | 
| - { | 
| - var response = message.data; | 
| - var callback = this._callbacks.get(response.callbackId); | 
| - if (callback) | 
| - { | 
| - this._callbacks.delete(response.callbackId); | 
| - if ("payload" in response) | 
| - callback(response.payload); | 
| - } | 
| - }, | 
| - | 
| - sendMessage: function(message, responseCallback) | 
| - { | 
| - if (!(this._messageManager instanceof Ci.nsIMessageSender)) | 
| - throw new Error("Not implemented"); | 
| - | 
| - var request = { | 
| - payload: message | 
| - }; | 
| - if (responseCallback) | 
| - { | 
| - request.callbackId = ++this._responseCallbackCounter; | 
| - this._callbacks.set(request.callbackId, responseCallback); | 
| - } | 
| - | 
| - this._messageManager.sendAsyncMessage("AdblockPlus:Message", request); | 
| - } | 
| - }; | 
| - | 
| - var EventTarget = global.ext._EventTarget = function() | 
| - { | 
| - this._listeners = []; | 
| + this._port = port; | 
| + this._windowID = windowID; | 
| }; | 
| EventTarget.prototype = { | 
| addListener: function(listener) | 
| { | 
| - if (this._listeners.indexOf(listener) == -1) | 
| - this._listeners.push(listener); | 
| + var wrapper = (message, sender) => | 
| 
 
Thomas Greiner
2016/04/18 13:22:50
Detail: I noticed that throughout this review you
 
Wladimir Palant
2016/04/18 15:28:56
The first-run page loads the files via usual <scri
 
Thomas Greiner
2016/04/18 17:47:14
Doesn't the same then also apply to `const`? (see
 
Wladimir Palant
2016/04/19 11:57:28
It doesn't, Firefox has been supporting const in "
 
 | 
| + { | 
| + if (this._windowID && this._windowID != message.targetID) | 
| + return undefined; | 
| + | 
| + return new Promise((resolve, reject) => | 
| + { | 
| + var sender = {}; | 
| + if (message.senderID) | 
| + { | 
| + const Page = require("ext_background").Page; | 
| 
 
Thomas Greiner
2016/04/18 13:22:50
Detail: I'm wondering why `Page` is in "ext_backgr
 
Wladimir Palant
2016/04/18 15:28:56
It's not shared functionality - pages only exist f
 
Thomas Greiner
2016/04/18 17:47:14
Ok, since this part of the code is only executed i
 
 | 
| + sender.page = new Page(message.senderID); | 
| + } | 
| + if (message.frames) | 
| + sender.frame = wrapFrames(message.frames); | 
| + if (!listener(message.payload, sender, resolve)) | 
| + resolve(undefined); | 
| + }); | 
| + }; | 
| + listener._ext_wrapper = wrapper; | 
| 
 
Thomas Greiner
2016/04/18 13:22:50
Detail: This property name is not in accordance to
 
Wladimir Palant
2016/04/18 15:28:56
Done.
 
 | 
| + this._port.on("ext_message", wrapper); | 
| }, | 
| + | 
| removeListener: function(listener) | 
| { | 
| - var idx = this._listeners.indexOf(listener); | 
| - if (idx != -1) | 
| - this._listeners.splice(idx, 1); | 
| - }, | 
| - _dispatch: function() | 
| - { | 
| - var results = []; | 
| - | 
| - for (var i = 0; i < this._listeners.length; i++) | 
| - results.push(this._listeners[i].apply(null, arguments)); | 
| - | 
| - return results; | 
| + if (listener._ext_wrapper) | 
| + this._port.off("ext_message", listener._ext_wrapper); | 
| } | 
| }; | 
| if (typeof exports == "object") | 
| exports = global.ext; | 
| })(this); |