| Index: lib/child/requestNotifier.js | 
| =================================================================== | 
| --- a/lib/child/requestNotifier.js | 
| +++ b/lib/child/requestNotifier.js | 
| @@ -31,21 +31,23 @@ let requestEntryMaxId = 0; | 
| * Active RequestNotifier instances by their ID | 
| * @type Map.<number,RequestNotifier> | 
| */ | 
| let notifiers = new Map(); | 
| addMessageListener("AdblockPlus:StartWindowScan", onStartScan); | 
| addMessageListener("AdblockPlus:ShutdownNotifier", onNotifierShutdown); | 
| addMessageListener("AdblockPlus:FlashNodes", onFlashNodes); | 
| +addMessageListener("AdblockPlus:RetrieveNodeSize", onRetrieveNodeSize); | 
| onShutdown.add(() => { | 
| removeMessageListener("AdblockPlus:StartWindowScan", onStartScan); | 
| removeMessageListener("AdblockPlus:ShutdownNotifier", onNotifierShutdown); | 
| removeMessageListener("AdblockPlus:FlashNodes", onFlashNodes); | 
| + removeMessageListener("AdblockPlus:RetrieveNodeSize", onRetrieveNodeSize); | 
| }); | 
| function onStartScan(message) | 
| { | 
| let {notifierID, outerWindowID} = message.data; | 
| let window = Services.wm.getOuterWindowWithId(outerWindowID); | 
| if (window) | 
| new RequestNotifier(window, notifierID); | 
| @@ -61,16 +63,24 @@ function onNotifierShutdown(message) | 
| function onFlashNodes(message) | 
| { | 
| let {notifierID, requests, scrollToItem} = message.data; | 
| let notifier = notifiers.get(notifierID); | 
| if (notifier) | 
| notifier.flashNodes(requests, scrollToItem); | 
| } | 
| +function onRetrieveNodeSize(message) | 
| +{ | 
| + let {notifierID, responseID, requests} = message.data; | 
| + let notifier = notifiers.get(notifierID); | 
| + if (notifier) | 
| + notifier.retrieveNodeSize(requests, responseID); | 
| +} | 
| + | 
| /** | 
| * Creates a notifier object for a particular window. After creation the window | 
| * will first be scanned for previously saved requests. Once that scan is | 
| * complete only new requests for this window will be reported. | 
| * @param {Window} window window to attach the notifier to | 
| * @param {Integer} notifierID Parent notifier ID to be messaged | 
| */ | 
| function RequestNotifier(window, notifierID) | 
| @@ -213,16 +223,58 @@ RequestNotifier.prototype = | 
| /** | 
| * Stops flashing nodes after a previous flashNodes() call. | 
| */ | 
| stopFlashing: function() | 
| { | 
| if (this.flasher) | 
| this.flasher.stop(); | 
| this.flasher = null; | 
| + }, | 
| + | 
| + /** | 
| + * Attempts to calculate the size of the nodes associated with the requests, | 
| + * Sends message to parent when complete. | 
| + * @param {number[]} requests list of request IDs that were previously | 
| + * reported by this notifier. | 
| + * @param {number} responseID ID to be sent with the response. | 
| + */ | 
| + retrieveNodeSize: function(requests, responseID) | 
| + { | 
| + function getNodeSize(node) | 
| + { | 
| + if (node instanceof Ci.nsIDOMHTMLImageElement && (node.naturalWidth || node.naturalHeight)) | 
| + return [node.naturalWidth, node.naturalHeight]; | 
| + else if (node instanceof Ci.nsIDOMHTMLElement && (node.offsetWidth || node.offsetHeight)) | 
| + return [node.offsetWidth, node.offsetHeight]; | 
| + else | 
| + return null; | 
| + } | 
| + | 
| + let size = null; | 
| + for (let id of requests) | 
| + { | 
| + if (!this.nodes.has(id)) | 
| + continue; | 
| + | 
| + let node = this.nodes.get(id); | 
| + if (Cu.isDeadWrapper(node)) | 
| + this.nodes.delete(node); | 
| + else | 
| + { | 
| + size = getNodeSize(node); | 
| + if (size) | 
| + break; | 
| + } | 
| + } | 
| + sendAsyncMessage("AdblockPlus:RetrieveNodeSizeResponse", { | 
| + notifierID: this.id, | 
| + responseID, | 
| + size | 
| + }); | 
| } | 
| }; | 
| /** | 
| * Attaches request data to a DOM node. | 
| * @param {Node} node node to attach data to | 
| * @param {Window} topWnd top-level window the node belongs to | 
| * @param {Object} hitData |