Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: include.preload.js

Issue 5088751004942336: Issue 370 - Right-clicked element is removed independent of created filter (Closed)
Patch Set: Rebase to rev 3c9cea80c481 Created July 18, 2014, 8:54 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include.postload.js ('k') | lib/basedomain.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: include.preload.js
===================================================================
--- a/include.preload.js
+++ b/include.preload.js
@@ -1,6 +1,6 @@
/*
* This file is part of Adblock Plus <http://adblockplus.org/>,
- * Copyright (C) 2006-2013 Eyeo GmbH
+ * Copyright (C) 2006-2014 Eyeo GmbH
*
* Adblock Plus is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
@@ -17,46 +17,6 @@
var SELECTOR_GROUP_SIZE = 20;
-var elemhideElt = null;
-
-// Sets the currently used CSS rules for elemhide filters
-function setElemhideCSSRules(selectors)
-{
- if (elemhideElt && elemhideElt.parentNode)
- elemhideElt.parentNode.removeChild(elemhideElt);
-
- if (!selectors)
- return;
-
- elemhideElt = document.createElement("style");
- elemhideElt.setAttribute("type", "text/css");
-
- // Try to insert the style into the <head> tag, inserting directly under the
- // document root breaks dev tools functionality:
- // http://code.google.com/p/chromium/issues/detail?id=178109
- (document.head || document.documentElement).appendChild(elemhideElt);
-
- var elt = elemhideElt; // Use a local variable to avoid racing conditions
- function setRules()
- {
- if (!elt.sheet)
- {
- // Stylesheet didn't initialize yet, wait a little longer
- window.setTimeout(setRules, 0);
- return;
- }
-
- // WebKit apparently chokes when the selector list in a CSS rule is huge.
- // So we split the elemhide selectors into groups.
- for (var i = 0, j = 0; i < selectors.length; i += SELECTOR_GROUP_SIZE, j++)
- {
- var selector = selectors.slice(i, i + SELECTOR_GROUP_SIZE).join(", ");
- elt.sheet.insertRule(selector + " { display: none !important; }", j);
- }
- }
- setRules();
-}
-
var typeMap = {
"img": "IMAGE",
"input": "IMAGE",
@@ -66,15 +26,13 @@
"iframe": "SUBDOCUMENT"
};
-function checkCollapse(event)
+function checkCollapse(element)
{
- var target = event.target;
- var tag = target.localName;
- var expectedEvent = (tag == "iframe" || tag == "frame" ? "load" : "error");
- if (tag in typeMap && event.type == expectedEvent)
+ var tag = element.localName;
+ if (tag in typeMap)
{
// This element failed loading, did we block it?
- var url = target.src;
+ var url = element.src;
if (!url)
return;
@@ -82,45 +40,193 @@
{
type: "should-collapse",
url: url,
- documentUrl: document.URL,
mediatype: typeMap[tag]
},
function(response)
{
- if (response && target.parentNode)
+ if (response && element.parentNode)
{
// <frame> cannot be removed, doing that will mess up the frameset
if (tag == "frame")
- target.style.setProperty("visibility", "hidden", "!important");
+ element.style.setProperty("visibility", "hidden", "important");
else
- target.parentNode.removeChild(target);
+ element.style.setProperty("display", "none", "important");
}
}
);
}
}
-function init()
+function checkExceptionKey()
{
- // Make sure this is really an HTML page, as Chrome runs these scripts on just about everything
- if (!(document.documentElement instanceof HTMLElement))
- return;
-
- document.addEventListener("error", checkCollapse, true);
- document.addEventListener("load", checkCollapse, true);
-
- ext.backgroundPage.sendMessage(
- {
- type: "get-selectors",
- frameUrl: window.location.href
- },
- setElemhideCSSRules
- );
+ var attr = document.documentElement.getAttribute("data-adblockkey");
+ if (attr)
+ ext.backgroundPage.sendMessage({type: "add-key-exception", token: attr});
}
-// In Chrome 18 the document might not be initialized yet
-if (document.documentElement)
- init();
-else
- window.setTimeout(init, 0);
+function hasInlineURL(element, attribute)
+{
+ var value = element.getAttribute(attribute);
+ return value == null || /^\s*(javascript:|about:|$)/i.test(value);
+}
+
+function isInlineFrame(element)
+{
+ switch (element.localName)
+ {
+ case "iframe":
+ return hasInlineURL(element, "src") || element.hasAttribute("srcdoc");
+ case "frame":
+ return hasInlineURL(element, "src");
+ case "object":
+ return hasInlineURL(element, "data") && element.contentDocument;
+ default:
+ return false;
+ }
+}
+
+// Converts relative to absolute URL
+// e.g.: foo.swf on http://example.com/whatever/bar.html
+// -> http://example.com/whatever/foo.swf
+function relativeToAbsoluteUrl(url)
+{
+ // If URL is already absolute, don't mess with it
+ if (!url || /^[\w\-]+:/i.test(url))
+ return url;
+
+ // Leading / means absolute path
+ // Leading // means network path
+ if (url[0] == '/')
+ {
+ if (url[1] == '/')
+ return document.location.protocol + url;
+ else
+ return document.location.protocol + "//" + document.location.host + url;
+ }
+
+ // Remove filename and add relative URL to it
+ var base = document.baseURI.match(/.+\//);
+ if (!base)
+ return document.baseURI + "/" + url;
+ return base[0] + url;
+}
+
+function init(document)
+{
+ var canUseShadow = "webkitCreateShadowRoot" in document.documentElement;
+ var fixInlineFrames = false;
+
+ var match = navigator.userAgent.match(/\bChrome\/(\d+)/);
+ if (match)
+ {
+ var chromeVersion = parseInt(match[1]);
+
+ // the <shadow> element is ignored in Chrome 32 (#309). Also Chrome 31-33
+ // crashes in some situations on some pages when using shadow DOM (#498).
+ // So we must not use Shadow DOM on those versions of Chrome.
+ if (chromeVersion >= 31 && chromeVersion <= 33)
+ canUseShadow = false;
+
+ // prior to Chrome 37, content scripts don't run on about:blank
+ // and about:srcdoc. So we have to apply element hiding and collapsing
+ // from the parent frame, when inline frames are loaded.
+ if (chromeVersion < 37)
+ fixInlineFrames = true;
+ }
+
+ // use Shadow DOM if available to don't mess with web pages that
+ // rely on the order of their own <style> tags (#309). However we
+ // must not create the shadow root in the response callback passed
+ // to sendMessage(), otherwise Chrome breaks some websites (#450).
+ if (canUseShadow)
+ {
+ var shadow = document.documentElement.webkitCreateShadowRoot();
+ shadow.appendChild(document.createElement("shadow"));
+ }
+
+ // Sets the currently used CSS rules for elemhide filters
+ var setElemhideCSSRules = function(selectors)
+ {
+ if (selectors.length == 0)
+ return;
+
+ var style = document.createElement("style");
+ style.setAttribute("type", "text/css");
+
+ if (canUseShadow)
+ {
+ shadow.appendChild(style);
+
+ try
+ {
+ document.querySelector("::content");
+
+ for (var i = 0; i < selectors.length; i++)
+ selectors[i] = "::content " + selectors[i];
+ }
+ catch (e)
+ {
+ for (var i = 0; i < selectors.length; i++)
+ selectors[i] = "::-webkit-distributed(" + selectors[i] + ")";
+ }
+ }
+ else
+ {
+ // Try to insert the style into the <head> tag, inserting directly under the
+ // document root breaks dev tools functionality:
+ // http://code.google.com/p/chromium/issues/detail?id=178109
+ (document.head || document.documentElement).appendChild(style);
+ }
+
+ var setRules = function()
+ {
+ // The sheet property might not exist yet if the
+ // <style> element was created for a sub frame
+ if (!style.sheet)
+ {
+ setTimeout(setRules, 0);
+ return;
+ }
+
+ // WebKit apparently chokes when the selector list in a CSS rule is huge.
+ // So we split the elemhide selectors into groups.
+ for (var i = 0; selectors.length > 0; i++)
+ {
+ var selector = selectors.splice(0, SELECTOR_GROUP_SIZE).join(", ");
+ style.sheet.insertRule(selector + " { display: none !important; }", i);
+ }
+ };
+
+ setRules();
+ };
+
+ document.addEventListener("error", function(event)
+ {
+ checkCollapse(event.target);
+ }, true);
+
+ document.addEventListener("load", function(event)
+ {
+ var element = event.target;
+
+ if (/^i?frame$/.test(element.localName))
+ checkCollapse(element);
+
+ if (fixInlineFrames && isInlineFrame(element))
+ {
+ init(element.contentDocument);
+
+ for (var tagName in typeMap)
+ Array.prototype.forEach.call(element.contentDocument.getElementsByTagName(tagName), checkCollapse);
+ }
+ }, true);
+
+ ext.backgroundPage.sendMessage({type: "get-selectors"}, setElemhideCSSRules);
+}
+
+if (document instanceof HTMLDocument)
+{
+ checkExceptionKey();
+ init(document);
+}
« no previous file with comments | « include.postload.js ('k') | lib/basedomain.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld