Title: [197764] trunk/Source/WebCore
Revision
197764
Author
[email protected]
Date
2016-03-08 06:59:53 -0800 (Tue, 08 Mar 2016)

Log Message

ElementRuleCollector should not mutate document and style
https://bugs.webkit.org/show_bug.cgi?id=155113

Reviewed by Andreas Kling.

Move applying of style relations out of ElementRuleCollector and StyleResolver.
This gets us closer to making StyleResolver const for Element.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::ElementRuleCollector):

    No need for style parameter anymore.

(WebCore::ElementRuleCollector::collectMatchingRules):
(WebCore::ElementRuleCollector::sortAndTransferMatchedRules):
(WebCore::ElementRuleCollector::ruleMatches):

    Client will now do the style and element mutations. Just collect the data here.

(WebCore::ElementRuleCollector::collectMatchingRulesForList):
(WebCore::ElementRuleCollector::commitStyleRelations): Deleted.

    Moves to StyleRelations.cpp

* css/ElementRuleCollector.h:
(WebCore::ElementRuleCollector::hasMatchedRules):
(WebCore::ElementRuleCollector::matchedPseudoElementIds):
(WebCore::ElementRuleCollector::styleRelations):
(WebCore::ElementRuleCollector::didMatchUncommonAttributeSelector):
* css/MediaQueryMatcher.cpp:
(WebCore::MediaQueryMatcher::prepareEvaluator):
(WebCore::MediaQueryMatcher::evaluate):
* css/SelectorChecker.cpp:
(WebCore::addStyleRelation):
(WebCore::isFirstChildElement):
(WebCore::isFirstOfType):
(WebCore::countElementsBefore):
(WebCore::countElementsOfTypeBefore):
(WebCore::SelectorChecker::matchRecursively):
(WebCore::SelectorChecker::checkOne):
* css/SelectorChecker.h:
(WebCore::SelectorChecker::CheckingContext::CheckingContext):
* css/StyleMedia.cpp:
(WebCore::StyleMedia::matchMedium):
* css/StyleResolver.cpp:
(WebCore::StyleResolver::StyleResolver):
(WebCore::isAtShadowBoundary):
(WebCore::StyleResolver::styleForElement):

    Apply the style relations affecting current style immediately.
    Pass the rest to the client.

(WebCore::StyleResolver::styleForKeyframe):
(WebCore::StyleResolver::pseudoStyleForElement):
(WebCore::StyleResolver::pseudoStyleRulesForElement):
* css/StyleResolver.h:
(WebCore::ElementStyle::ElementStyle):
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateAddStyleRelationIfResolvingStyle):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateAddStyleRelation):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorCheckerExcludingPseudoElements):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateDirectAdjacentTreeWalker):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateIndirectAdjacentTreeWalker):
(WebCore::SelectorCompiler::addStyleRelationFunction):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsActive):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsEmpty):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsFirstChild):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsHovered):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsLastChild):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsOnlyChild):
(WebCore::SelectorCompiler::makeContextStyleUniqueIfNecessaryAndTestIsPlaceholderShown):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChildOf):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthLastChild):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthLastChildOf):
* dom/Document.cpp:
(WebCore::Document::styleForElementIgnoringPendingStylesheets):

    Apply style relations.

(WebCore::Document::updateLayoutIfDimensionsOutOfDate):
* dom/Element.cpp:
(WebCore::Element::styleResolver):
(WebCore::Element::resolveStyle):
(WebCore::Element::didDetachRenderers):
(WebCore::Element::resolveCustomStyle):

    Return ElementStyle (which contains style relations along with the render style).
    Rename for consistency.

(WebCore::Element::cloneAttributesFromElement):
(WebCore::Element::customStyleForRenderer): Deleted.
* dom/Element.h:
(WebCore::Element::isVisibleInViewportChanged):
* dom/PseudoElement.cpp:
(WebCore::PseudoElement::clearHostElement):
(WebCore::PseudoElement::resolveCustomStyle):
(WebCore::PseudoElement::didAttachRenderers):
(WebCore::PseudoElement::customStyleForRenderer): Deleted.
* dom/PseudoElement.h:
* html/HTMLTitleElement.cpp:
(WebCore::HTMLTitleElement::computedTextWithDirection):
* html/shadow/SliderThumbElement.cpp:
(WebCore::SliderThumbElement::hostInput):
(WebCore::SliderThumbElement::resolveCustomStyle):
(WebCore::SliderThumbElement::shadowPseudoId):
(WebCore::SliderContainerElement::createElementRenderer):
(WebCore::SliderContainerElement::resolveCustomStyle):
(WebCore::SliderContainerElement::shadowPseudoId):
(WebCore::SliderThumbElement::customStyleForRenderer): Deleted.
(WebCore::SliderContainerElement::customStyleForRenderer): Deleted.
* html/shadow/SliderThumbElement.h:
* html/shadow/TextControlInnerElements.cpp:
(WebCore::TextControlInnerElement::create):
(WebCore::TextControlInnerElement::resolveCustomStyle):
(WebCore::TextControlInnerTextElement::renderer):
(WebCore::TextControlInnerTextElement::resolveCustomStyle):
(WebCore::TextControlPlaceholderElement::TextControlPlaceholderElement):
(WebCore::TextControlPlaceholderElement::resolveCustomStyle):
(WebCore::TextControlInnerElement::customStyleForRenderer): Deleted.
(WebCore::TextControlInnerTextElement::customStyleForRenderer): Deleted.
(WebCore::TextControlPlaceholderElement::customStyleForRenderer): Deleted.
* html/shadow/TextControlInnerElements.h:
* rendering/RenderElement.cpp:
(WebCore::RenderElement::getUncachedPseudoStyle):
* rendering/RenderNamedFlowFragment.cpp:
(WebCore::RenderNamedFlowFragment::computeStyleInRegion):
(WebCore::RenderNamedFlowFragment::computeChildrenStyleInRegion):
* style/StyleRelations.cpp: Added.
(WebCore::Style::commitRelationsToRenderStyle):

    Commit relations affecting style that is being computed.

(WebCore::Style::commitRelationsToDocument):

    Commit relations that mutate document.

* style/StyleRelations.h: Added.

    Factor style relation data structures and functions to a file of their own.

(WebCore::Style::Relation::Relation):
* style/StyleSharingResolver.cpp:
(WebCore::Style::SharingResolver::styleSharingCandidateMatchesRuleSet):
* style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::styleForElement):

    Apply style relations.

* style/StyleTreeResolver.h:
* svg/SVGElement.cpp:
(WebCore::SVGElement::synchronizeSystemLanguage):
(WebCore::SVGElement::resolveCustomStyle):
(WebCore::SVGElement::customStyleForRenderer): Deleted.
* svg/SVGElement.h:
* svg/SVGElementRareData.h:
(WebCore::SVGElementRareData::overrideComputedStyle):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/CMakeLists.txt (197763 => 197764)


--- trunk/Source/WebCore/CMakeLists.txt	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/CMakeLists.txt	2016-03-08 14:59:53 UTC (rev 197764)
@@ -2635,6 +2635,7 @@
     style/RenderTreePosition.cpp
     style/StyleChange.cpp
     style/StyleFontSizeFunctions.cpp
+    style/StyleRelations.cpp
     style/StyleResolveForDocument.cpp
     style/StyleSharingResolver.cpp
     style/StyleTreeResolver.cpp

Modified: trunk/Source/WebCore/ChangeLog (197763 => 197764)


--- trunk/Source/WebCore/ChangeLog	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/ChangeLog	2016-03-08 14:59:53 UTC (rev 197764)
@@ -1,3 +1,165 @@
+2016-03-07  Antti Koivisto  <[email protected]>
+
+        ElementRuleCollector should not mutate document and style
+        https://bugs.webkit.org/show_bug.cgi?id=155113
+
+        Reviewed by Andreas Kling.
+
+        Move applying of style relations out of ElementRuleCollector and StyleResolver.
+        This gets us closer to making StyleResolver const for Element.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/ElementRuleCollector.cpp:
+        (WebCore::ElementRuleCollector::ElementRuleCollector):
+
+            No need for style parameter anymore.
+
+        (WebCore::ElementRuleCollector::collectMatchingRules):
+        (WebCore::ElementRuleCollector::sortAndTransferMatchedRules):
+        (WebCore::ElementRuleCollector::ruleMatches):
+
+            Client will now do the style and element mutations. Just collect the data here.
+
+        (WebCore::ElementRuleCollector::collectMatchingRulesForList):
+        (WebCore::ElementRuleCollector::commitStyleRelations): Deleted.
+
+            Moves to StyleRelations.cpp
+
+        * css/ElementRuleCollector.h:
+        (WebCore::ElementRuleCollector::hasMatchedRules):
+        (WebCore::ElementRuleCollector::matchedPseudoElementIds):
+        (WebCore::ElementRuleCollector::styleRelations):
+        (WebCore::ElementRuleCollector::didMatchUncommonAttributeSelector):
+        * css/MediaQueryMatcher.cpp:
+        (WebCore::MediaQueryMatcher::prepareEvaluator):
+        (WebCore::MediaQueryMatcher::evaluate):
+        * css/SelectorChecker.cpp:
+        (WebCore::addStyleRelation):
+        (WebCore::isFirstChildElement):
+        (WebCore::isFirstOfType):
+        (WebCore::countElementsBefore):
+        (WebCore::countElementsOfTypeBefore):
+        (WebCore::SelectorChecker::matchRecursively):
+        (WebCore::SelectorChecker::checkOne):
+        * css/SelectorChecker.h:
+        (WebCore::SelectorChecker::CheckingContext::CheckingContext):
+        * css/StyleMedia.cpp:
+        (WebCore::StyleMedia::matchMedium):
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::StyleResolver):
+        (WebCore::isAtShadowBoundary):
+        (WebCore::StyleResolver::styleForElement):
+
+            Apply the style relations affecting current style immediately.
+            Pass the rest to the client.
+
+        (WebCore::StyleResolver::styleForKeyframe):
+        (WebCore::StyleResolver::pseudoStyleForElement):
+        (WebCore::StyleResolver::pseudoStyleRulesForElement):
+        * css/StyleResolver.h:
+        (WebCore::ElementStyle::ElementStyle):
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateAddStyleRelationIfResolvingStyle):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateAddStyleRelation):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorCheckerExcludingPseudoElements):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateDirectAdjacentTreeWalker):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateIndirectAdjacentTreeWalker):
+        (WebCore::SelectorCompiler::addStyleRelationFunction):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsActive):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsEmpty):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsFirstChild):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsHovered):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsLastChild):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsOnlyChild):
+        (WebCore::SelectorCompiler::makeContextStyleUniqueIfNecessaryAndTestIsPlaceholderShown):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChildOf):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthLastChild):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthLastChildOf):
+        * dom/Document.cpp:
+        (WebCore::Document::styleForElementIgnoringPendingStylesheets):
+
+            Apply style relations.
+
+        (WebCore::Document::updateLayoutIfDimensionsOutOfDate):
+        * dom/Element.cpp:
+        (WebCore::Element::styleResolver):
+        (WebCore::Element::resolveStyle):
+        (WebCore::Element::didDetachRenderers):
+        (WebCore::Element::resolveCustomStyle):
+
+            Return ElementStyle (which contains style relations along with the render style).
+            Rename for consistency.
+
+        (WebCore::Element::cloneAttributesFromElement):
+        (WebCore::Element::customStyleForRenderer): Deleted.
+        * dom/Element.h:
+        (WebCore::Element::isVisibleInViewportChanged):
+        * dom/PseudoElement.cpp:
+        (WebCore::PseudoElement::clearHostElement):
+        (WebCore::PseudoElement::resolveCustomStyle):
+        (WebCore::PseudoElement::didAttachRenderers):
+        (WebCore::PseudoElement::customStyleForRenderer): Deleted.
+        * dom/PseudoElement.h:
+        * html/HTMLTitleElement.cpp:
+        (WebCore::HTMLTitleElement::computedTextWithDirection):
+        * html/shadow/SliderThumbElement.cpp:
+        (WebCore::SliderThumbElement::hostInput):
+        (WebCore::SliderThumbElement::resolveCustomStyle):
+        (WebCore::SliderThumbElement::shadowPseudoId):
+        (WebCore::SliderContainerElement::createElementRenderer):
+        (WebCore::SliderContainerElement::resolveCustomStyle):
+        (WebCore::SliderContainerElement::shadowPseudoId):
+        (WebCore::SliderThumbElement::customStyleForRenderer): Deleted.
+        (WebCore::SliderContainerElement::customStyleForRenderer): Deleted.
+        * html/shadow/SliderThumbElement.h:
+        * html/shadow/TextControlInnerElements.cpp:
+        (WebCore::TextControlInnerElement::create):
+        (WebCore::TextControlInnerElement::resolveCustomStyle):
+        (WebCore::TextControlInnerTextElement::renderer):
+        (WebCore::TextControlInnerTextElement::resolveCustomStyle):
+        (WebCore::TextControlPlaceholderElement::TextControlPlaceholderElement):
+        (WebCore::TextControlPlaceholderElement::resolveCustomStyle):
+        (WebCore::TextControlInnerElement::customStyleForRenderer): Deleted.
+        (WebCore::TextControlInnerTextElement::customStyleForRenderer): Deleted.
+        (WebCore::TextControlPlaceholderElement::customStyleForRenderer): Deleted.
+        * html/shadow/TextControlInnerElements.h:
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::getUncachedPseudoStyle):
+        * rendering/RenderNamedFlowFragment.cpp:
+        (WebCore::RenderNamedFlowFragment::computeStyleInRegion):
+        (WebCore::RenderNamedFlowFragment::computeChildrenStyleInRegion):
+        * style/StyleRelations.cpp: Added.
+        (WebCore::Style::commitRelationsToRenderStyle):
+
+            Commit relations affecting style that is being computed.
+
+        (WebCore::Style::commitRelationsToDocument):
+
+            Commit relations that mutate document.
+
+        * style/StyleRelations.h: Added.
+
+            Factor style relation data structures and functions to a file of their own.
+
+        (WebCore::Style::Relation::Relation):
+        * style/StyleSharingResolver.cpp:
+        (WebCore::Style::SharingResolver::styleSharingCandidateMatchesRuleSet):
+        * style/StyleTreeResolver.cpp:
+        (WebCore::Style::TreeResolver::styleForElement):
+
+            Apply style relations.
+
+        * style/StyleTreeResolver.h:
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::synchronizeSystemLanguage):
+        (WebCore::SVGElement::resolveCustomStyle):
+        (WebCore::SVGElement::customStyleForRenderer): Deleted.
+        * svg/SVGElement.h:
+        * svg/SVGElementRareData.h:
+        (WebCore::SVGElementRareData::overrideComputedStyle):
+
 2016-03-08  Youenn Fablet  <[email protected]>
 
         [Fetch API] Implement fetch skeleton

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (197763 => 197764)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2016-03-08 14:59:53 UTC (rev 197764)
@@ -6627,6 +6627,8 @@
 		E45390490EAFD637003695C8 /* WebCoreSystemInterfaceIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = E45390380EAFD637003695C8 /* WebCoreSystemInterfaceIOS.mm */; };
 		E453904D0EAFD637003695C8 /* WidgetIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = E453903C0EAFD637003695C8 /* WidgetIOS.mm */; };
 		E45390AE0EAFF4B5003695C8 /* SystemMemoryIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45390AD0EAFF4B5003695C8 /* SystemMemoryIOS.cpp */; };
+		E461802D1C8DD2900026C02C /* StyleRelations.h in Headers */ = {isa = PBXBuildFile; fileRef = E461802C1C8DD2900026C02C /* StyleRelations.h */; };
+		E461802F1C8DD4D20026C02C /* StyleRelations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E461802E1C8DD4D20026C02C /* StyleRelations.cpp */; };
 		E461D65D1BB0C7F000CB5645 /* AuthorStyleSheets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E461D65C1BB0C7F000CB5645 /* AuthorStyleSheets.cpp */; };
 		E461D65F1BB0C80D00CB5645 /* AuthorStyleSheets.h in Headers */ = {isa = PBXBuildFile; fileRef = E461D65E1BB0C80D00CB5645 /* AuthorStyleSheets.h */; };
 		E462A4A1113E71BE004A4220 /* IntPointHash.h in Headers */ = {isa = PBXBuildFile; fileRef = E462A4A0113E71BE004A4220 /* IntPointHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -14664,6 +14666,8 @@
 		E45390380EAFD637003695C8 /* WebCoreSystemInterfaceIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreSystemInterfaceIOS.mm; sourceTree = "<group>"; };
 		E453903C0EAFD637003695C8 /* WidgetIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WidgetIOS.mm; sourceTree = "<group>"; };
 		E45390AD0EAFF4B5003695C8 /* SystemMemoryIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SystemMemoryIOS.cpp; sourceTree = "<group>"; };
+		E461802C1C8DD2900026C02C /* StyleRelations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleRelations.h; sourceTree = "<group>"; };
+		E461802E1C8DD4D20026C02C /* StyleRelations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleRelations.cpp; sourceTree = "<group>"; };
 		E461D65C1BB0C7F000CB5645 /* AuthorStyleSheets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AuthorStyleSheets.cpp; sourceTree = "<group>"; };
 		E461D65E1BB0C80D00CB5645 /* AuthorStyleSheets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthorStyleSheets.h; sourceTree = "<group>"; };
 		E462A4A0113E71BE004A4220 /* IntPointHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntPointHash.h; sourceTree = "<group>"; };
@@ -23549,6 +23553,8 @@
 				E401E0A31C3C0B8300F34D10 /* StyleChange.h */,
 				E4D58EB617B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp */,
 				E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */,
+				E461802E1C8DD4D20026C02C /* StyleRelations.cpp */,
+				E461802C1C8DD2900026C02C /* StyleRelations.h */,
 				E4D58EB217B4DBDC00CBDCA8 /* StyleResolveForDocument.cpp */,
 				E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */,
 				E47A3AC21C5EABBE00CCBFA7 /* StyleSharingResolver.cpp */,
@@ -25220,6 +25226,7 @@
 				FD315FFF12B0267600C1A359 /* ChannelMergerNode.h in Headers */,
 				FD31600212B0267600C1A359 /* ChannelSplitterNode.h in Headers */,
 				6550B6A0099DF0270090D781 /* CharacterData.h in Headers */,
+				E461802D1C8DD2900026C02C /* StyleRelations.h in Headers */,
 				C5592F781A92AA28001F8862 /* CharacterProperties.h in Headers */,
 				97B8FFD116AE7F960038388D /* CharacterReferenceParserInlines.h in Headers */,
 				B2C3DA2A0D006C1D00EF6F26 /* CharsetData.h in Headers */,
@@ -29297,6 +29304,7 @@
 				BC64B4D90CB4298A005F2B62 /* CSSFontFaceSrcValue.cpp in Sources */,
 				4A6E9FC313C17D1D0046A7F8 /* CSSFontFeatureValue.cpp in Sources */,
 				BC64B4DB0CB4298A005F2B62 /* CSSFontSelector.cpp in Sources */,
+				E461802F1C8DD4D20026C02C /* StyleRelations.cpp in Sources */,
 				A80E6CF10A1989CA007FB8C5 /* CSSFontValue.cpp in Sources */,
 				BC02A6460E09AAE9004B6D2B /* CSSFunctionValue.cpp in Sources */,
 				BC23E4E10DAACE0F009FDC91 /* CSSGradientValue.cpp in Sources */,

Modified: trunk/Source/WebCore/css/ElementRuleCollector.cpp (197763 => 197764)


--- trunk/Source/WebCore/css/ElementRuleCollector.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/css/ElementRuleCollector.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -78,9 +78,8 @@
     const bool includeEmptyRules;
 };
 
-ElementRuleCollector::ElementRuleCollector(Element& element, RenderStyle* style, const DocumentRuleSets& ruleSets, const SelectorFilter* selectorFilter)
+ElementRuleCollector::ElementRuleCollector(Element& element, const DocumentRuleSets& ruleSets, const SelectorFilter* selectorFilter)
     : m_element(element)
-    , m_style(style)
     , m_authorStyle(*ruleSets.authorStyle())
     , m_userStyle(ruleSets.userStyle())
     , m_selectorFilter(selectorFilter)
@@ -133,7 +132,6 @@
 void ElementRuleCollector::collectMatchingRules(const MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
 {
     ASSERT(matchRequest.ruleSet);
-    ASSERT_WITH_MESSAGE(!(m_mode == SelectorChecker::Mode::ResolvingStyle && !m_style), "When resolving style, the SelectorChecker must have a style to set the pseudo elements and/or to do marking. The SelectorCompiler also rely on that behavior.");
     ASSERT_WITH_MESSAGE(!(m_mode == SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements && m_pseudoStyleRequest.pseudoId != NOPSEUDO), "When in StyleInvalidation or SharingRules, SelectorChecker does not try to match the pseudo ID. While ElementRuleCollector supports matching a particular pseudoId in this case, this would indicate a error at the call site since matching a particular element should be unnecessary.");
 
 #if ENABLE(VIDEO_TRACK)
@@ -194,10 +192,7 @@
         return;
     }
 
-    // Now transfer the set of matched rules over to our list of declarations.
     for (const MatchedRule& matchedRule : m_matchedRules) {
-        if (m_style && matchedRule.ruleData->containsUncommonAttributeSelector())
-            m_style->setUnique();
         m_result.addMatchedProperties(matchedRule.ruleData->rule()->properties(), matchedRule.ruleData->rule(), matchedRule.ruleData->linkMatchType(), matchedRule.ruleData->propertyWhitelistType());
     }
 }
@@ -414,7 +409,12 @@
 #if CSS_SELECTOR_JIT_PROFILING
         ruleData.compiledSelectorUsed();
 #endif
-        return selectorChecker(&m_element, &specificity);
+        bool selectorMatches = selectorChecker(&m_element, &specificity);
+
+        if (selectorMatches && ruleData.containsUncommonAttributeSelector())
+            m_didMatchUncommonAttributeSelector = true;
+
+        return selectorMatches;
     }
 #endif // ENABLE(CSS_SELECTOR_JIT)
 
@@ -450,86 +450,16 @@
         selectorMatches = selectorChecker.match(*selector, m_element, context, specificity);
     }
 
-    commitStyleRelations(context.styleRelations);
+    if (ruleData.containsUncommonAttributeSelector()) {
+        if (selectorMatches || context.pseudoIDSet)
+            m_didMatchUncommonAttributeSelector = true;
+    }
+    m_matchedPseudoElementIds.merge(context.pseudoIDSet);
+    m_styleRelations.appendVector(context.styleRelations);
 
-    if (context.pseudoIDSet)
-        m_style->setHasPseudoStyles(context.pseudoIDSet);
-
     return selectorMatches;
 }
 
-// FIXME: Rule collector should not be doing mutations. Move this somewhere else.
-void ElementRuleCollector::commitStyleRelations(const SelectorChecker::StyleRelations& styleRelations)
-{
-    for (auto& relation : styleRelations) {
-        switch (relation.type) {
-        case SelectorChecker::StyleRelation::AffectedByActive:
-            if (&relation.element == &m_element)
-                m_style->setAffectedByActive();
-            else
-                relation.element.setChildrenAffectedByActive();
-            break;
-        case SelectorChecker::StyleRelation::AffectedByDrag:
-            if (&relation.element == &m_element)
-                m_style->setAffectedByDrag();
-            else
-                relation.element.setChildrenAffectedByDrag();
-            break;
-        case SelectorChecker::StyleRelation::AffectedByEmpty:
-            relation.element.setStyleAffectedByEmpty();
-            if (&relation.element == &m_element)
-                m_style->setEmptyState(relation.value);
-            break;
-        case SelectorChecker::StyleRelation::AffectedByHover:
-            if (&relation.element == &m_element)
-                m_style->setAffectedByHover();
-            else
-                relation.element.setChildrenAffectedByHover();
-            break;
-        case SelectorChecker::StyleRelation::AffectedByPreviousSibling:
-            relation.element.setStyleIsAffectedByPreviousSibling();
-            break;
-        case SelectorChecker::StyleRelation::AffectsNextSibling:
-            relation.element.setAffectsNextSiblingElementStyle();
-            break;
-        case SelectorChecker::StyleRelation::ChildrenAffectedByBackwardPositionalRules:
-            relation.element.setChildrenAffectedByBackwardPositionalRules();
-            break;
-        case SelectorChecker::StyleRelation::ChildrenAffectedByFirstChildRules:
-            relation.element.setChildrenAffectedByFirstChildRules();
-            break;
-        case SelectorChecker::StyleRelation::ChildrenAffectedByPropertyBasedBackwardPositionalRules:
-            relation.element.setChildrenAffectedByBackwardPositionalRules();
-            relation.element.setChildrenAffectedByPropertyBasedBackwardPositionalRules();
-            break;
-        case SelectorChecker::StyleRelation::ChildrenAffectedByLastChildRules:
-            relation.element.setChildrenAffectedByLastChildRules();
-            break;
-        case SelectorChecker::StyleRelation::FirstChild:
-            if (&relation.element == &m_element)
-                m_style->setFirstChildState();
-            else if (auto* style = relation.element.renderStyle())
-                style->setFirstChildState();
-            break;
-        case SelectorChecker::StyleRelation::LastChild:
-            if (&relation.element == &m_element)
-                m_style->setLastChildState();
-            else if (auto* style = relation.element.renderStyle())
-                style->setLastChildState();
-            break;
-        case SelectorChecker::StyleRelation::NthChildIndex:
-            relation.element.setChildIndex(relation.value);
-            break;
-        case SelectorChecker::StyleRelation::Unique:
-            if (&relation.element == &m_element)
-                m_style->setUnique();
-            else if (auto* style = relation.element.renderStyle())
-                style->setUnique();
-            break;
-        }
-    }
-}
-
 void ElementRuleCollector::collectMatchingRulesForList(const RuleSet::RuleDataVector* rules, const MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
 {
     if (!rules)

Modified: trunk/Source/WebCore/css/ElementRuleCollector.h (197763 => 197764)


--- trunk/Source/WebCore/css/ElementRuleCollector.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/css/ElementRuleCollector.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -45,7 +45,7 @@
 
 class ElementRuleCollector {
 public:
-    ElementRuleCollector(Element&, RenderStyle*, const DocumentRuleSets&, const SelectorFilter*);
+    ElementRuleCollector(Element&, const DocumentRuleSets&, const SelectorFilter*);
     ElementRuleCollector(Element&, const RuleSet& authorStyle, const SelectorFilter*);
 
     void matchAllRules(bool matchAuthorAndUserStyles, bool includeSMILProperties);
@@ -67,6 +67,10 @@
     bool hasMatchedRules() const { return !m_matchedRules.isEmpty(); }
     void clearMatchedRules();
 
+    const PseudoIdSet& matchedPseudoElementIds() const { return m_matchedPseudoElementIds; }
+    const Style::Relations& styleRelations() const { return m_styleRelations; }
+    bool didMatchUncommonAttributeSelector() const { return m_didMatchUncommonAttributeSelector; }
+
 private:
     void addElementStyleProperties(const StyleProperties*, bool isCacheable = true);
 
@@ -87,10 +91,7 @@
 
     void addMatchedRule(const MatchedRule&);
 
-    void commitStyleRelations(const SelectorChecker::StyleRelations&);
-
     Element& m_element;
-    RenderStyle* m_style { nullptr };
     const RuleSet& m_authorStyle;
     const RuleSet* m_userStyle { nullptr };
     const SelectorFilter* m_selectorFilter { nullptr };
@@ -108,7 +109,10 @@
 
     // Output.
     Vector<RefPtr<StyleRule>> m_matchedRuleList;
+    bool m_didMatchUncommonAttributeSelector { false };
     StyleResolver::MatchResult m_result;
+    Style::Relations m_styleRelations;
+    PseudoIdSet m_matchedPseudoElementIds;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/MediaQueryMatcher.cpp (197763 => 197764)


--- trunk/Source/WebCore/css/MediaQueryMatcher.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/css/MediaQueryMatcher.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -85,9 +85,9 @@
     if (!documentElement)
         return nullptr;
 
-    RefPtr<RenderStyle> rootStyle = m_document->ensureStyleResolver().styleForElement(*documentElement, m_document->renderStyle(), MatchOnlyUserAgentRules);
+    auto rootStyle = m_document->ensureStyleResolver().styleForElement(*documentElement, m_document->renderStyle(), MatchOnlyUserAgentRules).renderStyle;
 
-    return std::make_unique<MediaQueryEvaluator>(mediaType(), m_document->frame(), rootStyle.get());
+    return std::make_unique<MediaQueryEvaluator>(mediaType(), m_document->frame(), rootStyle.ptr());
 }
 
 bool MediaQueryMatcher::evaluate(const MediaQuerySet* media)

Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (197763 => 197764)


--- trunk/Source/WebCore/css/SelectorChecker.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -84,12 +84,12 @@
 
 };
 
-static inline void addStyleRelation(SelectorChecker::CheckingContext& checkingContext, const Element& element, SelectorChecker::StyleRelation::Type type, unsigned value = 1)
+static inline void addStyleRelation(SelectorChecker::CheckingContext& checkingContext, const Element& element, Style::Relation::Type type, unsigned value = 1)
 {
-    ASSERT(value == 1 || type == SelectorChecker::StyleRelation::NthChildIndex || type == SelectorChecker::StyleRelation::AffectedByEmpty);
+    ASSERT(value == 1 || type == Style::Relation::NthChildIndex || type == Style::Relation::AffectedByEmpty);
     if (checkingContext.resolvingMode != SelectorChecker::Mode::ResolvingStyle)
         return;
-    checkingContext.styleRelations.append({ const_cast<Element&>(element), type, value });
+    checkingContext.styleRelations.append({ element, type, value });
 }
 
 static inline bool isFirstChildElement(const Element& element)
@@ -105,7 +105,7 @@
 static inline bool isFirstOfType(SelectorChecker::CheckingContext& checkingContext, const Element& element, const QualifiedName& type)
 {
     for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
-        addStyleRelation(checkingContext, *sibling, SelectorChecker::StyleRelation::AffectsNextSibling);
+        addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
 
         if (sibling->hasTagName(type))
             return false;
@@ -127,7 +127,7 @@
     int count = 0;
     for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
 
-        addStyleRelation(checkingContext, *sibling, SelectorChecker::StyleRelation::AffectsNextSibling);
+        addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
 
         unsigned index = sibling->childIndex();
         if (index) {
@@ -143,7 +143,7 @@
 {
     int count = 0;
     for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
-        addStyleRelation(checkingContext, *sibling, SelectorChecker::StyleRelation::AffectsNextSibling);
+        addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
 
         if (sibling->hasTagName(type))
             ++count;
@@ -328,13 +328,13 @@
 
     case CSSSelector::DirectAdjacent:
         {
-            addStyleRelation(checkingContext, *context.element, StyleRelation::AffectedByPreviousSibling);
+            addStyleRelation(checkingContext, *context.element, Style::Relation::AffectedByPreviousSibling);
 
             Element* previousElement = context.element->previousElementSibling();
             if (!previousElement)
                 return MatchResult::fails(Match::SelectorFailsAllSiblings);
 
-            addStyleRelation(checkingContext, *previousElement, StyleRelation::AffectsNextSibling);
+            addStyleRelation(checkingContext, *previousElement, Style::Relation::AffectsNextSibling);
 
             nextContext.element = previousElement;
             nextContext.firstSelectorOfTheFragment = nextContext.selector;
@@ -349,12 +349,12 @@
             return MatchResult::updateWithMatchType(result, matchType);
         }
     case CSSSelector::IndirectAdjacent:
-        addStyleRelation(checkingContext, *context.element, StyleRelation::AffectedByPreviousSibling);
+        addStyleRelation(checkingContext, *context.element, Style::Relation::AffectedByPreviousSibling);
 
         nextContext.element = context.element->previousElementSibling();
         nextContext.firstSelectorOfTheFragment = nextContext.selector;
         for (; nextContext.element; nextContext.element = nextContext.element->previousElementSibling()) {
-            addStyleRelation(checkingContext, *nextContext.element, StyleRelation::AffectsNextSibling);
+            addStyleRelation(checkingContext, *nextContext.element, Style::Relation::AffectsNextSibling);
 
             PseudoIdSet ignoreDynamicPseudo;
             unsigned indirectAdjacentSpecificity = 0;
@@ -682,7 +682,7 @@
                         }
                     }
                 }
-                addStyleRelation(checkingContext, *context.element, StyleRelation::AffectedByEmpty, result);
+                addStyleRelation(checkingContext, *context.element, Style::Relation::AffectedByEmpty, result);
 
                 return result;
             }
@@ -691,15 +691,15 @@
             if (const Element* parentElement = element.parentElement()) {
                 bool isFirstChild = isFirstChildElement(element);
                 if (isFirstChild)
-                    addStyleRelation(checkingContext, element, StyleRelation::FirstChild);
-                addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByFirstChildRules);
+                    addStyleRelation(checkingContext, element, Style::Relation::FirstChild);
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByFirstChildRules);
                 return isFirstChild;
             }
             break;
         case CSSSelector::PseudoClassFirstOfType:
             // first-of-type matches the first element of its type
             if (element.parentElement()) {
-                addStyleRelation(checkingContext, element, StyleRelation::AffectedByPreviousSibling);
+                addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
                 return isFirstOfType(checkingContext, element, element.tagQName());
             }
             break;
@@ -708,15 +708,15 @@
             if (const Element* parentElement = element.parentElement()) {
                 bool isLastChild = parentElement->isFinishedParsingChildren() && isLastChildElement(element);
                 if (isLastChild)
-                    addStyleRelation(checkingContext, element, StyleRelation::LastChild);
-                addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByLastChildRules);
+                    addStyleRelation(checkingContext, element, Style::Relation::LastChild);
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByLastChildRules);
                 return isLastChild;
             }
             break;
         case CSSSelector::PseudoClassLastOfType:
             // last-of-type matches the last element of its type
             if (Element* parentElement = element.parentElement()) {
-                addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules);
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByBackwardPositionalRules);
                 if (!parentElement->isFinishedParsingChildren())
                     return false;
                 return isLastOfType(element, element.tagQName());
@@ -726,20 +726,20 @@
             if (Element* parentElement = element.parentElement()) {
                 bool firstChild = isFirstChildElement(element);
                 bool _onlyChild_ = firstChild && parentElement->isFinishedParsingChildren() && isLastChildElement(element);
-                addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByFirstChildRules);
-                addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByLastChildRules);
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByFirstChildRules);
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByLastChildRules);
                 if (firstChild)
-                    addStyleRelation(checkingContext, element, StyleRelation::FirstChild);
+                    addStyleRelation(checkingContext, element, Style::Relation::FirstChild);
                 if (onlyChild)
-                    addStyleRelation(checkingContext, element, StyleRelation::LastChild);
+                    addStyleRelation(checkingContext, element, Style::Relation::LastChild);
                 return onlyChild;
             }
             break;
         case CSSSelector::PseudoClassOnlyOfType:
             // FIXME: This selector is very slow.
             if (Element* parentElement = element.parentElement()) {
-                addStyleRelation(checkingContext, element, StyleRelation::AffectedByPreviousSibling);
-                addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules);
+                addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByBackwardPositionalRules);
                 if (!parentElement->isFinishedParsingChildren())
                     return false;
                 return isFirstOfType(checkingContext, element, element.tagQName()) && isLastOfType(element, element.tagQName());
@@ -778,7 +778,7 @@
             }
         case CSSSelector::PseudoClassPlaceholderShown:
             if (is<HTMLTextFormControlElement>(element)) {
-                addStyleRelation(checkingContext, element, StyleRelation::Unique);
+                addStyleRelation(checkingContext, element, Style::Relation::Unique);
                 return downcast<HTMLTextFormControlElement>(element).isPlaceholderVisible();
             }
             return false;
@@ -793,12 +793,12 @@
                     specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity);
                 }
 
-                addStyleRelation(checkingContext, element, StyleRelation::AffectedByPreviousSibling);
+                addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
 
                 int count = 1;
                 if (const CSSSelectorList* selectorList = selector.selectorList()) {
                     for (Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
-                        addStyleRelation(checkingContext, *sibling, StyleRelation::AffectsNextSibling);
+                        addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
 
                         unsigned ignoredSpecificity;
                         if (matchSelectorList(checkingContext, context, *sibling, *selectorList, ignoredSpecificity))
@@ -806,7 +806,7 @@
                     }
                 } else {
                     count += countElementsBefore(checkingContext, element);
-                    addStyleRelation(checkingContext, element, StyleRelation::NthChildIndex, count);
+                    addStyleRelation(checkingContext, element, Style::Relation::NthChildIndex, count);
                 }
 
                 if (selector.matchNth(count))
@@ -818,7 +818,7 @@
                 break;
 
             if (element.parentElement()) {
-                addStyleRelation(checkingContext, element, StyleRelation::AffectedByPreviousSibling);
+                addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
 
                 int count = 1 + countElementsOfTypeBefore(checkingContext, element, element.tagQName());
                 if (selector.matchNth(count))
@@ -835,9 +835,9 @@
                         return false;
                     specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity);
 
-                    addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByPropertyBasedBackwardPositionalRules);
+                    addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules);
                 } else
-                    addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules);
+                    addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByBackwardPositionalRules);
 
                 if (!parentElement->isFinishedParsingChildren())
                     return false;
@@ -860,7 +860,7 @@
             if (!selector.parseNth())
                 break;
             if (Element* parentElement = element.parentElement()) {
-                addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules);
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByBackwardPositionalRules);
 
                 if (!parentElement->isFinishedParsingChildren())
                     return false;
@@ -902,7 +902,7 @@
                 return false;
             return element.isLink() && context.visitedMatchType == VisitedMatchType::Enabled;
         case CSSSelector::PseudoClassDrag:
-            addStyleRelation(checkingContext, element, StyleRelation::AffectedByDrag);
+            addStyleRelation(checkingContext, element, Style::Relation::AffectedByDrag);
 
             if (element.renderer() && element.renderer()->isDragging())
                 return true;
@@ -911,7 +911,7 @@
             return matchesFocusPseudoClass(element);
         case CSSSelector::PseudoClassHover:
             if (m_strictParsing || element.isLink() || canMatchHoverOrActiveInQuirksMode(context)) {
-                addStyleRelation(checkingContext, element, StyleRelation::AffectedByHover);
+                addStyleRelation(checkingContext, element, Style::Relation::AffectedByHover);
 
                 if (element.hovered() || InspectorInstrumentation::forcePseudoState(const_cast<Element&>(element), CSSSelector::PseudoClassHover))
                     return true;
@@ -919,7 +919,7 @@
             break;
         case CSSSelector::PseudoClassActive:
             if (m_strictParsing || element.isLink() || canMatchHoverOrActiveInQuirksMode(context)) {
-                addStyleRelation(checkingContext, element, StyleRelation::AffectedByActive);
+                addStyleRelation(checkingContext, element, Style::Relation::AffectedByActive);
 
                 if (element.active() || InspectorInstrumentation::forcePseudoState(const_cast<Element&>(element), CSSSelector::PseudoClassActive))
                     return true;

Modified: trunk/Source/WebCore/css/SelectorChecker.h (197763 => 197764)


--- trunk/Source/WebCore/css/SelectorChecker.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/css/SelectorChecker.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -31,6 +31,7 @@
 #include "CSSSelector.h"
 #include "Element.h"
 #include "SpaceSplitString.h"
+#include "StyleRelations.h"
 #include <wtf/HashSet.h>
 #include <wtf/Vector.h>
 
@@ -76,29 +77,6 @@
 
     SelectorChecker(Document&);
 
-    struct StyleRelation {
-        enum Type {
-            AffectedByActive,
-            AffectedByDrag,
-            AffectedByEmpty,
-            AffectedByHover,
-            AffectedByPreviousSibling,
-            AffectsNextSibling,
-            ChildrenAffectedByBackwardPositionalRules,
-            ChildrenAffectedByFirstChildRules,
-            ChildrenAffectedByPropertyBasedBackwardPositionalRules,
-            ChildrenAffectedByLastChildRules,
-            FirstChild,
-            LastChild,
-            NthChildIndex,
-            Unique,
-        };
-        Element& element;
-        Type type;
-        unsigned value;
-    };
-    using StyleRelations = Vector<StyleRelation, 8>;
-
     struct CheckingContext {
         CheckingContext(SelectorChecker::Mode resolvingMode)
             : resolvingMode(resolvingMode)
@@ -111,7 +89,7 @@
         const ContainerNode* scope { nullptr };
 
         // FIXME: It would be nicer to have a separate object for return values. This requires some more work in the selector compiler.
-        StyleRelations styleRelations;
+        Style::Relations styleRelations;
         PseudoIdSet pseudoIDSet;
     };
 

Modified: trunk/Source/WebCore/css/StyleMedia.cpp (197763 => 197764)


--- trunk/Source/WebCore/css/StyleMedia.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/css/StyleMedia.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -61,13 +61,13 @@
     if (!documentElement)
         return false;
 
-    RefPtr<RenderStyle> rootStyle = document->ensureStyleResolver().styleForElement(*documentElement, document->renderStyle(), MatchOnlyUserAgentRules);
+    auto rootStyle = document->ensureStyleResolver().styleForElement(*documentElement, document->renderStyle(), MatchOnlyUserAgentRules).renderStyle;
 
     RefPtr<MediaQuerySet> media = MediaQuerySet::create();
     if (!media->parse(query))
         return false;
 
-    MediaQueryEvaluator screenEval(type(), m_frame, rootStyle.get());
+    MediaQueryEvaluator screenEval(type(), m_frame, rootStyle.ptr());
     return screenEval.eval(media.get());
 }
 

Modified: trunk/Source/WebCore/css/StyleResolver.cpp (197763 => 197764)


--- trunk/Source/WebCore/css/StyleResolver.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/css/StyleResolver.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -267,7 +267,7 @@
         m_medium = std::make_unique<MediaQueryEvaluator>("all");
 
     if (root)
-        m_rootDefaultStyle = styleForElement(*root, m_document.renderStyle(), MatchOnlyUserAgentRules);
+        m_rootDefaultStyle = styleForElement(*root, m_document.renderStyle(), MatchOnlyUserAgentRules).renderStyle;
 
     if (m_rootDefaultStyle && view)
         m_medium = std::make_unique<MediaQueryEvaluator>(view->mediaType(), &view->frame(), m_rootDefaultStyle.get());
@@ -371,7 +371,7 @@
     return parentNode && parentNode->isShadowRoot();
 }
 
-Ref<RenderStyle> StyleResolver::styleForElement(Element& element, RenderStyle* parentStyle, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
+ElementStyle StyleResolver::styleForElement(Element& element, RenderStyle* parentStyle, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
 {
     RELEASE_ASSERT(!m_inLoadPendingImages);
 
@@ -386,20 +386,22 @@
         state.setParentStyle(RenderStyle::clone(state.style()));
     }
 
+    auto& style = *state.style();
+
     if (element.isLink()) {
-        state.style()->setIsLink(true);
+        style.setIsLink(true);
         EInsideLink linkState = state.elementLinkState();
         if (linkState != NotInsideLink) {
             bool forceVisited = InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoClassVisited);
             if (forceVisited)
                 linkState = InsideVisitedLink;
         }
-        state.style()->setInsideLink(linkState);
+        style.setInsideLink(linkState);
     }
 
     CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(element);
 
-    ElementRuleCollector collector(element, state.style(), m_ruleSets, m_state.selectorFilter());
+    ElementRuleCollector collector(element, m_ruleSets, m_state.selectorFilter());
     collector.setRegionForStyling(regionForStyling);
     collector.setMedium(m_medium.get());
 
@@ -408,6 +410,15 @@
     else
         collector.matchAllRules(m_matchAuthorAndUserStyles, matchingBehavior != MatchAllRulesExcludingSMIL);
 
+    if (collector.matchedPseudoElementIds())
+        style.setHasPseudoStyles(collector.matchedPseudoElementIds());
+
+    // This is required for style sharing.
+    if (collector.didMatchUncommonAttributeSelector())
+        style.setUnique();
+
+    auto elementStyleRelations = Style::commitRelationsToRenderStyle(style, element, collector.styleRelations());
+
     applyMatchedProperties(collector.matchedResult(), element);
 
     // Clean up our style object's display and text decorations (among other fixups).
@@ -418,8 +429,7 @@
 
     state.clear(); // Clear out for the next resolve.
 
-    // Now return the style.
-    return state.takeStyle();
+    return { state.takeStyle(), WTFMove(elementStyleRelations) };
 }
 
 Ref<RenderStyle> StyleResolver::styleForKeyframe(const RenderStyle* elementStyle, const StyleKeyframe* keyframe, KeyframeValue& keyframeValue)
@@ -558,7 +568,7 @@
     // those rules.
 
     // Check UA, user and author rules.
-    ElementRuleCollector collector(element, m_state.style(), m_ruleSets, m_state.selectorFilter());
+    ElementRuleCollector collector(element, m_ruleSets, m_state.selectorFilter());
     collector.setPseudoStyleRequest(pseudoStyleRequest);
     collector.setMedium(m_medium.get());
     collector.matchUARules();
@@ -568,6 +578,8 @@
         collector.matchAuthorRules(false);
     }
 
+    ASSERT(!collector.matchedPseudoElementIds());
+
     if (collector.matchedResult().matchedProperties().isEmpty())
         return nullptr;
 
@@ -1040,7 +1052,7 @@
 
     m_state = State(*element, nullptr);
 
-    ElementRuleCollector collector(*element, nullptr, m_ruleSets, m_state.selectorFilter());
+    ElementRuleCollector collector(*element, m_ruleSets, m_state.selectorFilter());
     collector.setMode(SelectorChecker::Mode::CollectingRules);
     collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId));
     collector.setMedium(m_medium.get());

Modified: trunk/Source/WebCore/css/StyleResolver.h (197763 => 197764)


--- trunk/Source/WebCore/css/StyleResolver.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/css/StyleResolver.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -36,6 +36,7 @@
 #include "ScrollTypes.h"
 #include "SelectorChecker.h"
 #include "StyleInheritedData.h"
+#include "StyleRelations.h"
 #include "ViewportStyleResolver.h"
 #include <bitset>
 #include <memory>
@@ -123,6 +124,16 @@
     RenderScrollbar* scrollbar;
 };
 
+struct ElementStyle {
+    ElementStyle(Ref<RenderStyle>&& renderStyle, std::unique_ptr<Style::Relations> relations = { })
+        : renderStyle(WTFMove(renderStyle))
+        , relations(WTFMove(relations))
+    { }
+
+    Ref<RenderStyle> renderStyle;
+    std::unique_ptr<Style::Relations> relations;
+};
+
 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
 class StyleResolver {
     WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED;
@@ -130,7 +141,7 @@
     StyleResolver(Document&);
     ~StyleResolver();
 
-    Ref<RenderStyle> styleForElement(Element&, RenderStyle* parentStyle, RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
+    ElementStyle styleForElement(Element&, RenderStyle* parentStyle, RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
 
     void keyframeStylesForAnimation(Element&, const RenderStyle*, KeyframeList&);
 

Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (197763 => 197764)


--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -47,6 +47,7 @@
 #include "SVGElement.h"
 #include "SelectorCheckerTestFunctions.h"
 #include "StackAllocator.h"
+#include "StyleRelations.h"
 #include "StyledElement.h"
 #include <_javascript_Core/GPRInfo.h>
 #include <_javascript_Core/LinkBuffer.h>
@@ -323,8 +324,8 @@
     void generateElementIsTarget(Assembler::JumpList& failureCases);
 
     // Helpers.
-    void generateAddStyleRelationIfResolvingStyle(Assembler::RegisterID element, SelectorChecker::StyleRelation::Type, Optional<Assembler::RegisterID> value = { });
-    void generateAddStyleRelation(Assembler::RegisterID checkingContext, Assembler::RegisterID element, SelectorChecker::StyleRelation::Type, Optional<Assembler::RegisterID> value = { });
+    void generateAddStyleRelationIfResolvingStyle(Assembler::RegisterID element, Style::Relation::Type, Optional<Assembler::RegisterID> value = { });
+    void generateAddStyleRelation(Assembler::RegisterID checkingContext, Assembler::RegisterID element, Style::Relation::Type, Optional<Assembler::RegisterID> value = { });
     Assembler::Jump branchOnResolvingModeWithCheckingContext(Assembler::RelationalCondition, SelectorChecker::Mode, Assembler::RegisterID checkingContext);
     Assembler::Jump branchOnResolvingMode(Assembler::RelationalCondition, SelectorChecker::Mode, Assembler::RegisterID checkingContext);
     void generateElementIsFirstLink(Assembler::JumpList& failureCases, Assembler::RegisterID element);
@@ -1891,7 +1892,7 @@
             break;
         }
         if (shouldMarkStyleIsAffectedByPreviousSibling(fragment))
-            generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByPreviousSibling);
+            generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByPreviousSibling);
         generateBacktrackingTailsIfNeeded(failureCases, fragment);
     }
 
@@ -2135,7 +2136,7 @@
 void SelectorCodeGenerator::generateDirectAdjacentTreeWalker(Assembler::JumpList& failureCases, const SelectorFragment& fragment)
 {
     generateWalkToPreviousAdjacent(failureCases, fragment);
-    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectsNextSibling);
+    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectsNextSibling);
 
     Assembler::JumpList matchingTagNameFailureCases;
     Assembler::JumpList matchingPostTagNameFailureCases;
@@ -2160,7 +2161,7 @@
         m_backtrackingLevels.last().indirectAdjacentTreeWalkerBacktrackingPoint = m_assembler.label();
 
     generateWalkToPreviousAdjacent(failureCases, fragment);
-    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectsNextSibling);
+    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectsNextSibling);
 
     if (fragment.backtrackingFlags & BacktrackingFlag::IndirectAdjacentEntryPoint)
         m_backtrackingLevels.last().indirectAdjacentEntryPoint = m_assembler.label();
@@ -2170,7 +2171,7 @@
     localFailureCases.linkTo(loopStart, &m_assembler);
 }
 
-void SelectorCodeGenerator::generateAddStyleRelationIfResolvingStyle(Assembler::RegisterID element, SelectorChecker::StyleRelation::Type relationType, Optional<Assembler::RegisterID> value)
+void SelectorCodeGenerator::generateAddStyleRelationIfResolvingStyle(Assembler::RegisterID element, Style::Relation::Type relationType, Optional<Assembler::RegisterID> value)
 {
     if (m_selectorContext == SelectorContext::QuerySelector)
         return;
@@ -2185,10 +2186,10 @@
 
 static void addStyleRelationFunction(SelectorChecker::CheckingContext* checkingContext, Element* element)
 {
-    checkingContext->styleRelations.append({ *element, SelectorChecker::StyleRelation::AffectedByActive, 1 });
+    checkingContext->styleRelations.append({ *element, Style::Relation::AffectedByActive, 1 });
 }
 
-void SelectorCodeGenerator::generateAddStyleRelation(Assembler::RegisterID checkingContext, Assembler::RegisterID element, SelectorChecker::StyleRelation::Type relationType, Optional<Assembler::RegisterID> value)
+void SelectorCodeGenerator::generateAddStyleRelation(Assembler::RegisterID checkingContext, Assembler::RegisterID element, Style::Relation::Type relationType, Optional<Assembler::RegisterID> value)
 {
     ASSERT(m_selectorContext != SelectorContext::QuerySelector);
 
@@ -2199,20 +2200,20 @@
     functionCall.call();
 
     Assembler::Address vectorAddress(checkingContext, OBJECT_OFFSETOF(SelectorChecker::CheckingContext, styleRelations));
-    auto dataAddress = vectorAddress.withOffset(SelectorChecker::StyleRelations::dataMemoryOffset());
-    auto sizeAddress = vectorAddress.withOffset(SelectorChecker::StyleRelations::sizeMemoryOffset());
+    auto dataAddress = vectorAddress.withOffset(Style::Relations::dataMemoryOffset());
+    auto sizeAddress = vectorAddress.withOffset(Style::Relations::sizeMemoryOffset());
 
     LocalRegister relationPointer(m_registerAllocator);
     m_assembler.load32(sizeAddress, relationPointer);
     m_assembler.sub32(Assembler::TrustedImm32(1), relationPointer);
-    m_assembler.mul32(Assembler::TrustedImm32(sizeof(SelectorChecker::StyleRelation)), relationPointer, relationPointer);
+    m_assembler.mul32(Assembler::TrustedImm32(sizeof(Style::Relation)), relationPointer, relationPointer);
     m_assembler.addPtr(dataAddress, relationPointer);
 
-    Assembler::Address typeAddress(relationPointer, OBJECT_OFFSETOF(SelectorChecker::StyleRelation, type));
+    Assembler::Address typeAddress(relationPointer, OBJECT_OFFSETOF(Style::Relation, type));
     m_assembler.store32(Assembler::TrustedImm32(relationType), typeAddress);
 
     if (value) {
-        Assembler::Address valueAddress(relationPointer, OBJECT_OFFSETOF(SelectorChecker::StyleRelation, value));
+        Assembler::Address valueAddress(relationPointer, OBJECT_OFFSETOF(Style::Relation, value));
         m_assembler.store32(*value, valueAddress);
     }
 }
@@ -3056,7 +3057,7 @@
 {
     generateSpecialFailureInQuirksModeForActiveAndHoverIfNeeded(failureCases, fragment);
 
-    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByActive);
+    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByActive);
 
     FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
     functionCall.setFunctionAddress(elementIsActive);
@@ -3105,7 +3106,7 @@
     m_assembler.move(Assembler::TrustedImm32(1), isEmptyResults);
     notEmpty.link(&m_assembler);
 
-    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByEmpty, Assembler::RegisterID(isEmptyResults));
+    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByEmpty, Assembler::RegisterID(isEmptyResults));
 
     failureCases.append(m_assembler.branchTest32(Assembler::Zero, isEmptyResults));
 }
@@ -3140,14 +3141,14 @@
     LocalRegister checkingContext(m_registerAllocator);
     Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext);
 
-    generateAddStyleRelation(checkingContext, parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByFirstChildRules);
+    generateAddStyleRelation(checkingContext, parentElement, Style::Relation::ChildrenAffectedByFirstChildRules);
     m_registerAllocator.deallocateRegister(parentElement);
 
     // The parent marking is unconditional. If the matching is not a success, we can now fail.
     // Otherwise we need to apply setFirstChildState() on the RenderStyle.
     failureCases.append(m_assembler.branchTest32(Assembler::NonZero, isFirstChildRegister));
 
-    generateAddStyleRelation(checkingContext, elementAddressRegister, SelectorChecker::StyleRelation::FirstChild);
+    generateAddStyleRelation(checkingContext, elementAddressRegister, Style::Relation::FirstChild);
 
     notResolvingStyle.link(&m_assembler);
     failureCases.append(m_assembler.branchTest32(Assembler::NonZero, isFirstChildRegister));
@@ -3162,7 +3163,7 @@
 {
     generateSpecialFailureInQuirksModeForActiveAndHoverIfNeeded(failureCases, fragment);
 
-    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByHover);
+    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByHover);
 
     FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
     functionCall.setFunctionAddress(elementIsHovered);
@@ -3224,14 +3225,14 @@
     LocalRegister checkingContext(m_registerAllocator);
     Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext);
 
-    generateAddStyleRelation(checkingContext, parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByLastChildRules);
+    generateAddStyleRelation(checkingContext, parentElement, Style::Relation::ChildrenAffectedByLastChildRules);
     m_registerAllocator.deallocateRegister(parentElement);
 
     // The parent marking is unconditional. If the matching is not a success, we can now fail.
     // Otherwise we need to apply setLastChildState() on the RenderStyle.
     failureCases.append(m_assembler.branchTest32(Assembler::NonZero, isLastChildRegister));
 
-    generateAddStyleRelation(checkingContext, elementAddressRegister, SelectorChecker::StyleRelation::LastChild);
+    generateAddStyleRelation(checkingContext, elementAddressRegister, Style::Relation::LastChild);
 
     notResolvingStyle.link(&m_assembler);
     failureCases.append(m_assembler.branchTest32(Assembler::NonZero, isLastChildRegister));
@@ -3283,8 +3284,8 @@
     LocalRegister checkingContext(m_registerAllocator);
     Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext);
 
-    generateAddStyleRelation(checkingContext, parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByFirstChildRules);
-    generateAddStyleRelation(checkingContext, parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByLastChildRules);
+    generateAddStyleRelation(checkingContext, parentElement, Style::Relation::ChildrenAffectedByFirstChildRules);
+    generateAddStyleRelation(checkingContext, parentElement, Style::Relation::ChildrenAffectedByLastChildRules);
 
     m_registerAllocator.deallocateRegister(parentElement);
 
@@ -3292,8 +3293,8 @@
     // Otherwise we need to apply setLastChildState() on the RenderStyle.
     failureCases.append(m_assembler.branchTest32(Assembler::NonZero, isOnlyChildRegister));
 
-    generateAddStyleRelation(checkingContext, elementAddressRegister, SelectorChecker::StyleRelation::FirstChild);
-    generateAddStyleRelation(checkingContext, elementAddressRegister, SelectorChecker::StyleRelation::LastChild);
+    generateAddStyleRelation(checkingContext, elementAddressRegister, Style::Relation::FirstChild);
+    generateAddStyleRelation(checkingContext, elementAddressRegister, Style::Relation::LastChild);
 
     notResolvingStyle.link(&m_assembler);
     failureCases.append(m_assembler.branchTest32(Assembler::NonZero, isOnlyChildRegister));
@@ -3303,7 +3304,7 @@
 {
     if (is<HTMLTextFormControlElement>(*element)) {
         if (checkingContext->resolvingMode == SelectorChecker::Mode::ResolvingStyle)
-            checkingContext->styleRelations.append({ *element, SelectorChecker::StyleRelation::Unique, 1 });
+            checkingContext->styleRelations.append({ *element, Style::Relation::Unique, 1 });
         return downcast<HTMLTextFormControlElement>(*element).isPlaceholderVisible();
     }
     return false;
@@ -3457,7 +3458,7 @@
         return;
 
     if (!isAdjacentRelation(fragment.relationToRightFragment))
-        generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByPreviousSibling);
+        generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByPreviousSibling);
 
     // Setup the counter at 1.
     LocalRegisterWithPreference elementCounter(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
@@ -3475,7 +3476,7 @@
 
         Assembler::JumpList noCachedChildIndexCases;
         generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling);
-        generateAddStyleRelationIfResolvingStyle(previousSibling, SelectorChecker::StyleRelation::AffectsNextSibling);
+        generateAddStyleRelationIfResolvingStyle(previousSibling, Style::Relation::AffectsNextSibling);
         noCachedChildIndexCases.append(m_assembler.branchTest32(Assembler::Zero, Assembler::Address(previousSibling, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagHasRareData())));
         {
             LocalRegister elementRareData(m_registerAllocator);
@@ -3491,13 +3492,13 @@
 
         Assembler::Label loopStart = m_assembler.label();
         generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling);
-        generateAddStyleRelationIfResolvingStyle(previousSibling, SelectorChecker::StyleRelation::AffectsNextSibling);
+        generateAddStyleRelationIfResolvingStyle(previousSibling, Style::Relation::AffectsNextSibling);
         m_assembler.add32(Assembler::TrustedImm32(1), elementCounter);
         m_assembler.jump().linkTo(loopStart, &m_assembler);
         noMoreSiblingsCases.link(&m_assembler);
     }
 
-    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::NthChildIndex, Assembler::RegisterID(elementCounter));
+    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::NthChildIndex, Assembler::RegisterID(elementCounter));
 
     for (const auto& slot : validSubsetFilters)
         generateNthFilterTest(failureCases, elementCounter, slot.first, slot.second);
@@ -3524,7 +3525,7 @@
         return;
 
     if (!isAdjacentRelation(fragment.relationToRightFragment))
-        generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByPreviousSibling);
+        generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByPreviousSibling);
 
     for (const NthChildOfSelectorInfo* nthChildOfSelectorInfo : validSubsetFilters) {
         // Setup the counter at 1.
@@ -3541,7 +3542,7 @@
             Assembler::Label loopStart = m_assembler.label();
 
             generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling);
-            generateAddStyleRelationIfResolvingStyle(previousSibling, SelectorChecker::StyleRelation::AffectsNextSibling);
+            generateAddStyleRelationIfResolvingStyle(previousSibling, Style::Relation::AffectsNextSibling);
 
             Assembler::JumpList localFailureCases;
             generateElementMatchesSelectorList(localFailureCases, previousSibling, nthChildOfSelectorInfo->selectorList);
@@ -3564,7 +3565,7 @@
         LocalRegister parentElement(m_registerAllocator);
         generateWalkToParentElement(failureCases, parentElement);
 
-        generateAddStyleRelationIfResolvingStyle(parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByBackwardPositionalRules);
+        generateAddStyleRelationIfResolvingStyle(parentElement, Style::Relation::ChildrenAffectedByBackwardPositionalRules);
 
         failureCases.append(m_assembler.branchTest32(Assembler::Zero, Assembler::Address(parentElement, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsParsingChildrenFinished())));
 
@@ -3607,7 +3608,7 @@
         LocalRegister parentElement(m_registerAllocator);
         generateWalkToParentElement(failureCases, parentElement);
 
-        generateAddStyleRelationIfResolvingStyle(parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByPropertyBasedBackwardPositionalRules);
+        generateAddStyleRelationIfResolvingStyle(parentElement, Style::Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules);
 
         failureCases.append(m_assembler.branchTest32(Assembler::Zero, Assembler::Address(parentElement, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsParsingChildrenFinished())));
 

Modified: trunk/Source/WebCore/dom/Document.cpp (197763 => 197764)


--- trunk/Source/WebCore/dom/Document.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/dom/Document.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -2032,7 +2032,11 @@
     ResourceLoadSuspender suspender;
 
     TemporaryChange<bool> change(m_ignorePendingStylesheets, true);
-    return element.resolveStyle(parentStyle);
+    auto elementStyle = element.resolveStyle(parentStyle);
+
+    Style::commitRelationsToDocument(WTFMove(elementStyle.relations));
+
+    return WTFMove(elementStyle.renderStyle);
 }
 
 bool Document::updateLayoutIfDimensionsOutOfDate(Element& element, DimensionsCheck dimensionsCheck)

Modified: trunk/Source/WebCore/dom/Element.cpp (197763 => 197764)


--- trunk/Source/WebCore/dom/Element.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/dom/Element.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -1367,7 +1367,7 @@
     return document().ensureStyleResolver();
 }
 
-Ref<RenderStyle> Element::resolveStyle(RenderStyle* parentStyle)
+ElementStyle Element::resolveStyle(RenderStyle* parentStyle)
 {
     return styleResolver().styleForElement(*this, parentStyle);
 }
@@ -3287,10 +3287,10 @@
     ASSERT(hasCustomStyleResolveCallbacks());
 }
 
-RefPtr<RenderStyle> Element::customStyleForRenderer(RenderStyle&, RenderStyle*)
+Optional<ElementStyle> Element::resolveCustomStyle(RenderStyle&, RenderStyle*)
 {
     ASSERT(hasCustomStyleResolveCallbacks());
-    return nullptr;
+    return Nullopt;
 }
 
 void Element::cloneAttributesFromElement(const Element& other)

Modified: trunk/Source/WebCore/dom/Element.h (197763 => 197764)


--- trunk/Source/WebCore/dom/Element.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/dom/Element.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -52,6 +52,7 @@
 class PseudoElement;
 class RenderNamedFlowFragment;
 class RenderTreePosition;
+struct ElementStyle;
 
 enum SpellcheckAttributeState {
     SpellcheckAttributeTrue,
@@ -479,7 +480,7 @@
     virtual void didAttachRenderers();
     virtual void willDetachRenderers();
     virtual void didDetachRenderers();
-    virtual RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle, RenderStyle* shadowHostStyle);
+    virtual Optional<ElementStyle> resolveCustomStyle(RenderStyle& parentStyle, RenderStyle* shadowHostStyle);
 
     LayoutRect absoluteEventHandlerBounds(bool& includesFixedPositionElements) override;
 
@@ -498,7 +499,7 @@
 #endif
 
     StyleResolver& styleResolver();
-    Ref<RenderStyle> resolveStyle(RenderStyle* parentStyle);
+    ElementStyle resolveStyle(RenderStyle* parentStyle);
 
     virtual void isVisibleInViewportChanged() { }
 

Modified: trunk/Source/WebCore/dom/PseudoElement.cpp (197763 => 197764)


--- trunk/Source/WebCore/dom/PseudoElement.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/dom/PseudoElement.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -32,6 +32,7 @@
 #include "RenderElement.h"
 #include "RenderImage.h"
 #include "RenderQuote.h"
+#include "StyleResolver.h"
 
 namespace WebCore {
 
@@ -76,9 +77,12 @@
     m_hostElement = nullptr;
 }
 
-RefPtr<RenderStyle> PseudoElement::customStyleForRenderer(RenderStyle& parentStyle, RenderStyle*)
+Optional<ElementStyle> PseudoElement::resolveCustomStyle(RenderStyle& parentStyle, RenderStyle*)
 {
-    return m_hostElement->renderer()->getCachedPseudoStyle(m_pseudoId, &parentStyle);
+    auto* style = m_hostElement->renderer()->getCachedPseudoStyle(m_pseudoId, &parentStyle);
+    if (!style)
+        return Nullopt;
+    return ElementStyle(*style);
 }
 
 void PseudoElement::didAttachRenderers()

Modified: trunk/Source/WebCore/dom/PseudoElement.h (197763 => 197764)


--- trunk/Source/WebCore/dom/PseudoElement.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/dom/PseudoElement.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -45,7 +45,7 @@
     Element* hostElement() const { return m_hostElement; }
     void clearHostElement();
 
-    RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
+    Optional<ElementStyle> resolveCustomStyle(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
     void didAttachRenderers() override;
     void didRecalcStyle(Style::Change) override;
     bool rendererIsNeeded(const RenderStyle&) override;

Modified: trunk/Source/WebCore/html/HTMLTitleElement.cpp (197763 => 197764)


--- trunk/Source/WebCore/html/HTMLTitleElement.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/html/HTMLTitleElement.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -82,7 +82,7 @@
     if (RenderStyle* computedStyle = this->computedStyle())
         direction = computedStyle->direction();
     else {
-        auto style = resolveStyle(parentElement() ? parentElement()->renderStyle() : nullptr);
+        auto style = styleResolver().styleForElement(*this, parentElement() ? parentElement()->renderStyle() : nullptr).renderStyle;
         direction = style.get().direction();
     }
     return StringWithDirection(text(), direction);

Modified: trunk/Source/WebCore/html/shadow/SliderThumbElement.cpp (197763 => 197764)


--- trunk/Source/WebCore/html/shadow/SliderThumbElement.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/html/shadow/SliderThumbElement.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -44,6 +44,7 @@
 #include "RenderSlider.h"
 #include "RenderTheme.h"
 #include "ShadowRoot.h"
+#include "StyleResolver.h"
 
 #if ENABLE(IOS_TOUCH_EVENTS)
 #include "Document.h"
@@ -573,7 +574,7 @@
     return downcast<HTMLInputElement>(shadowHost());
 }
 
-RefPtr<RenderStyle> SliderThumbElement::customStyleForRenderer(RenderStyle&, RenderStyle* hostStyle)
+Optional<ElementStyle> SliderThumbElement::resolveCustomStyle(RenderStyle&, RenderStyle* hostStyle)
 {
     // This doesn't actually compute style. This is just a hack to pick shadow pseudo id when host style is known.
 
@@ -581,7 +582,7 @@
     static NeverDestroyed<const AtomicString> mediaSliderThumbShadowPseudoId("-webkit-media-slider-thumb", AtomicString::ConstructFromLiteral);
 
     if (!hostStyle)
-        return nullptr;
+        return Nullopt;
 
     switch (hostStyle->appearance()) {
     case MediaSliderPart:
@@ -596,7 +597,7 @@
         m_shadowPseudoId = sliderThumbShadowPseudoId;
     }
 
-    return nullptr;
+    return Nullopt;
 }
 
 const AtomicString& SliderThumbElement::shadowPseudoId() const
@@ -627,7 +628,7 @@
     return createRenderer<RenderSliderContainer>(*this, WTFMove(style));
 }
 
-RefPtr<RenderStyle> SliderContainerElement::customStyleForRenderer(RenderStyle&, RenderStyle* hostStyle)
+Optional<ElementStyle> SliderContainerElement::resolveCustomStyle(RenderStyle&, RenderStyle* hostStyle)
 {
     // This doesn't actually compute style. This is just a hack to pick shadow pseudo id when host style is known.
 
@@ -635,7 +636,7 @@
     static NeverDestroyed<const AtomicString> sliderContainer("-webkit-slider-container", AtomicString::ConstructFromLiteral);
 
     if (!hostStyle)
-        return nullptr;
+        return Nullopt;
 
     switch (hostStyle->appearance()) {
     case MediaSliderPart:
@@ -650,7 +651,7 @@
         m_shadowPseudoId = sliderContainer;
     }
 
-    return nullptr;
+    return Nullopt;
 }
 
 const AtomicString& SliderContainerElement::shadowPseudoId() const

Modified: trunk/Source/WebCore/html/shadow/SliderThumbElement.h (197763 => 197764)


--- trunk/Source/WebCore/html/shadow/SliderThumbElement.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/html/shadow/SliderThumbElement.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -78,7 +78,7 @@
 #endif
     void willDetachRenderers() override;
 
-    RefPtr<RenderStyle> customStyleForRenderer(RenderStyle&, RenderStyle*) override;
+    Optional<ElementStyle> resolveCustomStyle(RenderStyle&, RenderStyle*) override;
     const AtomicString& shadowPseudoId() const override;
 
     void startDragging();
@@ -135,7 +135,7 @@
 private:
     SliderContainerElement(Document&);
     RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
-    RefPtr<RenderStyle> customStyleForRenderer(RenderStyle&, RenderStyle*) override;
+    Optional<ElementStyle> resolveCustomStyle(RenderStyle&, RenderStyle*) override;
     const AtomicString& shadowPseudoId() const override;
 
     AtomicString m_shadowPseudoId;

Modified: trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp (197763 => 197764)


--- trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -40,6 +40,7 @@
 #include "RenderView.h"
 #include "ScriptController.h"
 #include "ShadowRoot.h"
+#include "StyleResolver.h"
 #include "TextEvent.h"
 #include "TextEventInputType.h"
 #include <wtf/Ref.h>
@@ -74,7 +75,7 @@
     return adoptRef(*new TextControlInnerElement(document));
 }
 
-RefPtr<RenderStyle> TextControlInnerElement::customStyleForRenderer(RenderStyle&, RenderStyle* shadowHostStyle)
+Optional<ElementStyle> TextControlInnerElement::resolveCustomStyle(RenderStyle&, RenderStyle* shadowHostStyle)
 {
     auto innerContainerStyle = RenderStyle::create();
     innerContainerStyle.get().inheritFrom(shadowHostStyle);
@@ -88,7 +89,7 @@
     // We don't want the shadow dom to be editable, so we set this block to read-only in case the input itself is editable.
     innerContainerStyle.get().setUserModify(READ_ONLY);
 
-    return WTFMove(innerContainerStyle);
+    return ElementStyle(WTFMove(innerContainerStyle));
 }
 
 // ---------------------------
@@ -133,9 +134,9 @@
     return downcast<RenderTextControlInnerBlock>(HTMLDivElement::renderer());
 }
 
-RefPtr<RenderStyle> TextControlInnerTextElement::customStyleForRenderer(RenderStyle&, RenderStyle* shadowHostStyle)
+Optional<ElementStyle> TextControlInnerTextElement::resolveCustomStyle(RenderStyle&, RenderStyle* shadowHostStyle)
 {
-    return downcast<HTMLTextFormControlElement>(*shadowHost()).createInnerTextStyle(*shadowHostStyle);
+    return ElementStyle(downcast<HTMLTextFormControlElement>(*shadowHost()).createInnerTextStyle(*shadowHostStyle));
 }
 
 // ----------------------------
@@ -147,18 +148,17 @@
     setHasCustomStyleResolveCallbacks();
 }
 
-RefPtr<RenderStyle> TextControlPlaceholderElement::customStyleForRenderer(RenderStyle& parentStyle, RenderStyle* shadowHostStyle)
+Optional<ElementStyle> TextControlPlaceholderElement::resolveCustomStyle(RenderStyle& parentStyle, RenderStyle* shadowHostStyle)
 {
     auto style = resolveStyle(&parentStyle);
 
     auto& controlElement = downcast<HTMLTextFormControlElement>(*containingShadowRoot()->host());
-    style->setDisplay(controlElement.isPlaceholderVisible() ? BLOCK : NONE);
+    style.renderStyle->setDisplay(controlElement.isPlaceholderVisible() ? BLOCK : NONE);
 
     if (is<HTMLInputElement>(controlElement)) {
         auto& inputElement = downcast<HTMLInputElement>(controlElement);
-        style->setTextOverflow(inputElement.shouldTruncateText(*shadowHostStyle) ? TextOverflowEllipsis : TextOverflowClip);
+        style.renderStyle->setTextOverflow(inputElement.shouldTruncateText(*shadowHostStyle) ? TextOverflowEllipsis : TextOverflowClip);
     }
-
     return WTFMove(style);
 }
 

Modified: trunk/Source/WebCore/html/shadow/TextControlInnerElements.h (197763 => 197764)


--- trunk/Source/WebCore/html/shadow/TextControlInnerElements.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/html/shadow/TextControlInnerElements.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -48,7 +48,7 @@
 
 protected:
     TextControlInnerElement(Document&);
-    RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
+    Optional<ElementStyle> resolveCustomStyle(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
 
 private:
     bool isMouseFocusable() const override { return false; }
@@ -65,7 +65,7 @@
 private:
     TextControlInnerTextElement(Document&);
     RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
-    RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
+    Optional<ElementStyle> resolveCustomStyle(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
     bool isMouseFocusable() const override { return false; }
     bool isTextControlInnerTextElement() const override { return true; }
 };
@@ -77,7 +77,7 @@
 private:
     TextControlPlaceholderElement(Document&);
     
-    RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
+    Optional<ElementStyle> resolveCustomStyle(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
 };
 
 class SearchFieldResultsButtonElement final : public HTMLDivElement {

Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (197763 => 197764)


--- trunk/Source/WebCore/rendering/RenderElement.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -1576,9 +1576,9 @@
     auto& styleResolver = element()->styleResolver();
 
     if (pseudoStyleRequest.pseudoId == FIRST_LINE_INHERITED) {
-        RefPtr<RenderStyle> result = styleResolver.styleForElement(*element(), parentStyle);
+        auto result = styleResolver.styleForElement(*element(), parentStyle).renderStyle;
         result->setStyleType(FIRST_LINE_INHERITED);
-        return result.release();
+        return WTFMove(result);
     }
 
     return styleResolver.pseudoStyleForElement(*element(), pseudoStyleRequest, *parentStyle);

Modified: trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp (197763 => 197764)


--- trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -352,9 +352,9 @@
     ASSERT(!renderer.isAnonymous());
 
     // FIXME: Region styling fails for pseudo-elements because the renderers don't have a node.
-    RefPtr<RenderStyle> renderObjectRegionStyle = renderer.element()->styleResolver().styleForElement(*renderer.element(), &parentStyle, MatchAllRules, this);
+    auto renderObjectRegionStyle = renderer.element()->styleResolver().styleForElement(*renderer.element(), &parentStyle, MatchAllRules, this).renderStyle;
 
-    return renderObjectRegionStyle.release();
+    return WTFMove(renderObjectRegionStyle);
 }
 
 void RenderNamedFlowFragment::computeChildrenStyleInRegion(RenderElement& renderer)

Added: trunk/Source/WebCore/style/StyleRelations.cpp (0 => 197764)


--- trunk/Source/WebCore/style/StyleRelations.cpp	                        (rev 0)
+++ trunk/Source/WebCore/style/StyleRelations.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StyleRelations.h"
+
+#include "Element.h"
+#include "NodeRenderStyle.h"
+#include "RenderStyle.h"
+
+namespace WebCore {
+namespace Style {
+
+std::unique_ptr<Relations> commitRelationsToRenderStyle(RenderStyle& style, const Element& element, const Relations& relations)
+{
+    std::unique_ptr<Relations> remainingRelations;
+
+    auto appendStyleRelation = [&remainingRelations] (const Relation& relation) {
+        if (!remainingRelations)
+            remainingRelations = std::make_unique<Relations>();
+        remainingRelations->append(relation);
+    };
+
+    for (auto& relation : relations) {
+        if (&relation.element != &element) {
+            appendStyleRelation(relation);
+            continue;
+        }
+        switch (relation.type) {
+        case Relation::AffectedByActive:
+            style.setAffectedByActive();
+            break;
+        case Relation::AffectedByDrag:
+            style.setAffectedByDrag();
+            break;
+        case Relation::AffectedByEmpty:
+            style.setEmptyState(relation.value);
+            appendStyleRelation(relation);
+            break;
+        case Relation::AffectedByHover:
+            style.setAffectedByHover();
+            break;
+        case Relation::FirstChild:
+            style.setFirstChildState();
+            break;
+        case Relation::LastChild:
+            style.setLastChildState();
+            break;
+        case Relation::Unique:
+            style.setUnique();
+            break;
+        case Relation::AffectedByPreviousSibling:
+        case Relation::AffectsNextSibling:
+        case Relation::ChildrenAffectedByBackwardPositionalRules:
+        case Relation::ChildrenAffectedByFirstChildRules:
+        case Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules:
+        case Relation::ChildrenAffectedByLastChildRules:
+        case Relation::NthChildIndex:
+            appendStyleRelation(relation);
+            break;
+        }
+    }
+    return remainingRelations;
+}
+
+void commitRelationsToDocument(std::unique_ptr<Relations> relations)
+{
+    if (!relations)
+        return;
+    for (auto& relation : *relations) {
+        auto& element = const_cast<Element&>(relation.element);
+        switch (relation.type) {
+        case Relation::AffectedByActive:
+            element.setChildrenAffectedByActive();
+            break;
+        case Relation::AffectedByDrag:
+            element.setChildrenAffectedByDrag();
+            break;
+        case Relation::AffectedByEmpty:
+            element.setStyleAffectedByEmpty();
+            break;
+        case Relation::AffectedByHover:
+            element.setChildrenAffectedByHover();
+            break;
+        case Relation::AffectedByPreviousSibling:
+            element.setStyleIsAffectedByPreviousSibling();
+            break;
+        case Relation::AffectsNextSibling:
+            element.setAffectsNextSiblingElementStyle();
+            break;
+        case Relation::ChildrenAffectedByBackwardPositionalRules:
+            element.setChildrenAffectedByBackwardPositionalRules();
+            break;
+        case Relation::ChildrenAffectedByFirstChildRules:
+            element.setChildrenAffectedByFirstChildRules();
+            break;
+        case Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules:
+            element.setChildrenAffectedByBackwardPositionalRules();
+            element.setChildrenAffectedByPropertyBasedBackwardPositionalRules();
+            break;
+        case Relation::ChildrenAffectedByLastChildRules:
+            element.setChildrenAffectedByLastChildRules();
+            break;
+        case Relation::FirstChild:
+            if (auto* style = element.renderStyle())
+                style->setFirstChildState();
+            break;
+        case Relation::LastChild:
+            if (auto* style = element.renderStyle())
+                style->setLastChildState();
+            break;
+        case Relation::NthChildIndex:
+            element.setChildIndex(relation.value);
+            break;
+        case Relation::Unique:
+            if (auto* style = element.renderStyle())
+                style->setUnique();
+            break;
+        }
+    }
+}
+
+}
+}

Added: trunk/Source/WebCore/style/StyleRelations.h (0 => 197764)


--- trunk/Source/WebCore/style/StyleRelations.h	                        (rev 0)
+++ trunk/Source/WebCore/style/StyleRelations.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StyleRelations_h
+#define StyleRelations_h
+
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Element;
+class RenderStyle;
+
+namespace Style {
+
+struct Relation {
+    enum Type {
+        AffectedByActive,
+        AffectedByDrag,
+        AffectedByEmpty,
+        AffectedByHover,
+        AffectedByPreviousSibling,
+        AffectsNextSibling,
+        ChildrenAffectedByBackwardPositionalRules,
+        ChildrenAffectedByFirstChildRules,
+        ChildrenAffectedByPropertyBasedBackwardPositionalRules,
+        ChildrenAffectedByLastChildRules,
+        FirstChild,
+        LastChild,
+        NthChildIndex,
+        Unique,
+    };
+    const Element& element;
+    Type type;
+    unsigned value;
+
+    Relation(const Element& element, Type type, unsigned value = 1)
+        : element(element)
+        , type(type)
+        , value(value)
+    { }
+};
+
+using Relations = Vector<Relation, 8>;
+
+std::unique_ptr<Relations> commitRelationsToRenderStyle(RenderStyle&, const Element&, const Relations&);
+void commitRelationsToDocument(std::unique_ptr<Relations>);
+
+}
+}
+
+#endif

Modified: trunk/Source/WebCore/style/StyleSharingResolver.cpp (197763 => 197764)


--- trunk/Source/WebCore/style/StyleSharingResolver.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/style/StyleSharingResolver.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -322,7 +322,7 @@
     if (!ruleSet)
         return false;
 
-    ElementRuleCollector collector(const_cast<StyledElement&>(element), nullptr, m_ruleSets, &m_selectorFilter);
+    ElementRuleCollector collector(const_cast<StyledElement&>(element), m_ruleSets, &m_selectorFilter);
     return collector.hasAnyMatchingRules(ruleSet);
 }
 

Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (197763 => 197764)


--- trunk/Source/WebCore/style/StyleTreeResolver.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -179,17 +179,20 @@
     }
 
     if (element.hasCustomStyleResolveCallbacks()) {
-        RenderStyle* shadowHostStyle = nullptr;
-        if (auto* shadowRoot = scope().shadowRoot)
-            shadowHostStyle = shadowRoot->host()->renderStyle();
-        if (RefPtr<RenderStyle> style = element.customStyleForRenderer(inheritedStyle, shadowHostStyle))
-            return style.releaseNonNull();
+        RenderStyle* shadowHostStyle = scope().shadowRoot ? scope().shadowRoot->host()->renderStyle() : nullptr;
+        if (auto customStyle = element.resolveCustomStyle(inheritedStyle, shadowHostStyle)) {
+            Style::commitRelationsToDocument(WTFMove(customStyle->relations));
+            return WTFMove(customStyle->renderStyle);
+        }
     }
 
     if (auto* sharingElement = scope().sharingResolver.resolve(element))
         return *sharingElement->renderStyle();
 
-    return scope().styleResolver.styleForElement(element, &inheritedStyle, MatchAllRules, nullptr, &scope().selectorFilter);
+    auto elementStyle = scope().styleResolver.styleForElement(element, &inheritedStyle, MatchAllRules, nullptr, &scope().selectorFilter);
+
+    Style::commitRelationsToDocument(WTFMove(elementStyle.relations));
+    return WTFMove(elementStyle.renderStyle);
 }
 
 #if ENABLE(CSS_REGIONS)

Modified: trunk/Source/WebCore/style/StyleTreeResolver.h (197763 => 197764)


--- trunk/Source/WebCore/style/StyleTreeResolver.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/style/StyleTreeResolver.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -28,6 +28,7 @@
 
 #include "RenderStyleConstants.h"
 #include "RenderTreePosition.h"
+#include "SelectorChecker.h"
 #include "SelectorFilter.h"
 #include "StyleChange.h"
 #include "StyleSharingResolver.h"
@@ -62,6 +63,7 @@
     Change resolveElement(Element&);
     void resolveBeforeOrAfterPseudoElement(Element&, Change, PseudoId, RenderTreePosition&);
 
+
     void createRenderTreeRecursively(Element&, RenderStyle&, RenderTreePosition&, RefPtr<RenderStyle>&& resolvedStyle);
     void createRenderer(Element&, RenderTreePosition&, RefPtr<RenderStyle>&& resolvedStyle);
     void createRenderTreeForBeforeOrAfterPseudoElement(Element&, PseudoId, RenderTreePosition&);

Modified: trunk/Source/WebCore/svg/SVGElement.cpp (197763 => 197764)


--- trunk/Source/WebCore/svg/SVGElement.cpp	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/svg/SVGElement.cpp	2016-03-08 14:59:53 UTC (rev 197764)
@@ -786,11 +786,11 @@
     contextElement->synchronizeSystemLanguage();
 }
 
-RefPtr<RenderStyle> SVGElement::customStyleForRenderer(RenderStyle& parentStyle, RenderStyle*)
+Optional<ElementStyle> SVGElement::resolveCustomStyle(RenderStyle& parentStyle, RenderStyle*)
 {
     // If the element is in a <use> tree we get the style from the definition tree.
     if (auto* styleElement = this->correspondingElement())
-        return styleElement->styleResolver().styleForElement(*styleElement, &parentStyle);
+        return styleElement->resolveStyle(&parentStyle);
 
     return resolveStyle(&parentStyle);
 }

Modified: trunk/Source/WebCore/svg/SVGElement.h (197763 => 197764)


--- trunk/Source/WebCore/svg/SVGElement.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/svg/SVGElement.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -119,7 +119,7 @@
     void synchronizeAnimatedSVGAttribute(const QualifiedName&) const;
     static void synchronizeAllAnimatedSVGAttribute(SVGElement*);
  
-    RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
+    Optional<ElementStyle> resolveCustomStyle(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
 
     static void synchronizeRequiredFeatures(SVGElement* contextElement);
     static void synchronizeRequiredExtensions(SVGElement* contextElement);

Modified: trunk/Source/WebCore/svg/SVGElementRareData.h (197763 => 197764)


--- trunk/Source/WebCore/svg/SVGElementRareData.h	2016-03-08 14:50:15 UTC (rev 197763)
+++ trunk/Source/WebCore/svg/SVGElementRareData.h	2016-03-08 14:59:53 UTC (rev 197764)
@@ -71,7 +71,7 @@
             return 0;
         if (!m_overrideComputedStyle || m_needsOverrideComputedStyleUpdate) {
             // The style computed here contains no CSS Animations/Transitions or SMIL induced rules - this is needed to compute the "base value" for the SMIL animation sandwhich model.
-            m_overrideComputedStyle = element.styleResolver().styleForElement(element, parentStyle, MatchAllRulesExcludingSMIL);
+            m_overrideComputedStyle = element.styleResolver().styleForElement(element, parentStyle, MatchAllRulesExcludingSMIL).renderStyle;
             m_needsOverrideComputedStyleUpdate = false;
         }
         ASSERT(m_overrideComputedStyle);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to