| Index: include.preload.js |
| =================================================================== |
| --- a/include.preload.js |
| +++ b/include.preload.js |
| @@ -331,56 +331,69 @@ |
| } |
| }; |
| -function reinjectRulesWhenRemoved(document, style) |
| +function reinjectStyleSheetWhenRemoved(document, style) |
| { |
| - var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; |
| + var MutationObserver = window.MutationObserver || |
| + window.WebKitMutationObserver; |
| if (!MutationObserver) |
| - return; |
| + return null; |
| - var observer = new MutationObserver(function(mutations) |
| + var parentNode = style.parentNode; |
| + var observer = new MutationObserver(function() |
| { |
| - var isStyleRemoved = false; |
| - for (var i = 0; i < mutations.length; i++) |
| - { |
| - if ([].indexOf.call(mutations[i].removedNodes, style) != -1) |
| - { |
| - isStyleRemoved = true; |
| - break; |
| - } |
| - } |
| - 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) |
| - { |
| - 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;"); |
| - } |
| - } |
| - ); |
| + if (style.parentNode != parentNode) |
| + parentNode.appendChild(style); |
| }); |
| - observer.observe(style.parentNode, {childList: true}); |
| + observer.observe(parentNode, {childList: true}); |
| return observer; |
| } |
| +function protectStyleSheet(document, style) |
| +{ |
| + var id = Math.random().toString(36).substr(2) |
| + style.id = id; |
| + |
| + var code = [ |
| + "(function()", |
| + "{", |
| + ' var style = document.getElementById("' + id + '") ||', |
| + ' document.documentElement.shadowRoot.getElementById("' + id + '");', |
|
Sebastian Noack
2016/03/18 17:58:54
(Yes, I know that this line is 6 characters too lo
kzar
2016/03/18 19:18:32
Acknowledged.
|
| + ' style.removeAttribute("id");' |
| + ]; |
| + |
| + var disableables = ["style", "style.sheet"]; |
| + for (var i = 0; i < disableables.length; i++) |
| + { |
| + code.push(" Object.defineProperty(" + disableables[i] + ', "disabled", ' |
| + + "{value: false, enumerable: true});"); |
| + } |
| + |
| + var methods = ["deleteRule", "removeRule"]; |
| + for (var j = 0; j < methods.length; j++) |
|
kzar
2016/03/18 19:18:32
Nit: Just re-use the existing `i` variable instead
Sebastian Noack
2016/03/18 19:23:55
I'm not sure whether it's a good idea to make the
|
| + { |
| + var method = methods[j]; |
| + if (method in CSSStyleSheet.prototype) |
| + { |
| + var origin = "CSSStyleSheet.prototype." + method; |
| + code.push(" var " + method + " = " + origin + ";", |
| + " " + origin + " = function(index)", |
| + " {", |
| + " if (this != style.sheet)", |
| + " " + method + ".apply(this, index);", |
| + " }"); |
| + } |
| + } |
| + |
| + code.push("})();"); |
| + |
| + var script = document.createElement("script"); |
| + script.async = false; |
| + script.textContent = code.join("\n"); |
| + document.documentElement.appendChild(script); |
| + document.documentElement.removeChild(script); |
| +} |
| + |
| function init(document) |
| { |
| var shadow = null; |
| @@ -424,7 +437,8 @@ |
| if (!style.sheet) |
| return; |
| - observer = reinjectRulesWhenRemoved(document, style); |
| + observer = reinjectStyleSheetWhenRemoved(document, style); |
| + protectStyleSheet(document, style); |
| } |
| // If using shadow DOM, we have to add the ::content pseudo-element |