diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 030f5bfe53b..879b1c4979b 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -706,6 +706,10 @@ struct nsFrameItems { // Appends the frame to the end of the list void AddChild(nsIFrame* aChild); + + // Inserts the frame somewhere in the list + void InsertChildAfter(nsIFrame* aChild, nsIFrame* aAfter); + // Remove the frame from the list, return PR_FALSE if not found. PRBool RemoveChild(nsIFrame* aChild); }; @@ -740,6 +744,24 @@ nsFrameItems::AddChild(nsIFrame* aChild) } } +void +nsFrameItems::InsertChildAfter(nsIFrame* aChild, nsIFrame* aAfter) +{ + if (!childList || (aAfter && !aAfter->GetNextSibling())) { + // Appending to the end of the list + AddChild(aChild); + return; + } + if (!aAfter) { + // Inserting at beginning of list + aChild->SetNextSibling(childList); + childList = aChild; + return; + } + aChild->SetNextSibling(aAfter->GetNextSibling()); + aAfter->SetNextSibling(aChild); +} + PRBool nsFrameItems::RemoveChild(nsIFrame* aFrame) { @@ -1152,7 +1174,9 @@ public: nsIFrame* aParentFrame, PRBool aCanBePositioned = PR_TRUE, PRBool aCanBeFloated = PR_TRUE, - PRBool aIsOutOfFlowPopup = PR_FALSE); + PRBool aIsOutOfFlowPopup = PR_FALSE, + PRBool aInsertAfter = PR_FALSE, + nsIFrame* aInsertAfterFrame = nsnull); protected: friend class nsFrameConstructorSaveState; @@ -1314,7 +1338,9 @@ nsFrameConstructorState::AddChild(nsIFrame* aNewFrame, nsIFrame* aParentFrame, PRBool aCanBePositioned, PRBool aCanBeFloated, - PRBool aIsOutOfFlowPopup) + PRBool aIsOutOfFlowPopup, + PRBool aInsertAfter, + nsIFrame* aInsertAfterFrame) { // The comments in GetGeometricParent regarding root table frames // all apply here, unfortunately. @@ -1387,7 +1413,11 @@ nsFrameConstructorState::AddChild(nsIFrame* aNewFrame, } #endif - frameItems->AddChild(aNewFrame); + if (aInsertAfter) { + frameItems->InsertChildAfter(aNewFrame, aInsertAfterFrame); + } else { + frameItems->AddChild(aNewFrame); + } // Now add the special siblings too. nsIFrame* specialSibling = aNewFrame; @@ -11641,6 +11671,7 @@ static PRBool IsFirstLetterContent(nsIContent* aContent) void nsCSSFrameConstructor::CreateFloatingLetterFrame( nsFrameConstructorState& aState, + nsIFrame* aBlockFrame, nsIContent* aTextContent, nsIFrame* aTextFrame, nsIContent* aBlockContent, @@ -11696,10 +11727,19 @@ nsCSSFrameConstructor::CreateFloatingLetterFrame( NS_ASSERTION(aResult.childList == nsnull, "aResult should be an empty nsFrameItems!"); + nsIFrame* insertAfter = nsnull; + nsIFrame* f; + // Put the new float before any of the floats in the block we're + // doing first-letter for, that is, before any floats whose parent is aBlockFrame + for (f = aState.mFloatedItems.childList; f; f = f->GetNextSibling()) { + if (f->GetParent() == aBlockFrame) + break; + insertAfter = f; + } rv = aState.AddChild(letterFrame, aResult, letterFrame->GetStyleDisplay(), aTextContent, aStyleContext, aParentFrame, PR_FALSE, - PR_TRUE); + PR_TRUE, PR_FALSE, PR_TRUE, insertAfter); if (nextTextFrame) { if (NS_FAILED(rv)) { @@ -11716,6 +11756,7 @@ nsCSSFrameConstructor::CreateFloatingLetterFrame( */ nsresult nsCSSFrameConstructor::CreateLetterFrame(nsFrameConstructorState& aState, + nsIFrame* aBlockFrame, nsIContent* aTextContent, nsIFrame* aParentFrame, nsFrameItems& aResult) @@ -11745,7 +11786,7 @@ nsCSSFrameConstructor::CreateLetterFrame(nsFrameConstructorState& aState, const nsStyleDisplay* display = sc->GetStyleDisplay(); if (display->IsFloating()) { // Make a floating first-letter frame - CreateFloatingLetterFrame(aState, aTextContent, textFrame, + CreateFloatingLetterFrame(aState, aBlockFrame, aTextContent, textFrame, blockContent, aParentFrame, sc, aResult); } @@ -11783,7 +11824,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame( nsIFrame* prevFrame = nsnull; nsFrameItems letterFrames; PRBool stopLooking = PR_FALSE; - rv = WrapFramesInFirstLetterFrame(aState, aBlockFrame, + rv = WrapFramesInFirstLetterFrame(aState, aBlockFrame, aBlockFrame, aBlockFrames.childList, &parentFrame, &textFrame, &prevFrame, letterFrames, &stopLooking); @@ -11829,6 +11870,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame( nsresult nsCSSFrameConstructor::WrapFramesInFirstLetterFrame( nsFrameConstructorState& aState, + nsIFrame* aBlockFrame, nsIFrame* aParentFrame, nsIFrame* aParentFrameList, nsIFrame** aModifiedParent, @@ -11851,7 +11893,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame( nsIContent* textContent = frame->GetContent(); if (IsFirstLetterContent(textContent)) { // Create letter frame to wrap up the text - rv = CreateLetterFrame(aState, textContent, + rv = CreateLetterFrame(aState, aBlockFrame, textContent, aParentFrame, aLetterFrames); if (NS_FAILED(rv)) { return rv; @@ -11869,7 +11911,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame( (nsGkAtoms::lineFrame == frameType) || (nsGkAtoms::positionedInlineFrame == frameType)) { nsIFrame* kids = frame->GetFirstChild(nsnull); - WrapFramesInFirstLetterFrame(aState, frame, kids, + WrapFramesInFirstLetterFrame(aState, aBlockFrame, frame, kids, aModifiedParent, aTextFrame, aPrevFrame, aLetterFrames, aStopLooking); if (*aStopLooking) { @@ -12102,7 +12144,7 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsFrameConstructorState& aState, nsIFrame* prevFrame = nsnull; nsFrameItems letterFrames; PRBool stopLooking = PR_FALSE; - rv = WrapFramesInFirstLetterFrame(aState, aBlockFrame, blockKids, + rv = WrapFramesInFirstLetterFrame(aState, aBlockFrame, aBlockFrame, blockKids, &parentFrame, &textFrame, &prevFrame, letterFrames, &stopLooking); if (NS_FAILED(rv)) { diff --git a/mozilla/layout/base/nsCSSFrameConstructor.h b/mozilla/layout/base/nsCSSFrameConstructor.h index 73ceaae33b3..c49fed33f59 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.h +++ b/mozilla/layout/base/nsCSSFrameConstructor.h @@ -833,6 +833,7 @@ private: // Methods support :first-letter style void CreateFloatingLetterFrame(nsFrameConstructorState& aState, + nsIFrame* aBlockFrame, nsIContent* aTextContent, nsIFrame* aTextFrame, nsIContent* aBlockContent, @@ -841,6 +842,7 @@ private: nsFrameItems& aResult); nsresult CreateLetterFrame(nsFrameConstructorState& aState, + nsIFrame* aBlockFrame, nsIContent* aTextContent, nsIFrame* aParentFrame, nsFrameItems& aResult); @@ -851,6 +853,7 @@ private: nsFrameItems& aBlockFrames); nsresult WrapFramesInFirstLetterFrame(nsFrameConstructorState& aState, + nsIFrame* aBlockFrame, nsIFrame* aParentFrame, nsIFrame* aParentFrameList, nsIFrame** aModifiedParent,