| Index: lib/content/snippets.js |
| =================================================================== |
| --- a/lib/content/snippets.js |
| +++ b/lib/content/snippets.js |
| @@ -115,16 +115,35 @@ |
| { |
| element.style.setProperty("display", "none", "important"); |
| } |
| }) |
| .observe(element, {attributes: true, attributeFilter: ["style"]}); |
| } |
| /** |
| + * Observes changes to a DOM node using a <code>MutationObserver</code>. |
| + * |
| + * @param {Node} target The DOM node to observe for changes. |
| + * @param {MutationObserverInit?} [options] Options that describe what DOM |
| + * mutations should be reported to the callback. |
| + * @param {function} callback A function that will be called on each DOM |
| + * mutation, taking a <code>MutationRecord</code> as its parameter. |
| + */ |
| +function observe(target, options, callback) |
| +{ |
| + new MutationObserver(mutations => |
| + { |
| + for (let mutation of mutations) |
| + callback(mutation); |
| + }) |
| + .observe(target, options); |
| +} |
| + |
| +/** |
| * Logs its arguments to the console. This may be used for testing and |
| * debugging. |
| * |
| * @param {...*} [args] The arguments to log. |
| */ |
| function log(...args) |
| { |
| console.log(...args); |
| @@ -235,8 +254,39 @@ |
| return root; |
| } |
| }); |
| } |
| exports["hide-if-shadow-contains"] = makeInjector(hideIfShadowContains, |
| hideElement); |
| + |
| +/** |
| + * Readds to the document any removed HTML elements that match a CSS selector. |
| + * |
| + * @param {string} selector The CSS selector that a removed HTML element should |
| + * match for it to be added back. |
| + * @param {string?} [parentSelector] The CSS selector that a removed HTML |
| + * element's former parent should match for it to be added back. |
| + */ |
| +function readd(selector, parentSelector = null) |
| +{ |
| + observe(document, {childList: true, subtree: true}, mutation => |
| + { |
| + if (mutation.removedNodes && |
| + (!parentSelector || (mutation.target instanceof Element && |
| + mutation.target.matches(parentSelector)))) |
| + { |
| + for (let node of mutation.removedNodes) |
| + { |
| + if (node instanceof HTMLElement && node.matches(selector)) |
| + { |
| + // We don't have the location of the element in its former parent, |
| + // but it's usually OK to just add it at the end. |
| + mutation.target.appendChild(node); |
| + } |
| + } |
| + } |
| + }); |
| +} |
| + |
| +exports.readd = readd; |