| Index: include.preload.js |
| =================================================================== |
| --- a/include.preload.js |
| +++ b/include.preload.js |
| @@ -331,61 +331,78 @@ |
| } |
| }; |
| -function reinjectRulesWhenRemoved(document, style) |
| +function runInPage(document, arg, fn) |
| { |
| - var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; |
| - if (!MutationObserver) |
| - return; |
| + var script = document.createElement("script"); |
| + script.async = false; |
| + script.textContent = "(" + fn + ")(" + arg + ");"; |
| + document.documentElement.appendChild(script); |
| + document.documentElement.removeChild(script); |
| +} |
| - var observer = new MutationObserver(function(mutations) |
| +function protectStylesheet(document, style) |
| +{ |
| + var id = Math.random().toString(36).substr(2); |
| + style.id = id; |
| + |
| + runInPage(document, '"' + id + '"', function(id) |
| { |
| - var isStyleRemoved = false; |
| - for (var i = 0; i < mutations.length; i++) |
| + var style = document.getElementById(id) || |
| + document.documentElement.shadowRoot.getElementById(id); |
| + style.removeAttribute("id"); |
| + |
| + var removeChild = Node.prototype.removeChild; |
| + Node.prototype.removeChild = function(child) |
| { |
| - if ([].indexOf.call(mutations[i].removedNodes, style) != -1) |
| + if (child != style) |
| + removeChild.call(this, child); |
| + }; |
| + |
| + var remove = Element.prototype.remove; |
| + if (remove) |
| + Element.prototype.remove = function() |
| { |
| - isStyleRemoved = true; |
| - break; |
| + if (this != style) |
| + remove.call(this); |
| + }; |
| + |
| + var deleteRule = CSSStyleSheet.prototype.deleteRule; |
| + CSSStyleSheet.prototype.deleteRule = function(index) |
| + { |
| + if (this != style.sheet) |
| + deleteRule.call(this, index); |
| + }; |
| + |
| + var removeRule = CSSStyleSheet.prototype.removeRule; |
| + if (removeRule) |
| + CSSStyleSheet.prototype.removeRule = function(index) |
| + { |
| + if (this != style.sheet) |
| + removeRule.call(this, index); |
| + }; |
| + |
| + Object.defineProperty( |
| + style, 'disabled', |
| + { |
| + value: false, |
| + enumerable: true |
| } |
| - } |
| - if (!isStyleRemoved) |
| - return; |
| + ); |
| - observer.disconnect(); |
| - |
| - var n = document.styleSheets.length; |
| - if (n == 0) |
| - return; |
| - |
| - var stylesheet = document.styleSheets[n - 1]; |
| - ext.backgroundPage.sendMessage( |
| - {type: "get-selectors"}, |
| - |
| - function(response) |
| + Object.defineProperty( |
| + style.sheet, 'disabled', |
| { |
| - var selectors = response.selectors; |
| - while (selectors.length > 0) |
| - { |
| - var selector = selectors.splice(0, SELECTOR_GROUP_SIZE).join(", "); |
| - |
| - // Using non-standard addRule() here. This is the only way |
| - // to add rules at the end of a cross-origin stylesheet |
| - // because we don't know how many rules are already in there |
| - stylesheet.addRule(selector, "display: none !important;"); |
| - } |
| + value: false, |
| + enumerable: true |
| } |
| ); |
| }); |
| - |
| - observer.observe(style.parentNode, {childList: true}); |
| - return observer; |
| } |
| function init(document) |
| { |
| var shadow = null; |
| var style = null; |
| - var observer = null; |
| var tracer = null; |
| var propertyFilters = new CSSPropertyFilters(window, addElemHideSelectors); |
| @@ -424,7 +441,7 @@ |
| if (!style.sheet) |
| return; |
| - observer = reinjectRulesWhenRemoved(document, style); |
| + protectStylesheet(document, style); |
| } |
| // If using shadow DOM, we have to add the ::content pseudo-element |
| @@ -461,10 +478,6 @@ |
| if (!selectors || !CSSPropertyFiltersLoaded) |
| return; |
| - if (observer) |
| - observer.disconnect(); |
| - observer = null; |
| - |
| if (tracer) |
| tracer.disconnect(); |
| tracer = null; |