Bug 363813. Ensure that floating first-letter frames get inserted in the right place in the list of new floated items. r+sr=dbaron
git-svn-id: svn://10.0.0.236/trunk@218543 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user