Index: lib/content/snippets.js |
=================================================================== |
--- a/lib/content/snippets.js |
+++ b/lib/content/snippets.js |
@@ -900,8 +900,85 @@ |
} |
return fetch_.apply(this, args); |
}; |
} |
exports["strip-fetch-query-parameter"] = makeInjector(stripFetchQueryParameter, |
toRegExp, regexEscape); |
+ |
+function hideIfContainsVisibleText(search, hideSelector, innerSelector = null) |
+{ |
+ /** |
+ * Determine if the text inside the element is visible. |
+ * @param {Element} element the leaf element we are checking. |
+ * @param {?CSSStyle} style the computed style of element. |
+ * @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 children. |
+ * @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); |
+ |
+ new MutationObserver(() => |
+ { |
+ for (let element of document.querySelectorAll(hideSelector)) |
+ { |
+ let inners = |
+ innerSelector ? element.querySelectorAll(innerSelector) : [element]; |
+ for (let inner of inners) |
+ { |
+ let content = getVisibleContent(inner); |
+ if (re.test(content)) |
+ hideElement(element); |
+ } |
+ } |
+ }) |
+ .observe(document, {childList: true, characterData: true, subtree: true}); |
+} |
+ |
+exports["hide-if-contains-visible-text"] = |
+ makeInjector(hideIfContainsVisibleText, hideElement); |