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

Powered by Google App Engine
This is Rietveld