| Left: | ||
| Right: |
| LEFT | RIGHT |
|---|---|
| 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 |
| 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() | 18 (function() |
| 19 { | 19 { |
| 20 safari.self.tab.dispatchMessage("loading", document.location.href); | 20 // the safari object is missing in frames created from javascript: URLs. |
| 21 | 21 // So we have to fallback to the safari object from the parent frame. |
| 22 | 22 if (!("safari" in window)) |
| 23 /* Background page proxy */ | 23 window.safari = window.parent.safari; |
| 24 | |
| 25 | |
| 26 /* Intialization */ | |
| 24 | 27 |
| 25 var beforeLoadEvent = document.createEvent("Event"); | 28 var beforeLoadEvent = document.createEvent("Event"); |
| 26 beforeLoadEvent.initEvent("beforeload"); | 29 beforeLoadEvent.initEvent("beforeload"); |
| 27 | 30 |
| 28 var proxy = { | 31 var isTopLevel = window == window.top; |
| 29 objects: [], | 32 var isPrerendered = document.visibilityState == "prerender"; |
| 30 callbacks: [], | 33 |
| 31 | 34 var documentInfo = safari.self.tab.canLoad( |
| 32 send: function(message) | 35 beforeLoadEvent, |
| 33 { | 36 { |
| 34 return safari.self.tab.canLoad(beforeLoadEvent, {type: "proxy", payload: m essage}); | 37 category: "loading", |
| 35 }, | 38 url: document.location.href, |
| 36 checkResult: function(result) | 39 referrer: document.referrer, |
| 37 { | 40 isTopLevel: isTopLevel, |
| 38 if (!result.succeed) | 41 isPrerendered: isPrerendered |
| 39 throw result.error; | 42 } |
| 40 }, | 43 ); |
| 41 deserializeResult: function(result) | 44 |
| 42 { | 45 if (isTopLevel && isPrerendered) |
| 43 this.checkResult(result); | 46 { |
| 44 return this.deserialize(result.result); | 47 var onVisibilitychange = function() |
| 45 }, | 48 { |
| 46 serialize: function(obj, memo) | 49 safari.self.tab.dispatchMessage("replaced", {pageId: documentInfo.pageId}) ; |
| 47 { | 50 document.removeEventListener("visibilitychange", onVisibilitychange); |
| 48 var objectId = this.getObjectId(obj); | 51 }; |
| 49 if (objectId != -1) | 52 document.addEventListener("visibilitychange", onVisibilitychange); |
| 50 return {type: "hosted", objectId: objectId}; | 53 } |
| 51 | 54 |
| 52 if (typeof obj == "function") | 55 |
| 53 { | 56 /* Web requests */ |
| 54 var callbackId = this.callbacks.indexOf(obj); | |
| 55 | |
| 56 if (callbackId == -1) | |
| 57 { | |
| 58 callbackId = this.callbacks.push(obj) - 1; | |
| 59 | |
| 60 if (callbackId == 0) | |
|
Wladimir Palant
2014/01/15 16:21:01
This is non-obvious and needs a short explanation
| |
| 61 { | |
| 62 safari.self.addEventListener("message", function(event) | |
| 63 { | |
| 64 if (event.name == "proxyCallback") | |
| 65 { | |
| 66 this.callbacks[event.message.callbackId].apply( | |
| 67 this.getObject(event.message.contextId), | |
| 68 this.deserializeSequence(event.message.args) | |
| 69 ); | |
| 70 } | |
| 71 }.bind(this)); | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 return {type: "callback", callbackId: callbackId}; | |
| 76 } | |
| 77 | |
| 78 if (typeof obj == "object" && | |
| 79 obj != null && | |
| 80 obj.constructor != Date && | |
| 81 obj.constructor != RegExp) | |
| 82 { | |
| 83 if (!memo) | |
| 84 memo = {specs: [], objects: []}; | |
| 85 | |
| 86 var idx = memo.objects.indexOf(obj); | |
| 87 if (idx != -1) | |
| 88 return memo.specs[idx]; | |
| 89 | |
| 90 var spec = {}; | |
| 91 memo.specs.push(spec); | |
| 92 memo.objects.push(obj); | |
| 93 | |
| 94 if (obj.constructor == Array) | |
| 95 { | |
| 96 spec.type = "array"; | |
| 97 spec.items = []; | |
| 98 | |
| 99 for (var i = 0; i < obj.length; i++) | |
| 100 spec.items.push(this.serialize(obj[i], memo)); | |
| 101 } | |
| 102 else | |
| 103 { | |
| 104 spec.type = "object"; | |
| 105 spec.properties = {}; | |
| 106 | |
| 107 for (var k in obj) | |
| 108 spec.properties[k] = this.serialize(obj[k], memo); | |
| 109 } | |
| 110 | |
| 111 return spec; | |
| 112 } | |
| 113 | |
| 114 return {type: "value", value: obj}; | |
| 115 }, | |
| 116 deserializeSequence: function(specs, array, memo) | |
| 117 { | |
| 118 if (!array) | |
| 119 array = []; | |
| 120 | |
| 121 if (!memo) | |
| 122 memo = {specs: [], arrays: []}; | |
| 123 | |
| 124 for (var i = 0; i < specs.length; i++) | |
| 125 array.push(this.deserialize(specs[i], memo)); | |
| 126 | |
| 127 return array; | |
| 128 }, | |
| 129 deserialize: function(spec, memo) | |
| 130 { | |
| 131 switch (spec.type) | |
| 132 { | |
| 133 case "value": | |
| 134 return spec.value; | |
| 135 case "object": | |
| 136 return this.getObject(spec.objectId); | |
| 137 case "array": | |
| 138 if (!memo) | |
| 139 memo = {specs: [], arrays: []}; | |
| 140 | |
| 141 var idx = memo.specs.indexOf(spec); | |
| 142 if (idx != -1) | |
| 143 return memo.arrays[idx]; | |
| 144 | |
| 145 var array = []; | |
| 146 memo.specs.push(spec); | |
| 147 memo.arrays.push(array); | |
| 148 | |
| 149 return this.deserializeSequence(spec.items, array, memo); | |
| 150 } | |
| 151 }, | |
| 152 getObjectId: function(obj) | |
| 153 { | |
| 154 return this.objects.indexOf(obj); | |
| 155 }, | |
| 156 getProperty: function(objectId, property) | |
| 157 { | |
| 158 return this.deserializeResult( | |
| 159 this.send( | |
| 160 { | |
| 161 type: "getProperty", | |
| 162 objectId: objectId, | |
| 163 property: property | |
| 164 }) | |
| 165 ); | |
| 166 }, | |
| 167 createProperty: function(property, enumerable) | |
| 168 { | |
| 169 var proxy = this; | |
| 170 return { | |
| 171 get: function() | |
| 172 { | |
| 173 return proxy.getProperty(proxy.getObjectId(this), property); | |
| 174 }, | |
| 175 set: function(value) | |
| 176 { | |
| 177 proxy.checkResult( | |
| 178 proxy.send( | |
| 179 { | |
| 180 type: "setProperty", | |
| 181 objectId: proxy.getObjectId(this), | |
| 182 property: property, | |
| 183 value: proxy.serialize(value) | |
| 184 }) | |
| 185 ); | |
| 186 }, | |
| 187 enumerable: enumerable, | |
| 188 configurable: true | |
| 189 }; | |
| 190 }, | |
| 191 createFunction: function(objectId) | |
| 192 { | |
| 193 var proxy = this; | |
| 194 return function() | |
| 195 { | |
| 196 return proxy.deserializeResult( | |
| 197 proxy.send( | |
| 198 { | |
| 199 type: "callFunction", | |
| 200 functionId: objectId, | |
| 201 contextId: proxy.getObjectId(this), | |
| 202 args: Array.prototype.map.call( | |
| 203 arguments, | |
| 204 proxy.serialize.bind(proxy) | |
| 205 ) | |
| 206 }) | |
| 207 ); | |
| 208 }; | |
| 209 }, | |
| 210 getObject: function(objectId) | |
| 211 { | |
| 212 var objectInfo = this.send({ | |
| 213 type: "inspectObject", | |
| 214 objectId: objectId | |
| 215 }); | |
| 216 | |
| 217 var obj = this.objects[objectId]; | |
| 218 if (obj) | |
| 219 Object.getOwnPropertyNames(obj).forEach(function(prop) { delete obj[prop ]; }); | |
| 220 else | |
| 221 { | |
| 222 if (objectInfo.isFunction) | |
| 223 obj = this.createFunction(objectId); | |
| 224 else | |
| 225 obj = {}; | |
| 226 | |
| 227 this.objects[objectId] = obj; | |
| 228 } | |
| 229 | |
| 230 var ignored = []; | |
| 231 if ("prototypeOf" in objectInfo) | |
| 232 { | |
| 233 var prototype = window[objectInfo.prototypeOf].prototype; | |
| 234 | |
| 235 ignored = Object.getOwnPropertyNames(prototype); | |
| 236 ignored.splice(ignored.indexOf("constructor"), 1); | |
|
Wladimir Palant
2014/01/15 16:21:01
The assumption here is that ignored.indexOf() will
| |
| 237 | |
| 238 obj.__proto__ = prototype; | |
| 239 } | |
| 240 else | |
| 241 { | |
| 242 if (objectInfo.isFunction) | |
| 243 { | |
| 244 ignored = Object.getOwnPropertyNames(function() {}); | |
| 245 ignored.splice(ignored.indexOf("prototype"), 1); | |
| 246 } | |
| 247 else | |
| 248 ignored = []; | |
| 249 | |
| 250 if ("prototypeId" in objectInfo) | |
| 251 obj.__proto__ = this.getObject(objectInfo.prototypeId); | |
| 252 else | |
| 253 obj.__proto__ = null; | |
| 254 } | |
| 255 | |
| 256 for (var property in objectInfo.properties) | |
| 257 { | |
| 258 if (ignored.indexOf(property) != -1) | |
| 259 continue; | |
| 260 | |
| 261 if (!Object.hasOwnProperty(obj, property) || Object.getOwnPropertyDescri ptor(obj, property).configurable) | |
| 262 { | |
| 263 Object.defineProperty(obj, property, this.createProperty( | |
| 264 property, objectInfo.properties[property].enumerable | |
| 265 )); | |
| 266 } | |
| 267 else | |
| 268 obj[property] = this.getProperty(objectId, property); | |
| 269 } | |
| 270 | |
| 271 return obj; | |
| 272 } | |
| 273 }; | |
| 274 | |
| 275 | |
| 276 /* Web request blocking */ | |
| 277 | 57 |
| 278 document.addEventListener("beforeload", function(event) | 58 document.addEventListener("beforeload", function(event) |
| 279 { | 59 { |
| 280 var type; | 60 var type; |
| 281 | |
| 282 switch(event.target.localName) | 61 switch(event.target.localName) |
| 283 { | 62 { |
| 284 case "frame": | 63 case "frame": |
| 285 case "iframe": | 64 case "iframe": |
| 286 type = "frame"; | 65 type = "sub_frame"; |
| 287 break; | 66 break; |
| 288 case "img": | 67 case "img": |
| 289 type = "image"; | 68 type = "image"; |
| 290 break; | 69 break; |
| 291 case "object": | 70 case "object": |
| 292 case "embed": | 71 case "embed": |
| 293 type = "object"; | 72 type = "object"; |
| 294 break; | 73 break; |
| 295 case "script": | 74 case "script": |
| 296 type = "script"; | 75 type = "script"; |
| 297 break; | 76 break; |
| 298 case "link": | 77 case "link": |
| 299 if (/\bstylesheet\b/i.test(event.target.rel)) | 78 if (/\bstylesheet\b/i.test(event.target.rel)) |
| 300 { | 79 { |
| 301 type = "stylesheet"; | 80 type = "stylesheet"; |
| 302 break; | 81 break; |
| 303 } | 82 } |
| 304 default: | 83 default: |
| 305 type = "other"; | 84 type = "other"; |
| 306 } | 85 } |
| 307 | 86 |
| 308 if (!safari.self.tab.canLoad(event, {type: "webRequest", payload: {url: even t.url, type: type}})) | 87 if (!safari.self.tab.canLoad( |
| 88 event, { | |
| 89 category: "webRequest", | |
| 90 url: event.url, | |
| 91 type: type, | |
| 92 pageId: documentInfo.pageId, | |
| 93 frameId: documentInfo.frameId | |
| 94 } | |
| 95 )) | |
| 96 { | |
| 309 event.preventDefault(); | 97 event.preventDefault(); |
| 98 | |
| 99 // Safari doesn't dispatch an "error" event when preventing an element | |
| 100 // from loading by cancelling the "beforeload" event. So we have to | |
| 101 // dispatch it manually. Otherwise element collapsing wouldn't work. | |
| 102 if (type != "sub_frame") | |
| 103 { | |
| 104 var evt = document.createEvent("Event"); | |
| 105 evt.initEvent(type == "error"); | |
| 106 event.target.dispatchEvent(evt); | |
| 107 } | |
| 108 } | |
| 310 }, true); | 109 }, true); |
| 311 | 110 |
| 312 | 111 |
| 313 /* API */ | 112 /* Context menus */ |
| 113 | |
| 114 document.addEventListener("contextmenu", function(event) | |
| 115 { | |
| 116 var element = event.srcElement; | |
| 117 safari.self.tab.setContextMenuEventUserInfo(event, { | |
| 118 pageId: documentInfo.pageId, | |
| 119 srcUrl: ("src" in element) ? element.src : null, | |
| 120 tagName: element.localName | |
| 121 }); | |
| 122 }); | |
| 123 | |
| 124 | |
| 125 /* Background page */ | |
| 126 | |
| 127 var backgroundPageProxy = { | |
| 128 objects: [], | |
| 129 callbacks: [], | |
| 130 | |
| 131 send: function(message) | |
| 132 { | |
| 133 message.category = "proxy"; | |
| 134 message.pageId = documentInfo.pageId; | |
| 135 | |
| 136 return safari.self.tab.canLoad(beforeLoadEvent, message); | |
| 137 }, | |
| 138 checkResult: function(result) | |
| 139 { | |
| 140 if (!result.succeed) | |
| 141 throw result.error; | |
| 142 }, | |
| 143 deserializeResult: function(result) | |
| 144 { | |
| 145 this.checkResult(result); | |
| 146 return this.deserialize(result.result); | |
| 147 }, | |
| 148 serialize: function(obj, memo) | |
| 149 { | |
| 150 if (typeof obj == "object" && obj != null || typeof obj == "function") | |
| 151 { | |
| 152 if ("__proxyObjectId" in obj) | |
| 153 return {type: "hosted", objectId: obj.__proxyObjectId}; | |
| 154 | |
| 155 if (typeof obj == "function") | |
| 156 { | |
| 157 var callbackId; | |
| 158 if ("__proxyCallbackId" in obj) | |
| 159 callbackId = obj.__proxyCallbackId; | |
| 160 else | |
| 161 { | |
| 162 callbackId = this.callbacks.push(obj) - 1; | |
| 163 Object.defineProperty(obj, "__proxyCallbackId", {value: callbackId}) ; | |
| 164 } | |
| 165 | |
| 166 return {type: "callback", callbackId: callbackId, frameId: documentInf o.frameId}; | |
| 167 } | |
| 168 | |
| 169 if (obj.constructor != Date && obj.constructor != RegExp) | |
| 170 { | |
| 171 if (!memo) | |
| 172 memo = {specs: [], objects: []}; | |
| 173 | |
| 174 var idx = memo.objects.indexOf(obj); | |
| 175 if (idx != -1) | |
| 176 return memo.specs[idx]; | |
| 177 | |
| 178 var spec = {}; | |
| 179 memo.specs.push(spec); | |
| 180 memo.objects.push(obj); | |
| 181 | |
| 182 if (obj.constructor == Array) | |
| 183 { | |
| 184 spec.type = "array"; | |
| 185 spec.items = []; | |
| 186 | |
| 187 for (var i = 0; i < obj.length; i++) | |
| 188 spec.items.push(this.serialize(obj[i], memo)); | |
| 189 } | |
| 190 else | |
| 191 { | |
| 192 spec.type = "object"; | |
| 193 spec.properties = {}; | |
| 194 | |
| 195 for (var k in obj) | |
| 196 spec.properties[k] = this.serialize(obj[k], memo); | |
| 197 } | |
| 198 | |
| 199 return spec; | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 return {type: "value", value: obj}; | |
| 204 }, | |
| 205 deserializeSequence: function(specs, array, memo) | |
| 206 { | |
| 207 if (!array) | |
| 208 array = []; | |
| 209 | |
| 210 if (!memo) | |
| 211 memo = {specs: [], arrays: []}; | |
| 212 | |
| 213 for (var i = 0; i < specs.length; i++) | |
| 214 array.push(this.deserialize(specs[i], memo)); | |
| 215 | |
| 216 return array; | |
| 217 }, | |
| 218 deserialize: function(spec, memo) | |
| 219 { | |
| 220 switch (spec.type) | |
| 221 { | |
| 222 case "value": | |
| 223 return spec.value; | |
| 224 case "object": | |
| 225 return this.getObject(spec.objectId); | |
| 226 case "array": | |
| 227 if (!memo) | |
| 228 memo = {specs: [], arrays: []}; | |
| 229 | |
| 230 var idx = memo.specs.indexOf(spec); | |
| 231 if (idx != -1) | |
| 232 return memo.arrays[idx]; | |
| 233 | |
| 234 var array = []; | |
| 235 memo.specs.push(spec); | |
| 236 memo.arrays.push(array); | |
| 237 | |
| 238 return this.deserializeSequence(spec.items, array, memo); | |
| 239 } | |
| 240 }, | |
| 241 getProperty: function(objectId, property) | |
| 242 { | |
| 243 return this.deserializeResult( | |
| 244 this.send( | |
| 245 { | |
| 246 type: "getProperty", | |
| 247 objectId: objectId, | |
| 248 property: property | |
| 249 }) | |
| 250 ); | |
| 251 }, | |
| 252 createProperty: function(property, enumerable) | |
| 253 { | |
| 254 var proxy = this; | |
| 255 return { | |
| 256 get: function() | |
| 257 { | |
| 258 return proxy.getProperty(this.__proxyObjectId, property); | |
| 259 }, | |
| 260 set: function(value) | |
| 261 { | |
| 262 proxy.checkResult( | |
| 263 proxy.send( | |
| 264 { | |
| 265 type: "setProperty", | |
| 266 objectId: this.__proxyObjectId, | |
| 267 property: property, | |
| 268 value: proxy.serialize(value) | |
| 269 }) | |
| 270 ); | |
| 271 }, | |
| 272 enumerable: enumerable, | |
| 273 configurable: true | |
| 274 }; | |
| 275 }, | |
| 276 createFunction: function(objectId) | |
| 277 { | |
| 278 var proxy = this; | |
| 279 return function() | |
| 280 { | |
| 281 return proxy.deserializeResult( | |
| 282 proxy.send( | |
| 283 { | |
| 284 type: "callFunction", | |
| 285 functionId: objectId, | |
| 286 contextId: this.__proxyObjectId, | |
| 287 args: Array.prototype.map.call( | |
| 288 arguments, | |
| 289 proxy.serialize.bind(proxy) | |
| 290 ) | |
| 291 }) | |
| 292 ); | |
| 293 }; | |
| 294 }, | |
| 295 handleCallback: function(message) | |
| 296 { | |
| 297 this.callbacks[message.callbackId].apply( | |
| 298 this.getObject(message.contextId), | |
| 299 this.deserializeSequence(message.args) | |
| 300 ); | |
| 301 }, | |
| 302 getObject: function(objectId) | |
| 303 { | |
| 304 var objectInfo = this.send({ | |
| 305 type: "inspectObject", | |
| 306 objectId: objectId | |
| 307 }); | |
| 308 | |
| 309 var obj = this.objects[objectId]; | |
| 310 if (obj) | |
| 311 Object.getOwnPropertyNames(obj).forEach(function(prop) { delete obj[prop ]; }); | |
| 312 else | |
| 313 { | |
| 314 if (objectInfo.isFunction) | |
| 315 obj = this.createFunction(objectId); | |
| 316 else | |
| 317 obj = {}; | |
| 318 | |
| 319 this.objects[objectId] = obj; | |
| 320 Object.defineProperty(obj, "__proxyObjectId", {value: objectId}); | |
| 321 } | |
| 322 | |
| 323 var excluded = []; | |
| 324 var included = []; | |
| 325 if ("prototypeOf" in objectInfo) | |
| 326 { | |
| 327 var prototype = window[objectInfo.prototypeOf].prototype; | |
| 328 | |
| 329 excluded = Object.getOwnPropertyNames(prototype); | |
| 330 included = ["constructor"]; | |
| 331 | |
| 332 obj.__proto__ = prototype; | |
| 333 } | |
| 334 else | |
| 335 { | |
| 336 if (objectInfo.isFunction) | |
| 337 { | |
| 338 excluded = Object.getOwnPropertyNames(function() {}); | |
| 339 included = ["prototype"]; | |
| 340 } | |
| 341 | |
| 342 if ("prototypeId" in objectInfo) | |
| 343 obj.__proto__ = this.getObject(objectInfo.prototypeId); | |
| 344 else | |
| 345 obj.__proto__ = null; | |
| 346 } | |
| 347 | |
| 348 for (var property in objectInfo.properties) | |
| 349 { | |
| 350 if (excluded.indexOf(property) == -1 || included.indexOf(property) != -1 ) | |
| 351 { | |
| 352 var desc = Object.getOwnPropertyDescriptor(obj, property); | |
| 353 | |
| 354 if (!desc || desc.configurable) | |
| 355 { | |
| 356 Object.defineProperty(obj, property, this.createProperty( | |
| 357 property, objectInfo.properties[property].enumerable | |
| 358 )); | |
| 359 } | |
| 360 else if (desc.writable) | |
| 361 obj[property] = this.getProperty(objectId, property); | |
| 362 } | |
| 363 } | |
| 364 | |
| 365 return obj; | |
| 366 } | |
| 367 }; | |
| 314 | 368 |
| 315 ext.backgroundPage = { | 369 ext.backgroundPage = { |
| 316 _eventTarget: safari.self, | 370 sendMessage: function(message, responseCallback) |
| 317 _messageDispatcher: safari.self.tab, | 371 { |
| 318 | 372 messageProxy.sendMessage(message, responseCallback, documentInfo); |
| 319 sendMessage: sendMessage, | 373 }, |
| 320 getWindow: function() { return proxy.getObject(0); } | 374 getWindow: function() |
| 375 { | |
| 376 return backgroundPageProxy.getObject(0); | |
| 377 } | |
| 321 }; | 378 }; |
| 322 | 379 |
| 323 ext.onMessage = new MessageEventTarget(safari.self); | 380 |
| 381 /* Message processing */ | |
| 382 | |
| 383 var messageProxy = new ext._MessageProxy(safari.self.tab); | |
| 384 | |
| 385 safari.self.addEventListener("message", function(event) | |
| 386 { | |
| 387 if (event.message.pageId == documentInfo.pageId) | |
| 388 { | |
| 389 if (event.name == "request") | |
| 390 { | |
| 391 messageProxy.handleRequest(event.message, {}); | |
| 392 return; | |
| 393 } | |
| 394 | |
| 395 if (event.message.frameId == documentInfo.frameId) | |
| 396 { | |
| 397 switch (event.name) | |
| 398 { | |
| 399 case "response": | |
| 400 messageProxy.handleResponse(event.message); | |
| 401 break; | |
| 402 case "proxyCallback": | |
| 403 backgroundPageProxy.handleCallback(event.message); | |
| 404 break; | |
| 405 } | |
| 406 } | |
| 407 } | |
| 408 }); | |
| 324 })(); | 409 })(); |
| LEFT | RIGHT |