Index: ext/common.js |
=================================================================== |
--- a/ext/common.js |
+++ b/ext/common.js |
@@ -12,148 +12,76 @@ |
* 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; |
- } |
- }; |
+ var wrapperSymbol = Symbol("ext-wrapper"); |
- var getSender = global.ext._getSender = function(origin) |
+ function wrapFrames(frames) |
{ |
- if (origin instanceof Ci.nsIDOMXULElement) |
- return origin.messageManager; |
- else if (origin instanceof Ci.nsIMessageSender) |
- return origin; |
- else |
+ if (!frames.length) |
return null; |
- }; |
- var MessageProxy = global.ext._MessageProxy = function(messageManager, messageTarget) |
+ // 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) |
{ |
- 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) => |
+ { |
+ if (this._windowID && this._windowID != message.targetID) |
+ return undefined; |
+ |
+ return new Promise((resolve, reject) => |
+ { |
+ var sender = {}; |
+ if (message.senderID) |
+ { |
+ // We will only get here on the background side so we can access |
+ // the Page object. |
+ const Page = require("ext_background").Page; |
+ sender.page = new Page(message.senderID); |
+ } |
+ if (message.frames) |
+ sender.frame = wrapFrames(message.frames); |
+ if (!listener(message.payload, sender, resolve)) |
+ resolve(undefined); |
+ }); |
+ }; |
+ listener[wrapperSymbol] = wrapper; |
+ 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[wrapperSymbol]) |
+ this._port.off("ext_message", listener[wrapperSymbol]); |
} |
}; |
if (typeof exports == "object") |
exports = global.ext; |
})(this); |