From 884eb773c817c60eb80b9efe9f7fa648cf14b33b Mon Sep 17 00:00:00 2001 From: "bzbarsky@mit.edu" Date: Sun, 15 Apr 2007 17:42:54 -0700 Subject: [PATCH] Improve detection of blocks with first-letter style. Bug 372550, r+sr=dbaron --- layout/base/nsCSSFrameConstructor.cpp | 37 ++++++++++++++++++++++---- layout/base/nsCSSFrameConstructor.h | 4 +++ layout/generic/nsBlockFrame.cpp | 18 +++++-------- layout/generic/nsBlockFrame.h | 2 ++ layout/reftests/bugs/362901-1-ref.html | 25 +++++++++++++++++ layout/reftests/bugs/362901-1.html | 34 +++++++++++++++++++++++ layout/reftests/bugs/reftest.list | 1 + 7 files changed, 104 insertions(+), 17 deletions(-) create mode 100644 layout/reftests/bugs/362901-1-ref.html create mode 100644 layout/reftests/bugs/362901-1.html diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 6b3bd06773bc..3305274a4378 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -9465,10 +9465,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, // Examine the containing-block for the removed content and see if // :first-letter style applies. nsIFrame* containingBlock = GetFloatContainingBlock(parentFrame); - PRBool haveFLS = containingBlock ? - HaveFirstLetterStyle(containingBlock->GetContent(), - containingBlock->GetStyleContext()) : - PR_FALSE; + PRBool haveFLS = containingBlock && HaveFirstLetterStyle(containingBlock); if (haveFLS) { // Trap out to special routine that handles adjusting a blocks // frame tree when first-letter style is present. @@ -9846,7 +9843,7 @@ nsCSSFrameConstructor::CharacterDataChanged(nsIContent* aContent, // See if the block has first-letter style applied to it. nsIContent* blockContent = block->GetContent(); nsStyleContext* blockSC = block->GetStyleContext(); - haveFirstLetterStyle = HaveFirstLetterStyle(blockContent, blockSC); + haveFirstLetterStyle = HaveFirstLetterStyle(block); if (haveFirstLetterStyle) { RemoveLetterFrames(mPresShell->GetPresContext(), mPresShell, mPresShell->FrameManager(), block); @@ -11176,6 +11173,22 @@ nsCSSFrameConstructor::HaveFirstLetterStyle(nsIContent* aContent, mPresShell->GetPresContext()); } +PRBool +nsCSSFrameConstructor::HaveFirstLetterStyle(nsIFrame* aBlockFrame) +{ + NS_PRECONDITION(aBlockFrame, "Need a frame"); + +#ifdef DEBUG + nsBlockFrame* block; + NS_ASSERTION(NS_SUCCEEDED(aBlockFrame->QueryInterface(kBlockFrameCID, + (void**)&block)) && + block, + "Not a block frame?"); +#endif + + return (aBlockFrame->GetStateBits() & NS_BLOCK_HAS_FIRST_LETTER_STYLE) != 0; +} + PRBool nsCSSFrameConstructor::HaveFirstLineStyle(nsIContent* aContent, nsStyleContext* aStyleContext) @@ -11775,6 +11788,16 @@ nsCSSFrameConstructor::CreateLetterFrame(nsFrameConstructorState& aState, NS_PRECONDITION(aTextContent->IsNodeOfType(nsINode::eTEXT), "aTextContent isn't text"); +#ifdef DEBUG + { + nsBlockFrame* block; + NS_ASSERTION(NS_SUCCEEDED(aBlockFrame->QueryInterface(kBlockFrameCID, + (void**)&block)) && + block, + "Not a block frame?"); + } +#endif + // Get style context for the first-letter-frame nsStyleContext* parentStyleContext = aParentFrame->GetStyleContext(); if (parentStyleContext) { @@ -11840,6 +11863,8 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame( { nsresult rv = NS_OK; + aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE); + nsIFrame* parentFrame = nsnull; nsIFrame* textFrame = nsnull; nsIFrame* prevFrame = nsnull; @@ -12159,6 +12184,8 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsFrameConstructorState& aState, { nsresult rv = NS_OK; + aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE); + nsIFrame* blockKids = aBlockFrame->GetFirstChild(nsnull); nsIFrame* parentFrame = nsnull; nsIFrame* textFrame = nsnull; diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index c750fa5c1683..5d4a226e13b7 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -762,6 +762,10 @@ private: PRBool HaveFirstLetterStyle(nsIContent* aContent, nsStyleContext* aStyleContext); + // Check whether a given block has first-letter style. Make sure to + // only pass in blocks! And don't pass in null either. + PRBool HaveFirstLetterStyle(nsIFrame* aBlockFrame); + PRBool HaveFirstLineStyle(nsIContent* aContent, nsStyleContext* aStyleContext); diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index e15f4722bdbd..ffef8e1c60f6 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -5942,18 +5942,12 @@ nsBlockFrame::SetInitialChildList(nsIAtom* aListName, else { nsPresContext* presContext = PresContext(); - // Lookup up the two pseudo style contexts - if (nsnull == GetPrevInFlow()) { - nsRefPtr firstLetterStyle = GetFirstLetterStyle(presContext); - if (nsnull != firstLetterStyle) { - mState |= NS_BLOCK_HAS_FIRST_LETTER_STYLE; -#ifdef NOISY_FIRST_LETTER - ListTag(stdout); - printf(": first-letter style found\n"); -#endif - } - } - + NS_ASSERTION(GetPrevContinuation() || + (nsRefPtr(GetFirstLetterStyle(presContext)) != + nsnull) == + ((mState & NS_BLOCK_HAS_FIRST_LETTER_STYLE) != 0), + "NS_BLOCK_HAS_FIRST_LETTER_STYLE state out of sync"); + rv = AddFrames(aChildList, nsnull); if (NS_FAILED(rv)) { return rv; diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index b8725fca6457..31295ec9057e 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -291,12 +291,14 @@ protected: } virtual ~nsBlockFrame(); +#ifdef DEBUG already_AddRefed GetFirstLetterStyle(nsPresContext* aPresContext) { return aPresContext->StyleSet()-> ProbePseudoStyleFor(mContent, nsCSSPseudoElements::firstLetter, mStyleContext); } +#endif /* * Overides member function of nsHTMLContainerFrame. Needed to handle the diff --git a/layout/reftests/bugs/362901-1-ref.html b/layout/reftests/bugs/362901-1-ref.html new file mode 100644 index 000000000000..f86ef41d5130 --- /dev/null +++ b/layout/reftests/bugs/362901-1-ref.html @@ -0,0 +1,25 @@ + + + + + + +
Text
+
Text
+
Text
+
Text
+ +
Text
+
Text
+
Text
+
Text
+ +
TextMore Text
+
TextMore Text
+
TextMore Text
+
TextMore Text
+ + + diff --git a/layout/reftests/bugs/362901-1.html b/layout/reftests/bugs/362901-1.html new file mode 100644 index 000000000000..e8926aa47294 --- /dev/null +++ b/layout/reftests/bugs/362901-1.html @@ -0,0 +1,34 @@ + + + + + + + +
Text
+
Text
+
Text
+
Text
+ +
+
+
+
+ +
More Text
+
More Text
+
More Text
+
More Text
+ + + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 7d8578626765..a84d2ab7e9a9 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -157,6 +157,7 @@ fails == 351641-2b.html 351641-2-ref.html # bug 358433 (2006-10-19) != 362594-2b.html 362594-1-standards-ref.html == 362594-2b.html 362594-2-standards-ref.html == 362594-2c.html 362594-2-standards-ref.html +== 362901-1.html 362901-1-ref.html == 363329-1.html 363329-1-ref.html == 363329-2.html 363329-2-ref.html == 363637-1.html 363637-1-ref.html