Bug 1229437 part 4 - Reparent floats inside pulled ruby column. draft
authorXidorn Quan <quanxunzhen@gmail.com>
Mon, 21 Dec 2015 14:02:46 +1100
changeset 325657 76d90c4b6b7323a07a4f14f5ef8c6d8b8445d0db
parent 325656 bc1f375edf7743ab39cf0c01912ac506516b545c
child 325658 d388d2e01578953ff0f27e8d76ddeefd604f7215
push id10021
push userxquan@mozilla.com
push dateTue, 26 Jan 2016 07:10:42 +0000
bugs1229437
milestone47.0a1
Bug 1229437 part 4 - Reparent floats inside pulled ruby column.
layout/generic/nsRubyBaseContainerFrame.cpp
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -719,49 +719,78 @@ nsRubyBaseContainerFrame::PullOneColumn(
 {
   const AutoRubyTextContainerArray& textContainers =
     aPullFrameState.mTextContainers;
   const uint32_t rtcCount = textContainers.Length();
 
   nsIFrame* nextBase = GetNextInFlowChild(aPullFrameState.mBase);
   MOZ_ASSERT(!nextBase || nextBase->GetType() == nsGkAtoms::rubyBaseFrame);
   aColumn.mBaseFrame = static_cast<nsRubyBaseFrame*>(nextBase);
-  aIsComplete = !aColumn.mBaseFrame;
+  bool foundFrame = !!aColumn.mBaseFrame;
   bool pullingIntraLevelWhitespace =
     aColumn.mBaseFrame && aColumn.mBaseFrame->IsIntraLevelWhitespace();
 
   aColumn.mTextFrames.ClearAndRetainStorage();
   for (uint32_t i = 0; i < rtcCount; i++) {
     nsIFrame* nextText =
       textContainers[i]->GetNextInFlowChild(aPullFrameState.mTexts[i]);
     MOZ_ASSERT(!nextText || nextText->GetType() == nsGkAtoms::rubyTextFrame);
     nsRubyTextFrame* textFrame = static_cast<nsRubyTextFrame*>(nextText);
     aColumn.mTextFrames.AppendElement(textFrame);
-    // If there exists any frame in continations, we haven't
-    // completed the reflow process.
-    aIsComplete = aIsComplete && !nextText;
+    foundFrame = foundFrame || nextText;
     if (nextText && !pullingIntraLevelWhitespace) {
       pullingIntraLevelWhitespace = textFrame->IsIntraLevelWhitespace();
     }
   }
+  // If there exists any frame in continations, we haven't
+  // completed the reflow process.
+  aIsComplete = !foundFrame;
+  if (!foundFrame) {
+    return;
+  }
 
   aColumn.mIsIntraLevelWhitespace = pullingIntraLevelWhitespace;
   if (pullingIntraLevelWhitespace) {
     // We are pulling an intra-level whitespace. Drop all frames which
     // are not part of this intra-level whitespace column. (Those frames
     // are really part of the *next* column, after the pulled one.)
     if (aColumn.mBaseFrame && !aColumn.mBaseFrame->IsIntraLevelWhitespace()) {
       aColumn.mBaseFrame = nullptr;
     }
     for (uint32_t i = 0; i < rtcCount; i++) {
       nsRubyTextFrame*& textFrame = aColumn.mTextFrames[i];
       if (textFrame && !textFrame->IsIntraLevelWhitespace()) {
         textFrame = nullptr;
       }
     }
+  } else {
+    // We are not pulling an intra-level whitespace, which means all
+    // elements we are going to pull can have non-whitespace content,
+    // which may contain float which we need to reparent.
+    nsBlockFrame* oldFloatCB = nullptr;
+    for (nsIFrame* frame : aColumn) {
+      oldFloatCB = nsLayoutUtils::GetFloatContainingBlock(frame);
+      break;
+    }
+#ifdef DEBUG
+    MOZ_ASSERT(oldFloatCB, "Must have found a float containing block");
+    for (nsIFrame* frame : aColumn) {
+      MOZ_ASSERT(nsLayoutUtils::GetFloatContainingBlock(frame) == oldFloatCB,
+                 "All frames in the same ruby column should share "
+                 "the same old float containing block");
+    }
+#endif
+    nsBlockFrame* newFloatCB =
+      nsLayoutUtils::GetAsBlock(aLineLayout->LineContainerFrame());
+    MOZ_ASSERT(newFloatCB, "Must have a float containing block");
+    if (oldFloatCB != newFloatCB) {
+      for (nsIFrame* frame : aColumn) {
+        newFloatCB->ReparentFloats(frame, oldFloatCB, false);
+      }
+    }
   }
 
   // Pull the frames of this column.
   if (aColumn.mBaseFrame) {
     DebugOnly<nsIFrame*> pulled = PullNextInFlowChild(aPullFrameState.mBase);
     MOZ_ASSERT(pulled == aColumn.mBaseFrame, "pulled a wrong frame?");
   }
   for (uint32_t i = 0; i < rtcCount; i++) {