Bug 499841. Pass the block frame that contains the first letter style to RemoveFirstLetterFrames so that the NS_BLOCK_HAS_FIRST_LETTER_CHILD bit can be unset on it. Always set the NS_BLOCK_HAS_FIRST_LETTER_CHILD bit on the first continuation only. r=bzbarsky

--HG--
extra : rebase_source : 411297490d6d18244fa7caa3194facfedc28ea86
This commit is contained in:
Timothy Nikkel 2009-12-22 17:44:35 -06:00
parent 01699b9589
commit 5f6a955352
4 changed files with 31 additions and 16 deletions

View File

@ -9653,6 +9653,8 @@ nsCSSFrameConstructor::CreateLetterFrame(nsIFrame* aBlockFrame,
SetInitialSingleChild(letterFrame, textFrame);
aResult.Clear();
aResult.AddChild(letterFrame);
NS_ASSERTION(!aBlockFrame->GetPrevContinuation(),
"should have the first continuation here");
aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD);
}
}
@ -9871,6 +9873,7 @@ nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext,
nsIPresShell* aPresShell,
nsFrameManager* aFrameManager,
nsIFrame* aFrame,
nsIFrame* aBlockFrame,
PRBool* aStopLooking)
{
nsIFrame* prevSibling = nsnull;
@ -9913,13 +9916,15 @@ nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext,
aFrameManager->InsertFrames(aFrame, nsnull, prevSibling, textList);
*aStopLooking = PR_TRUE;
aFrame->RemoveStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD);
NS_ASSERTION(!aBlockFrame->GetPrevContinuation(),
"should have the first continuation here");
aBlockFrame->RemoveStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD);
break;
}
else if (IsInlineFrame(kid)) {
// Look inside child inline frame for the letter frame
RemoveFirstLetterFrames(aPresContext, aPresShell, aFrameManager, kid,
aStopLooking);
RemoveFirstLetterFrames(aPresContext, aPresShell, aFrameManager,
kid, aBlockFrame, aStopLooking);
if (*aStopLooking) {
break;
}
@ -9938,22 +9943,23 @@ nsCSSFrameConstructor::RemoveLetterFrames(nsPresContext* aPresContext,
nsIFrame* aBlockFrame)
{
aBlockFrame = aBlockFrame->GetFirstContinuation();
nsIFrame* continuation = aBlockFrame;
PRBool stopLooking = PR_FALSE;
nsresult rv;
do {
rv = RemoveFloatingFirstLetterFrames(aPresContext, aPresShell,
aFrameManager,
aBlockFrame, &stopLooking);
continuation, &stopLooking);
if (NS_SUCCEEDED(rv) && !stopLooking) {
rv = RemoveFirstLetterFrames(aPresContext, aPresShell, aFrameManager,
aBlockFrame, &stopLooking);
continuation, aBlockFrame, &stopLooking);
}
if (stopLooking) {
break;
}
aBlockFrame = aBlockFrame->GetNextContinuation();
} while (aBlockFrame);
continuation = continuation->GetNextContinuation();
} while (continuation);
return rv;
}
@ -9962,7 +9968,8 @@ nsresult
nsCSSFrameConstructor::RecoverLetterFrames(nsIFrame* aBlockFrame)
{
aBlockFrame = aBlockFrame->GetFirstContinuation();
nsIFrame* continuation = aBlockFrame;
nsIFrame* parentFrame = nsnull;
nsIFrame* textFrame = nsnull;
nsIFrame* prevFrame = nsnull;
@ -9971,9 +9978,9 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsIFrame* aBlockFrame)
nsresult rv;
do {
// XXX shouldn't this bit be set already (bug 408493), assert instead?
aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE);
rv = WrapFramesInFirstLetterFrame(aBlockFrame, aBlockFrame,
aBlockFrame->GetFirstChild(nsnull),
continuation->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE);
rv = WrapFramesInFirstLetterFrame(aBlockFrame, continuation,
continuation->GetFirstChild(nsnull),
&parentFrame, &textFrame, &prevFrame,
letterFrames, &stopLooking);
if (NS_FAILED(rv)) {
@ -9982,8 +9989,8 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsIFrame* aBlockFrame)
if (stopLooking) {
break;
}
aBlockFrame = aBlockFrame->GetNextContinuation();
} while (aBlockFrame);
continuation = continuation->GetNextContinuation();
} while (continuation);
if (parentFrame) {
// Take the old textFrame out of the parents child list

View File

@ -1568,6 +1568,7 @@ private:
nsIPresShell* aPresShell,
nsFrameManager* aFrameManager,
nsIFrame* aFrame,
nsIFrame* aBlockFrame,
PRBool* aStopLooking);
// Special remove method for those pesky floating first-letter frames

View File

@ -3520,6 +3520,9 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
(NS_BLOCK_HAS_FIRST_LETTER_STYLE & mState)) {
aLineLayout.SetFirstLetterStyleOK(PR_TRUE);
}
NS_ASSERTION(!((NS_BLOCK_HAS_FIRST_LETTER_CHILD & mState) &&
GetPrevContinuation()),
"first letter child bit should only be on first continuation");
// Reflow the frames that are already on the line first
nsresult rv = NS_OK;
@ -6318,8 +6321,12 @@ nsBlockFrame::Init(nsIContent* aContent,
// Copy over the block frame type flags
nsBlockFrame* blockFrame = (nsBlockFrame*)aPrevInFlow;
// Don't copy NS_BLOCK_HAS_FIRST_LETTER_CHILD as that is set on the first
// continuation only.
SetFlags(blockFrame->mState &
(NS_BLOCK_FLAGS_MASK & ~NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET));
(NS_BLOCK_FLAGS_MASK &
(~NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET &
~NS_BLOCK_HAS_FIRST_LETTER_CHILD)));
}
nsresult rv = nsBlockFrameSuper::Init(aContent, aParent, aPrevInFlow);

View File

@ -68,7 +68,7 @@ class nsTableColFrame;
* NS_BLOCK_HAS_FIRST_LETTER_CHILD means that there is an inflow first-letter
* frame among the block's descendants. If there is a floating first-letter
* frame, or the block has first-letter style but has no first letter, this
* bit is not set.
* bit is not set. This bit is set on the first continuation only.
*/
#define NS_BLOCK_NO_AUTO_MARGINS 0x00200000
#define NS_BLOCK_MARGIN_ROOT 0x00400000