| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
| 3 * Copyright (C) 2006-2016 Eyeo GmbH | 3 * Copyright (C) 2006-2016 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 /** | 18 /** |
| 19 * @fileOverview Stores Adblock Plus data to be attached to a window. | 19 * @fileOverview Stores Adblock Plus data to be attached to a window. |
| 20 */ | 20 */ |
| 21 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); | 21 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); |
| 22 | 22 |
| 23 let {port} = require("messaging"); |
| 23 let {Utils} = require("utils"); | 24 let {Utils} = require("utils"); |
| 24 let {Flasher} = require("child/flasher"); | 25 let {Flasher} = require("child/flasher"); |
| 25 | 26 |
| 26 let nodeData = new WeakMap(); | 27 let nodeData = new WeakMap(); |
| 27 let windowStats = new WeakMap(); | 28 let windowStats = new WeakMap(); |
| 28 let windowData = new WeakMap(); | 29 let windowData = new WeakMap(); |
| 29 let requestEntryMaxId = 0; | 30 let requestEntryMaxId = 0; |
| 30 | 31 |
| 31 /** | 32 /** |
| 32 * Active RequestNotifier instances by their ID | 33 * Active RequestNotifier instances by their ID |
| 33 * @type Map.<number,RequestNotifier> | 34 * @type Map.<number,RequestNotifier> |
| 34 */ | 35 */ |
| 35 let notifiers = new Map(); | 36 let notifiers = new Map(); |
| 36 | 37 |
| 37 addMessageListener("AdblockPlus:StartWindowScan", onStartScan); | 38 port.on("startWindowScan", onStartScan); |
| 38 addMessageListener("AdblockPlus:ShutdownNotifier", onNotifierShutdown); | 39 port.on("shutdownNotifier", onNotifierShutdown); |
| 39 addMessageListener("AdblockPlus:FlashNodes", onFlashNodes); | 40 port.on("flashNodes", onFlashNodes); |
| 40 addMessageListener("AdblockPlus:RetrieveNodeSize", onRetrieveNodeSize); | 41 port.on("retrieveNodeSize", onRetrieveNodeSize); |
| 41 addMessageListener("AdblockPlus:StoreNodesForEntries", onStoreNodes); | 42 port.on("storeNodesForEntries", onStoreNodes); |
| 42 addMessageListener("AdblockPlus:RetrieveWindowStats", onRetrieveWindowStats); | 43 port.on("retrieveWindowStats", onRetrieveWindowStats); |
| 43 addMessageListener("AdblockPlus:StoreWindowData", onStoreWindowData); | 44 port.on("storeWindowData", onStoreWindowData); |
| 44 addMessageListener("AdblockPlus:RetrieveWindowData", onRetrieveWindowData); | 45 port.on("retrieveWindowData", onRetrieveWindowData); |
| 45 | 46 |
| 46 onShutdown.add(() => { | 47 function onStartScan({notifierID, outerWindowID}) |
| 47 removeMessageListener("AdblockPlus:StartWindowScan", onStartScan); | |
| 48 removeMessageListener("AdblockPlus:ShutdownNotifier", onNotifierShutdown); | |
| 49 removeMessageListener("AdblockPlus:FlashNodes", onFlashNodes); | |
| 50 removeMessageListener("AdblockPlus:RetrieveNodeSize", onRetrieveNodeSize); | |
| 51 removeMessageListener("AdblockPlus:StoreNodesForEntries", onStoreNodes); | |
| 52 removeMessageListener("AdblockPlus:RetrieveWindowStats", onRetrieveWindowStats
); | |
| 53 removeMessageListener("AdblockPlus:StoreWindowData", onStoreWindowData); | |
| 54 removeMessageListener("AdblockPlus:RetrieveWindowData", onRetrieveWindowData); | |
| 55 }); | |
| 56 | |
| 57 function onStartScan(message) | |
| 58 { | 48 { |
| 59 let {notifierID, outerWindowID} = message.data; | |
| 60 let window = Services.wm.getOuterWindowWithId(outerWindowID); | 49 let window = Services.wm.getOuterWindowWithId(outerWindowID); |
| 61 if (window) | 50 if (window) |
| 62 new RequestNotifier(window, notifierID); | 51 new RequestNotifier(window, notifierID); |
| 63 } | 52 } |
| 64 | 53 |
| 65 function onNotifierShutdown(message) | 54 function onNotifierShutdown(notifierID) |
| 66 { | 55 { |
| 67 let notifier = notifiers.get(message.data); | 56 let notifier = notifiers.get(notifierID); |
| 68 if (notifier) | 57 if (notifier) |
| 69 notifier.shutdown(); | 58 notifier.shutdown(); |
| 70 } | 59 } |
| 71 | 60 |
| 72 function onFlashNodes(message) | 61 function onFlashNodes({notifierID, requests, scrollToItem}) |
| 73 { | 62 { |
| 74 let {notifierID, requests, scrollToItem} = message.data; | |
| 75 let notifier = notifiers.get(notifierID); | 63 let notifier = notifiers.get(notifierID); |
| 76 if (notifier) | 64 if (notifier) |
| 77 notifier.flashNodes(requests, scrollToItem); | 65 notifier.flashNodes(requests, scrollToItem); |
| 78 } | 66 } |
| 79 | 67 |
| 80 function onRetrieveNodeSize(message) | 68 function onRetrieveNodeSize({notifierID, requests}) |
| 81 { | 69 { |
| 82 let {notifierID, responseID, requests} = message.data; | |
| 83 let notifier = notifiers.get(notifierID); | 70 let notifier = notifiers.get(notifierID); |
| 84 if (notifier) | 71 if (notifier) |
| 85 notifier.retrieveNodeSize(requests, responseID); | 72 return notifier.retrieveNodeSize(requests); |
| 86 } | 73 } |
| 87 | 74 |
| 88 function onStoreNodes(message) | 75 function onStoreNodes({notifierID, requests}) |
| 89 { | 76 { |
| 90 let {notifierID, responseID, requests} = message.data; | |
| 91 let notifier = notifiers.get(notifierID); | 77 let notifier = notifiers.get(notifierID); |
| 92 if (notifier) | 78 if (notifier) |
| 93 notifier.storeNodesForEntries(requests, responseID); | 79 return notifier.storeNodesForEntries(requests); |
| 94 } | 80 } |
| 95 | 81 |
| 96 function onRetrieveWindowStats(message) | 82 function onRetrieveWindowStats(outerWindowID) |
| 97 { | 83 { |
| 98 let {responseID, outerWindowID} = message.data; | |
| 99 let window = Services.wm.getOuterWindowWithId(outerWindowID); | 84 let window = Services.wm.getOuterWindowWithId(outerWindowID); |
| 100 if (window) | 85 if (window) |
| 101 { | 86 return RequestNotifier.getWindowStatistics(window); |
| 102 let stats = RequestNotifier.getWindowStatistics(window); | |
| 103 sendAsyncMessage("AdblockPlus:RetrieveWindowStatsResponse", { | |
| 104 responseID, | |
| 105 stats | |
| 106 }); | |
| 107 } | |
| 108 } | 87 } |
| 109 | 88 |
| 110 function onStoreWindowData(message) | 89 function onStoreWindowData({outerWindowID, data}) |
| 111 { | 90 { |
| 112 let {outerWindowID, data} = message.data; | |
| 113 let window = Services.wm.getOuterWindowWithId(outerWindowID); | 91 let window = Services.wm.getOuterWindowWithId(outerWindowID); |
| 114 if (window) | 92 if (window) |
| 115 windowData.set(window.document, data); | 93 windowData.set(window.document, data); |
| 116 }; | 94 }; |
| 117 | 95 |
| 118 function onRetrieveWindowData(message) | 96 function onRetrieveWindowData(outerWindowID) |
| 119 { | 97 { |
| 120 let {responseID, outerWindowID} = message.data; | |
| 121 let window = Services.wm.getOuterWindowWithId(outerWindowID); | 98 let window = Services.wm.getOuterWindowWithId(outerWindowID); |
| 122 if (window) | 99 if (window) |
| 123 { | 100 return windowData.get(window.document) || null; |
| 124 let data = windowData.get(window.document) || null; | |
| 125 sendAsyncMessage("AdblockPlus:RetrieveWindowDataResponse", { | |
| 126 responseID, | |
| 127 data | |
| 128 }); | |
| 129 } | |
| 130 }; | 101 }; |
| 131 | 102 |
| 132 /** | 103 /** |
| 133 * Creates a notifier object for a particular window. After creation the window | 104 * Creates a notifier object for a particular window. After creation the window |
| 134 * will first be scanned for previously saved requests. Once that scan is | 105 * will first be scanned for previously saved requests. Once that scan is |
| 135 * complete only new requests for this window will be reported. | 106 * complete only new requests for this window will be reported. |
| 136 * @param {Window} window window to attach the notifier to | 107 * @param {Window} window window to attach the notifier to |
| 137 * @param {Integer} notifierID Parent notifier ID to be messaged | 108 * @param {Integer} notifierID Parent notifier ID to be messaged |
| 138 */ | 109 */ |
| 139 function RequestNotifier(window, notifierID) | 110 function RequestNotifier(window, notifierID) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 | 151 |
| 181 /** | 152 /** |
| 182 * Notifies the parent about a new request. | 153 * Notifies the parent about a new request. |
| 183 * @param {Node} node DOM node that the request is associated with | 154 * @param {Node} node DOM node that the request is associated with |
| 184 * @param {Object} entry | 155 * @param {Object} entry |
| 185 */ | 156 */ |
| 186 notifyListener: function(node, entry) | 157 notifyListener: function(node, entry) |
| 187 { | 158 { |
| 188 if (this.nodes) | 159 if (this.nodes) |
| 189 this.nodes.set(entry.id, node); | 160 this.nodes.set(entry.id, node); |
| 190 sendAsyncMessage("AdblockPlus:FoundNodeData", { | 161 port.emit("foundNodeData", { |
| 191 notifierID: this.id, | 162 notifierID: this.id, |
| 192 data: entry | 163 data: entry |
| 193 }); | 164 }); |
| 194 }, | 165 }, |
| 195 | 166 |
| 196 onComplete: function() | 167 onComplete: function() |
| 197 { | 168 { |
| 198 sendAsyncMessage("AdblockPlus:ScanComplete", this.id); | 169 port.emit("scanComplete", this.id); |
| 199 }, | 170 }, |
| 200 | 171 |
| 201 /** | 172 /** |
| 202 * Number of currently posted scan events (will be 0 when the scan finishes | 173 * Number of currently posted scan events (will be 0 when the scan finishes |
| 203 * running). | 174 * running). |
| 204 */ | 175 */ |
| 205 eventsPosted: 0, | 176 eventsPosted: 0, |
| 206 | 177 |
| 207 /** | 178 /** |
| 208 * Starts the initial scan of the window (will recurse into frames). | 179 * Starts the initial scan of the window (will recurse into frames). |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 * Stops flashing nodes after a previous flashNodes() call. | 248 * Stops flashing nodes after a previous flashNodes() call. |
| 278 */ | 249 */ |
| 279 stopFlashing: function() | 250 stopFlashing: function() |
| 280 { | 251 { |
| 281 if (this.flasher) | 252 if (this.flasher) |
| 282 this.flasher.stop(); | 253 this.flasher.stop(); |
| 283 this.flasher = null; | 254 this.flasher = null; |
| 284 }, | 255 }, |
| 285 | 256 |
| 286 /** | 257 /** |
| 287 * Attempts to calculate the size of the nodes associated with the requests, | 258 * Attempts to calculate the size of the nodes associated with the requests. |
| 288 * Sends message to parent when complete. | |
| 289 * @param {number[]} requests list of request IDs that were previously | 259 * @param {number[]} requests list of request IDs that were previously |
| 290 * reported by this notifier. | 260 * reported by this notifier. |
| 291 * @param {number} responseID ID to be sent with the response. | 261 * @return {number[]|null} either an array containing width and height or |
| 262 * null if the size could not be calculated. |
| 292 */ | 263 */ |
| 293 retrieveNodeSize: function(requests, responseID) | 264 retrieveNodeSize: function(requests) |
| 294 { | 265 { |
| 295 function getNodeSize(node) | 266 function getNodeSize(node) |
| 296 { | 267 { |
| 297 if (node instanceof Ci.nsIDOMHTMLImageElement && (node.naturalWidth || nod
e.naturalHeight)) | 268 if (node instanceof Ci.nsIDOMHTMLImageElement && (node.naturalWidth || nod
e.naturalHeight)) |
| 298 return [node.naturalWidth, node.naturalHeight]; | 269 return [node.naturalWidth, node.naturalHeight]; |
| 299 else if (node instanceof Ci.nsIDOMHTMLElement && (node.offsetWidth || node
.offsetHeight)) | 270 else if (node instanceof Ci.nsIDOMHTMLElement && (node.offsetWidth || node
.offsetHeight)) |
| 300 return [node.offsetWidth, node.offsetHeight]; | 271 return [node.offsetWidth, node.offsetHeight]; |
| 301 else | 272 else |
| 302 return null; | 273 return null; |
| 303 } | 274 } |
| 304 | 275 |
| 305 let size = null; | 276 let size = null; |
| 306 for (let id of requests) | 277 for (let id of requests) |
| 307 { | 278 { |
| 308 if (!this.nodes.has(id)) | 279 if (!this.nodes.has(id)) |
| 309 continue; | 280 continue; |
| 310 | 281 |
| 311 let node = this.nodes.get(id); | 282 let node = this.nodes.get(id); |
| 312 if (Cu.isDeadWrapper(node)) | 283 if (Cu.isDeadWrapper(node)) |
| 313 this.nodes.delete(node); | 284 this.nodes.delete(node); |
| 314 else | 285 else |
| 315 { | 286 { |
| 316 size = getNodeSize(node); | 287 size = getNodeSize(node); |
| 317 if (size) | 288 if (size) |
| 318 break; | 289 break; |
| 319 } | 290 } |
| 320 } | 291 } |
| 321 sendAsyncMessage("AdblockPlus:NotifierResponse", { | 292 return size; |
| 322 notifierID: this.id, | |
| 323 responseID, | |
| 324 response: size | |
| 325 }); | |
| 326 }, | 293 }, |
| 327 | 294 |
| 328 /** | 295 /** |
| 329 * Stores the nodes associated with the requests and generates a unique ID | 296 * Stores the nodes associated with the requests and generates a unique ID |
| 330 * for them that can be used with Policy.refilterNodes(). Sends message to | 297 * for them that can be used with Policy.refilterNodes(). |
| 331 * parent when complete. | |
| 332 * @param {number[]} requests list of request IDs that were previously | 298 * @param {number[]} requests list of request IDs that were previously |
| 333 * reported by this notifier. | 299 * reported by this notifier. |
| 334 * @param {number} responseID ID to be sent with the response. | 300 * @return {string} unique identifiers associated with the nodes. |
| 335 */ | 301 */ |
| 336 storeNodesForEntries: function(requests, responseID) | 302 storeNodesForEntries: function(requests) |
| 337 { | 303 { |
| 338 let nodes = []; | 304 let nodes = []; |
| 339 for (let id of requests) | 305 for (let id of requests) |
| 340 { | 306 { |
| 341 if (!this.nodes.has(id)) | 307 if (!this.nodes.has(id)) |
| 342 continue; | 308 continue; |
| 343 | 309 |
| 344 let node = this.nodes.get(id); | 310 let node = this.nodes.get(id); |
| 345 if (Cu.isDeadWrapper(node)) | 311 if (Cu.isDeadWrapper(node)) |
| 346 this.nodes.delete(node); | 312 this.nodes.delete(node); |
| 347 else | 313 else |
| 348 nodes.push(node); | 314 nodes.push(node); |
| 349 } | 315 } |
| 350 | 316 |
| 351 let {storeNodes} = require("child/contentPolicy"); | 317 let {storeNodes} = require("child/contentPolicy"); |
| 352 let id = storeNodes(nodes); | 318 return storeNodes(nodes); |
| 353 sendAsyncMessage("AdblockPlus:NotifierResponse", { | |
| 354 notifierID: this.id, | |
| 355 responseID, | |
| 356 response: id | |
| 357 }); | |
| 358 } | 319 } |
| 359 }; | 320 }; |
| 360 | 321 |
| 361 /** | 322 /** |
| 362 * Attaches request data to a DOM node. | 323 * Attaches request data to a DOM node. |
| 363 * @param {Node} node node to attach data to | 324 * @param {Node} node node to attach data to |
| 364 * @param {Window} topWnd top-level window the node belongs to | 325 * @param {Window} topWnd top-level window the node belongs to |
| 365 * @param {Object} hitData | 326 * @param {Object} hitData |
| 366 * @param {String} hitData.contentType request type, e.g. "IMAGE" | 327 * @param {String} hitData.contentType request type, e.g. "IMAGE" |
| 367 * @param {String} hitData.docDomain domain of the document that initiated the
request | 328 * @param {String} hitData.docDomain domain of the document that initiated the
request |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 node = node.parentNode; | 435 node = node.parentNode; |
| 475 } | 436 } |
| 476 else | 437 else |
| 477 { | 438 { |
| 478 node = null; | 439 node = null; |
| 479 } | 440 } |
| 480 } | 441 } |
| 481 | 442 |
| 482 return null; | 443 return null; |
| 483 }; | 444 }; |
| OLD | NEW |