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

Unified Diff: include.preload.js

Issue 29350213: Issue 4364 - Drop support for Chrome 29-40 and remove legacy code (Closed)
Patch Set: Got rid of init(), refactored element hiding code into a class Created Aug. 25, 2016, 3:10 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 | « composer.postload.js ('k') | metadata.chrome » ('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
@@ -16,7 +16,6 @@
*/
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
-var SELECTOR_GROUP_SIZE = 200;
var typeMap = {
"img": "IMAGE",
@@ -196,9 +195,8 @@
}
}
-function ElementHidingTracer(document, selectors)
+function ElementHidingTracer(selectors)
{
- this.document = document;
this.selectors = selectors;
this.changedNodes = [];
@@ -264,7 +262,7 @@
// Forget previously changed nodes that are no longer in the DOM.
for (var i = 0; i < this.changedNodes.length; i++)
{
- if (!this.document.contains(this.changedNodes[i]))
+ if (!document.contains(this.changedNodes[i]))
this.changedNodes.splice(i--, 1);
}
@@ -274,7 +272,7 @@
var node = mutation.target;
// Ignore mutations of nodes that aren't in the DOM anymore.
- if (!this.document.contains(node))
+ if (!document.contains(node))
continue;
// Since querySelectorAll() doesn't consider the root itself
@@ -317,10 +315,10 @@
trace: function()
{
- this.checkNodes([this.document]);
+ this.checkNodes([document]);
this.observer.observe(
- this.document,
+ document,
{
childList: true,
attributes: true,
@@ -331,13 +329,13 @@
disconnect: function()
{
- this.document.removeEventListener("DOMContentLoaded", this.trace);
+ document.removeEventListener("DOMContentLoaded", this.trace);
this.observer.disconnect();
clearTimeout(this.timeout);
}
};
-function runInDocument(document, fn, arg)
+function runInDocument(fn, arg)
{
var script = document.createElement("script");
script.type = "application/javascript";
@@ -352,7 +350,7 @@
// us. As a workaround we wrap WebSocket, preventing blocked WebSocket
// connections from being opened.
// [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353
-function wrapWebSocket(document)
+function wrapWebSocket()
{
if (typeof WebSocket == "undefined")
return;
@@ -372,7 +370,7 @@
});
});
- runInDocument(document, function(eventName)
+ runInDocument(function(eventName)
{
// As far as possible we must track everything we use that could be
// sabotaged by the website later in order to circumvent us.
@@ -432,43 +430,48 @@
}, eventName);
}
-function init(document)
+function ElemHide()
{
- var shadow = null;
- var style = null;
- var observer = null;
- var tracer = null;
+ this.shadow = this.createShadowTree();
+ this.style = null;
+ this.tracer = null;
- wrapWebSocket(document);
+ this.propertyFilters = new CSSPropertyFilters(
+ window,
+ function(callback)
+ {
+ ext.backgroundPage.sendMessage({
+ type: "filters.get",
+ what: "cssproperties"
+ }, callback);
+ },
+ this.addSelectors.bind(this)
+ );
+}
+ElemHide.prototype = {
+ selectorGroupSize: 200,
- function getPropertyFilters(callback)
+ createShadowTree: function()
{
- ext.backgroundPage.sendMessage({
- type: "filters.get",
- what: "cssproperties"
- }, callback);
- }
- var propertyFilters = new CSSPropertyFilters(window, getPropertyFilters,
- addElemHideSelectors);
+ // Use Shadow DOM if available to don't mess with web pages that rely
+ // on the order of their own <style> tags (#309). However, creating a
+ // shadow root breaks running CSS transitions. So we have to create
+ // the shadow root before transistions might start (#452).
+ if (!("createShadowRoot" in document.documentElement))
+ return null;
- // Use Shadow DOM if available to don't mess with web pages that rely on
- // the order of their own <style> tags (#309).
- //
- // However, creating a shadow root breaks running CSS transitions. So we
- // have to create the shadow root before transistions might start (#452).
- //
- // Also, using shadow DOM causes issues on some Google websites,
- // including Google Docs, Gmail and Blogger (#1770, #2602, #2687).
- if ("createShadowRoot" in document.documentElement &&
- !/\.(?:google|blogger)\.com$/.test(document.domain))
- {
- shadow = document.documentElement.createShadowRoot();
+ // Using shadow DOM causes issues on some Google websites,
+ // including Google Docs, Gmail and Blogger (#1770, #2602, #2687).
+ if (/\.(?:google|blogger)\.com$/.test(document.domain))
+ return null;
+
+ var shadow = document.documentElement.createShadowRoot();
shadow.appendChild(document.createElement("shadow"));
- // Stop the website from messing with our shadowRoot
+ // Stop the website from messing with our shadow root (#4191, #4298).
if ("shadowRoot" in Element.prototype)
{
- runInDocument(document, function()
+ runInDocument(function()
{
var ourShadowRoot = document.documentElement.shadowRoot;
var desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoot");
@@ -483,34 +486,37 @@
});
}, null);
}
- }
- function addElemHideSelectors(selectors)
+ return shadow;
+ },
+
+ addSelectors: function(selectors)
{
if (selectors.length == 0)
return;
- if (!style)
+ if (!this.style)
{
// Create <style> element lazily, only if we add styles. Add it to
// the shadow DOM if possible. Otherwise fallback to the <head> or
// <html> element. If we have injected a style element before that
// has been removed (the sheet property is null), create a new one.
- style = document.createElement("style");
- (shadow || document.head || document.documentElement).appendChild(style);
+ this.style = document.createElement("style");
+ (this.shadow || document.head
+ || document.documentElement).appendChild(this.style);
// It can happen that the frame already navigated to a different
// document while we were waiting for the background page to respond.
// In that case the sheet property will stay null, after addind the
// <style> element to the shadow DOM.
- if (!style.sheet)
+ if (!this.style.sheet)
return;
}
// If using shadow DOM, we have to add the ::content pseudo-element
// before each selector, in order to match elements within the
// insertion point.
- if (shadow)
+ if (this.shadow)
{
var preparedSelectors = [];
for (var i = 0; i < selectors.length; i++)
@@ -527,41 +533,37 @@
// (Chrome also has a limit, larger... but we're not certain exactly what it
// is! Edge apparently has no such limit.)
// [1] - https://github.com/WebKit/webkit/blob/1cb2227f6b2a1035f7bdc46e5ab69debb75fc1de/Source/WebCore/css/RuleSet.h#L68
- for (var i = 0; i < selectors.length; i += SELECTOR_GROUP_SIZE)
+ for (var i = 0; i < selectors.length; i += this.selectorGroupSize)
{
- var selector = selectors.slice(i, i + SELECTOR_GROUP_SIZE).join(", ");
- style.sheet.addRule(selector, "display: none !important;");
+ var selector = selectors.slice(i, i + this.selectorGroupSize).join(", ");
+ this.style.sheet.addRule(selector, "display: none !important;");
}
- };
+ },
- var updateStylesheet = function()
+ apply: function()
{
var selectors = null;
- var CSSPropertyFiltersLoaded = false;
+ var propertyFiltersLoaded = false;
var checkLoaded = function()
{
- if (!selectors || !CSSPropertyFiltersLoaded)
+ if (!selectors || !propertyFiltersLoaded)
return;
- if (observer)
- observer.disconnect();
- observer = null;
+ if (this.tracer)
+ this.tracer.disconnect();
+ this.tracer = null;
- if (tracer)
- tracer.disconnect();
- tracer = null;
+ if (this.style && this.style.parentElement)
+ this.style.parentElement.removeChild(this.style);
+ this.style = null;
- if (style && style.parentElement)
- style.parentElement.removeChild(style);
- style = null;
-
- addElemHideSelectors(selectors.selectors);
- propertyFilters.apply();
+ this.addSelectors(selectors.selectors);
+ this.propertyFilters.apply();
if (selectors.trace)
- tracer = new ElementHidingTracer(document, selectors.selectors);
- };
+ this.tracer = new ElementHidingTracer(selectors.selectors);
+ }.bind(this);
ext.backgroundPage.sendMessage({type: "get-selectors"}, function(response)
{
@@ -569,14 +571,21 @@
checkLoaded();
});
- propertyFilters.load(function()
+ this.propertyFilters.load(function()
{
- CSSPropertyFiltersLoaded = true;
+ propertyFiltersLoaded = true;
checkLoaded();
});
- };
+ }
+};
- updateStylesheet();
+if (document instanceof HTMLDocument)
+{
+ checkSitekey();
+ wrapWebSocket();
+
+ var elemhide = new ElemHide();
+ elemhide.apply();
document.addEventListener("error", function(event)
{
@@ -586,35 +595,7 @@
document.addEventListener("load", function(event)
{
var element = event.target;
-
if (/^i?frame$/.test(element.localName))
checkCollapse(element);
-
- if (/\bChrome\//.test(navigator.userAgent))
- {
- var contentDocument = getContentDocument(element);
- if (contentDocument)
- {
- var contentWindow = contentDocument.defaultView;
- if (contentDocument instanceof contentWindow.HTMLDocument)
- {
- // Prior to Chrome 37, content scripts cannot run in
- // dynamically created frames. Also on Chrome 37-40
- // document_start content scripts (like this one) don't
- // run either in those frames due to https://crbug.com/416907.
- // So we have to apply element hiding from the parent frame.
- if (!("init" in contentWindow))
- init(contentDocument);
- }
- }
- }
}, true);
-
- return updateStylesheet;
}
-
-if (document instanceof HTMLDocument)
-{
- checkSitekey();
- window.updateStylesheet = init(document);
-}
« no previous file with comments | « composer.postload.js ('k') | metadata.chrome » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld