| Index: lib/contentPolicy.js | 
| =================================================================== | 
| --- a/lib/contentPolicy.js | 
| +++ b/lib/contentPolicy.js | 
| @@ -25,17 +25,16 @@ Cu.import("resource://gre/modules/Servic | 
| let {TimeLine} = require("timeline"); | 
| let {Utils} = require("utils"); | 
| let {Prefs} = require("prefs"); | 
| let {FilterStorage} = require("filterStorage"); | 
| let {BlockingFilter, WhitelistFilter} = require("filterClasses"); | 
| let {defaultMatcher} = require("matcher"); | 
| let {objectMouseEventHander} = require("objectTabs"); | 
| let {RequestNotifier} = require("requestNotifier"); | 
| -let {ElemHide} = require("elemHide"); | 
| /** | 
| * List of explicitly supported content types | 
| * @type Array of String | 
| */ | 
| let contentTypes = ["OTHER", "SCRIPT", "IMAGE", "STYLESHEET", "OBJECT", "SUBDOCUMENT", "DOCUMENT", "XMLHTTPREQUEST", "OBJECT_SUBREQUEST", "FONT", "MEDIA"]; | 
| /** | 
| @@ -138,91 +137,106 @@ let Policy = exports.Policy = | 
| { | 
| Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET); | 
| }) | 
| TimeLine.log("done registering stylesheet"); | 
| TimeLine.leave("Done initializing content policy"); | 
| }, | 
| + processWindow: function(wnd) | 
| + { | 
| + let uri = wnd.document.documentURIObject; | 
| + if (!uri) | 
| + return true; | 
| + | 
| + if (!Policy.isBlockableScheme(uri.scheme)) | 
| + return true; | 
| + | 
| + let topWnd = wnd.top; | 
| + if (!topWnd || !topWnd.location || !topWnd.location.href) | 
| + return true; | 
| + | 
| + let testWnd = wnd; | 
| + let parentWndLocation = getWindowLocation(testWnd); | 
| + while (true) | 
| + { | 
| + let testWndLocation = parentWndLocation; | 
| + parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWindowLocation(testWnd.parent)); | 
| + | 
| + let match = Policy.isWhitelisted(testWndLocation, parentWndLocation); | 
| + | 
| + if (match == null) | 
| + { | 
| + let keydata = (testWnd.document && testWnd.document.documentElement ? testWnd.document.documentElement.getAttribute("data-adblockkey") : null); | 
| + if (keydata && keydata.indexOf("_") >= 0) | 
| + { | 
| + let [key, signature] = keydata.split("_", 2); | 
| + let keyMatch = defaultMatcher.matchesByKey(testWndLocation, key.replace(/=/g, ""), docDomain); | 
| + if (keyMatch && Utils.crypto) | 
| + { | 
| + // Website specifies a key that we know but is the signature valid? | 
| + let uri = Services.io.newURI(testWndLocation, null, null); | 
| + let params = [ | 
| + uri.path.replace(/#.*/, ""), // REQUEST_URI | 
| + uri.asciiHost, // HTTP_HOST | 
| + Utils.httpProtocol.userAgent // HTTP_USER_AGENT | 
| + ]; | 
| + if (Utils.verifySignature(key, signature, params.join("\0"))) | 
| + match = keyMatch; // XXX what is this? | 
| + } | 
| + } | 
| + } | 
| + | 
| + if (match instanceof WhitelistFilter) | 
| + { | 
| + FilterStorage.increaseHitCount(match, wnd); | 
| + RequestNotifier.addNodeData(testWnd.document, topWnd, Policy.type.DOCUMENT, getHostname(parentWndLocation), false, testWndLocation, match); | 
| + return true; | 
| + } | 
| + | 
| + if (testWnd.parent == testWnd) | 
| + break; | 
| + else | 
| + testWnd = testWnd.parent; | 
| + } | 
| + | 
| + return false; | 
| + }, | 
| + | 
| /** | 
| * Checks whether a node should be blocked, hides it if necessary | 
| * @param wnd {nsIDOMWindow} | 
| * @param node {nsIDOMElement} | 
| * @param contentType {String} | 
| * @param location {nsIURI} | 
| * @param collapse {Boolean} true to force hiding of the node | 
| * @return {Boolean} false if the node should be blocked | 
| */ | 
| processNode: function(wnd, node, contentType, location, collapse) | 
| { | 
| - let topWnd = wnd.top; | 
| - if (!topWnd || !topWnd.location || !topWnd.location.href) | 
| + if (Policy.processWindow(wnd)) | 
| return true; | 
| + let topWnd = wnd.top; | 
| let originWindow = Utils.getOriginWindow(wnd); | 
| let wndLocation = originWindow.location.href; | 
| let docDomain = getHostname(wndLocation); | 
| - let match = null; | 
| - if (!match && Prefs.enabled) | 
| - { | 
| - let testWnd = wnd; | 
| - let parentWndLocation = getWindowLocation(testWnd); | 
| - while (true) | 
| - { | 
| - let testWndLocation = parentWndLocation; | 
| - parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWindowLocation(testWnd.parent)); | 
| - match = Policy.isWhitelisted(testWndLocation, parentWndLocation); | 
| - | 
| - if (!(match instanceof WhitelistFilter)) | 
| - { | 
| - let keydata = (testWnd.document && testWnd.document.documentElement ? testWnd.document.documentElement.getAttribute("data-adblockkey") : null); | 
| - if (keydata && keydata.indexOf("_") >= 0) | 
| - { | 
| - let [key, signature] = keydata.split("_", 2); | 
| - let keyMatch = defaultMatcher.matchesByKey(testWndLocation, key.replace(/=/g, ""), docDomain); | 
| - if (keyMatch && Utils.crypto) | 
| - { | 
| - // Website specifies a key that we know but is the signature valid? | 
| - let uri = Services.io.newURI(testWndLocation, null, null); | 
| - let params = [ | 
| - uri.path.replace(/#.*/, ""), // REQUEST_URI | 
| - uri.asciiHost, // HTTP_HOST | 
| - Utils.httpProtocol.userAgent // HTTP_USER_AGENT | 
| - ]; | 
| - if (Utils.verifySignature(key, signature, params.join("\0"))) | 
| - match = keyMatch; | 
| - } | 
| - } | 
| - } | 
| - | 
| - if (match instanceof WhitelistFilter) | 
| - { | 
| - FilterStorage.increaseHitCount(match, wnd); | 
| - RequestNotifier.addNodeData(testWnd.document, topWnd, Policy.type.DOCUMENT, getHostname(parentWndLocation), false, testWndLocation, match); | 
| - return true; | 
| - } | 
| - | 
| - if (testWnd.parent == testWnd) | 
| - break; | 
| - else | 
| - testWnd = testWnd.parent; | 
| - } | 
| - } | 
| // Data loaded by plugins should be attached to the document | 
| if (contentType == Policy.type.OBJECT_SUBREQUEST && node instanceof Ci.nsIDOMElement) | 
| node = node.ownerDocument; | 
| // Fix type for objects misrepresented as frames or images | 
| if (contentType != Policy.type.OBJECT && (node instanceof Ci.nsIDOMHTMLObjectElement || node instanceof Ci.nsIDOMHTMLEmbedElement)) | 
| contentType = Policy.type.OBJECT; | 
| let locationText = location.spec; | 
| - if (!match && contentType == Policy.type.ELEMHIDE) | 
| + let match = null; | 
| + if (contentType == Policy.type.ELEMHIDE) | 
| { | 
| let testWnd = wnd; | 
| let parentWndLocation = getWindowLocation(testWnd); | 
| while (true) | 
| { | 
| let testWndLocation = parentWndLocation; | 
| parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWindowLocation(testWnd.parent)); | 
| let parentDocDomain = getHostname(parentWndLocation); | 
| @@ -242,16 +256,17 @@ let Policy = exports.Policy = | 
| match = location; | 
| locationText = match.text.replace(/^.*?#/, '#'); | 
| location = locationText; | 
| if (!match.isActiveOnDomain(docDomain)) | 
| return true; | 
| + let {ElemHide} = require("elemHide"); | 
| let exception = ElemHide.getException(match, docDomain); | 
| if (exception) | 
| { | 
| FilterStorage.increaseHitCount(exception, wnd); | 
| RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdParty, locationText, exception); | 
| return true; | 
| } | 
| } |