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

Unified Diff: include.postload.js

Issue 5468762555809792: Issue 1601 - Generate blocking filters for all URLs associated with the selected element (Closed)
Patch Set: Simplified code Created Nov. 26, 2014, 1:55 p.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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: include.postload.js
===================================================================
--- a/include.postload.js
+++ b/include.postload.js
@@ -175,6 +175,84 @@
}
}
+function getElementURLs(element) {
+ var urls = [];
+
+ if (element.src)
+ urls.push(element.src);
+
+ switch (element.localName)
+ {
+ case "object":
+ var url = element.getAttribute("data");
Wladimir Palant 2014/12/08 11:43:00 For reference: <object> also has archive and codeb
Sebastian Noack 2014/12/08 16:45:04 I agree, also note they are obsolete since HTML5,
Wladimir Palant 2014/12/08 20:31:09 Oh, you didn't have to deal with Java? :)
Sebastian Noack 2014/12/08 21:12:49 I see, that stuff is for Java. I prefer to ignore
+ if (url)
+ return [resolveURL(url)];
+
+ for (var i = 0; i < element.children.length; i++)
+ {
+ var child = element.children[i];
+ if (child.localName != "param")
+ continue;
+
+ var name = child.getAttribute("name");
+ if (name != "movie" && name != "src")
+ continue;
+
+ var value = child.getAttribute("value");
+ if (!value)
+ continue;
+
+ return [resolveURL(value)];
+ }
+
+ return [];
+
+ case "video":
+ case "audio":
+ case "picture":
+ for (var i = 0; i < element.children.length; i++)
+ {
+ var child = element.children[i];
+
+ if (child.localName != "source")
+ continue;
Wladimir Palant 2014/12/08 11:43:00 It seems that we need to handle <track> elements a
Sebastian Noack 2014/12/08 16:45:04 Done.
+
+ if (child.src)
+ urls.push(child.src);
+
+ urls = urls.concat(parseSrcSet(child));
Wladimir Palant 2014/12/08 11:43:00 Rather than generate a new array, I'd prefer: url
Sebastian Noack 2014/12/08 16:45:04 Right, I forgot that push() can add multiple items
+ }
+
+ if (element.poster)
+ urls.push(element.poster);
+
+ break;
+
+ case "img":
+ urls = urls.concat(parseSrcSet(element));
+ }
+
+ return urls;
+}
+
+function isBlockable(element)
+{
+ if (element.id)
+ return true;
+ if (element.classList.length > 0)
+ return true;
+ if (getElementURLs(element).length > 0)
+ return true;
+
+ // We only generate filters based on the "style" attribute,
+ // if this is the only way we can generate a filter, and
+ // only if there are at least two CSS properties defined.
+ if (/:.+:/.test(element.getAttribute("style")))
+ return true;
+
+ return false;
+}
+
// Gets the absolute position of an element by walking up the DOM tree,
// adding up offsets.
// I hope there's a better way because it just seems absolutely stupid
@@ -198,8 +276,7 @@
// If element doesn't have at least one of class name, ID or URL, give up
// because we don't know how to construct a filter rule for it
- var url = getElementURL(elt);
- if(!elt.className && !elt.id && !url)
+ if(!isBlockable(elt))
return;
// If the element isn't rendered (since its or one of its ancestor's
@@ -210,7 +287,6 @@
var thisStyle = getComputedStyle(elt, null);
var overlay = document.createElement('div');
overlay.prisoner = elt;
- overlay.prisonerURL = url;
overlay.className = "__adblockplus__overlay";
overlay.setAttribute('style', 'opacity:0.4; background-color:#ffffff; display:inline-box; ' + 'width:' + thisStyle.width + '; height:' + thisStyle.height + '; position:absolute; overflow:hidden; -webkit-box-sizing:border-box;');
var pos = getAbsolutePosition(elt);
@@ -277,7 +353,7 @@
clickHide_deactivate();
// Add overlays for elements with URLs so user can easily click them
- var elts = document.querySelectorAll('object,embed,img,iframe');
+ var elts = document.querySelectorAll('object,embed,img,iframe,video,audio,picture');
for(var i=0; i<elts.length; i++)
addElementOverlay(elts[i]);
@@ -345,7 +421,7 @@
return;
var target = e.target;
- while (target.parentNode && !(target.id || target.className || target.src || /:.+:/.test(target.getAttribute("style"))))
+ while (target.parentNode && !isBlockable(target))
target = target.parentNode;
if (target == document.documentElement || target == document.body)
target = null;
@@ -398,20 +474,17 @@
return;
var elt = currentElement;
- var url = null;
if (currentElement.classList.contains("__adblockplus__overlay"))
- {
elt = currentElement.prisoner;
- url = currentElement.prisonerURL;
- }
- else if (elt.src)
- url = elt.src;
clickHideFilters = new Array();
selectorList = new Array();
var addSelector = function(selector)
{
+ if (selectorList.indexOf(selector) != -1)
+ return;
+
clickHideFilters.push(document.domain + "##" + selector);
selectorList.push(selector);
};
@@ -429,20 +502,23 @@
addSelector(selector);
}
- if (url)
+ var urls = getElementURLs(elt);
+ for (var i = 0; i < urls.length; i++)
{
- var src = elt.getAttribute("src");
- var selector = src && escapeCSS(elt.localName) + '[src=' + quote(src) + ']';
+ var url = urls[i];
Sebastian Noack 2014/11/26 14:01:22 A fair amount of complexity here, only came from g
if (/^https?:/i.test(url))
{
- clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"));
+ var filter = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||");
- if (selector)
- selectorList.push(selector);
+ if (clickHideFilters.indexOf(filter) == -1)
+ clickHideFilters.push(filter);
+
+ continue;
}
- else if (selector)
- addSelector(selector);
+
+ if (url == elt.src)
+ addSelector(escapeCSS(elt.localName) + '[src=' + quote(elt.getAttribute("src")) + ']');
}
// restore the original style, before generating the fallback filter that
@@ -470,29 +546,22 @@
e.stopPropagation();
}
-// Extracts source URL from an IMG, OBJECT, EMBED, or IFRAME
-function getElementURL(elt) {
- // Check children of object nodes for "param" nodes with name="movie" that specify a URL
- // in value attribute
- var url;
- if(elt.localName.toUpperCase() == "OBJECT" && !(url = elt.getAttribute("data"))) {
- // No data attribute, look in PARAM child tags for a URL for the swf file
- var params = elt.querySelectorAll("param[name=\"movie\"]");
- // This OBJECT could contain an EMBED we already nuked, in which case there's no URL
- if(params[0])
- url = params[0].getAttribute("value");
- else {
- params = elt.querySelectorAll("param[name=\"src\"]");
- if(params[0])
- url = params[0].getAttribute("value");
- }
+function parseSrcSet(element)
+{
+ if (!element.srcset)
+ return [];
+ var urls = element.srcset.split(",");
+ for (var i = 0; i < urls.length; i++)
+ {
+ var url = urls[i].replace(/^\s+/, "").replace(/(\s+\S+)?\s*$/, "");
Wladimir Palant 2014/12/08 11:43:00 Use urls[i].trim()? According to http://kangax.git
Sebastian Noack 2014/12/08 16:45:04 Done.
if (url)
- url = resolveURL(url);
- } else if(!url) {
- url = elt.src || elt.href;
+ urls[i] = resolveURL(url);
Wladimir Palant 2014/12/08 11:43:00 What about descriptions? See http://html5hub.com/s
Sebastian Noack 2014/12/08 16:45:04 Those are stripped by the regex above.
+ else
+ urls.splice(i--, 1);
}
- return url;
+
+ return urls;
}
// This function Copyright (c) 2008 Jeni Tennison, from jquery.uri.js
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld