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

Unified Diff: lib/content/snippets.js

Issue 30024560: Issue 7450 - Implement hide-if-contains-visible-text snippet (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: a couple of jsdocs fixes Created April 18, 2019, 12:19 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 | « no previous file | test/browser/_utils.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/content/snippets.js
===================================================================
--- a/lib/content/snippets.js
+++ b/lib/content/snippets.js
@@ -403,52 +403,148 @@
}
exports["hide-if-shadow-contains"] = makeInjector(hideIfShadowContains,
toRegExp, regexEscape,
hideElement);
/**
* Hides any HTML element or one of its ancestors matching a CSS selector if
- * the text content of the element contains a given string.
+ * it matches the provided condition.
*
- * @param {string} search The string to look for in HTML elements. If the
- * string begins and ends with a slash (<code>/</code>), the text in between
- * is treated as a regular expression.
+ * @param {function} match The function that provides the matching condition.
* @param {string} selector The CSS selector that an HTML element must match
* for it to be hidden.
- * @param {string?} [searchSelector] The CSS selector that an HTML element
+ * @param {?string} [searchSelector] The CSS selector that an HTML element
* containing the given string must match. Defaults to the value of the
* <code>selector</code> argument.
*/
-function hideIfContains(search, selector = "*", searchSelector = null)
+function hideIfMatches(match, selector, searchSelector)
{
if (searchSelector == null)
searchSelector = selector;
- let re = toRegExp(search);
-
new MutationObserver(() =>
{
for (let element of document.querySelectorAll(searchSelector))
{
- if (re.test(element.textContent))
+ if (match(element))
{
let closest = element.closest(selector);
if (closest)
hideElement(closest);
}
}
})
.observe(document, {childList: true, characterData: true, subtree: true});
}
+/**
+ * Hides any HTML element or one of its ancestors matching a CSS selector if
+ * the text content of the element contains a given string.
+ *
+ * @param {string} search The string to look for in HTML elements. If the
+ * string begins and ends with a slash (<code>/</code>), the text in between
+ * is treated as a regular expression.
+ * @param {string} selector The CSS selector that an HTML element must match
+ * for it to be hidden.
+ * @param {?string} [searchSelector] The CSS selector that an HTML element
+ * containing the given string must match. Defaults to the value of the
+ * <code>selector</code> argument.
+ */
+function hideIfContains(search, selector = "*", searchSelector = null)
+{
+ let re = toRegExp(search);
+
+ hideIfMatches(element => re.test(element.textContent),
+ selector, searchSelector);
+}
+
exports["hide-if-contains"] = hideIfContains;
/**
+ * Hides any HTML element matching a CSS selector if the visible text content
+ * of the element contains a given string.
+ *
+ * @param {string} search The string to match to the visible text. Is considered
+ * visible text that isn't hidden by CSS properties or other means.
+ * If the string begins and ends with a slash (<code>/</code>), the
+ * text in between is treated as a regular expression.
+ * @param {string} selector The CSS selector that an HTML element must match
+ * for it to be hidden.
+ * @param {?string} [searchSelector] The CSS selector that an HTML element
+ * containing the given string must match. Defaults to the value of the
+ * <code>selector</code> argument.
+ */
+function hideIfContainsVisibleText(search, selector, searchSelector = null)
+{
+ /**
+ * Determines if the text inside the element is visible.
+ * @param {Element} element The element we are checking.
+ * @param {?CSSStyleDeclaration} [style] The computed style of element. If
+ * falsey it will be queried.
+ * @returns {bool} Whether the text is visible.
+ */
+ function isTextVisible(element, style)
+ {
+ if (!style)
+ style = window.getComputedStyle(element);
+
+ if (style.getPropertyValue("opacity") == "0")
+ return false;
+ if (style.getPropertyValue("font-size") == "0px")
+ return false;
+ if (style.getPropertyValue("color") ==
+ style.getPropertyValue("background-color"))
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Returns the visible text content from an element and its descendants.
+ * @param {Element} element The element whose visible text we want.
+ * @returns {string} The text that is visible.
+ */
+ function getVisibleContent(element)
+ {
+ let style = window.getComputedStyle(element);
+ if (style.getPropertyValue("display") == "none")
+ return "";
+ let visibility = style.getPropertyValue("visibility");
+ if (visibility == "hidden" || visibility == "collapse")
+ return "";
+
+ 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, style))
+ text += node.nodeValue;
+ break;
+ }
+ }
+ return text;
+ }
+
+ let re = toRegExp(search);
+
+ hideIfMatches(element => re.test(getVisibleContent(element)),
+ selector, searchSelector);
+}
+
+exports["hide-if-contains-visible-text"] =
+ makeInjector(hideIfContainsVisibleText, hideIfMatches, hideElement);
+
+/**
* Hides any HTML element or one of its ancestors matching a CSS selector if
* the text content of the element contains a given string and, optionally, if
* the element's computed style contains a given string.
*
* @param {string} search The string to look for in HTML elements. If the
* string begins and ends with a slash (<code>/</code>), the text in between
* is treated as a regular expression.
* @param {string} selector The CSS selector that an HTML element must match
« no previous file with comments | « no previous file | test/browser/_utils.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld