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 |