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

Unified Diff: include.preload.js

Issue 29893559: Issue 6999 - Generate style sheets in background page (Closed) Base URL: https://hg.adblockplus.org/adblockpluschrome/
Patch Set: Apply patch for ElementHidingTracer Created Sept. 30, 2018, 8:35 a.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 | « dependencies ('k') | lib/contentFiltering.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
@@ -220,17 +220,17 @@
{
if (collapse)
{
if (selector)
{
if (!collapsingSelectors.has(selector))
{
collapsingSelectors.add(selector);
- contentFiltering.addSelectors([selector], null, "collapsing", true);
+ contentFiltering.addSelectors([selector], "collapsing", true);
}
}
else
{
hideElement(element);
}
}
}
@@ -253,63 +253,52 @@
this.trace = this.trace.bind(this);
if (document.readyState == "loading")
document.addEventListener("DOMContentLoaded", this.trace);
else
this.trace();
}
ElementHidingTracer.prototype = {
- addSelectors(selectors, filters)
+ addSelectors(selectors)
{
- let pairs = selectors.map((sel, i) => [sel, filters && filters[i]]);
+ if (document.readyState != "loading")
+ this.checkNodes([document], selectors);
- if (document.readyState != "loading")
- this.checkNodes([document], pairs);
-
- this.selectors.push(...pairs);
+ this.selectors.push(...selectors);
},
- checkNodes(nodes, pairs)
+ checkNodes(nodes, selectors)
{
- let selectors = [];
- let filters = [];
+ let effectiveSelectors = [];
- for (let [selector, filter] of pairs)
+ for (let selector of selectors)
{
nodes: for (let node of nodes)
{
for (let element of node.querySelectorAll(selector))
{
// Only consider selectors that actually have an effect on the
// computed styles, and aren't overridden by rules with higher
// priority, or haven't been circumvented in a different way.
if (getComputedStyle(element).display == "none")
{
- // For regular element hiding, we don't know the exact filter,
- // but the background page can find it with the given selector.
- // In case of element hiding emulation, the generated selector
- // we got here is different from the selector part of the filter,
- // but in this case we can send the whole filter text instead.
- if (filter)
- filters.push(filter);
- else
- selectors.push(selector);
-
+ effectiveSelectors.push(selector);
break nodes;
}
}
}
}
- if (selectors.length > 0 || filters.length > 0)
+ if (effectiveSelectors.length > 0)
{
browser.runtime.sendMessage({
type: "hitLogger.traceElemHide",
- selectors, filters
+ selectors: effectiveSelectors,
+ filters: []
});
}
},
onTimeout()
{
this.checkNodes(this.changedNodes, this.selectors);
this.changedNodes = [];
@@ -392,39 +381,24 @@
clearTimeout(this.timeout);
}
};
function ContentFiltering()
{
this.styles = new Map();
this.tracer = null;
- this.inline = true;
- this.elemHideEmulation = new ElemHideEmulation(
- () => {},
- this.hideElements.bind(this)
- );
+ this.elemHideEmulation = new ElemHideEmulation(this.hideElements.bind(this));
}
ContentFiltering.prototype = {
- selectorGroupSize: 1024,
-
- addSelectorsInline(selectors, groupName, appendOnly = false)
+ addStyleSheetInline(styleSheet, groupName = "standard", appendOnly = false)
{
let style = this.styles.get(groupName);
- if (style && !appendOnly)
- {
- while (style.sheet.cssRules.length > 0)
- style.sheet.deleteRule(0);
- }
-
- if (selectors.length == 0)
- return;
-
if (!style)
{
// Create <style> element lazily, only if we add styles. Add it 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");
(document.head || document.documentElement).appendChild(style);
@@ -434,64 +408,46 @@
// In that case the sheet property may stay null, after adding the
// <style> element.
if (!style.sheet)
return;
this.styles.set(groupName, style);
}
- // Chromium's Blink engine supports only up to 8,192 simple selectors, and
- // even fewer compound selectors, in a rule. The exact number of selectors
- // that would work depends on their sizes (e.g. "#foo .bar" has a
- // size of 2). Since we don't know the sizes of the selectors here, we
- // simply split them into groups of 1,024, based on the reasonable
- // assumption that the average selector won't have a size greater than 8.
- // The alternative would be to calculate the sizes of the selectors and
- // divide them up accordingly, but this approach is more efficient and has
- // worked well in practice. In theory this could still lead to some
- // selectors not working on Chromium, but it is highly unlikely.
- // See issue #6298 and https://crbug.com/804179
- for (let i = 0; i < selectors.length; i += this.selectorGroupSize)
- {
- let selector = selectors.slice(i, i + this.selectorGroupSize).join(", ");
- style.sheet.insertRule(selector + "{display: none !important;}",
- style.sheet.cssRules.length);
- }
+ if (appendOnly)
+ style.textContent += styleSheet;
+ else
+ style.textContent = styleSheet;
},
- addSelectors(selectors, filters, groupName = "emulated", appendOnly = false)
+ addSelectors(selectors, groupName = "standard", appendOnly = false)
{
- if (this.inline)
+ browser.runtime.sendMessage({
+ type: "content.injectSelectors",
+ selectors,
+ groupName,
+ appendOnly
+ },
+ styleSheet =>
{
- // Insert the style rules inline if we have been instructed by the
- // background page to do so. This is usually the case, except on platforms
- // that do support user stylesheets via the browser.tabs.insertCSS API
- // (Firefox 53 onwards for now and possibly Chrome in the near future).
- // Once all supported platforms have implemented this API, we can remove
- // the code below. See issue #5090.
- // Related Chrome and Firefox issues:
- // https://bugs.chromium.org/p/chromium/issues/detail?id=632009
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1310026
- this.addSelectorsInline(selectors, groupName, appendOnly);
- }
- else
- {
- browser.runtime.sendMessage({
- type: "content.injectSelectors",
- selectors,
- groupName,
- appendOnly
- });
- }
-
- // Only trace selectors that are based directly on hiding filters
- // (i.e. leave out collapsing selectors).
- if (this.tracer && groupName != "collapsing")
- this.tracer.addSelectors(selectors, filters);
+ if (styleSheet)
+ {
+ // Insert the style sheet inline if we have been instructed by the
+ // background page to do so. This is rarely the case, except on
+ // platforms that do not support user stylesheets via the
+ // browser.tabs.insertCSS API (Firefox <53, Chrome <66, and Edge).
+ // Once all supported platforms have implemented this API, we can remove
+ // the code below. See issue #5090.
+ // Related Chrome and Firefox issues:
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=632009
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1310026
+ this.addStyleSheetInline(styleSheet, groupName, appendOnly);
+ }
+ });
},
hideElements(elements, filters)
{
for (let element of elements)
hideElement(element);
if (this.tracer)
@@ -514,23 +470,21 @@
{
if (this.tracer)
this.tracer.disconnect();
this.tracer = null;
if (response.trace)
this.tracer = new ElementHidingTracer();
- this.inline = response.inline;
-
- if (this.inline)
- this.addSelectorsInline(response.selectors, "standard");
+ if (response.inline)
+ this.addStyleSheetInline(response.styleSheet.code);
if (this.tracer)
- this.tracer.addSelectors(response.selectors);
+ this.tracer.addSelectors(response.styleSheet.selectors);
this.elemHideEmulation.apply(response.emulatedPatterns);
});
}
};
if (document instanceof HTMLDocument)
{
« no previous file with comments | « dependencies ('k') | lib/contentFiltering.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld