Bug 598832 part 16. Use a single TreeMatchContext for all the style resolution that the frame constructor does as part of a single frame construction batch. r=dbaron
This commit is contained in:
@@ -150,6 +150,7 @@
|
|||||||
#include "nsSVGOuterSVGFrame.h"
|
#include "nsSVGOuterSVGFrame.h"
|
||||||
|
|
||||||
#include "nsRefreshDriver.h"
|
#include "nsRefreshDriver.h"
|
||||||
|
#include "nsRuleProcessorData.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
@@ -744,6 +745,8 @@ public:
|
|||||||
|
|
||||||
nsCOMArray<nsIContent> mGeneratedTextNodesWithInitializer;
|
nsCOMArray<nsIContent> mGeneratedTextNodesWithInitializer;
|
||||||
|
|
||||||
|
TreeMatchContext mTreeMatchContext;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
// Use the passed-in history state.
|
// Use the passed-in history state.
|
||||||
nsFrameConstructorState(nsIPresShell* aPresShell,
|
nsFrameConstructorState(nsIPresShell* aPresShell,
|
||||||
@@ -906,6 +909,8 @@ nsFrameConstructorState::nsFrameConstructorState(nsIPresShell* aPresShe
|
|||||||
HasTransform()),
|
HasTransform()),
|
||||||
mHavePendingPopupgroup(PR_FALSE),
|
mHavePendingPopupgroup(PR_FALSE),
|
||||||
mCreatingExtraFrames(PR_FALSE),
|
mCreatingExtraFrames(PR_FALSE),
|
||||||
|
mTreeMatchContext(PR_TRUE, nsRuleWalker::eRelevantLinkUnvisited,
|
||||||
|
aPresShell->GetDocument()),
|
||||||
mCurrentPendingBindingInsertionPoint(&mPendingBindings)
|
mCurrentPendingBindingInsertionPoint(&mPendingBindings)
|
||||||
{
|
{
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
@@ -938,6 +943,8 @@ nsFrameConstructorState::nsFrameConstructorState(nsIPresShell* aPresShell,
|
|||||||
HasTransform()),
|
HasTransform()),
|
||||||
mHavePendingPopupgroup(PR_FALSE),
|
mHavePendingPopupgroup(PR_FALSE),
|
||||||
mCreatingExtraFrames(PR_FALSE),
|
mCreatingExtraFrames(PR_FALSE),
|
||||||
|
mTreeMatchContext(PR_TRUE, nsRuleWalker::eRelevantLinkUnvisited,
|
||||||
|
aPresShell->GetDocument()),
|
||||||
mCurrentPendingBindingInsertionPoint(&mPendingBindings)
|
mCurrentPendingBindingInsertionPoint(&mPendingBindings)
|
||||||
{
|
{
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
@@ -1688,7 +1695,8 @@ nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aStat
|
|||||||
pseudoStyleContext =
|
pseudoStyleContext =
|
||||||
styleSet->ProbePseudoElementStyle(aParentContent->AsElement(),
|
styleSet->ProbePseudoElementStyle(aParentContent->AsElement(),
|
||||||
aPseudoElement,
|
aPseudoElement,
|
||||||
aStyleContext);
|
aStyleContext,
|
||||||
|
aState.mTreeMatchContext);
|
||||||
if (!pseudoStyleContext)
|
if (!pseudoStyleContext)
|
||||||
return;
|
return;
|
||||||
// |ProbePseudoStyleFor| checked the 'display' property and the
|
// |ProbePseudoStyleFor| checked the 'display' property and the
|
||||||
@@ -4546,7 +4554,8 @@ nsCSSFrameConstructor::InitAndRestoreFrame(const nsFrameConstructorState& aState
|
|||||||
|
|
||||||
already_AddRefed<nsStyleContext>
|
already_AddRefed<nsStyleContext>
|
||||||
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame* aParentFrame,
|
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame* aParentFrame,
|
||||||
nsIContent* aContent)
|
nsIContent* aContent,
|
||||||
|
nsFrameConstructorState* aState)
|
||||||
{
|
{
|
||||||
nsStyleContext* parentStyleContext = nsnull;
|
nsStyleContext* parentStyleContext = nsnull;
|
||||||
NS_ASSERTION(aContent->GetParent(), "Must have parent here");
|
NS_ASSERTION(aContent->GetParent(), "Must have parent here");
|
||||||
@@ -4565,17 +4574,24 @@ nsCSSFrameConstructor::ResolveStyleContext(nsIFrame* aParentFrame,
|
|||||||
// previous page's fixed-pos frame?
|
// previous page's fixed-pos frame?
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResolveStyleContext(parentStyleContext, aContent);
|
return ResolveStyleContext(parentStyleContext, aContent, aState);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsStyleContext>
|
already_AddRefed<nsStyleContext>
|
||||||
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
|
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
|
||||||
nsIContent* aContent)
|
nsIContent* aContent,
|
||||||
|
nsFrameConstructorState* aState)
|
||||||
{
|
{
|
||||||
nsStyleSet *styleSet = mPresShell->StyleSet();
|
nsStyleSet *styleSet = mPresShell->StyleSet();
|
||||||
|
|
||||||
if (aContent->IsElement()) {
|
if (aContent->IsElement()) {
|
||||||
|
if (aState) {
|
||||||
|
return styleSet->ResolveStyleFor(aContent->AsElement(),
|
||||||
|
aParentStyleContext,
|
||||||
|
aState->mTreeMatchContext);
|
||||||
|
}
|
||||||
return styleSet->ResolveStyleFor(aContent->AsElement(), aParentStyleContext);
|
return styleSet->ResolveStyleFor(aContent->AsElement(), aParentStyleContext);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
|
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
|
||||||
@@ -5031,7 +5047,7 @@ nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
nsRefPtr<nsStyleContext> styleContext;
|
nsRefPtr<nsStyleContext> styleContext;
|
||||||
styleContext = ResolveStyleContext(aParentFrame, aContent);
|
styleContext = ResolveStyleContext(aParentFrame, aContent, &aState);
|
||||||
|
|
||||||
AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
|
AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
|
||||||
aContent->Tag(), aContent->GetNameSpaceID(),
|
aContent->Tag(), aContent->GetNameSpaceID(),
|
||||||
@@ -5113,7 +5129,8 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (resolveStyle) {
|
if (resolveStyle) {
|
||||||
styleContext = ResolveStyleContext(styleContext->GetParent(), aContent);
|
styleContext =
|
||||||
|
ResolveStyleContext(styleContext->GetParent(), aContent, &aState);
|
||||||
display = styleContext->GetStyleDisplay();
|
display = styleContext->GetStyleDisplay();
|
||||||
aStyleContext = styleContext;
|
aStyleContext = styleContext;
|
||||||
}
|
}
|
||||||
@@ -5829,7 +5846,9 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling,
|
|||||||
NS_NOTREACHED("Shouldn't happen");
|
NS_NOTREACHED("Shouldn't happen");
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
styleContext = ResolveStyleContext(styleParent, aContent);
|
// XXXbz when this code is killed, the state argument to
|
||||||
|
// ResolveStyleContext can be made non-optional.
|
||||||
|
styleContext = ResolveStyleContext(styleParent, aContent, nsnull);
|
||||||
if (!styleContext) return PR_FALSE;
|
if (!styleContext) return PR_FALSE;
|
||||||
const nsStyleDisplay* display = styleContext->GetStyleDisplay();
|
const nsStyleDisplay* display = styleContext->GetStyleDisplay();
|
||||||
aDisplay = display->mDisplay;
|
aDisplay = display->mDisplay;
|
||||||
@@ -10558,7 +10577,7 @@ nsCSSFrameConstructor::CreateListBoxContent(nsPresContext* aPresContext,
|
|||||||
mTempFrameTreeState);
|
mTempFrameTreeState);
|
||||||
|
|
||||||
nsRefPtr<nsStyleContext> styleContext;
|
nsRefPtr<nsStyleContext> styleContext;
|
||||||
styleContext = ResolveStyleContext(aParentFrame, aChild);
|
styleContext = ResolveStyleContext(aParentFrame, aChild, &state);
|
||||||
|
|
||||||
// Pre-check for display "none" - only if we find that, do we create
|
// Pre-check for display "none" - only if we find that, do we create
|
||||||
// any frame at all
|
// any frame at all
|
||||||
@@ -10941,7 +10960,7 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<nsStyleContext> childContext =
|
nsRefPtr<nsStyleContext> childContext =
|
||||||
ResolveStyleContext(parentStyleContext, content);
|
ResolveStyleContext(parentStyleContext, content, &aState);
|
||||||
|
|
||||||
AddFrameConstructionItemsInternal(aState, content, nsnull, content->Tag(),
|
AddFrameConstructionItemsInternal(aState, content, nsnull, content->Tag(),
|
||||||
content->GetNameSpaceID(),
|
content->GetNameSpaceID(),
|
||||||
|
|||||||
@@ -429,12 +429,16 @@ private:
|
|||||||
nsIFrame* aNewFrame,
|
nsIFrame* aNewFrame,
|
||||||
PRBool aAllowCounters = PR_TRUE);
|
PRBool aAllowCounters = PR_TRUE);
|
||||||
|
|
||||||
|
// aState can be null if not available; it's used as an optimization.
|
||||||
|
// XXXbz IsValidSibling is the only caller that doesn't pass a state here!
|
||||||
already_AddRefed<nsStyleContext>
|
already_AddRefed<nsStyleContext>
|
||||||
ResolveStyleContext(nsIFrame* aParentFrame,
|
ResolveStyleContext(nsIFrame* aParentFrame,
|
||||||
nsIContent* aContent);
|
nsIContent* aContent,
|
||||||
|
nsFrameConstructorState* aState);
|
||||||
already_AddRefed<nsStyleContext>
|
already_AddRefed<nsStyleContext>
|
||||||
ResolveStyleContext(nsStyleContext* aParentStyleContext,
|
ResolveStyleContext(nsStyleContext* aParentStyleContext,
|
||||||
nsIContent* aContent);
|
nsIContent* aContent,
|
||||||
|
nsFrameConstructorState* aState);
|
||||||
|
|
||||||
// Construct a frame for aContent and put it in aFrameItems. This should
|
// Construct a frame for aContent and put it in aFrameItems. This should
|
||||||
// only be used in cases when it's known that the frame won't need table
|
// only be used in cases when it's known that the frame won't need table
|
||||||
|
|||||||
@@ -761,23 +761,32 @@ PRBool nsStyleSet::BuildDefaultStyleData(nsPresContext* aPresContext)
|
|||||||
already_AddRefed<nsStyleContext>
|
already_AddRefed<nsStyleContext>
|
||||||
nsStyleSet::ResolveStyleFor(Element* aElement,
|
nsStyleSet::ResolveStyleFor(Element* aElement,
|
||||||
nsStyleContext* aParentContext)
|
nsStyleContext* aParentContext)
|
||||||
|
{
|
||||||
|
TreeMatchContext treeContext(PR_TRUE, nsRuleWalker::eRelevantLinkUnvisited,
|
||||||
|
aElement->GetOwnerDoc());
|
||||||
|
return ResolveStyleFor(aElement, aParentContext, treeContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsStyleContext>
|
||||||
|
nsStyleSet::ResolveStyleFor(Element* aElement,
|
||||||
|
nsStyleContext* aParentContext,
|
||||||
|
TreeMatchContext& aTreeMatchContext)
|
||||||
{
|
{
|
||||||
NS_ENSURE_FALSE(mInShutdown, nsnull);
|
NS_ENSURE_FALSE(mInShutdown, nsnull);
|
||||||
NS_ASSERTION(aElement, "aElement must not be null");
|
NS_ASSERTION(aElement, "aElement must not be null");
|
||||||
|
|
||||||
nsRuleWalker ruleWalker(mRuleTree);
|
nsRuleWalker ruleWalker(mRuleTree);
|
||||||
TreeMatchContext treeContext(PR_TRUE, nsRuleWalker::eRelevantLinkUnvisited,
|
aTreeMatchContext.ResetForUnvisitedMatching();
|
||||||
aElement->GetOwnerDoc());
|
|
||||||
ElementRuleProcessorData data(PresContext(), aElement, &ruleWalker,
|
ElementRuleProcessorData data(PresContext(), aElement, &ruleWalker,
|
||||||
treeContext);
|
aTreeMatchContext);
|
||||||
FileRules(EnumRulesMatching<ElementRuleProcessorData>, &data, aElement,
|
FileRules(EnumRulesMatching<ElementRuleProcessorData>, &data, aElement,
|
||||||
&ruleWalker);
|
&ruleWalker);
|
||||||
|
|
||||||
nsRuleNode *ruleNode = ruleWalker.CurrentNode();
|
nsRuleNode *ruleNode = ruleWalker.CurrentNode();
|
||||||
nsRuleNode *visitedRuleNode = nsnull;
|
nsRuleNode *visitedRuleNode = nsnull;
|
||||||
|
|
||||||
if (treeContext.HaveRelevantLink()) {
|
if (aTreeMatchContext.HaveRelevantLink()) {
|
||||||
treeContext.ResetForVisitedMatching();
|
aTreeMatchContext.ResetForVisitedMatching();
|
||||||
ruleWalker.Reset();
|
ruleWalker.Reset();
|
||||||
FileRules(EnumRulesMatching<ElementRuleProcessorData>, &data, aElement,
|
FileRules(EnumRulesMatching<ElementRuleProcessorData>, &data, aElement,
|
||||||
&ruleWalker);
|
&ruleWalker);
|
||||||
@@ -906,6 +915,18 @@ already_AddRefed<nsStyleContext>
|
|||||||
nsStyleSet::ProbePseudoElementStyle(Element* aParentElement,
|
nsStyleSet::ProbePseudoElementStyle(Element* aParentElement,
|
||||||
nsCSSPseudoElements::Type aType,
|
nsCSSPseudoElements::Type aType,
|
||||||
nsStyleContext* aParentContext)
|
nsStyleContext* aParentContext)
|
||||||
|
{
|
||||||
|
TreeMatchContext treeContext(PR_TRUE, nsRuleWalker::eRelevantLinkUnvisited,
|
||||||
|
aParentElement->GetOwnerDoc());
|
||||||
|
return ProbePseudoElementStyle(aParentElement, aType, aParentContext,
|
||||||
|
treeContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsStyleContext>
|
||||||
|
nsStyleSet::ProbePseudoElementStyle(Element* aParentElement,
|
||||||
|
nsCSSPseudoElements::Type aType,
|
||||||
|
nsStyleContext* aParentContext,
|
||||||
|
TreeMatchContext& aTreeMatchContext)
|
||||||
{
|
{
|
||||||
NS_ENSURE_FALSE(mInShutdown, nsnull);
|
NS_ENSURE_FALSE(mInShutdown, nsnull);
|
||||||
|
|
||||||
@@ -915,10 +936,9 @@ nsStyleSet::ProbePseudoElementStyle(Element* aParentElement,
|
|||||||
|
|
||||||
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
|
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
|
||||||
nsRuleWalker ruleWalker(mRuleTree);
|
nsRuleWalker ruleWalker(mRuleTree);
|
||||||
TreeMatchContext treeContext(PR_TRUE, nsRuleWalker::eRelevantLinkUnvisited,
|
aTreeMatchContext.ResetForUnvisitedMatching();
|
||||||
aParentElement->GetOwnerDoc());
|
|
||||||
PseudoElementRuleProcessorData data(PresContext(), aParentElement,
|
PseudoElementRuleProcessorData data(PresContext(), aParentElement,
|
||||||
&ruleWalker, aType, treeContext);
|
&ruleWalker, aType, aTreeMatchContext);
|
||||||
WalkRestrictionRule(aType, &ruleWalker);
|
WalkRestrictionRule(aType, &ruleWalker);
|
||||||
// not the root if there was a restriction rule
|
// not the root if there was a restriction rule
|
||||||
nsRuleNode *adjustedRoot = ruleWalker.CurrentNode();
|
nsRuleNode *adjustedRoot = ruleWalker.CurrentNode();
|
||||||
@@ -932,8 +952,8 @@ nsStyleSet::ProbePseudoElementStyle(Element* aParentElement,
|
|||||||
|
|
||||||
nsRuleNode *visitedRuleNode = nsnull;
|
nsRuleNode *visitedRuleNode = nsnull;
|
||||||
|
|
||||||
if (treeContext.HaveRelevantLink()) {
|
if (aTreeMatchContext.HaveRelevantLink()) {
|
||||||
treeContext.ResetForVisitedMatching();
|
aTreeMatchContext.ResetForVisitedMatching();
|
||||||
ruleWalker.Reset();
|
ruleWalker.Reset();
|
||||||
FileRules(EnumRulesMatching<PseudoElementRuleProcessorData>, &data,
|
FileRules(EnumRulesMatching<PseudoElementRuleProcessorData>, &data,
|
||||||
aParentElement, &ruleWalker);
|
aParentElement, &ruleWalker);
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class nsIURI;
|
|||||||
class nsCSSFontFaceRule;
|
class nsCSSFontFaceRule;
|
||||||
class nsRuleWalker;
|
class nsRuleWalker;
|
||||||
struct RuleProcessorData;
|
struct RuleProcessorData;
|
||||||
|
struct TreeMatchContext;
|
||||||
|
|
||||||
class nsEmptyStyleRule : public nsIStyleRule
|
class nsEmptyStyleRule : public nsIStyleRule
|
||||||
{
|
{
|
||||||
@@ -100,6 +101,11 @@ class nsStyleSet
|
|||||||
ResolveStyleFor(mozilla::dom::Element* aElement,
|
ResolveStyleFor(mozilla::dom::Element* aElement,
|
||||||
nsStyleContext* aParentContext);
|
nsStyleContext* aParentContext);
|
||||||
|
|
||||||
|
already_AddRefed<nsStyleContext>
|
||||||
|
ResolveStyleFor(mozilla::dom::Element* aElement,
|
||||||
|
nsStyleContext* aParentContext,
|
||||||
|
TreeMatchContext& aTreeMatchContext);
|
||||||
|
|
||||||
// Get a style context (with the given parent) for the
|
// Get a style context (with the given parent) for the
|
||||||
// sequence of style rules in the |aRules| array.
|
// sequence of style rules in the |aRules| array.
|
||||||
already_AddRefed<nsStyleContext>
|
already_AddRefed<nsStyleContext>
|
||||||
@@ -138,6 +144,11 @@ class nsStyleSet
|
|||||||
ProbePseudoElementStyle(mozilla::dom::Element* aParentElement,
|
ProbePseudoElementStyle(mozilla::dom::Element* aParentElement,
|
||||||
nsCSSPseudoElements::Type aType,
|
nsCSSPseudoElements::Type aType,
|
||||||
nsStyleContext* aParentContext);
|
nsStyleContext* aParentContext);
|
||||||
|
already_AddRefed<nsStyleContext>
|
||||||
|
ProbePseudoElementStyle(mozilla::dom::Element* aParentElement,
|
||||||
|
nsCSSPseudoElements::Type aType,
|
||||||
|
nsStyleContext* aParentContext,
|
||||||
|
TreeMatchContext& aTreeMatchContext);
|
||||||
|
|
||||||
// Get a style context for an anonymous box. aPseudoTag is the
|
// Get a style context for an anonymous box. aPseudoTag is the
|
||||||
// pseudo-tag to use and must be non-null.
|
// pseudo-tag to use and must be non-null.
|
||||||
|
|||||||
Reference in New Issue
Block a user