Index: Source/core/css/resolver/StyleResolver.cpp |
diff --git a/Source/core/css/resolver/StyleResolver.cpp b/Source/core/css/resolver/StyleResolver.cpp |
index bcca08f5eafdebef0fd226a30c33249206d39b9c..470aeaf0206d443c558ab10b0353663b4a824319 100644 |
--- a/Source/core/css/resolver/StyleResolver.cpp |
+++ b/Source/core/css/resolver/StyleResolver.cpp |
@@ -59,6 +59,7 @@ |
#include "core/css/StyleRuleImport.h" |
#include "core/css/StyleSheetContents.h" |
#include "core/css/resolver/AnimatedStyleBuilder.h" |
+#include "core/css/resolver/ElementResolveContext.h" |
#include "core/css/resolver/MatchResult.h" |
#include "core/css/resolver/MediaQueryResult.h" |
#include "core/css/resolver/SharedStyleFinder.h" |
@@ -127,6 +128,52 @@ static void addFontFaceRule(Document* document, CSSFontSelector* cssFontSelector |
cssFontSelector->fontFaceCache()->add(cssFontSelector, fontFaceRule, fontFace); |
} |
+class AnimationResolveContext { |
+ STACK_ALLOCATED(); |
+public: |
+ AnimationResolveContext(Element* element) |
+ : m_activeAnimations(element ? element->activeAnimations() : nullptr) |
+ , m_baseRenderStyle(m_activeAnimations ? m_activeAnimations->baseRenderStyle() : nullptr) |
+ { |
+ } |
+ ActiveAnimations* activeAnimations() const { return m_activeAnimations; } |
+ const RenderStyle* baseRenderStyle() const { return m_baseRenderStyle; } |
+private: |
+ ActiveAnimations* m_activeAnimations; |
+ const RenderStyle* m_baseRenderStyle; |
+}; |
+ |
+class StyleBasisContext { |
+ STACK_ALLOCATED(); |
+public: |
+ StyleBasisContext(Element* element, RenderStyle* parentStyle) |
+ : m_pseudoElement(nullptr) |
+ , m_elementContext(*element, parentStyle) |
+ , m_animationContext(element) |
+ , m_allowsInheritance(m_elementContext.parentStyle()) |
+ { |
+ } |
+ |
+ StyleBasisContext(Element* element, RenderStyle* parentStyle, const PseudoStyleRequest& pseudoRequest) |
+ : m_pseudoElement(element->pseudoElement(pseudoRequest.pseudoId)) |
+ , m_elementContext(*element, parentStyle) |
+ , m_animationContext(m_pseudoElement) |
+ , m_allowsInheritance(pseudoRequest.allowsInheritance(m_elementContext.parentStyle())) |
+ { |
+ } |
+ |
+ PseudoElement* pseudoElement() const { return m_pseudoElement; } |
+ const ElementResolveContext& elementContext() const { return m_elementContext; } |
+ const AnimationResolveContext& animationContext() const { return m_animationContext; } |
+ bool allowsInheritance() const { return m_allowsInheritance; } |
+ |
+private: |
+ PseudoElement* m_pseudoElement; |
+ ElementResolveContext m_elementContext; |
+ AnimationResolveContext m_animationContext; |
+ bool m_allowsInheritance; |
+}; |
+ |
StyleResolver::StyleResolver(Document& document) |
: m_document(document) |
, m_viewportStyleResolver(ViewportStyleResolver::create(&document)) |
@@ -548,6 +595,7 @@ void StyleResolver::loadPendingResources(StyleResolverState& state) |
PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent, StyleSharingBehavior sharingBehavior, |
RuleMatchingBehavior matchingBehavior) |
{ |
+ ASSERT(element); |
ASSERT(document().frame()); |
ASSERT(document().settings()); |
ASSERT(!hasPendingAuthorStyleSheets()); |
@@ -572,26 +620,23 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS |
if (element == document().documentElement()) |
resetDirectionAndWritingModeOnDocument(document()); |
- StyleResolverState state(document(), element, defaultParent); |
- if (sharingBehavior == AllowStyleSharing && state.parentStyle()) { |
- SharedStyleFinder styleFinder(state.elementContext(), m_features, m_siblingRuleSet.get(), m_uncommonAttributeRuleSet.get(), *this); |
+ StyleBasisContext styleContext(element, defaultParent); |
+ const ElementResolveContext& elementContext = styleContext.elementContext(); |
+ |
+ if (sharingBehavior == AllowStyleSharing && elementContext.parentStyle()) { |
+ SharedStyleFinder styleFinder(elementContext, m_features, m_siblingRuleSet.get(), m_uncommonAttributeRuleSet.get(), *this); |
if (RefPtr<RenderStyle> sharedStyle = styleFinder.findSharedStyle()) |
return sharedStyle.release(); |
} |
- ActiveAnimations* activeAnimations = element->activeAnimations(); |
- const RenderStyle* baseRenderStyle = activeAnimations ? activeAnimations->baseRenderStyle() : nullptr; |
+ StyleResolverState state(document(), elementContext, styleForContext(styleContext), parentStyleForContext(styleContext)); |
+ |
+ const AnimationResolveContext& animationContext = styleContext.animationContext(); |
+ |
+ if (!animationContext.baseRenderStyle() && styleContext.allowsInheritance()) |
+ state.style()->inheritFrom(elementContext.parentStyle(), isAtShadowBoundary(element) ? RenderStyle::AtShadowBoundary : RenderStyle::NotAtShadowBoundary); |
- if (baseRenderStyle) { |
- state.setStyle(RenderStyle::clone(baseRenderStyle)); |
- } else if (state.parentStyle()) { |
- state.setStyle(RenderStyle::create()); |
- state.style()->inheritFrom(state.parentStyle(), isAtShadowBoundary(element) ? RenderStyle::AtShadowBoundary : RenderStyle::NotAtShadowBoundary); |
- } else { |
- state.setStyle(defaultStyleForElement()); |
- state.setParentStyle(RenderStyle::clone(state.style())); |
- } |
// contenteditable attribute (implemented by -webkit-user-modify) should |
// be propagated from shadow host to distributed node. |
if (state.distributedToInsertionPoint()) { |
@@ -612,7 +657,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS |
state.style()->setInsideLink(linkState); |
} |
- if (!baseRenderStyle) { |
+ if (!animationContext.baseRenderStyle()) { |
bool needsCollection = false; |
CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetsForElement(element, needsCollection); |
@@ -633,8 +678,8 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS |
adjustRenderStyle(state, element); |
- if (activeAnimations) |
- activeAnimations->updateBaseRenderStyle(state.style()); |
+ if (animationContext.activeAnimations()) |
+ animationContext.activeAnimations()->updateBaseRenderStyle(state.style()); |
} |
// FIXME: The CSSWG wants to specify that the effects of animations are applied before |
@@ -663,15 +708,11 @@ PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element& element, const |
if (&element == document().documentElement()) |
resetDirectionAndWritingModeOnDocument(document()); |
- StyleResolverState state(document(), &element, parentStyle); |
+ StyleResolverState state(document(), &element, RenderStyle::clone(&elementStyle), parentStyle); |
MatchResult result; |
result.addMatchedProperties(&keyframe->properties()); |
- ASSERT(!state.style()); |
- |
- // Create the style |
- state.setStyle(RenderStyle::clone(&elementStyle)); |
// We don't need to bother with !important. Since there is only ever one |
// decl, there's nothing to override. So just add the first properties. |
@@ -703,8 +744,7 @@ PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnap |
style = RenderStyle::clone(element.renderStyle()); |
else |
style = RenderStyle::create(); |
- StyleResolverState state(element.document(), &element); |
- state.setStyle(style); |
+ StyleResolverState state(element.document(), &element, style); |
return createAnimatableValueSnapshot(state, property, value); |
} |
@@ -714,6 +754,29 @@ PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnap |
return CSSAnimatableValueFactory::create(property, *state.style()); |
} |
+PassRefPtr<RenderStyle> StyleResolver::styleForContext(const StyleBasisContext& styleContext) |
+{ |
+ const AnimationResolveContext& animationContext = styleContext.animationContext(); |
+ |
+ if (animationContext.baseRenderStyle()) |
+ return RenderStyle::clone(animationContext.baseRenderStyle()); |
+ if (styleContext.allowsInheritance()) |
+ return RenderStyle::create(); |
+ return defaultStyleForElement(); |
+} |
+ |
+PassRefPtr<RenderStyle> StyleResolver::parentStyleForContext(const StyleBasisContext& styleContext) |
+{ |
+ const ElementResolveContext& elementContext = styleContext.elementContext(); |
+ const AnimationResolveContext& animationContext = styleContext.animationContext(); |
+ |
+ if (styleContext.allowsInheritance()) |
+ return elementContext.parentStyle(); |
+ if (animationContext.baseRenderStyle()) |
+ return defaultStyleForElement(); |
+ return nullptr; |
+} |
+ |
PassRefPtrWillBeRawPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& parent, PseudoId pseudoId) |
{ |
RenderObject* parentRenderer = parent.renderer(); |
@@ -736,8 +799,9 @@ PassRefPtrWillBeRawPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded |
return PseudoElement::create(&parent, pseudoId); |
} |
- StyleResolverState state(document(), &parent, parentStyle); |
- if (!pseudoStyleForElementInternal(parent, pseudoId, parentStyle, state)) |
+ StyleBasisContext styleContext(&parent, parentStyle, pseudoId); |
+ StyleResolverState state(document(), styleContext.elementContext(), styleForContext(styleContext), parentStyleForContext(styleContext)); |
+ if (!pseudoStyleForElementInternal(pseudoId, state, styleContext)) |
return nullptr; |
RefPtr<RenderStyle> style = state.takeStyle(); |
ASSERT(style); |
@@ -754,7 +818,7 @@ PassRefPtrWillBeRawPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded |
return pseudo.release(); |
} |
-bool StyleResolver::pseudoStyleForElementInternal(Element& element, const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle, StyleResolverState& state) |
+bool StyleResolver::pseudoStyleForElementInternal(const PseudoStyleRequest& pseudoStyleRequest, StyleResolverState& state, const StyleBasisContext& styleContext) |
{ |
ASSERT(document().frame()); |
ASSERT(document().settings()); |
@@ -762,29 +826,21 @@ bool StyleResolver::pseudoStyleForElementInternal(Element& element, const Pseudo |
StyleResolverParentScope::ensureParentStackIsPushed(); |
- Element* pseudoElement = element.pseudoElement(pseudoStyleRequest.pseudoId); |
+ const ElementResolveContext& elementContext = styleContext.elementContext(); |
+ const AnimationResolveContext& animationContext = styleContext.animationContext(); |
- ActiveAnimations* activeAnimations = pseudoElement ? pseudoElement->activeAnimations() : nullptr; |
- const RenderStyle* baseRenderStyle = activeAnimations ? activeAnimations->baseRenderStyle() : nullptr; |
- |
- if (baseRenderStyle) { |
- state.setStyle(RenderStyle::clone(baseRenderStyle)); |
- } else if (pseudoStyleRequest.allowsInheritance(state.parentStyle())) { |
- state.setStyle(RenderStyle::create()); |
- state.style()->inheritFrom(state.parentStyle()); |
- } else { |
- state.setStyle(defaultStyleForElement()); |
- state.setParentStyle(RenderStyle::clone(state.style())); |
- } |
+ if (!animationContext.baseRenderStyle() && styleContext.allowsInheritance()) |
+ state.style()->inheritFrom(elementContext.parentStyle()); |
state.style()->setStyleType(pseudoStyleRequest.pseudoId); |
// Since we don't use pseudo-elements in any of our quirk/print |
// user agent rules, don't waste time walking those rules. |
- if (!baseRenderStyle) { |
+ if (!animationContext.baseRenderStyle()) { |
+ |
// Check UA, user and author rules. |
- ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style()); |
+ ElementRuleCollector collector(elementContext, m_selectorFilter, state.style()); |
collector.setPseudoStyleRequest(pseudoStyleRequest); |
matchUARules(collector); |
@@ -805,14 +861,14 @@ bool StyleResolver::pseudoStyleForElementInternal(Element& element, const Pseudo |
// in the adjustRenderStyle code. |
adjustRenderStyle(state, 0); |
- if (activeAnimations) |
- activeAnimations->updateBaseRenderStyle(state.style()); |
+ if (animationContext.activeAnimations()) |
+ animationContext.activeAnimations()->updateBaseRenderStyle(state.style()); |
} |
// FIXME: The CSSWG wants to specify that the effects of animations are applied before |
// important rules, but this currently happens here as we require adjustment to have happened |
// before deciding which properties to transition. |
- if (applyAnimatedProperties(state, pseudoElement)) |
+ if (applyAnimatedProperties(state, styleContext.pseudoElement())) |
adjustRenderStyle(state, 0); |
didAccess(); |
@@ -829,8 +885,9 @@ PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* element, c |
if (!element) |
return nullptr; |
- StyleResolverState state(document(), element, parentStyle); |
- if (!pseudoStyleForElementInternal(*element, pseudoStyleRequest, parentStyle, state)) { |
+ StyleBasisContext styleContext(element, parentStyle, pseudoStyleRequest); |
+ StyleResolverState state(document(), styleContext.elementContext(), styleForContext(styleContext), parentStyleForContext(styleContext)); |
+ if (!pseudoStyleForElementInternal(pseudoStyleRequest, state, styleContext)) { |
if (pseudoStyleRequest.type == PseudoStyleRequest::ForRenderer) |
return nullptr; |
return state.takeStyle(); |
@@ -847,9 +904,8 @@ PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex) |
{ |
ASSERT(!hasPendingAuthorStyleSheets()); |
resetDirectionAndWritingModeOnDocument(document()); |
- StyleResolverState state(document(), document().documentElement()); // m_rootElementStyle will be set to the document style. |
+ StyleResolverState state(document(), document().documentElement(), RenderStyle::create()); // m_rootElementStyle will be set to the document style. |
- state.setStyle(RenderStyle::create()); |
const RenderStyle* rootElementStyle = state.rootElementStyle() ? state.rootElementStyle() : document().renderStyle(); |
ASSERT(rootElementStyle); |
state.style()->inheritFrom(rootElementStyle); |
@@ -900,8 +956,7 @@ void StyleResolver::collectViewportRules() |
PassRefPtr<RenderStyle> StyleResolver::defaultStyleForElement() |
{ |
- StyleResolverState state(document(), 0); |
- state.setStyle(RenderStyle::create()); |
+ StyleResolverState state(document(), nullptr, RenderStyle::create()); |
rune
2014/10/30 15:23:50
I don't think you need a StyleResolverState here.
andersr
2014/10/31 13:02:15
Done.
|
state.fontBuilder().setInitial(state.style()->effectiveZoom()); |
state.style()->font().update(document().styleEngine()->fontSelector()); |
return state.takeStyle(); |
@@ -925,8 +980,8 @@ void StyleResolver::updateFont(StyleResolverState& state) |
PassRefPtrWillBeRawPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element, unsigned rulesToInclude) |
{ |
ASSERT(element); |
- StyleResolverState state(document(), element); |
- ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style()); |
+ ElementResolveContext elementContext(*element, nullptr); |
+ ElementRuleCollector collector(elementContext, m_selectorFilter, nullptr); |
collector.setMode(SelectorChecker::CollectingStyleRules); |
collectPseudoRulesForElement(element, collector, NOPSEUDO, rulesToInclude); |
return collector.matchedStyleRuleList(); |
@@ -935,8 +990,8 @@ PassRefPtrWillBeRawPtr<StyleRuleList> StyleResolver::styleRulesForElement(Elemen |
PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude) |
{ |
ASSERT(element); |
- StyleResolverState state(document(), element); |
- ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style()); |
+ ElementResolveContext elementContext(*element, nullptr); |
+ ElementRuleCollector collector(elementContext, m_selectorFilter, nullptr); |
collector.setMode(SelectorChecker::CollectingCSSRules); |
collectPseudoRulesForElement(element, collector, pseudoId, rulesToInclude); |
return collector.matchedCSSRuleList(); |
@@ -1525,8 +1580,7 @@ void StyleResolver::printStats() |
void StyleResolver::applyPropertiesToStyle(const CSSPropertyValue* properties, size_t count, RenderStyle* style) |
{ |
- StyleResolverState state(document(), document().documentElement(), style); |
- state.setStyle(style); |
+ StyleResolverState state(document(), document().documentElement(), style, style); |
for (size_t i = 0; i < count; ++i) { |
if (properties[i].value) { |