Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: include.preload.js

Issue 29338588: Issue 3699 - Patch DOM API in order to prevent disabling the injected stylesheet (Closed)
Patch Set: Created March 17, 2016, 7:47 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | safari/include.youtube.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « no previous file | safari/include.youtube.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld