From 044fbf5585bd94961b4c40fc4382e5180f4a1300 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Fri, 5 Sep 2014 13:48:44 +1000 Subject: [PATCH] Bug 931668 - Part 3: Add a style context bit to represent whether it depends on style data from its grandparent or higher ancestor. r=dbaron --HG-- extra : rebase_source : 64deabb466cfaaeae220a00024cd05d8e87832bc --- layout/style/nsRuleNode.cpp | 43 +++++++++++++++++++++++++++++++++++ layout/style/nsRuleNode.h | 2 ++ layout/style/nsStyleContext.h | 6 +++++ layout/style/nsStyleStruct.h | 6 +++-- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index d12d5a05176..b1f445f047f 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -1630,6 +1630,38 @@ nsRuleNode::PropagateDependentBit(nsStyleStructID aSID, nsRuleNode* aHighestNode } } +/* static */ void +nsRuleNode::PropagateGrandancestorBit(nsStyleContext* aContext, + nsStyleContext* aContextInheritedFrom) +{ + MOZ_ASSERT(aContext); + MOZ_ASSERT(aContextInheritedFrom && + aContextInheritedFrom != aContext && + aContextInheritedFrom != aContext->GetParent(), + "aContextInheritedFrom must be an ancestor of aContext's parent"); + + aContext->AddStyleBit(NS_STYLE_USES_GRANDANCESTOR_STYLE); + + nsStyleContext* context = aContext->GetParent(); + if (!context) { + return; + } + + for (;;) { + nsStyleContext* parent = context->GetParent(); + if (!parent) { + MOZ_ASSERT(false, "aContextInheritedFrom must be an ancestor of " + "aContext's parent"); + break; + } + if (parent == aContextInheritedFrom) { + break; + } + context->AddStyleBit(NS_STYLE_USES_GRANDANCESTOR_STYLE); + context = parent; + } +} + /* * The following "Check" functions are used for determining what type of * sharing can be used for the data on this rule node. MORE HERE... @@ -2308,6 +2340,9 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID, parentContext->GetPseudo() == nsCSSPseudoElements::firstLine) { parentContext = parentContext->GetParent(); } + if (parentContext && parentContext != aContext->GetParent()) { + PropagateGrandancestorBit(aContext, parentContext); + } } if (parentContext) { // We have a parent, and so we should just inherit from the parent. @@ -3893,6 +3928,13 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext, parentFont = *aFont; } + + if (higherContext && contextPath.Length() > 1) { + // contextPath is a list of all ancestor style contexts, so it must have + // at least two elements for it to result in a dependency on grandancestor + // styles. + PropagateGrandancestorBit(aContext, higherContext); + } } const void* @@ -7535,6 +7577,7 @@ nsRuleNode::ComputePositionData(void* aStartStruct, const nsStylePosition* grandparentPos = grandparentContext->StylePosition(); inheritedAlignSelf = grandparentPos->mAlignItems; + aContext->AddStyleBit(NS_STYLE_USES_GRANDANCESTOR_STYLE); } } } diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index 7ba6954c203..4b098ecc394 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -426,6 +426,8 @@ protected: void PropagateDependentBit(nsStyleStructID aSID, nsRuleNode* aHighestNode, void* aStruct); void PropagateNoneBit(uint32_t aBit, nsRuleNode* aHighestNode); + static void PropagateGrandancestorBit(nsStyleContext* aContext, + nsStyleContext* aContextInheritedFrom); const void* SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContext); diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 35a20563a62..6fd62dd6fc8 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -193,6 +193,12 @@ public: } } + // Does this style context, or any of its descendants, have any style values + // that were computed based on this style context's grandparent style context + // or any of the grandparent's ancestors? + bool UsesGrandancestorStyle() const + { return !!(mBits & NS_STYLE_USES_GRANDANCESTOR_STYLE); } + // Tell this style context to cache aStruct as the struct for aSID void SetStyle(nsStyleStructID aSID, void* aStruct); diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 3316f0fdf6c..cdfd553cfc5 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -49,9 +49,11 @@ class imgIContainer; #define NS_STYLE_RELEVANT_LINK_VISITED 0x004000000 // See nsStyleContext::IsStyleIfVisited #define NS_STYLE_IS_STYLE_IF_VISITED 0x008000000 +// See nsStyleContext::UsesGrandancestorStyle +#define NS_STYLE_USES_GRANDANCESTOR_STYLE 0x010000000 // See nsStyleContext::GetPseudoEnum -#define NS_STYLE_CONTEXT_TYPE_MASK 0x1f0000000 -#define NS_STYLE_CONTEXT_TYPE_SHIFT 28 +#define NS_STYLE_CONTEXT_TYPE_MASK 0x3e0000000 +#define NS_STYLE_CONTEXT_TYPE_SHIFT 29 // Additional bits for nsRuleNode's mDependentBits: #define NS_RULE_NODE_GC_MARK 0x02000000