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

Side by Side Diff: safari/content.js

Issue 16067002: Added Safari Support (Closed)
Patch Set: Fixed some bug introduced by rebasing, and fix absolute URLs on extension pages in Safari with JS. Created Oct. 30, 2013, 5:24 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 | « safari/common.js ('k') | stats.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2013 Eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
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/>.
16 */
17
18 (function()
19 {
20 /* Background page proxy */
21
22 var proxy = {
23 objects: [],
24 callbacks: [],
25
26 send: function(message)
27 {
28 var evt = document.createEvent("Event");
29 evt.initEvent("beforeload");
30 return safari.self.tab.canLoad(evt, {type: "proxy", payload: message});
31 },
32 checkResult: function(result)
33 {
34 if (!result.succeed)
35 throw result.error;
36 },
37 deserializeResult: function(result)
38 {
39 this.checkResult(result);
40 return this.deserialize(result.result);
41 },
42 serialize: function(obj, memo)
43 {
44 var objectId = this.objects.indexOf(obj);
45 if (objectId != -1)
46 return {type: "hosted", objectId: objectId};
47
48 if (typeof obj == "function")
49 {
50 var callbackId = this.callbacks.indexOf(obj);
51
52 if (callbackId == -1)
53 {
54 callbackId = this.callbacks.push(obj) - 1;
55
56 safari.self.addEventListener("message", function(event)
57 {
58 if (event.name == "proxyCallback")
59 if (event.message.callbackId == callbackId)
60 obj.apply(
61 this.getObject(event.message.contextId),
62 this.deserializeSequence(event.message.args)
63 );
64 }.bind(this));
65 }
66
67 return {type: "callback", callbackId: callbackId};
68 }
69
70 if (typeof obj == "object")
71 if (obj != null)
72 if (obj.constructor != Date)
73 if (obj.constructor != RegExp)
74 {
75 if (!memo)
76 memo = {specs: [], objects: []};
77
78 var idx = memo.objects.indexOf(obj);
79 if (idx != -1)
80 return memo.specs[idx];
81
82 var spec = {};
83 memo.specs.push(spec);
84 memo.objects.push(obj);
85
86 if (obj.constructor == Array)
87 {
88 spec.type = "array";
89 spec.items = [];
90
91 for (var i = 0; i < obj.length; i++)
92 spec.items.push(this.serialize(obj[i], memo));
93 }
94 else
95 {
96 spec.type = "object";
97 spec.properties = {};
98
99 for (var k in obj)
100 spec.properties[k] = this.serialize(obj[k], memo);
101 }
102
103 return spec;
104 }
105
106 return {type: "value", value: obj};
107 },
108 deserializeSequence: function(specs, array, memo)
109 {
110 if (!array)
111 array = [];
112
113 if (!memo)
114 memo = {specs: [], arrays: []};
115
116 for (var i = 0; i < specs.length; i++)
117 array.push(this.deserialize(specs[i], memo));
118
119 return array;
120 },
121 deserialize: function(spec, memo)
122 {
123 switch (spec.type)
124 {
125 case "value":
126 return spec.value;
127 case "object":
128 case "function":
129 return this.getObject(spec.objectId, spec.type);
130 case "array":
131 if (!memo)
132 memo = {specs: [], arrays: []};
133
134 var idx = memo.specs.indexOf(spec);
135 if (idx != -1)
136 return memo.arrays[idx];
137
138 var array = [];
139 memo.specs.push(spec);
140 memo.arrays.push(array);
141
142 return this.deserializeSequence(spec.items, array, memo);
143 }
144 },
145 getProperty: function(objectId, property)
146 {
147 return this.deserializeResult(
148 this.send({
149 type: "getProperty",
150 objectId: objectId,
151 property: property
152 })
153 );
154 },
155 createProperty: function(objectId, property, enumerable)
156 {
157 return {
158 get: function()
159 {
160 return this.getProperty(objectId, property);
161 }.bind(this),
162 set: function(value)
163 {
164 this.checkResult(
165 this.send({
166 type: "setProperty",
167 objectId: objectId,
168 property: property,
169 value: this.serialize(value)
170 })
171 )
172 }.bind(this),
173 enumerable: enumerable
174 };
175 },
176 createObject: function(objectId)
177 {
178 var objectInfo = this.send({
179 type: "inspectObject",
180 objectId: objectId
181 });
182
183 var prototype;
184 if (objectInfo.prototypeId != null)
185 prototype = this.getObject(objectInfo.prototypeId);
186 else
187 prototype = Object.prototype;
188
189 var properties = {};
190 for (var property in objectInfo.properties)
191 properties[property] = this.createProperty(
192 objectId, property,
193 objectInfo.properties[property].enumerable
194 );
195
196 return Object.create(prototype, properties);
197 },
198 createFunction: function(objectId)
199 {
200 var objectInfo = this.send({
201 type: "inspectObject",
202 objectId: objectId
203 });
204
205 var proxy = this;
206 var func = function()
207 {
208 return proxy.deserializeResult(
209 proxy.send({
210 type: "callFunction",
211 functionId: objectId,
212 contextId: proxy.objects.indexOf(this),
213 args: Array.prototype.map.call(
214 arguments,
215 proxy.serialize.bind(proxy)
216 )
217 })
218 );
219 };
220
221 var builtin = Object.getOwnPropertyNames(func);
222 for (var property in objectInfo.properties)
223 if (builtin.indexOf(property) == -1)
224 Object.defineProperty(func, property, this.createProperty(
225 objectId, property,
226 objectInfo.properties[property].enumerable
227 ));
228
229 func.prototype = this.getProperty(objectId, "prototype");
230 return func;
231 },
232 getObject: function(objectId, type)
233 {
234 var obj = this.objects[objectId];
235
236 if (!obj)
237 {
238 if (type == "function")
239 obj = this.createFunction(objectId);
240 else
241 obj = this.createObject(objectId);
242
243 this.objects[objectId] = obj;
244 }
245
246 return obj;
247 }
248 };
249
250
251 /* Web request blocking */
252
253 document.addEventListener("beforeload", function(event)
254 {
255 var type;
256
257 switch(event.target.nodeName)
258 {
259 case "FRAME":
260 case "IFRAME":
261 type = "frame";
262 break;
263 case "IMG":
264 type = "image";
265 break;
266 case "OBJECT":
267 case "EMBED":
268 type = "object";
269 break;
270 case "SCRIPT":
271 type = "script";
272 break;
273 case "LINK":
274 if (/(^|\s)stylesheet($|\s)/i.test(event.target.rel))
275 {
276 type = "stylesheet";
277 break;
278 }
279 default:
280 type = "other";
281 }
282
283 if (!safari.self.tab.canLoad(event, {type: "webRequest", payload: {url: even t.url, type: type}}))
284 event.preventDefault();
285 }, true);
286
287
288 /* Fix absolute URLs on extention pages */
289
290 if (document.location.href.indexOf(safari.extension.baseURI) == 0) {
291 document.addEventListener("DOMContentLoaded", function(event)
292 {
293 var attributes = ['href', 'src'];
294 for (var i = 0; i < attributes.length; i++)
295 {
296 var elements = document.querySelectorAll("[" + attributes[i] + "^='/']") ;
297 for (var j = 0; j < elements.length; j++)
298 elements[j][attributes[i]] = safari.extension.baseURI + elements[j][at tributes[i]].substr(1);
299 }
300 });
301 }
302
303
304 /* API */
305
306 ext.backgroundPage = {
307 _eventTarget: safari.self,
308 _messageDispatcher: safari.self.tab,
309
310 sendMessage: sendMessage,
311 getWindow: function() { return proxy.getObject(0); }
312 };
313
314 ext.onMessage = new MessageEventTarget(safari.self);
315 })();
OLDNEW
« no previous file with comments | « safari/common.js ('k') | stats.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld