| Left: | ||
| Right: |
| 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-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 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 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 { | 114 { |
| 115 Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService. USER_SHEET); | 115 Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService. USER_SHEET); |
| 116 }); | 116 }); |
| 117 }, | 117 }, |
| 118 | 118 |
| 119 /** | 119 /** |
| 120 * Checks whether a node should be blocked, hides it if necessary | 120 * Checks whether a node should be blocked, hides it if necessary |
| 121 * @param wnd {nsIDOMWindow} | 121 * @param wnd {nsIDOMWindow} |
| 122 * @param node {nsIDOMElement} | 122 * @param node {nsIDOMElement} |
| 123 * @param contentType {String} | 123 * @param contentType {String} |
| 124 * @param location {nsIURI} | 124 * @param location {String} |
| 125 * @param collapse {Boolean} true to force hiding of the node | 125 * @param collapse {Boolean} true to force hiding of the node |
| 126 * @return {Boolean} false if the node should be blocked | 126 * @return {Boolean} false if the node should be blocked |
| 127 */ | 127 */ |
| 128 processNode: function(wnd, node, contentType, location, collapse) | 128 processNode: function(wnd, node, contentType, location, collapse) |
| 129 { | 129 { |
| 130 let topWnd = wnd.top; | 130 let topWnd = wnd.top; |
| 131 if (!topWnd || !topWnd.location || !topWnd.location.href) | 131 if (!topWnd || !topWnd.location || !topWnd.location.href) |
| 132 return true; | 132 return true; |
| 133 | 133 |
| 134 // Interpret unknown types as "other" | 134 // Interpret unknown types as "other" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 } | 200 } |
| 201 | 201 |
| 202 // Data loaded by plugins should be attached to the document | 202 // Data loaded by plugins should be attached to the document |
| 203 if (contentType == "OBJECT_SUBREQUEST" && node instanceof Ci.nsIDOMElement) | 203 if (contentType == "OBJECT_SUBREQUEST" && node instanceof Ci.nsIDOMElement) |
| 204 node = node.ownerDocument; | 204 node = node.ownerDocument; |
| 205 | 205 |
| 206 // Fix type for objects misrepresented as frames or images | 206 // Fix type for objects misrepresented as frames or images |
| 207 if (contentType != "OBJECT" && (node instanceof Ci.nsIDOMHTMLObjectElement | | node instanceof Ci.nsIDOMHTMLEmbedElement)) | 207 if (contentType != "OBJECT" && (node instanceof Ci.nsIDOMHTMLObjectElement | | node instanceof Ci.nsIDOMHTMLEmbedElement)) |
| 208 contentType = "OBJECT"; | 208 contentType = "OBJECT"; |
| 209 | 209 |
| 210 let locationText = location.spec; | |
| 211 if (!match && contentType == "ELEMHIDE") | 210 if (!match && contentType == "ELEMHIDE") |
| 212 { | 211 { |
| 213 match = location; | 212 match = location; |
| 214 locationText = match.text.replace(/^.*?#/, '#'); | 213 location = match.text.replace(/^.*?#/, '#'); |
|
tschuster
2015/10/31 11:55:23
Wait, how does this work?
On the right hand side
Wladimir Palant
2015/11/01 12:18:09
Yes, this is quite a hack. Calls with content type
| |
| 215 location = locationText; | |
| 216 | 214 |
| 217 if (!match.isActiveOnDomain(docDomain)) | 215 if (!match.isActiveOnDomain(docDomain)) |
| 218 return true; | 216 return true; |
| 219 | 217 |
| 220 let exception = ElemHide.getException(match, docDomain); | 218 let exception = ElemHide.getException(match, docDomain); |
| 221 if (exception) | 219 if (exception) |
| 222 { | 220 { |
| 223 FilterStorage.increaseHitCount(exception, wnd); | 221 FilterStorage.increaseHitCount(exception, wnd); |
| 224 RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, false, locationText, exception); | 222 RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, false, location, exception); |
| 225 return true; | 223 return true; |
| 226 } | 224 } |
| 227 | 225 |
| 228 if (nogeneric && match.isGeneric()) | 226 if (nogeneric && match.isGeneric()) |
| 229 return true; | 227 return true; |
| 230 } | 228 } |
| 231 | 229 |
| 232 let thirdParty = (contentType == "ELEMHIDE" ? false : isThirdParty(location, docDomain)); | 230 let thirdParty = (contentType == "ELEMHIDE" ? false : isThirdParty(location, docDomain)); |
| 233 | 231 |
| 234 if (!match && Prefs.enabled && RegExpFilter.typeMap.hasOwnProperty(contentTy pe)) | 232 if (!match && Prefs.enabled && RegExpFilter.typeMap.hasOwnProperty(contentTy pe)) |
| 235 { | 233 { |
| 236 match = defaultMatcher.matchesAny(locationText, RegExpFilter.typeMap[conte ntType], | 234 match = defaultMatcher.matchesAny(location, RegExpFilter.typeMap[contentTy pe], |
| 237 docDomain, thirdParty, sitekey, nogeneri c); | 235 docDomain, thirdParty, sitekey, nogeneri c); |
| 238 if (match instanceof BlockingFilter && node.ownerDocument && !nonVisualTyp es.has(contentType)) | 236 if (match instanceof BlockingFilter && node.ownerDocument && !nonVisualTyp es.has(contentType)) |
| 239 { | 237 { |
| 240 let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fas tcollapse); | 238 let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fas tcollapse); |
| 241 if (collapse || prefCollapse) | 239 if (collapse || prefCollapse) |
| 242 schedulePostProcess(node); | 240 schedulePostProcess(node); |
| 243 } | 241 } |
| 244 | 242 |
| 245 // Track mouse events for objects | 243 // Track mouse events for objects |
| 246 if (!match && contentType == "OBJECT" && node.nodeType == Ci.nsIDOMNode.EL EMENT_NODE) | 244 if (!match && contentType == "OBJECT" && node.nodeType == Ci.nsIDOMNode.EL EMENT_NODE) |
| 247 { | 245 { |
| 248 node.addEventListener("mouseover", objectMouseEventHander, true); | 246 node.addEventListener("mouseover", objectMouseEventHander, true); |
| 249 node.addEventListener("mouseout", objectMouseEventHander, true); | 247 node.addEventListener("mouseout", objectMouseEventHander, true); |
| 250 } | 248 } |
| 251 } | 249 } |
| 252 | 250 |
| 253 // Store node data | 251 // Store node data |
| 254 RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdParty , locationText, match); | 252 RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdParty , location, match); |
| 255 if (match) | 253 if (match) |
| 256 FilterStorage.increaseHitCount(match, wnd); | 254 FilterStorage.increaseHitCount(match, wnd); |
| 257 | 255 |
| 258 return !match || match instanceof WhitelistFilter; | 256 return !match || match instanceof WhitelistFilter; |
| 259 }, | 257 }, |
| 260 | 258 |
| 261 /** | 259 /** |
| 262 * Checks whether the location's scheme is blockable. | 260 * Checks whether the location's scheme is blockable. |
| 263 * @param location {nsIURI} | 261 * @param location {nsIURI} |
| 264 * @return {Boolean} | 262 * @return {Boolean} |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 | 381 |
| 384 let wnd = Utils.getWindow(node); | 382 let wnd = Utils.getWindow(node); |
| 385 if (!wnd) | 383 if (!wnd) |
| 386 return Ci.nsIContentPolicy.ACCEPT; | 384 return Ci.nsIContentPolicy.ACCEPT; |
| 387 | 385 |
| 388 // Ignore whitelisted schemes | 386 // Ignore whitelisted schemes |
| 389 let location = Utils.unwrapURL(contentLocation); | 387 let location = Utils.unwrapURL(contentLocation); |
| 390 if (!Policy.isBlockableScheme(location)) | 388 if (!Policy.isBlockableScheme(location)) |
| 391 return Ci.nsIContentPolicy.ACCEPT; | 389 return Ci.nsIContentPolicy.ACCEPT; |
| 392 | 390 |
| 393 let result = Policy.processNode(wnd, node, types.get(contentType), location, false); | 391 let result = Policy.processNode(wnd, node, types.get(contentType), location. spec, false); |
| 394 return (result ? Ci.nsIContentPolicy.ACCEPT : Ci.nsIContentPolicy.REJECT_REQ UEST); | 392 return (result ? Ci.nsIContentPolicy.ACCEPT : Ci.nsIContentPolicy.REJECT_REQ UEST); |
| 395 }, | 393 }, |
| 396 | 394 |
| 397 shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode , mimeType, extra) | 395 shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode , mimeType, extra) |
| 398 { | 396 { |
| 399 return Ci.nsIContentPolicy.ACCEPT; | 397 return Ci.nsIContentPolicy.ACCEPT; |
| 400 }, | 398 }, |
| 401 | 399 |
| 402 // | 400 // |
| 403 // nsIObserver interface implementation | 401 // nsIObserver interface implementation |
| 404 // | 402 // |
| 405 observe: function(subject, topic, data, additional) | 403 observe: function(subject, topic, data, additional) |
| 406 { | 404 { |
| 407 switch (topic) | 405 switch (topic) |
| 408 { | 406 { |
| 409 case "content-document-global-created": | 407 case "content-document-global-created": |
| 410 { | 408 { |
| 411 if (!(subject instanceof Ci.nsIDOMWindow) || !subject.opener) | 409 if (!(subject instanceof Ci.nsIDOMWindow) || !subject.opener) |
| 412 return; | 410 return; |
| 413 | 411 |
| 414 let uri = additional || Utils.makeURI(subject.location.href); | 412 let uri = additional || subject.location.href; |
| 415 if (!Policy.processNode(subject.opener, subject.opener.document, "POPUP" , uri, false)) | 413 if (!Policy.processNode(subject.opener, subject.opener.document, "POPUP" , uri, false)) |
| 416 { | 414 { |
| 417 subject.stop(); | 415 subject.stop(); |
| 418 Utils.runAsync(() => subject.close()); | 416 Utils.runAsync(() => subject.close()); |
| 419 } | 417 } |
| 420 else if (uri.spec == "about:blank") | 418 else if (uri == "about:blank") |
| 421 { | 419 { |
| 422 // An about:blank pop-up most likely means that a load will be | 420 // An about:blank pop-up most likely means that a load will be |
| 423 // initiated asynchronously. Wait for that. | 421 // initiated asynchronously. Wait for that. |
| 424 Utils.runAsync(function() | 422 Utils.runAsync(function() |
| 425 { | 423 { |
| 426 let channel = subject.QueryInterface(Ci.nsIInterfaceRequestor) | 424 let channel = subject.QueryInterface(Ci.nsIInterfaceRequestor) |
| 427 .getInterface(Ci.nsIDocShell) | 425 .getInterface(Ci.nsIDocShell) |
| 428 .QueryInterface(Ci.nsIDocumentLoader) | 426 .QueryInterface(Ci.nsIDocumentLoader) |
| 429 .documentChannel; | 427 .documentChannel; |
| 430 if (channel) | 428 if (channel) |
| 431 this.observe(subject, topic, data, channel.URI); | 429 this.observe(subject, topic, data, channel.URI.spec); |
| 432 }); | 430 }); |
| 433 } | 431 } |
| 434 break; | 432 break; |
| 435 } | 433 } |
| 436 } | 434 } |
| 437 }, | 435 }, |
| 438 | 436 |
| 439 // | 437 // |
| 440 // nsIChannelEventSink interface implementation | 438 // nsIChannelEventSink interface implementation |
| 441 // | 439 // |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 456 if (!wnd) | 454 if (!wnd) |
| 457 return; | 455 return; |
| 458 | 456 |
| 459 if (contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT) | 457 if (contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT) |
| 460 { | 458 { |
| 461 if (wnd.history.length <= 1 && wnd.opener) | 459 if (wnd.history.length <= 1 && wnd.opener) |
| 462 { | 460 { |
| 463 // Special treatment for pop-up windows. Note that we might not have | 461 // Special treatment for pop-up windows. Note that we might not have |
| 464 // seen the original channel yet because the redirect happened before | 462 // seen the original channel yet because the redirect happened before |
| 465 // the async code in observe() had a chance to run. | 463 // the async code in observe() had a chance to run. |
| 466 this.observe(wnd, "content-document-global-created", null, oldChannel. URI); | 464 this.observe(wnd, "content-document-global-created", null, oldChannel. URI.spec); |
| 467 this.observe(wnd, "content-document-global-created", null, newChannel. URI); | 465 this.observe(wnd, "content-document-global-created", null, newChannel. URI.spec); |
| 468 } | 466 } |
| 469 return; | 467 return; |
| 470 } | 468 } |
| 471 | 469 |
| 472 if (!Policy.processNode(wnd, wnd.document, types.get(contentType), newChan nel.URI, false)) | 470 if (!Policy.processNode(wnd, wnd.document, types.get(contentType), newChan nel.URI.spec, false)) |
| 473 result = Cr.NS_BINDING_ABORTED; | 471 result = Cr.NS_BINDING_ABORTED; |
| 474 } | 472 } |
| 475 catch (e) | 473 catch (e) |
| 476 { | 474 { |
| 477 // We shouldn't throw exceptions here - this will prevent the redirect. | 475 // We shouldn't throw exceptions here - this will prevent the redirect. |
| 478 Cu.reportError(e); | 476 Cu.reportError(e); |
| 479 } | 477 } |
| 480 finally | 478 finally |
| 481 { | 479 { |
| 482 callback.onRedirectVerifyCallback(result); | 480 callback.onRedirectVerifyCallback(result); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 } catch(e) {} | 642 } catch(e) {} |
| 645 } | 643 } |
| 646 | 644 |
| 647 // Firefox branch | 645 // Firefox branch |
| 648 return wnd.location.href; | 646 return wnd.location.href; |
| 649 } | 647 } |
| 650 | 648 |
| 651 /** | 649 /** |
| 652 * Checks whether the location's origin is different from document's origin. | 650 * Checks whether the location's origin is different from document's origin. |
| 653 */ | 651 */ |
| 654 function isThirdParty(/**nsIURI*/location, /**String*/ docDomain) /**Boolean*/ | 652 function isThirdParty(/**String*/location, /**String*/ docDomain) /**Boolean*/ |
| 655 { | 653 { |
| 656 if (!location || !docDomain) | 654 if (!location || !docDomain) |
| 657 return true; | 655 return true; |
| 658 | 656 |
| 657 let uri = Utils.makeURI(location); | |
| 659 try | 658 try |
| 660 { | 659 { |
| 661 return Utils.effectiveTLD.getBaseDomain(location) != Utils.effectiveTLD.getB aseDomainFromHost(docDomain); | 660 return Utils.effectiveTLD.getBaseDomain(uri) != Utils.effectiveTLD.getBaseDo mainFromHost(docDomain); |
| 662 } | 661 } |
| 663 catch (e) | 662 catch (e) |
| 664 { | 663 { |
| 665 // EffectiveTLDService throws on IP addresses, just compare the host name | 664 // EffectiveTLDService throws on IP addresses, just compare the host name |
| 666 let host = ""; | 665 let host = ""; |
| 667 try | 666 try |
| 668 { | 667 { |
| 669 host = location.host; | 668 host = uri.host; |
| 670 } catch (e) {} | 669 } catch (e) {} |
| 671 return host != docDomain; | 670 return host != docDomain; |
| 672 } | 671 } |
| 673 } | 672 } |
| 674 | 673 |
| 675 /** | 674 /** |
| 676 * Re-checks filters on an element. | 675 * Re-checks filters on an element. |
| 677 */ | 676 */ |
| 678 function refilterNode(/**Node*/ node, /**RequestEntry*/ entry) | 677 function refilterNode(/**Node*/ node, /**RequestEntry*/ entry) |
| 679 { | 678 { |
| 680 let wnd = Utils.getWindow(node); | 679 let wnd = Utils.getWindow(node); |
| 681 if (!wnd || wnd.closed) | 680 if (!wnd || wnd.closed) |
| 682 return; | 681 return; |
| 683 | 682 |
| 684 if (entry.type == "OBJECT") | 683 if (entry.type == "OBJECT") |
| 685 { | 684 { |
| 686 node.removeEventListener("mouseover", objectMouseEventHander, true); | 685 node.removeEventListener("mouseover", objectMouseEventHander, true); |
| 687 node.removeEventListener("mouseout", objectMouseEventHander, true); | 686 node.removeEventListener("mouseout", objectMouseEventHander, true); |
| 688 } | 687 } |
| 689 Policy.processNode(wnd, node, entry.type, Utils.makeURI(entry.location), true) ; | 688 Policy.processNode(wnd, node, entry.type, entry.location, true); |
| 690 } | 689 } |
| OLD | NEW |