Commit a1834f53 authored by roc+%cs.cmu.edu's avatar roc+%cs.cmu.edu
Browse files

Bug 363813. Ensure that floating first-letter frames get inserted in the right...

Bug 363813. Ensure that floating first-letter frames get inserted in the right place in the list of new floated items. r+sr=dbaron
parent f79b2fa2
Loading
Loading
Loading
Loading
+51 −9
Original line number Diff line number Diff line
@@ -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

  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)) {
+3 −0
Original line number Diff line number Diff line
@@ -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,