Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: ext/common.js

Issue 29338928: Issue 3853 - Use new messaging API for the first-run page (Closed)
Patch Set: Addressed comments Created April 19, 2016, 11:56 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ext/background.js ('k') | ext/content.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 (function(global) 18 (function(global)
19 { 19 {
20 const Ci = Components.interfaces;
21
22 if (!global.ext) 20 if (!global.ext)
23 global.ext = {}; 21 global.ext = {};
24 22
25 var holder = { 23 var wrapperSymbol = Symbol("ext-wrapper");
26 get Page()
27 {
28 delete this.Page;
29 this.Page = (typeof require == "function" ?
30 require("ext_background").Page :
31 function() {});
32 return this.Page;
33 }
34 };
35 24
36 var getSender = global.ext._getSender = function(origin) 25 function wrapFrames(frames)
37 { 26 {
38 if (origin instanceof Ci.nsIDOMXULElement) 27 if (!frames.length)
39 return origin.messageManager;
40 else if (origin instanceof Ci.nsIMessageSender)
41 return origin;
42 else
43 return null; 28 return null;
44 };
45 29
46 var MessageProxy = global.ext._MessageProxy = function(messageManager, message Target) 30 // We have frames as an array, non-Firefox code expects url and parent
31 // properties however.
32 Object.defineProperty(frames, "url", {
33 enumerable: true,
34 get: () => new URL(frames[0].location)
35 });
36
37 Object.defineProperty(frames, "parent", {
38 enumerable: true,
39 get: () => wrapFrames(frames.slice(1))
40 });
41
42 return frames;
43 }
44
45 var EventTarget = global.ext._EventTarget = function(port, windowID)
47 { 46 {
48 this._messageManager = messageManager; 47 this._port = port;
49 this._messageTarget = messageTarget; 48 this._windowID = windowID;
50 this._callbacks = new Map();
51 this._responseCallbackCounter = 0;
52
53 this._handleRequest = this._handleRequest.bind(this);
54 this._handleResponse = this._handleResponse.bind(this);
55 this._messageManager.addMessageListener("AdblockPlus:Message", this._handleR equest);
56 this._messageManager.addMessageListener("AdblockPlus:Response", this._handle Response);
57 };
58 MessageProxy.prototype = {
59 _disconnect: function()
60 {
61 this._messageManager.removeMessageListener("AdblockPlus:Message", this._ha ndleRequest);
62 this._messageManager.removeMessageListener("AdblockPlus:Response", this._h andleResponse);
63 },
64
65 _sendResponse: function(sender, callbackId, message)
66 {
67 var response = {
68 callbackId: callbackId
69 };
70 if (typeof response != "undefined")
71 response.payload = message;
72 sender.sendAsyncMessage("AdblockPlus:Response", response);
73 },
74
75 _handleRequest: function(message)
76 {
77 var sender = getSender(message.target);
78 var request = message.data;
79
80 var sent = false;
81 var sendResponse;
82 if (sender && "callbackId" in request)
83 {
84 sendResponse = function(message)
85 {
86 this._sendResponse(sender, request.callbackId, message);
87 sent = true;
88 }.bind(this);
89 }
90 else
91 sendResponse = function() {};
92
93 var results = this._messageTarget._dispatch(request.payload, {
94 page: new holder.Page(sender)
95 }, sendResponse);
96 if (!sent && results.indexOf(true) == -1)
97 sendResponse(undefined);
98 },
99
100 _handleResponse: function(message)
101 {
102 var response = message.data;
103 var callback = this._callbacks.get(response.callbackId);
104 if (callback)
105 {
106 this._callbacks.delete(response.callbackId);
107 if ("payload" in response)
108 callback(response.payload);
109 }
110 },
111
112 sendMessage: function(message, responseCallback)
113 {
114 if (!(this._messageManager instanceof Ci.nsIMessageSender))
115 throw new Error("Not implemented");
116
117 var request = {
118 payload: message
119 };
120 if (responseCallback)
121 {
122 request.callbackId = ++this._responseCallbackCounter;
123 this._callbacks.set(request.callbackId, responseCallback);
124 }
125
126 this._messageManager.sendAsyncMessage("AdblockPlus:Message", request);
127 }
128 };
129
130 var EventTarget = global.ext._EventTarget = function()
131 {
132 this._listeners = [];
133 }; 49 };
134 EventTarget.prototype = { 50 EventTarget.prototype = {
135 addListener: function(listener) 51 addListener: function(listener)
136 { 52 {
137 if (this._listeners.indexOf(listener) == -1) 53 var wrapper = (message, sender) =>
138 this._listeners.push(listener); 54 {
55 if (this._windowID && this._windowID != message.targetID)
56 return undefined;
57
58 return new Promise((resolve, reject) =>
59 {
60 var sender = {};
61 if (message.senderID)
62 {
63 // We will only get here on the background side so we can access
64 // the Page object.
65 const Page = require("ext_background").Page;
66 sender.page = new Page(message.senderID);
67 }
68 if (message.frames)
69 sender.frame = wrapFrames(message.frames);
70 if (!listener(message.payload, sender, resolve))
71 resolve(undefined);
72 });
73 };
74 listener[wrapperSymbol] = wrapper;
75 this._port.on("ext_message", wrapper);
139 }, 76 },
77
140 removeListener: function(listener) 78 removeListener: function(listener)
141 { 79 {
142 var idx = this._listeners.indexOf(listener); 80 if (listener[wrapperSymbol])
143 if (idx != -1) 81 this._port.off("ext_message", listener[wrapperSymbol]);
144 this._listeners.splice(idx, 1);
145 },
146 _dispatch: function()
147 {
148 var results = [];
149
150 for (var i = 0; i < this._listeners.length; i++)
151 results.push(this._listeners[i].apply(null, arguments));
152
153 return results;
154 } 82 }
155 }; 83 };
156 84
157 if (typeof exports == "object") 85 if (typeof exports == "object")
158 exports = global.ext; 86 exports = global.ext;
159 })(this); 87 })(this);
OLDNEW
« no previous file with comments | « ext/background.js ('k') | ext/content.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld