<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[194762] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/194762">194762</a></dd>
<dt>Author</dt> <dd>antti@apple.com</dd>
<dt>Date</dt> <dd>2016-01-08 01:06:10 -0800 (Fri, 08 Jan 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Enable selector filtering for shadow trees
https://bugs.webkit.org/show_bug.cgi?id=152831
Reviewed by Simon Fraser.
Selector filtering doesn't currently work in shadow trees making style resolve for them slow.
This is because SelectorFilter is not in "consistent" state.
This patch moves SelectorFilter ownership from StyleResolver to TreeResolver and guarantees
it is always upadated consistently. It eliminates a bunch of now unnecessary consistency checks
and special cases.
* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::ElementRuleCollector):
Assert for consistency instead of testing for it.
(WebCore::ElementRuleCollector::matchedResult):
(WebCore::ElementRuleCollector::collectMatchingRulesForList):
Selector filter can now be used if it exists.
* css/ElementRuleCollector.h:
(WebCore::ElementRuleCollector::ElementRuleCollector): Deleted.
* css/RuleSet.cpp:
(WebCore::RuleSet::addRule):
Disable selector filtering for custom shadow pseudo rules. They are resolved by shadow DOM resolver
but may contain components matching the normal DOM.
* css/RuleSet.h:
(WebCore::RuleData::descendantSelectorIdentifierHashes):
(WebCore::RuleData::disableSelectorFiltering):
(WebCore::RuleData::compilationStatus):
(WebCore::RuleData::compiledSelectorCodeRef):
* css/SelectorFilter.cpp:
(WebCore::collectElementIdentifierHashes):
(WebCore::SelectorFilter::parentStackIsConsistent):
New consistency conditions. This is now used for asserts only.
(WebCore::SelectorFilter::pushParentStackFrame):
(WebCore::SelectorFilter::popParentStackFrame):
Selector filter only filters the current tree context, replace parentOrShadowHostElement with parentElement.
(WebCore::SelectorFilter::setupParentStack): Deleted.
No longer needed.
(WebCore::SelectorFilter::pushParent):
Remove consistency check. These cases no longer happen.
* css/SelectorFilter.h:
(WebCore::SelectorFilter::popParent):
(WebCore::SelectorFilter::parentStackIsEmpty):
(WebCore::SelectorFilter::fastRejectSelector):
(WebCore::SelectorFilter::parentStackIsConsistent): Deleted.
* css/StyleInvalidationAnalysis.cpp:
(WebCore::StyleInvalidationAnalysis::invalidateIfNeeded):
(WebCore::StyleInvalidationAnalysis::invalidateStyle):
* css/StyleResolver.cpp:
(WebCore::StyleResolver::appendAuthorStyleSheets):
(WebCore::StyleResolver::addKeyframeStyle):
(WebCore::StyleResolver::initElement):
(WebCore::StyleResolver::State::initForStyleResolve):
We no longer owner the selector filter. Move it to State.
(WebCore::StyleResolver::styleSharingCandidateMatchesRuleSet):
(WebCore::isAtShadowBoundary):
(WebCore::StyleResolver::styleForElement):
(WebCore::StyleResolver::pseudoStyleForElement):
(WebCore::StyleResolver::pseudoStyleRulesForElement):
(WebCore::StyleResolver::pushParentElement): Deleted.
(WebCore::StyleResolver::popParentElement): Deleted.
No need for this logic.
* css/StyleResolver.h:
(WebCore::StyleResolver::ruleSets):
(WebCore::StyleResolver::mediaQueryEvaluator):
(WebCore::StyleResolver::State::document):
(WebCore::StyleResolver::State::setAuthorRollback):
(WebCore::StyleResolver::State::setUserRollback):
(WebCore::StyleResolver::State::selectorFilter):
(WebCore::StyleResolver::state):
(WebCore::checkRegionSelector):
(WebCore::StyleResolver::selectorFilter): Deleted.
(WebCore::StyleResolverParentPusher::StyleResolverParentPusher): Deleted.
(WebCore::StyleResolverParentPusher::push): Deleted.
(WebCore::StyleResolverParentPusher::~StyleResolverParentPusher): Deleted.
* style/StyleTreeResolver.cpp:
This now owns the selector filter for a tree context.
(WebCore::Style::SelectorFilterPusher::SelectorFilterPusher):
(WebCore::Style::SelectorFilterPusher::push):
(WebCore::Style::SelectorFilterPusher::~SelectorFilterPusher):
(WebCore::Style::TreeResolver::TreeResolver):
(WebCore::Style::TreeResolver::styleForElement):
(WebCore::Style::TreeResolver::createRenderTreeForSlotAssignees):
(WebCore::Style::TreeResolver::createRenderTreeRecursively):
(WebCore::Style::TreeResolver::resolveChildren):
(WebCore::Style::TreeResolver::resolveRecursively):
Push the filter in a few more places to keep it consistent in shadow trees.
* style/StyleTreeResolver.h:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssElementRuleCollectorcpp">trunk/Source/WebCore/css/ElementRuleCollector.cpp</a></li>
<li><a href="#trunkSourceWebCorecssElementRuleCollectorh">trunk/Source/WebCore/css/ElementRuleCollector.h</a></li>
<li><a href="#trunkSourceWebCorecssRuleSetcpp">trunk/Source/WebCore/css/RuleSet.cpp</a></li>
<li><a href="#trunkSourceWebCorecssRuleSeth">trunk/Source/WebCore/css/RuleSet.h</a></li>
<li><a href="#trunkSourceWebCorecssSelectorFiltercpp">trunk/Source/WebCore/css/SelectorFilter.cpp</a></li>
<li><a href="#trunkSourceWebCorecssSelectorFilterh">trunk/Source/WebCore/css/SelectorFilter.h</a></li>
<li><a href="#trunkSourceWebCorecssStyleInvalidationAnalysiscpp">trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp</a></li>
<li><a href="#trunkSourceWebCorecssStyleResolvercpp">trunk/Source/WebCore/css/StyleResolver.cpp</a></li>
<li><a href="#trunkSourceWebCorecssStyleResolverh">trunk/Source/WebCore/css/StyleResolver.h</a></li>
<li><a href="#trunkSourceWebCorestyleStyleTreeResolvercpp">trunk/Source/WebCore/style/StyleTreeResolver.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleStyleTreeResolverh">trunk/Source/WebCore/style/StyleTreeResolver.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/ChangeLog        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -1,3 +1,116 @@
</span><ins>+2016-01-07 Antti Koivisto <antti@apple.com>
+
+ Enable selector filtering for shadow trees
+ https://bugs.webkit.org/show_bug.cgi?id=152831
+
+ Reviewed by Simon Fraser.
+
+ Selector filtering doesn't currently work in shadow trees making style resolve for them slow.
+ This is because SelectorFilter is not in "consistent" state.
+
+ This patch moves SelectorFilter ownership from StyleResolver to TreeResolver and guarantees
+ it is always upadated consistently. It eliminates a bunch of now unnecessary consistency checks
+ and special cases.
+
+ * css/ElementRuleCollector.cpp:
+ (WebCore::ElementRuleCollector::ElementRuleCollector):
+
+ Assert for consistency instead of testing for it.
+
+ (WebCore::ElementRuleCollector::matchedResult):
+ (WebCore::ElementRuleCollector::collectMatchingRulesForList):
+
+ Selector filter can now be used if it exists.
+
+ * css/ElementRuleCollector.h:
+ (WebCore::ElementRuleCollector::ElementRuleCollector): Deleted.
+ * css/RuleSet.cpp:
+ (WebCore::RuleSet::addRule):
+
+ Disable selector filtering for custom shadow pseudo rules. They are resolved by shadow DOM resolver
+ but may contain components matching the normal DOM.
+
+ * css/RuleSet.h:
+ (WebCore::RuleData::descendantSelectorIdentifierHashes):
+ (WebCore::RuleData::disableSelectorFiltering):
+ (WebCore::RuleData::compilationStatus):
+ (WebCore::RuleData::compiledSelectorCodeRef):
+ * css/SelectorFilter.cpp:
+ (WebCore::collectElementIdentifierHashes):
+ (WebCore::SelectorFilter::parentStackIsConsistent):
+
+ New consistency conditions. This is now used for asserts only.
+
+ (WebCore::SelectorFilter::pushParentStackFrame):
+ (WebCore::SelectorFilter::popParentStackFrame):
+
+ Selector filter only filters the current tree context, replace parentOrShadowHostElement with parentElement.
+
+ (WebCore::SelectorFilter::setupParentStack): Deleted.
+
+ No longer needed.
+
+ (WebCore::SelectorFilter::pushParent):
+
+ Remove consistency check. These cases no longer happen.
+
+ * css/SelectorFilter.h:
+ (WebCore::SelectorFilter::popParent):
+ (WebCore::SelectorFilter::parentStackIsEmpty):
+ (WebCore::SelectorFilter::fastRejectSelector):
+ (WebCore::SelectorFilter::parentStackIsConsistent): Deleted.
+ * css/StyleInvalidationAnalysis.cpp:
+ (WebCore::StyleInvalidationAnalysis::invalidateIfNeeded):
+ (WebCore::StyleInvalidationAnalysis::invalidateStyle):
+ * css/StyleResolver.cpp:
+ (WebCore::StyleResolver::appendAuthorStyleSheets):
+ (WebCore::StyleResolver::addKeyframeStyle):
+ (WebCore::StyleResolver::initElement):
+ (WebCore::StyleResolver::State::initForStyleResolve):
+
+ We no longer owner the selector filter. Move it to State.
+
+ (WebCore::StyleResolver::styleSharingCandidateMatchesRuleSet):
+ (WebCore::isAtShadowBoundary):
+ (WebCore::StyleResolver::styleForElement):
+ (WebCore::StyleResolver::pseudoStyleForElement):
+ (WebCore::StyleResolver::pseudoStyleRulesForElement):
+ (WebCore::StyleResolver::pushParentElement): Deleted.
+ (WebCore::StyleResolver::popParentElement): Deleted.
+
+ No need for this logic.
+
+ * css/StyleResolver.h:
+ (WebCore::StyleResolver::ruleSets):
+ (WebCore::StyleResolver::mediaQueryEvaluator):
+ (WebCore::StyleResolver::State::document):
+ (WebCore::StyleResolver::State::setAuthorRollback):
+ (WebCore::StyleResolver::State::setUserRollback):
+ (WebCore::StyleResolver::State::selectorFilter):
+ (WebCore::StyleResolver::state):
+ (WebCore::checkRegionSelector):
+ (WebCore::StyleResolver::selectorFilter): Deleted.
+ (WebCore::StyleResolverParentPusher::StyleResolverParentPusher): Deleted.
+ (WebCore::StyleResolverParentPusher::push): Deleted.
+ (WebCore::StyleResolverParentPusher::~StyleResolverParentPusher): Deleted.
+ * style/StyleTreeResolver.cpp:
+
+ This now owns the selector filter for a tree context.
+
+ (WebCore::Style::SelectorFilterPusher::SelectorFilterPusher):
+ (WebCore::Style::SelectorFilterPusher::push):
+ (WebCore::Style::SelectorFilterPusher::~SelectorFilterPusher):
+ (WebCore::Style::TreeResolver::TreeResolver):
+ (WebCore::Style::TreeResolver::styleForElement):
+ (WebCore::Style::TreeResolver::createRenderTreeForSlotAssignees):
+ (WebCore::Style::TreeResolver::createRenderTreeRecursively):
+ (WebCore::Style::TreeResolver::resolveChildren):
+ (WebCore::Style::TreeResolver::resolveRecursively):
+
+ Push the filter in a few more places to keep it consistent in shadow trees.
+
+ * style/StyleTreeResolver.h:
+
</ins><span class="cx"> 2016-01-07 Zalan Bujtas <zalan@apple.com>
</span><span class="cx">
</span><span class="cx"> Move computeLineBoundsForText from GraphicsContext* to GraphicsContext.
</span></span></pre></div>
<a id="trunkSourceWebCorecssElementRuleCollectorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/ElementRuleCollector.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/ElementRuleCollector.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/ElementRuleCollector.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include "RenderRegion.h"
</span><span class="cx"> #include "SVGElement.h"
</span><span class="cx"> #include "SelectorCompiler.h"
</span><ins>+#include "SelectorFilter.h"
</ins><span class="cx"> #include "ShadowRoot.h"
</span><span class="cx"> #include "StyleProperties.h"
</span><span class="cx"> #include "StyledElement.h"
</span><span class="lines">@@ -75,6 +76,15 @@
</span><span class="cx"> const bool includeEmptyRules;
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+ElementRuleCollector::ElementRuleCollector(Element& element, RenderStyle* style, const DocumentRuleSets& ruleSets, const SelectorFilter* selectorFilter)
+ : m_element(element)
+ , m_style(style)
+ , m_ruleSets(ruleSets)
+ , m_selectorFilter(selectorFilter)
+{
+ ASSERT(!m_selectorFilter || m_selectorFilter->parentStackIsConsistent(element.parentNode()));
+}
+
</ins><span class="cx"> StyleResolver::MatchResult& ElementRuleCollector::matchedResult()
</span><span class="cx"> {
</span><span class="cx"> ASSERT(m_mode == SelectorChecker::Mode::ResolvingStyle);
</span><span class="lines">@@ -352,7 +362,7 @@
</span><span class="cx"> if (!ruleData.canMatchPseudoElement() && m_pseudoStyleRequest.pseudoId != NOPSEUDO)
</span><span class="cx"> continue;
</span><span class="cx">
</span><del>- if (m_canUseFastReject && m_selectorFilter.fastRejectSelector<RuleData::maximumIdentifierCount>(ruleData.descendantSelectorIdentifierHashes()))
</del><ins>+ if (m_selectorFilter && m_selectorFilter->fastRejectSelector<RuleData::maximumIdentifierCount>(ruleData.descendantSelectorIdentifierHashes()))
</ins><span class="cx"> continue;
</span><span class="cx">
</span><span class="cx"> StyleRule* rule = ruleData.rule();
</span></span></pre></div>
<a id="trunkSourceWebCorecssElementRuleCollectorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/ElementRuleCollector.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/ElementRuleCollector.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/ElementRuleCollector.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -45,14 +45,7 @@
</span><span class="cx">
</span><span class="cx"> class ElementRuleCollector {
</span><span class="cx"> public:
</span><del>- ElementRuleCollector(Element& element, RenderStyle* style, const DocumentRuleSets& ruleSets, const SelectorFilter& selectorFilter)
- : m_element(element)
- , m_style(style)
- , m_ruleSets(ruleSets)
- , m_selectorFilter(selectorFilter)
- , m_canUseFastReject(m_selectorFilter.parentStackIsConsistent(element.parentNode()))
- {
- }
</del><ins>+ ElementRuleCollector(Element&, RenderStyle*, const DocumentRuleSets&, const SelectorFilter*);
</ins><span class="cx">
</span><span class="cx"> void matchAllRules(bool matchAuthorAndUserStyles, bool includeSMILProperties);
</span><span class="cx"> void matchUARules();
</span><span class="lines">@@ -94,14 +87,13 @@
</span><span class="cx"> Element& m_element;
</span><span class="cx"> RenderStyle* m_style;
</span><span class="cx"> const DocumentRuleSets& m_ruleSets;
</span><del>- const SelectorFilter& m_selectorFilter;
</del><ins>+ const SelectorFilter* m_selectorFilter;
</ins><span class="cx">
</span><span class="cx"> bool m_isPrintStyle { false };
</span><span class="cx"> const RenderRegion* m_regionForStyling { nullptr };
</span><span class="cx"> PseudoStyleRequest m_pseudoStyleRequest { NOPSEUDO };
</span><span class="cx"> bool m_sameOriginOnly { false };
</span><span class="cx"> SelectorChecker::Mode m_mode { SelectorChecker::Mode::ResolvingStyle };
</span><del>- bool m_canUseFastReject;
</del><span class="cx">
</span><span class="cx"> Vector<MatchedRule, 64> m_matchedRules;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorecssRuleSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/RuleSet.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/RuleSet.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/RuleSet.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -225,6 +225,8 @@
</span><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> if (selector->isCustomPseudoElement()) {
</span><ins>+ // FIXME: Custom pseudo elements are handled by the shadow tree's selector filter. It doesn't know about the main DOM.
+ ruleData.disableSelectorFiltering();
</ins><span class="cx"> addToRuleSet(selector->value().impl(), m_shadowPseudoElementRules, ruleData);
</span><span class="cx"> return;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecssRuleSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/RuleSet.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/RuleSet.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/RuleSet.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -84,6 +84,8 @@
</span><span class="cx"> static const unsigned maximumIdentifierCount = 4;
</span><span class="cx"> const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
</span><span class="cx">
</span><ins>+ void disableSelectorFiltering() { m_descendantSelectorIdentifierHashes[0] = 0; }
+
</ins><span class="cx"> #if ENABLE(CSS_SELECTOR_JIT)
</span><span class="cx"> SelectorCompilationStatus compilationStatus() const { return m_compilationStatus; }
</span><span class="cx"> JSC::MacroAssemblerCodeRef compiledSelectorCodeRef() const { return m_compiledSelectorCodeRef; }
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorFiltercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorFilter.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorFilter.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/SelectorFilter.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include "SelectorFilter.h"
</span><span class="cx">
</span><span class="cx"> #include "CSSSelector.h"
</span><ins>+#include "ShadowRoot.h"
</ins><span class="cx"> #include "StyledElement.h"
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -53,11 +54,18 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool SelectorFilter::parentStackIsConsistent(const ContainerNode* parentNode) const
+{
+ if (!parentNode || is<Document>(parentNode) || is<ShadowRoot>(parentNode))
+ return m_parentStack.isEmpty();
+
+ return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode;
+}
+
</ins><span class="cx"> void SelectorFilter::pushParentStackFrame(Element* parent)
</span><span class="cx"> {
</span><del>- ASSERT(m_ancestorIdentifierFilter);
- ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent->parentOrShadowHostElement());
- ASSERT(!m_parentStack.isEmpty() || !parent->parentOrShadowHostElement());
</del><ins>+ ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent->parentElement());
+ ASSERT(!m_parentStack.isEmpty() || !parent->parentElement());
</ins><span class="cx"> m_parentStack.append(ParentStackFrame(parent));
</span><span class="cx"> ParentStackFrame& parentFrame = m_parentStack.last();
</span><span class="cx"> // Mix tags, class names and ids into some sort of weird bouillabaisse.
</span><span class="lines">@@ -65,50 +73,25 @@
</span><span class="cx"> collectElementIdentifierHashes(parent, parentFrame.identifierHashes);
</span><span class="cx"> size_t count = parentFrame.identifierHashes.size();
</span><span class="cx"> for (size_t i = 0; i < count; ++i)
</span><del>- m_ancestorIdentifierFilter->add(parentFrame.identifierHashes[i]);
</del><ins>+ m_ancestorIdentifierFilter.add(parentFrame.identifierHashes[i]);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void SelectorFilter::popParentStackFrame()
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!m_parentStack.isEmpty());
</span><del>- ASSERT(m_ancestorIdentifierFilter);
</del><span class="cx"> const ParentStackFrame& parentFrame = m_parentStack.last();
</span><span class="cx"> size_t count = parentFrame.identifierHashes.size();
</span><span class="cx"> for (size_t i = 0; i < count; ++i)
</span><del>- m_ancestorIdentifierFilter->remove(parentFrame.identifierHashes[i]);
</del><ins>+ m_ancestorIdentifierFilter.remove(parentFrame.identifierHashes[i]);
</ins><span class="cx"> m_parentStack.removeLast();
</span><span class="cx"> if (m_parentStack.isEmpty()) {
</span><del>- ASSERT(m_ancestorIdentifierFilter->likelyEmpty());
- m_ancestorIdentifierFilter = nullptr;
</del><ins>+ ASSERT(m_ancestorIdentifierFilter.likelyEmpty());
+ m_ancestorIdentifierFilter.clear();
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SelectorFilter::setupParentStack(Element* parent)
-{
- ASSERT(m_parentStack.isEmpty() == !m_ancestorIdentifierFilter);
- // Kill whatever we stored before.
- m_parentStack.shrink(0);
- m_ancestorIdentifierFilter = std::make_unique<CountingBloomFilter<bloomFilterKeyBits>>();
- // Fast version if parent is a root element:
- if (!parent->parentNode() && !parent->isShadowRoot()) {
- pushParentStackFrame(parent);
- return;
- }
- // Otherwise climb up the tree.
- Vector<Element*, 30> ancestors;
- for (Element* ancestor = parent; ancestor; ancestor = ancestor->parentOrShadowHostElement())
- ancestors.append(ancestor);
- for (size_t n = ancestors.size(); n; --n)
- pushParentStackFrame(ancestors[n - 1]);
-}
-
</del><span class="cx"> void SelectorFilter::pushParent(Element* parent)
</span><span class="cx"> {
</span><del>- ASSERT(m_ancestorIdentifierFilter);
- // We may get invoked for some random elements in some wacky cases during style resolve.
- // Pause maintaining the stack in this case.
- if (m_parentStack.last().element != parent->parentOrShadowHostElement())
- return;
</del><span class="cx"> pushParentStackFrame(parent);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorFilterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorFilter.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorFilter.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/SelectorFilter.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -43,11 +43,10 @@
</span><span class="cx"> void pushParentStackFrame(Element* parent);
</span><span class="cx"> void popParentStackFrame();
</span><span class="cx">
</span><del>- void setupParentStack(Element* parent);
</del><span class="cx"> void pushParent(Element* parent);
</span><span class="cx"> void popParent() { popParentStackFrame(); }
</span><span class="cx"> bool parentStackIsEmpty() const { return m_parentStack.isEmpty(); }
</span><del>- bool parentStackIsConsistent(const ContainerNode* parentNode) const { return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode; }
</del><ins>+ bool parentStackIsConsistent(const ContainerNode* parentNode) const;
</ins><span class="cx">
</span><span class="cx"> template <unsigned maximumIdentifierCount>
</span><span class="cx"> inline bool fastRejectSelector(const unsigned* identifierHashes) const;
</span><span class="lines">@@ -64,15 +63,14 @@
</span><span class="cx">
</span><span class="cx"> // With 100 unique strings in the filter, 2^12 slot table has false positive rate of ~0.2%.
</span><span class="cx"> static const unsigned bloomFilterKeyBits = 12;
</span><del>- std::unique_ptr<CountingBloomFilter<bloomFilterKeyBits>> m_ancestorIdentifierFilter;
</del><ins>+ CountingBloomFilter<bloomFilterKeyBits> m_ancestorIdentifierFilter;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> template <unsigned maximumIdentifierCount>
</span><span class="cx"> inline bool SelectorFilter::fastRejectSelector(const unsigned* identifierHashes) const
</span><span class="cx"> {
</span><del>- ASSERT(m_ancestorIdentifierFilter);
</del><span class="cx"> for (unsigned n = 0; n < maximumIdentifierCount && identifierHashes[n]; ++n) {
</span><del>- if (!m_ancestorIdentifierFilter->mayContain(identifierHashes[n]))
</del><ins>+ if (!m_ancestorIdentifierFilter.mayContain(identifierHashes[n]))
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx"> return false;
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleInvalidationAnalysiscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx">
</span><span class="cx"> switch (element.styleChangeType()) {
</span><span class="cx"> case NoStyleChange: {
</span><del>- ElementRuleCollector ruleCollector(element, nullptr, m_ruleSets, filter);
</del><ins>+ ElementRuleCollector ruleCollector(element, nullptr, m_ruleSets, &filter);
</ins><span class="cx"> ruleCollector.setMode(SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements);
</span><span class="cx"> ruleCollector.matchAuthorRules(false);
</span><span class="cx">
</span><span class="lines">@@ -145,11 +145,6 @@
</span><span class="cx"> else
</span><span class="cx"> it.traverseNextSkippingChildren();
</span><span class="cx"> }
</span><del>-
- while (!parentStack.isEmpty()) {
- parentStack.removeLast();
- filter.popParent();
- }
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void StyleInvalidationAnalysis::invalidateStyle(Document& document)
</span><span class="lines">@@ -163,7 +158,6 @@
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> SelectorFilter filter;
</span><del>- filter.setupParentStack(documentElement);
</del><span class="cx"> invalidateStyleForTree(*documentElement, filter);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleResolvercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleResolver.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleResolver.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/StyleResolver.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -293,28 +293,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void StyleResolver::pushParentElement(Element* parent)
-{
- const ContainerNode* parentsParent = parent->parentOrShadowHostElement();
-
- // We are not always invoked consistently. For example, script execution can cause us to enter
- // style recalc in the middle of tree building. We may also be invoked from somewhere within the tree.
- // Reset the stack in this case, or if we see a new root element.
- // Otherwise just push the new parent.
- if (!parentsParent || m_selectorFilter.parentStackIsEmpty())
- m_selectorFilter.setupParentStack(parent);
- else
- m_selectorFilter.pushParent(parent);
-}
-
-void StyleResolver::popParentElement(Element* parent)
-{
- // Note that we may get invoked for some random elements in some wacky cases during style resolve.
- // Pause maintaining the stack in this case.
- if (m_selectorFilter.parentStackIsConsistent(parent))
- m_selectorFilter.popParent();
-}
-
</del><span class="cx"> // This is a simplified style setting function for keyframe styles
</span><span class="cx"> void StyleResolver::addKeyframeStyle(PassRefPtr<StyleRuleKeyframes> rule)
</span><span class="cx"> {
</span><span class="lines">@@ -387,7 +365,7 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline void StyleResolver::State::initForStyleResolve(Document& document, Element* e, RenderStyle* parentStyle, const RenderRegion* regionForStyling)
</del><ins>+inline void StyleResolver::State::initForStyleResolve(Document& document, Element* e, RenderStyle* parentStyle, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
</ins><span class="cx"> {
</span><span class="cx"> m_regionForStyling = regionForStyling;
</span><span class="cx">
</span><span class="lines">@@ -408,6 +386,8 @@
</span><span class="cx"> m_authorRollback = nullptr;
</span><span class="cx"> m_userRollback = nullptr;
</span><span class="cx">
</span><ins>+ m_selectorFilter = selectorFilter;
+
</ins><span class="cx"> updateConversionData();
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -475,7 +455,7 @@
</span><span class="cx"> if (!ruleSet)
</span><span class="cx"> return false;
</span><span class="cx">
</span><del>- ElementRuleCollector collector(*m_state.element(), m_state.style(), m_ruleSets, m_selectorFilter);
</del><ins>+ ElementRuleCollector collector(*m_state.element(), m_state.style(), m_ruleSets, m_state.selectorFilter());
</ins><span class="cx"> return collector.hasAnyMatchingRules(ruleSet);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -723,7 +703,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Ref<RenderStyle> StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent,
</span><del>- StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling)
</del><ins>+ StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
</ins><span class="cx"> {
</span><span class="cx"> RELEASE_ASSERT(!m_inLoadPendingImages);
</span><span class="cx">
</span><span class="lines">@@ -741,7 +721,8 @@
</span><span class="cx">
</span><span class="cx"> State& state = m_state;
</span><span class="cx"> initElement(element);
</span><del>- state.initForStyleResolve(document(), element, defaultParent, regionForStyling);
</del><ins>+ state.initForStyleResolve(document(), element, defaultParent, regionForStyling, selectorFilter);
+
</ins><span class="cx"> if (sharingBehavior == AllowStyleSharing) {
</span><span class="cx"> if (RenderStyle* sharedStyle = locateSharedStyle()) {
</span><span class="cx"> state.clear();
</span><span class="lines">@@ -773,7 +754,7 @@
</span><span class="cx"> if (needsCollection)
</span><span class="cx"> m_ruleSets.collectFeatures();
</span><span class="cx">
</span><del>- ElementRuleCollector collector(*element, state.style(), m_ruleSets, m_selectorFilter);
</del><ins>+ ElementRuleCollector collector(*element, state.style(), m_ruleSets, m_state.selectorFilter());
</ins><span class="cx"> collector.setRegionForStyling(regionForStyling);
</span><span class="cx"> collector.setMedium(m_medium.get());
</span><span class="cx">
</span><span class="lines">@@ -939,7 +920,7 @@
</span><span class="cx"> // those rules.
</span><span class="cx">
</span><span class="cx"> // Check UA, user and author rules.
</span><del>- ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_selectorFilter);
</del><ins>+ ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_state.selectorFilter());
</ins><span class="cx"> collector.setPseudoStyleRequest(pseudoStyleRequest);
</span><span class="cx"> collector.setMedium(m_medium.get());
</span><span class="cx"> collector.matchUARules();
</span><span class="lines">@@ -1418,7 +1399,7 @@
</span><span class="cx"> initElement(element);
</span><span class="cx"> m_state.initForStyleResolve(document(), element, nullptr);
</span><span class="cx">
</span><del>- ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_selectorFilter);
</del><ins>+ ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_state.selectorFilter());
</ins><span class="cx"> collector.setMode(SelectorChecker::Mode::CollectingRules);
</span><span class="cx"> collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId));
</span><span class="cx"> collector.setMedium(m_medium.get());
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleResolverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleResolver.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleResolver.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/css/StyleResolver.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -35,7 +35,6 @@
</span><span class="cx"> #include "RuntimeEnabledFeatures.h"
</span><span class="cx"> #include "ScrollTypes.h"
</span><span class="cx"> #include "SelectorChecker.h"
</span><del>-#include "SelectorFilter.h"
</del><span class="cx"> #include "StyleInheritedData.h"
</span><span class="cx"> #include "ViewportStyleResolver.h"
</span><span class="cx"> #include <bitset>
</span><span class="lines">@@ -76,6 +75,7 @@
</span><span class="cx"> class RenderScrollbar;
</span><span class="cx"> class RuleData;
</span><span class="cx"> class RuleSet;
</span><ins>+class SelectorFilter;
</ins><span class="cx"> class Settings;
</span><span class="cx"> class StyleImage;
</span><span class="cx"> class StyleKeyframe;
</span><span class="lines">@@ -135,12 +135,8 @@
</span><span class="cx"> StyleResolver(Document&);
</span><span class="cx"> ~StyleResolver();
</span><span class="cx">
</span><del>- // Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
- void pushParentElement(Element*);
- void popParentElement(Element*);
-
</del><span class="cx"> Ref<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle, StyleSharingBehavior = AllowStyleSharing,
</span><del>- RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr);
</del><ins>+ RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
</ins><span class="cx">
</span><span class="cx"> void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
</span><span class="cx">
</span><span class="lines">@@ -160,7 +156,6 @@
</span><span class="cx">
</span><span class="cx"> DocumentRuleSets& ruleSets() { return m_ruleSets; }
</span><span class="cx"> const DocumentRuleSets& ruleSets() const { return m_ruleSets; }
</span><del>- SelectorFilter& selectorFilter() { return m_selectorFilter; }
</del><span class="cx">
</span><span class="cx"> const MediaQueryEvaluator& mediaQueryEvaluator() const { return *m_medium; }
</span><span class="cx">
</span><span class="lines">@@ -385,7 +380,7 @@
</span><span class="cx">
</span><span class="cx"> public:
</span><span class="cx"> void initElement(Element*);
</span><del>- void initForStyleResolve(Document&, Element*, RenderStyle* parentStyle, const RenderRegion* regionForStyling = nullptr);
</del><ins>+ void initForStyleResolve(Document&, Element*, RenderStyle* parentStyle, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
</ins><span class="cx"> void clear();
</span><span class="cx">
</span><span class="cx"> Document& document() const { return m_element->document(); }
</span><span class="lines">@@ -443,6 +438,8 @@
</span><span class="cx">
</span><span class="cx"> void setAuthorRollback(std::unique_ptr<CascadedProperties>& rollback) { m_authorRollback = WTFMove(rollback); }
</span><span class="cx"> void setUserRollback(std::unique_ptr<CascadedProperties>& rollback) { m_userRollback = WTFMove(rollback); }
</span><ins>+
+ const SelectorFilter* selectorFilter() const { return m_selectorFilter; }
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> void updateConversionData();
</span><span class="lines">@@ -480,6 +477,8 @@
</span><span class="cx"> CascadeLevel m_cascadeLevel { UserAgentLevel };
</span><span class="cx"> std::unique_ptr<CascadedProperties> m_authorRollback;
</span><span class="cx"> std::unique_ptr<CascadedProperties> m_userRollback;
</span><ins>+
+ const SelectorFilter* m_selectorFilter { nullptr };
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> State& state() { return m_state; }
</span><span class="lines">@@ -559,7 +558,6 @@
</span><span class="cx"> RefPtr<RenderStyle> m_rootDefaultStyle;
</span><span class="cx">
</span><span class="cx"> Document& m_document;
</span><del>- SelectorFilter m_selectorFilter;
</del><span class="cx">
</span><span class="cx"> bool m_matchAuthorAndUserStyles;
</span><span class="cx">
</span><span class="lines">@@ -618,34 +616,6 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-class StyleResolverParentPusher {
-public:
- StyleResolverParentPusher(Element* parent)
- : m_parent(parent)
- , m_pushedStyleResolver(nullptr)
- { }
- void push()
- {
- if (m_pushedStyleResolver)
- return;
- m_pushedStyleResolver = &m_parent->styleResolver();
- m_pushedStyleResolver->pushParentElement(m_parent);
- }
- ~StyleResolverParentPusher()
- {
- if (!m_pushedStyleResolver)
- return;
- // This tells us that our pushed style selector is in a bad state,
- // so we should just bail out in that scenario.
- ASSERT(m_pushedStyleResolver == &m_parent->styleResolver());
- m_pushedStyleResolver->popParentElement(m_parent);
- }
-
-private:
- Element* m_parent;
- StyleResolver* m_pushedStyleResolver;
-};
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // StyleResolver_h
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleTreeResolvercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleTreeResolver.cpp        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -66,6 +66,36 @@
</span><span class="cx"> static void detachRenderTree(Element&, DetachType);
</span><span class="cx"> static void resolveTextNode(Text&, RenderTreePosition&);
</span><span class="cx">
</span><ins>+class SelectorFilterPusher {
+public:
+ enum PushMode { Push, NoPush };
+ SelectorFilterPusher(SelectorFilter& selectorFilter, Element& parent, PushMode pushMode = Push)
+ : m_selectorFilter(selectorFilter)
+ , m_parent(parent)
+ {
+ if (pushMode == Push)
+ push();
+ }
+ void push()
+ {
+ if (m_didPush)
+ return;
+ m_didPush = true;
+ m_selectorFilter.pushParent(&m_parent);
+ }
+ ~SelectorFilterPusher()
+ {
+ if (!m_didPush)
+ return;
+ m_selectorFilter.popParent();
+ }
+
+private:
+ SelectorFilter& m_selectorFilter;
+ Element& m_parent;
+ bool m_didPush { false };
+};
+
</ins><span class="cx"> TreeResolver::TreeResolver(Document& document)
</span><span class="cx"> : m_document(document)
</span><span class="cx"> , m_styleResolver(document.ensureStyleResolver())
</span><span class="lines">@@ -97,7 +127,7 @@
</span><span class="cx"> if (RefPtr<RenderStyle> style = element.customStyleForRenderer(inheritedStyle))
</span><span class="cx"> return style.releaseNonNull();
</span><span class="cx"> }
</span><del>- return m_styleResolver.styleForElement(&element, &inheritedStyle);
</del><ins>+ return m_styleResolver.styleForElement(&element, &inheritedStyle, AllowStyleSharing, MatchAllRules, nullptr, &m_selectorFilter);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(CSS_REGIONS)
</span><span class="lines">@@ -410,8 +440,10 @@
</span><span class="cx"> else if (is<Element>(*child))
</span><span class="cx"> m_shadowHostTreeResolver->createRenderTreeRecursively(downcast<Element>(*child), inheritedStyle, renderTreePosition, nullptr);
</span><span class="cx"> }
</span><del>- } else
</del><ins>+ } else {
+ SelectorFilterPusher selectorFilterPusher(m_selectorFilter, slot);
</ins><span class="cx"> createRenderTreeForChildren(slot, inheritedStyle, renderTreePosition);
</span><ins>+ }
</ins><span class="cx">
</span><span class="cx"> slot.clearNeedsStyleRecalc();
</span><span class="cx"> slot.clearChildNeedsStyleRecalc();
</span><span class="lines">@@ -436,16 +468,17 @@
</span><span class="cx"> createRenderer(current, inheritedStyle, renderTreePosition, WTFMove(resolvedStyle));
</span><span class="cx">
</span><span class="cx"> if (auto* renderer = current.renderer()) {
</span><del>- StyleResolverParentPusher parentPusher(&current);
</del><ins>+ SelectorFilterPusher selectorFilterPusher(m_selectorFilter, current, SelectorFilterPusher::NoPush);
</ins><span class="cx">
</span><span class="cx"> RenderTreePosition childRenderTreePosition(*renderer);
</span><span class="cx"> createRenderTreeForBeforeOrAfterPseudoElement(current, BEFORE, childRenderTreePosition);
</span><span class="cx">
</span><span class="cx"> auto* shadowRoot = current.shadowRoot();
</span><del>- if (shadowRoot)
</del><ins>+ if (shadowRoot) {
+ selectorFilterPusher.push();
</ins><span class="cx"> createRenderTreeForShadowRoot(*shadowRoot);
</span><del>- else if (current.firstChild())
- parentPusher.push();
</del><ins>+ } else if (current.firstChild())
+ selectorFilterPusher.push();
</ins><span class="cx">
</span><span class="cx"> bool skipChildren = shadowRoot;
</span><span class="cx"> if (!skipChildren)
</span><span class="lines">@@ -730,7 +763,7 @@
</span><span class="cx">
</span><span class="cx"> void TreeResolver::resolveChildren(Element& current, RenderStyle& inheritedStyle, Change change, RenderTreePosition& childRenderTreePosition)
</span><span class="cx"> {
</span><del>- StyleResolverParentPusher parentPusher(&current);
</del><ins>+ SelectorFilterPusher selectorFilterPusher(m_selectorFilter, current, SelectorFilterPusher::NoPush);
</ins><span class="cx">
</span><span class="cx"> bool elementNeedingStyleRecalcAffectsNextSiblingElementStyle = false;
</span><span class="cx"> for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
</span><span class="lines">@@ -751,7 +784,7 @@
</span><span class="cx"> } else if (childElement.needsStyleRecalc())
</span><span class="cx"> elementNeedingStyleRecalcAffectsNextSiblingElementStyle = childElement.affectsNextSiblingElementStyle();
</span><span class="cx"> if (change >= Inherit || childElement.childNeedsStyleRecalc() || childElement.needsStyleRecalc()) {
</span><del>- parentPusher.push();
</del><ins>+ selectorFilterPusher.push();
</ins><span class="cx"> resolveRecursively(childElement, inheritedStyle, childRenderTreePosition, change);
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -803,6 +836,8 @@
</span><span class="cx"> if (change != Detach && renderer) {
</span><span class="cx"> auto* shadowRoot = current.shadowRoot();
</span><span class="cx"> if (shadowRoot && (change >= Inherit || shadowRoot->childNeedsStyleRecalc() || shadowRoot->needsStyleRecalc())) {
</span><ins>+ SelectorFilterPusher selectorFilterPusher(m_selectorFilter, current);
+
</ins><span class="cx"> TreeResolver shadowTreeResolver(*shadowRoot, *this);
</span><span class="cx"> shadowTreeResolver.resolveShadowTree(change, renderer->style());
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleTreeResolverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleTreeResolver.h (194761 => 194762)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleTreeResolver.h        2016-01-08 08:36:47 UTC (rev 194761)
+++ trunk/Source/WebCore/style/StyleTreeResolver.h        2016-01-08 09:06:10 UTC (rev 194762)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #define StyleTreeResolver_h
</span><span class="cx">
</span><span class="cx"> #include "RenderStyleConstants.h"
</span><ins>+#include "SelectorFilter.h"
</ins><span class="cx"> #include "StyleChange.h"
</span><span class="cx"> #include <functional>
</span><span class="cx"> #include <wtf/RefPtr.h>
</span><span class="lines">@@ -82,6 +83,8 @@
</span><span class="cx">
</span><span class="cx"> ShadowRoot* m_shadowRoot { nullptr };
</span><span class="cx"> TreeResolver* m_shadowHostTreeResolver { nullptr };
</span><ins>+
+ SelectorFilter m_selectorFilter;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> void detachRenderTree(Element&);
</span></span></pre>
</div>
</div>
</body>
</html>