From b0b3b72fbd6f14a0d0ba4193c2327ee995b1f7cb Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Fri, 26 Apr 2013 10:49:07 +0200 Subject: [PATCH] Bug 861643 - nsFirstLineFrame continuations should fixup its style context in Init instead of Reflow. r=bzbarsky --- layout/generic/nsInlineFrame.cpp | 56 +++++++++++++++++--------------- layout/generic/nsInlineFrame.h | 2 ++ 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index c842367523d3..c6f905d9e0b5 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -938,6 +938,35 @@ NS_NewFirstLineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) NS_IMPL_FRAMEARENA_HELPERS(nsFirstLineFrame) +void +nsFirstLineFrame::Init(nsIContent* aContent, nsIFrame* aParent, + nsIFrame* aPrevInFlow) +{ + nsInlineFrame::Init(aContent, aParent, aPrevInFlow); + if (!aPrevInFlow) { + MOZ_ASSERT(StyleContext()->GetPseudo() == nsCSSPseudoElements::firstLine); + return; + } + + // This frame is a continuation - fixup the style context if aPrevInFlow + // is the first-in-flow (the only one with a ::first-line pseudo). + if (aPrevInFlow->StyleContext()->GetPseudo() == nsCSSPseudoElements::firstLine) { + MOZ_ASSERT(GetFirstInFlow() == aPrevInFlow); + // Create a new style context that is a child of the parent + // style context thus removing the ::first-line style. This way + // we behave as if an anonymous (unstyled) span was the child + // of the parent frame. + nsStyleContext* parentContext = aParent->StyleContext(); + nsRefPtr newSC = PresContext()->StyleSet()-> + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozLineFrame, parentContext); + SetStyleContext(newSC); + } else { + MOZ_ASSERT(GetFirstInFlow() != aPrevInFlow); + MOZ_ASSERT(aPrevInFlow->StyleContext()->GetPseudo() == + nsCSSAnonBoxes::mozLineFrame); + } +} + #ifdef DEBUG NS_IMETHODIMP nsFirstLineFrame::GetFrameName(nsAString& aResult) const @@ -1041,33 +1070,6 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext, } irs.mPrevFrame = nullptr; } - else { -// XXX do this in the Init method instead - // For continuations, we need to check and see if our style - // context is right. If its the same as the first-in-flow, then - // we need to fix it up (that way :first-line style doesn't leak - // into this continuation since we aren't the first line). - nsFirstLineFrame* first = (nsFirstLineFrame*) GetFirstInFlow(); - if (mStyleContext == first->mStyleContext) { - // Fixup our style context and our children. First get the - // proper parent context. - nsStyleContext* parentContext = first->GetParent()->StyleContext(); - // Create a new style context that is a child of the parent - // style context thus removing the :first-line style. This way - // we behave as if an anonymous (unstyled) span was the child - // of the parent frame. - nsRefPtr newSC; - newSC = aPresContext->StyleSet()-> - ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozLineFrame, parentContext); - if (newSC) { - // Switch to the new style context. - SetStyleContext(newSC); - - // Re-resolve all children - ReparentChildListStyle(aPresContext, mFrames, this); - } - } - } NS_ASSERTION(!aReflowState.mLineLayout->GetInFirstLine(), "Nested first-line frames? BOGUS"); diff --git a/layout/generic/nsInlineFrame.h b/layout/generic/nsInlineFrame.h index 937f1b0a0d5c..e0ecbc2ad88b 100644 --- a/layout/generic/nsInlineFrame.h +++ b/layout/generic/nsInlineFrame.h @@ -192,6 +192,8 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, nsIFrame* aParent, + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; virtual void PullOverflowsFromPrevInFlow() MOZ_OVERRIDE; protected: