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: Created March 22, 2016, 1:54 p.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 function wrapFrames(frames)
26 get Page() 24 {
27 { 25 if (!frames.length)
28 delete this.Page; 26 return null;
29 this.Page = (typeof require == "function" ?
30 require("ext_background").Page :
31 function() {});
32 return this.Page;
33 }
34 };
35 27
36 var getSender = global.ext._getSender = function(origin) 28 // We have frames as an array, non-Firefox code expects url and parent
29 // properties however.
30 Object.defineProperty(frames, "url", {
31 enumerable: true,
32 get: () => new URL(frames[0].location)
33 });
34
35 Object.defineProperty(frames, "parent", {
36 enumerable: true,
37 get: () => wrapFrames(frames.slice(1))
38 });
39
40 return frames;
41 }
42
43 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
37 { 44 {
38 if (origin instanceof Ci.nsIDOMXULElement) 45 this._port = port;
39 return origin.messageManager; 46 this._windowID = windowID;
40 else if (origin instanceof Ci.nsIMessageSender)
41 return origin;
42 else
43 return null;
44 };
45
46 var MessageProxy = global.ext._MessageProxy = function(messageManager, message Target)
47 {
48 this._messageManager = messageManager;
49 this._messageTarget = messageTarget;
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 }; 47 };
134 EventTarget.prototype = { 48 EventTarget.prototype = {
135 addListener: function(listener) 49 addListener: function(listener)
136 { 50 {
137 if (this._listeners.indexOf(listener) == -1) 51 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 "
138 this._listeners.push(listener); 52 {
53 if (this._windowID && this._windowID != message.targetID)
54 return undefined;
55
56 return new Promise((resolve, reject) =>
57 {
58 var sender = {};
59 if (message.senderID)
60 {
61 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
62 sender.page = new Page(message.senderID);
63 }
64 if (message.frames)
65 sender.frame = wrapFrames(message.frames);
66 if (!listener(message.payload, sender, resolve))
67 resolve(undefined);
68 });
69 };
70 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.
71 this._port.on("ext_message", wrapper);
139 }, 72 },
73
140 removeListener: function(listener) 74 removeListener: function(listener)
141 { 75 {
142 var idx = this._listeners.indexOf(listener); 76 if (listener._ext_wrapper)
143 if (idx != -1) 77 this._port.off("ext_message", listener._ext_wrapper);
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 } 78 }
155 }; 79 };
156 80
157 if (typeof exports == "object") 81 if (typeof exports == "object")
158 exports = global.ext; 82 exports = global.ext;
159 })(this); 83 })(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