Bug 705877 part 6. Make frame construction use ancestor filters when resolving style. r=dbaron

This commit is contained in:
Boris Zbarsky 2012-03-12 22:54:15 -05:00
parent 23a4ff3a52
commit afdc791a4a

View File

@ -2313,6 +2313,9 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
nsFrameConstructorState state(mPresShell, mFixedContainingBlock, nsnull,
nsnull, aFrameState);
// Initialize the ancestor filter with null for now; we'll push
// aDocElement once we finish resolving style for it.
state.mTreeMatchContext.mAncestorFilter.Init(nsnull);
// XXXbz why, exactly?
if (!mTempFrameTreeState)
@ -2379,6 +2382,9 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
return NS_OK;
}
AncestorFilter::AutoAncestorPusher
ancestorPusher(true, state.mTreeMatchContext.mAncestorFilter, aDocElement);
// Make sure to start any background image loads for the root element now.
styleContext->StartBackgroundImageLoads();
@ -3598,6 +3604,20 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
nsStyleContext* const styleContext = aItem.mStyleContext;
const nsStyleDisplay* display = styleContext->GetStyleDisplay();
nsIContent* const content = aItem.mContent;
// Push the content as a style ancestor now, so we don't have to do
// it in our various full-constructor functions. In particular,
// since a number of full-constructor functions don't actually call
// ProcessChildren in some cases (e.g. for CSS anonymous table boxes
// or for situations where only anonymouse children are having
// frames constructed), this is the best place to bottleneck the
// pushing of the content instead of having to do it in multiple
// places.
AncestorFilter::AutoAncestorPusher
ancestorPusher(aState.mTreeMatchContext.mAncestorFilter.HasFilter(),
aState.mTreeMatchContext.mAncestorFilter,
content->IsElement() ? content->AsElement() : nsnull);
nsIFrame* newFrame;
nsIFrame* primaryFrame;
@ -3611,8 +3631,6 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
primaryFrame = newFrame;
} else {
nsIContent* const content = aItem.mContent;
newFrame =
(*data->mFunc.mCreationFunc)(mPresShell, styleContext);
if (!newFrame) {
@ -3823,6 +3841,10 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsFrameConstructorState& aState,
nsFrameConstructorState::PendingBindingAutoPusher pusher(aState,
aPendingBinding);
AncestorFilter::AutoAncestorPusher
ancestorPusher(aState.mTreeMatchContext.mAncestorFilter.HasFilter(),
aState.mTreeMatchContext.mAncestorFilter,
aParent->AsElement());
nsIAnonymousContentCreator* creator = do_QueryFrame(aParentFrame);
NS_ASSERTION(creator,
@ -6511,6 +6533,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
GetAbsoluteContainingBlock(parentFrame),
GetFloatContainingBlock(parentFrame));
state.mTreeMatchContext.mAncestorFilter.Init(aContainer->AsElement());
// See if the containing block has :first-letter style applied.
bool haveFirstLetterStyle = false, haveFirstLineStyle = false;
@ -6938,7 +6961,9 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
GetAbsoluteContainingBlock(parentFrame),
GetFloatContainingBlock(parentFrame),
aFrameState);
state.mTreeMatchContext.mAncestorFilter.Init(aContainer ?
aContainer->AsElement() :
nsnull);
// Recover state for the containing block - we need to know if
// it has :first-letter or :first-line style applied to it. The
@ -8658,6 +8683,11 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
mRootElementFrame);
state.mCreatingExtraFrames = true;
// We can't use an ancestor filter here, because we're not going to
// be usefully recurring down the tree. This means that other
// places in frame construction can't assume a filter is
// initialized!
// Iterate across fixed frames and replicate each whose placeholder is a
// descendant of aFrame. (We don't want to explicitly copy placeholders that
// are within fixed frames, because that would cause duplicates on the new
@ -10484,6 +10514,9 @@ nsCSSFrameConstructor::CreateListBoxContent(nsPresContext* aPresContext,
GetFloatContainingBlock(aParentFrame),
mTempFrameTreeState);
// If we ever initialize the ancestor filter on |state|, make sure
// to push the right parent!
nsRefPtr<nsStyleContext> styleContext;
styleContext = ResolveStyleContext(aParentFrame, aChild, &state);
@ -10828,6 +10861,12 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState,
// Probe for generated content before
nsStyleContext* const parentStyleContext = aParentItem.mStyleContext;
nsIContent* const parentContent = aParentItem.mContent;
AncestorFilter::AutoAncestorPusher
ancestorPusher(aState.mTreeMatchContext.mAncestorFilter.HasFilter(),
aState.mTreeMatchContext.mAncestorFilter,
parentContent->AsElement());
CreateGeneratedContentItem(aState, nsnull, parentContent, parentStyleContext,
nsCSSPseudoElements::ePseudo_before,
aParentItem.mChildItems);