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

Side by Side Diff: safari/content.js

Issue 5670052883857408: Fixed properties defined on prototype in Safari background page proxy (Closed)
Patch Set: Created Nov. 17, 2013, 5:16 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 | « no previous file | no next file » | 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 <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2013 Eyeo GmbH 3 * Copyright (C) 2006-2013 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
(...skipping 10 matching lines...) Expand all
21 21
22 22
23 /* Background page proxy */ 23 /* Background page proxy */
24 var proxy = { 24 var proxy = {
25 objects: [], 25 objects: [],
26 callbacks: [], 26 callbacks: [],
27 27
28 send: function(message) 28 send: function(message)
29 { 29 {
30 var evt = document.createEvent("Event"); 30 var evt = document.createEvent("Event");
31 evt.initEvent("beforeload"); 31 evt.initEvent("beforeload");
Wladimir Palant 2013/11/21 08:15:58 Can we reuse the same event instead of creating a
Sebastian Noack 2014/02/26 11:27:19 This was addressed by http://codereview.adblockplu
32 return safari.self.tab.canLoad(evt, {type: "proxy", payload: message}); 32 return safari.self.tab.canLoad(evt, {type: "proxy", payload: message});
33 }, 33 },
34 checkResult: function(result) 34 checkResult: function(result)
35 { 35 {
36 if (!result.succeed) 36 if (!result.succeed)
37 throw result.error; 37 throw result.error;
38 }, 38 },
39 deserializeResult: function(result) 39 deserializeResult: function(result)
40 { 40 {
41 this.checkResult(result); 41 this.checkResult(result);
42 return this.deserialize(result.result); 42 return this.deserialize(result.result);
43 }, 43 },
44 serialize: function(obj, memo) 44 serialize: function(obj, memo)
45 { 45 {
46 var objectId = this.objects.indexOf(obj); 46 var objectId = this.objects.indexOf(obj);
Wladimir Palant 2013/11/21 08:15:58 this.getObjectId() should be used here.
Sebastian Noack 2014/02/26 11:27:19 getObjectId() is gone now.
47 if (objectId != -1) 47 if (objectId != -1)
48 return {type: "hosted", objectId: objectId}; 48 return {type: "hosted", objectId: objectId};
49 49
50 if (typeof obj == "function") 50 if (typeof obj == "function")
51 { 51 {
52 var callbackId = this.callbacks.indexOf(obj); 52 var callbackId = this.callbacks.indexOf(obj);
Wladimir Palant 2013/11/21 08:15:58 As with objects, it is better to put the callback
Sebastian Noack 2013/11/21 21:17:08 But this would make the ID visible externally and
Wladimir Palant 2014/01/15 16:21:01 It's not like we are messing with some website her
Sebastian Noack 2014/02/26 11:27:19 Done.
53 53
54 if (callbackId == -1) 54 if (callbackId == -1)
55 { 55 {
56 callbackId = this.callbacks.push(obj) - 1; 56 callbackId = this.callbacks.push(obj) - 1;
57 57
58 safari.self.addEventListener("message", function(event) 58 safari.self.addEventListener("message", function(event)
59 { 59 {
60 if (event.name == "proxyCallback") 60 if (event.name == "proxyCallback")
61 if (event.message.callbackId == callbackId) 61 if (event.message.callbackId == callbackId)
Wladimir Palant 2013/11/21 08:15:58 You should use && here and put brackets around the
Sebastian Noack 2014/02/26 11:27:19 This was addressed by http://codereview.adblockplu
62 obj.apply( 62 obj.apply(
63 this.getObject(event.message.contextId), 63 this.getObject(event.message.contextId),
64 this.deserializeSequence(event.message.args) 64 this.deserializeSequence(event.message.args)
65 ); 65 );
66 }.bind(this)); 66 }.bind(this));
Wladimir Palant 2013/11/21 08:15:58 Why add a new listener for each single callback? T
Sebastian Noack 2014/02/26 11:27:19 This was addressed by http://codereview.adblockplu
67 } 67 }
68 68
69 return {type: "callback", callbackId: callbackId}; 69 return {type: "callback", callbackId: callbackId};
70 } 70 }
71 71
72 if (typeof obj == "object" && 72 if (typeof obj == "object" &&
73 obj != null && 73 obj != null &&
74 obj.constructor != Date && 74 obj.constructor != Date &&
75 obj.constructor != RegExp) 75 obj.constructor != RegExp)
76 { 76 {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 if (idx != -1) 136 if (idx != -1)
137 return memo.arrays[idx]; 137 return memo.arrays[idx];
138 138
139 var array = []; 139 var array = [];
140 memo.specs.push(spec); 140 memo.specs.push(spec);
141 memo.arrays.push(array); 141 memo.arrays.push(array);
142 142
143 return this.deserializeSequence(spec.items, array, memo); 143 return this.deserializeSequence(spec.items, array, memo);
144 } 144 }
145 }, 145 },
146 getObjectId: function(obj)
147 {
148 return this.objects.indexOf(obj);
Wladimir Palant 2013/11/21 08:15:58 Why iterate through the entire array when we can c
Sebastian Noack 2014/02/26 11:27:19 Done.
149 },
146 getProperty: function(objectId, property) 150 getProperty: function(objectId, property)
147 { 151 {
148 return this.deserializeResult( 152 return this.deserializeResult(
149 this.send( 153 this.send(
150 { 154 {
151 type: "getProperty", 155 type: "getProperty",
152 objectId: objectId, 156 objectId: objectId,
153 property: property 157 property: property
154 }) 158 })
155 ); 159 );
156 }, 160 },
157 createProperty: function(objectId, property, enumerable) 161 createProperty: function(property, enumerable)
158 { 162 {
163 var proxy = this;
159 return { 164 return {
160 get: function() 165 get: function()
161 { 166 {
162 return this.getProperty(objectId, property); 167 return proxy.getProperty(proxy.getObjectId(this), property);
163 }.bind(this), 168 },
164 set: function(value) 169 set: function(value)
165 { 170 {
166 this.checkResult( 171 proxy.checkResult(
167 this.send( 172 proxy.send(
168 { 173 {
169 type: "setProperty", 174 type: "setProperty",
170 objectId: objectId, 175 objectId: proxy.getObjectId(this),
171 property: property, 176 property: property,
172 value: this.serialize(value) 177 value: proxy.serialize(value)
173 }) 178 })
174 ); 179 );
175 }.bind(this), 180 },
176 enumerable: enumerable, 181 enumerable: enumerable,
177 configurable: true 182 configurable: true
178 }; 183 };
179 }, 184 },
180 createFunction: function(objectId) 185 createFunction: function(objectId)
181 { 186 {
182 var proxy = this; 187 var proxy = this;
183 return function() 188 return function()
184 { 189 {
185 return proxy.deserializeResult( 190 return proxy.deserializeResult(
186 proxy.send( 191 proxy.send(
187 { 192 {
188 type: "callFunction", 193 type: "callFunction",
189 functionId: objectId, 194 functionId: objectId,
190 contextId: proxy.objects.indexOf(this), 195 contextId: proxy.getObjectId(this),
191 args: Array.prototype.map.call( 196 args: Array.prototype.map.call(
192 arguments, 197 arguments,
193 proxy.serialize.bind(proxy) 198 proxy.serialize.bind(proxy)
194 ) 199 )
195 }) 200 })
196 ); 201 );
197 }; 202 };
198 }, 203 },
199 getObject: function(objectId) { 204 getObject: function(objectId) {
Sebastian Noack 2014/02/26 11:27:19 This was addressed by http://codereview.adblockplu
200 var objectInfo = this.send({ 205 var objectInfo = this.send({
201 type: "inspectObject", 206 type: "inspectObject",
202 objectId: objectId 207 objectId: objectId
203 }); 208 });
204 209
205 var obj = this.objects[objectId]; 210 var obj = this.objects[objectId];
206 if (obj) 211 if (obj)
Wladimir Palant 2013/11/21 08:15:58 Nit: I generally dislike blindly requesting proper
Sebastian Noack 2013/11/21 21:17:08 First using the in opreator and then getting the a
Wladimir Palant 2014/01/15 16:21:01 Very Python-like logic. Except that property looku
Sebastian Noack 2014/02/26 11:27:19 I've benchmarked this, and on Firefox using the in
207 Object.getOwnPropertyNames(obj).forEach(function(prop) { delete obj[prop ]; }); 212 Object.getOwnPropertyNames(obj).forEach(function(prop) { delete obj[prop ]; });
208 else 213 else
209 { 214 {
210 if (objectInfo.isFunction) 215 if (objectInfo.isFunction)
211 obj = this.createFunction(objectId); 216 obj = this.createFunction(objectId);
212 else 217 else
213 obj = {}; 218 obj = {};
214 219
215 this.objects[objectId] = obj; 220 this.objects[objectId] = obj;
216 } 221 }
217 222
218 var ignored = []; 223 var ignored = [];
219 if ("prototypeOf" in objectInfo) 224 if ("prototypeOf" in objectInfo)
220 { 225 {
221 var prototype = window[objectInfo.prototypeOf].prototype; 226 var prototype = window[objectInfo.prototypeOf].prototype;
222 227
223 ignored = Object.getOwnPropertyNames(prototype); 228 ignored = Object.getOwnPropertyNames(prototype);
224 ignored.splice(ignored.indexOf("constructor"), 1); 229 ignored.splice(ignored.indexOf("constructor"), 1);
Wladimir Palant 2013/11/21 08:15:58 I think there is something conceptually wrong here
Sebastian Noack 2013/11/21 21:17:08 Only own properties are sent. This code only handl
225 230
226 obj.__proto__ = prototype; 231 obj.__proto__ = prototype;
227 } 232 }
228 else 233 else
229 { 234 {
230 if (objectInfo.isFunction) 235 if (objectInfo.isFunction)
231 ignored = Object.getOwnPropertyNames(function() {}); 236 ignored = Object.getOwnPropertyNames(function() {});
232 else 237 else
233 ignored = []; 238 ignored = [];
234 239
235 if ("prototypeId" in objectInfo) 240 if ("prototypeId" in objectInfo)
236 obj.__proto__ = this.getObject(objectInfo.prototypeId); 241 obj.__proto__ = this.getObject(objectInfo.prototypeId);
237 else 242 else
238 obj.__proto__ = null; 243 obj.__proto__ = null;
Wladimir Palant 2013/11/21 08:15:58 Note that __proto__ is deprecated. It would be bet
239 } 244 }
240 245
241 for (var property in objectInfo.properties) 246 for (var property in objectInfo.properties)
242 if (ignored.indexOf(property) == -1) 247 if (ignored.indexOf(property) == -1)
243 Object.defineProperty(obj, property, this.createProperty( 248 Object.defineProperty(obj, property, this.createProperty(
244 objectId, property, 249 property, objectInfo.properties[property].enumerable
245 objectInfo.properties[property].enumerable
246 )); 250 ));
Wladimir Palant 2013/11/21 08:15:58 Style nit: please always put brackets around multi
Sebastian Noack 2014/02/26 11:27:19 Done.
247 251
248 if (objectInfo.isFunction) 252 if (objectInfo.isFunction)
249 obj.prototype = this.getProperty(objectId, "prototype"); 253 obj.prototype = this.getProperty(objectId, "prototype");
Wladimir Palant 2013/11/21 08:15:58 I'm not sure whether this special case is the best
Sebastian Noack 2014/02/26 11:27:19 Done.
250 254
251 return obj; 255 return obj;
252 } 256 }
253 }; 257 };
254 258
255 259
256 /* Web request blocking */ 260 /* Web request blocking */
257 261
258 document.addEventListener("beforeload", function(event) 262 document.addEventListener("beforeload", function(event)
259 { 263 {
260 var type; 264 var type;
261 265
262 switch(event.target.nodeName) 266 switch(event.target.nodeName)
Wladimir Palant 2013/11/21 08:15:58 Please use localName and check for lower-case tag
Sebastian Noack 2014/02/26 11:27:19 This was addressed by http://codereview.adblockplu
263 { 267 {
264 case "FRAME": 268 case "FRAME":
265 case "IFRAME": 269 case "IFRAME":
266 type = "frame"; 270 type = "frame";
267 break; 271 break;
268 case "IMG": 272 case "IMG":
269 type = "image"; 273 type = "image";
270 break; 274 break;
271 case "OBJECT": 275 case "OBJECT":
272 case "EMBED": 276 case "EMBED":
273 type = "object"; 277 type = "object";
274 break; 278 break;
275 case "SCRIPT": 279 case "SCRIPT":
276 type = "script"; 280 type = "script";
277 break; 281 break;
278 case "LINK": 282 case "LINK":
279 if (/(^|\s)stylesheet($|\s)/i.test(event.target.rel)) 283 if (/(^|\s)stylesheet($|\s)/i.test(event.target.rel))
Wladimir Palant 2013/11/21 08:15:58 /\bstylesheet\b/i should do here.
Sebastian Noack 2013/11/21 21:17:08 There is no \b in regular expressions in JS (at le
Sebastian Noack 2013/11/27 17:43:16 I'm wrong. Nevermind.
Sebastian Noack 2014/02/26 11:27:19 This was addressed by http://codereview.adblockplu
280 { 284 {
281 type = "stylesheet"; 285 type = "stylesheet";
282 break; 286 break;
283 } 287 }
284 default: 288 default:
285 type = "other"; 289 type = "other";
286 } 290 }
287 291
288 if (!safari.self.tab.canLoad(event, {type: "webRequest", payload: {url: even t.url, type: type}})) 292 if (!safari.self.tab.canLoad(event, {type: "webRequest", payload: {url: even t.url, type: type}}))
289 event.preventDefault(); 293 event.preventDefault();
290 }, true); 294 }, true);
291 295
292 296
293 /* API */ 297 /* API */
294 298
295 ext.backgroundPage = { 299 ext.backgroundPage = {
296 _eventTarget: safari.self, 300 _eventTarget: safari.self,
297 _messageDispatcher: safari.self.tab, 301 _messageDispatcher: safari.self.tab,
298 302
299 sendMessage: sendMessage, 303 sendMessage: sendMessage,
300 getWindow: function() { return proxy.getObject(0); } 304 getWindow: function() { return proxy.getObject(0); }
301 }; 305 };
302 306
303 ext.onMessage = new MessageEventTarget(safari.self); 307 ext.onMessage = new MessageEventTarget(safari.self);
304 })(); 308 })();
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld