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: Added missing copyright disclaimers and websql implementation Created Oct. 23, 2013, 2:46 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
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 /* Background page proxy */
20
21 var proxy = {
22 objects: [],
23 callbacks: [],
24
25 send: function(message) {
26 var evt = document.createEvent("Event");
27 evt.initEvent("beforeload");
28 return safari.self.tab.canLoad(evt, {type: "proxy", payload: message});
29 },
30 checkResult: function(result) {
31 if (!result.succeed)
32 throw result.error;
33 },
34 deserializeResult: function(result) {
35 this.checkResult(result);
36 return this.deserialize(result.result);
37 },
38 serialize: function(obj, memo) {
39 var objectId = this.objects.indexOf(obj);
40 if (objectId != -1)
41 return {type: "hosted", objectId: objectId};
42
43 if (typeof obj == "function") {
44 var callbackId = this.callbacks.indexOf(obj);
45
46 if (callbackId == -1) {
47 callbackId = this.callbacks.push(obj) - 1;
48
49 safari.self.addEventListener("message", function(event) {
50 if (event.name == "proxyCallback")
51 if (event.message.callbackId == callbackId)
52 obj.apply(
53 this.getObject(event.message.contextId),
54 this.deserializeSequence(event.message.args)
55 );
56 }.bind(this));
57 }
58
59 return {type: "callback", callbackId: callbackId};
60 }
61
62 if (typeof obj == "object")
63 if (obj != null)
64 if (obj.constructor != Date)
65 if (obj.constructor != RegExp) {
66 if (!memo)
67 memo = {specs: [], objects: []};
68
69 var idx = memo.objects.indexOf(obj);
70 if (idx != -1)
71 return memo.specs[idx];
72
73 var spec = {};
74 memo.specs.push(spec);
75 memo.objects.push(obj);
76
77 if (obj.constructor == Array) {
78 spec.type = "array";
79 spec.items = [];
80
81 for (var i = 0; i < obj.length; i++)
82 spec.items.push(this.serialize(obj[i], memo));
83 } else {
84 spec.type = "object";
85 spec.properties = {};
86
87 for (var k in obj)
88 spec.properties[k] = this.serialize(obj[k], memo);
89 }
90
91 return spec;
92 }
93
94 return {type: "value", value: obj};
95 },
96 deserializeSequence: function(specs, array, memo) {
97 if (!array)
98 array = [];
99
100 if (!memo)
101 memo = {specs: [], arrays: []};
102
103 for (var i = 0; i < specs.length; i++)
104 array.push(this.deserialize(specs[i], memo));
105
106 return array;
107 },
108 deserialize: function(spec, memo) {
109 switch (spec.type) {
110 case "value":
111 return spec.value;
112 case "object":
113 case "function":
114 return this.getObject(spec.objectId, spec.type);
115 case "array":
116 if (!memo)
117 memo = {specs: [], arrays: []};
118
119 var idx = memo.specs.indexOf(spec);
120 if (idx != -1)
121 return memo.arrays[idx];
122
123 var array = [];
124 memo.specs.push(spec);
125 memo.arrays.push(array);
126
127 return this.deserializeSequence(spec.items, array, memo);
128 }
129 },
130 getProperty: function(objectId, property) {
131 return this.deserializeResult(
132 this.send({
133 type: "getProperty",
134 objectId: objectId,
135 property: property
136 })
137 );
138 },
139 createProperty: function(objectId, property, enumerable) {
140 return {
141 get: function() {
142 return this.getProperty(objectId, property);
143 }.bind(this),
144 set: function(value) {
145 this.checkResult(
146 this.send({
147 type: "setProperty",
148 objectId: objectId,
149 property: property,
150 value: this.serialize(value)
151 })
152 )
153 }.bind(this),
154 enumerable: enumerable
155 };
156 },
157 createObject: function(objectId) {
158 var objectInfo = this.send({
159 type: "inspectObject",
160 objectId: objectId
161 });
162
163 var prototype;
164 if (objectInfo.prototypeId != null)
165 prototype = this.getObject(objectInfo.prototypeId);
166 else
167 prototype = Object.prototype;
168
169 var properties = {};
170 for (var property in objectInfo.properties)
171 properties[property] = this.createProperty(
172 objectId, property,
173 objectInfo.properties[property].enumerable
174 );
175
176 return Object.create(prototype, properties);
177 },
178 createFunction: function(objectId) {
179 var objectInfo = this.send({
180 type: "inspectObject",
181 objectId: objectId
182 });
183
184 var proxy = this;
185 var func = function() {
186 return proxy.deserializeResult(
187 proxy.send({
188 type: "callFunction",
189 functionId: objectId,
190 contextId: proxy.objects.indexOf(this),
191 args: Array.prototype.map.call(
192 arguments,
193 proxy.serialize.bind(proxy)
194 )
195 })
196 );
197 };
198
199 var builtin = Object.getOwnPropertyNames(func);
200 for (var property in objectInfo.properties)
201 if (builtin.indexOf(property) == -1)
202 Object.defineProperty(func, property, this.createProperty(
203 objectId, property,
204 objectInfo.properties[property].enumerable
205 ));
206
207 func.prototype = this.getProperty(objectId, "prototype");
208 return func;
209 },
210 getObject: function(objectId, type) {
211 var obj = this.objects[objectId];
212
213 if (!obj) {
214 if (type == "function")
215 obj = this.createFunction(objectId);
216 else
217 obj = this.createObject(objectId);
218
219 this.objects[objectId] = obj;
220 }
221
222 return obj;
223 }
224 };
225
226
227 /* Web request blocking */
228
229 document.addEventListener("beforeload", function(event) {
230 var type;
231
232 switch(event.target.nodeName) {
233 case "FRAME":
234 case "IFRAME":
235 type = "frame";
236 break;
237 case "IMG":
238 type = "image";
239 break;
240 case "OBJECT":
241 case "EMBED":
242 type = "object";
243 break;
244 case "SCRIPT":
245 type = "script";
246 break;
247 case "LINK":
248 if (/(^|\s)stylesheet($|\s)/i.test(event.target.rel)) {
249 type = "stylesheet";
250 break;
251 }
252 default:
253 type = "other";
254 }
255
256 if (!safari.self.tab.canLoad(event, {type: "webRequest", payload: {url: even t.url, type: type}}))
257 event.preventDefault();
258 }, true);
259
260 /* API */
261
262 ext.backgroundPage = {
263 _eventTarget: safari.self,
264 _messageDispatcher: safari.self.tab,
265
266 sendMessage: sendMessage,
267 getWindow: function() { return proxy.getObject(0); }
268 };
269
270 ext.onMessage = new MessageEventTarget(safari.self);
271 })();
OLDNEW
« chrome/common.js ('K') | « safari/common.js ('k') | utils.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld