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

Unified Diff: lib/content/elemHideEmulation.js

Issue 30024560: Issue 7450 - Implement hide-if-contains-visible-text snippet (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Created March 6, 2019, 3:21 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 | test/browser/elemHideEmulation.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/content/elemHideEmulation.js
===================================================================
--- a/lib/content/elemHideEmulation.js
+++ b/lib/content/elemHideEmulation.js
@@ -337,40 +337,104 @@
if (testInfo)
testInfo.lastProcessedElements.add(element);
}
}
}
}
+/**
+ * Determine if the text inside the element is visible.
+ * @param {Element} element the leaf element we are checking.
+ * @returns {bool} whether the text is visible.
+ */
+function isTextVisible(element)
+{
+ let style = window.getComputedStyle(element);
hub 2019/03/06 16:34:11 I wonder if it is worth complexifying the code to
Manish Jethani 2019/03/12 12:24:09 If you have `<div style="display: none"><div>Spons
hub 2019/03/14 10:12:40 I think we can constrain to "visible within the sp
Manish Jethani 2019/03/14 11:36:33 OK, perhaps I can change my example to this: `<art
hub 2019/03/20 14:19:55 Actually I believe it should not hide it. But it d
hub 2019/03/20 16:31:11 This is handled properly now.
+
+ if (style.getPropertyValue("opacity") == "0")
+ return false;
+ if (style.getPropertyValue("font-size") == "0px")
+ return false;
+ let visibility = style.getPropertyValue("visibility");
+ if (visibility == "hidden" || visibility == "collapse")
+ return false;
+ if (style.getPropertyValue("display") == "none")
+ return false;
+ if (style.getPropertyValue("color") ==
+ style.getPropertyValue("background-color"))
+ return false;
+
+ return true;
+}
+
+/**
+ * Returns the visible text content from an element and its children.
+ * @param {Element} element the element whose visible text we want.
+ * @returns {String} the text that is visible.
+ */
+function getVisibleContent(element)
Manish Jethani 2019/03/12 08:44:01 Instead of doing all this, why not just use the `i
hub 2019/03/12 09:29:29 innerText doesn't know about opacity, 0 sized font
Manish Jethani 2019/03/12 12:24:09 Acknowledged.
+{
+ let text = "";
+ for (let node of element.childNodes)
+ {
+ switch (node.nodeType)
+ {
+ case Node.ELEMENT_NODE:
+ text += getVisibleContent(node);
+ break;
+ case Node.TEXT_NODE:
+ if (isTextVisible(element))
+ text += node.nodeValue;
+ break;
+ }
+ }
+ return text;
+}
+
class ContainsSelector
{
- constructor(textContent)
+ constructor(textContent, onlyVisible = false)
{
this.dependsOnDOM = true;
this.dependsOnCharacterData = true;
+ this._onlyVisible = onlyVisible;
this._regexp = makeRegExpParameter(textContent);
}
*getSelectors(prefix, subtree, styles, targets)
{
for (let element of this.getElements(prefix, subtree, styles, targets))
yield [makeSelector(element), subtree];
}
*getElements(prefix, subtree, styles, targets)
{
let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ?
prefix + "*" : prefix;
let elements = scopedQuerySelectorAll(subtree, actualPrefix);
- if (elements)
+ if (!elements)
+ return;
+
+ if (this._onlyVisible)
+ {
+ for (let element of elements)
+ {
+ let visibleContent = getVisibleContent(element);
+ if (this._regexp && this._regexp.test(visibleContent))
+ yield element;
+ else
+ yield null;
+ }
+ }
+ else
{
let lastRoot = null;
for (let element of elements)
{
// For a filter like div:-abp-contains(Hello) and a subtree like
// <div id="a"><div id="b"><div id="c">Hello</div></div></div>
// we're only interested in div#a
if (lastRoot && lastRoot.contains(element))
@@ -661,16 +725,18 @@
{
let hasSelectors = this.parseSelector(content.text);
if (hasSelectors == null)
return null;
selectors.push(new HasSelector(hasSelectors));
}
else if (match[1] == "contains")
selectors.push(new ContainsSelector(content.text));
+ else if (match[1] == "contains-visible")
+ selectors.push(new ContainsSelector(content.text, true));
else
{
// this is an error, can't parse selector.
console.error(new SyntaxError("Failed to parse Adblock Plus " +
`selector ${selector}, invalid ` +
`pseudo-class :-abp-${match[1]}().`));
return null;
}
« no previous file with comments | « no previous file | test/browser/elemHideEmulation.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld