Bug 1269046 part 2: Spin out a helper function to hold nsAbsoluteContainingBlock's code for resolving abspos offsets. r?mats draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Wed, 12 Oct 2016 13:22:26 -0700
changeset 424479 669f62626129e9587de612875aff9337df7fa3f0
parent 424478 10b5068e754d6814528a0b8b13fcfd90d102eb49
child 424480 1e7560a05c6501388516212feed19c59a070699b
push id32165
push userdholbert@mozilla.com
push dateWed, 12 Oct 2016 20:22:46 +0000
reviewersmats
bugs1269046
milestone52.0a1
Bug 1269046 part 2: Spin out a helper function to hold nsAbsoluteContainingBlock's code for resolving abspos offsets. r?mats MozReview-Commit-ID: 5tvCIEhAsPH
layout/generic/nsAbsoluteContainingBlock.cpp
layout/generic/nsAbsoluteContainingBlock.h
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -327,16 +327,61 @@ nsAbsoluteContainingBlock::DoMarkFramesD
       kidFrame->AddStateBits(NS_FRAME_IS_DIRTY);
     } else if (FrameDependsOnContainer(kidFrame, true, true)) {
       // Add the weakest flags that will make sure we reflow this frame later
       kidFrame->AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
     }
   }
 }
 
+void
+nsAbsoluteContainingBlock::ResolveSizeDependentOffsets(
+  nsPresContext* aPresContext,
+  ReflowInput& aKidReflowInput,
+  const LogicalSize& aKidSize,
+  const LogicalMargin& aMargin,
+  LogicalMargin* aOffsets,
+  LogicalSize* aLogicalCBSize)
+{
+  WritingMode wm = aKidReflowInput.GetWritingMode();
+  WritingMode outerWM = aKidReflowInput.mParentReflowInput->GetWritingMode();
+  bool didResolveOffsets = false;
+
+  if ((NS_AUTOOFFSET == aOffsets->IStart(outerWM)) ||
+      (NS_AUTOOFFSET == aOffsets->BStart(outerWM))) {
+    if (-1 == aLogicalCBSize->ISize(wm)) {
+      // Get the containing block width/height
+      const ReflowInput* parentRI = aKidReflowInput.mParentReflowInput;
+      *aLogicalCBSize =
+        aKidReflowInput.ComputeContainingBlockRectangle(aPresContext,
+                                                        parentRI);
+    }
+
+    if (NS_AUTOOFFSET == aOffsets->IStart(outerWM)) {
+      NS_ASSERTION(NS_AUTOOFFSET != aOffsets->IEnd(outerWM),
+                   "Can't solve for both start and end");
+      aOffsets->IStart(outerWM) =
+        aLogicalCBSize->ConvertTo(outerWM, wm).ISize(outerWM) -
+        aOffsets->IEnd(outerWM) - aMargin.IStartEnd(outerWM) -
+        aKidSize.ISize(outerWM);
+    }
+    if (NS_AUTOOFFSET == aOffsets->BStart(outerWM)) {
+      aOffsets->BStart(outerWM) =
+        aLogicalCBSize->ConvertTo(outerWM, wm).BSize(outerWM) -
+        aOffsets->BEnd(outerWM) - aMargin.BStartEnd(outerWM) -
+        aKidSize.BSize(outerWM);
+    }
+    didResolveOffsets = true;
+  }
+
+  if (didResolveOffsets) {
+    aKidReflowInput.SetComputedLogicalOffsets(aOffsets->ConvertTo(wm, outerWM));
+  }
+}
+
 // XXX Optimize the case where it's a resize reflow and the absolutely
 // positioned child has the exact same size and position and skip the
 // reflow...
 
 // When bug 154892 is checked in, make sure that when 
 // mChildListID == kFixedList, the height is unconstrained.
 // since we don't allow replicated frames to split.
 
@@ -429,41 +474,18 @@ nsAbsoluteContainingBlock::ReflowAbsolut
 
   const LogicalSize kidSize = kidDesiredSize.Size(wm).ConvertTo(outerWM, wm);
 
   LogicalMargin offsets =
     kidReflowInput.ComputedLogicalOffsets().ConvertTo(outerWM, wm);
 
   // If we're solving for start in either inline or block direction,
   // then compute it now that we know the dimensions.
-  if ((NS_AUTOOFFSET == offsets.IStart(outerWM)) ||
-      (NS_AUTOOFFSET == offsets.BStart(outerWM))) {
-    if (-1 == logicalCBSize.ISize(wm)) {
-      // Get the containing block width/height
-      logicalCBSize =
-        kidReflowInput.ComputeContainingBlockRectangle(aPresContext,
-                                                       &aReflowInput);
-    }
-
-    if (NS_AUTOOFFSET == offsets.IStart(outerWM)) {
-      NS_ASSERTION(NS_AUTOOFFSET != offsets.IEnd(outerWM),
-                   "Can't solve for both start and end");
-      offsets.IStart(outerWM) =
-        logicalCBSize.ConvertTo(outerWM, wm).ISize(outerWM) -
-        offsets.IEnd(outerWM) - margin.IStartEnd(outerWM) -
-        kidSize.ISize(outerWM);
-    }
-    if (NS_AUTOOFFSET == offsets.BStart(outerWM)) {
-      offsets.BStart(outerWM) =
-        logicalCBSize.ConvertTo(outerWM, wm).BSize(outerWM) -
-        offsets.BEnd(outerWM) - margin.BStartEnd(outerWM) -
-        kidSize.BSize(outerWM);
-    }
-    kidReflowInput.SetComputedLogicalOffsets(offsets.ConvertTo(wm, outerWM));
-  }
+  ResolveSizeDependentOffsets(aPresContext, kidReflowInput, kidSize, margin,
+                              &offsets, &logicalCBSize);
 
   // Position the child relative to our padding edge
   LogicalRect rect(outerWM,
                    border.IStart(outerWM) + offsets.IStart(outerWM) +
                      margin.IStart(outerWM),
                    border.BStart(outerWM) + offsets.BStart(outerWM) +
                      margin.BStart(outerWM),
                    kidSize.ISize(outerWM), kidSize.BSize(outerWM));
--- a/layout/generic/nsAbsoluteContainingBlock.h
+++ b/layout/generic/nsAbsoluteContainingBlock.h
@@ -122,16 +122,32 @@ protected:
   /**
    * Returns true if the position of aFrame depends on the position of
    * its placeholder or if the position or size of aFrame depends on a
    * containing block dimension that changed.
    */
   bool FrameDependsOnContainer(nsIFrame* aFrame, bool aCBWidthChanged,
                                bool aCBHeightChanged);
 
+  /**
+   * After an abspos child's size is known, this method can be used to
+   * resolve size-dependent values in the ComputedLogicalOffsets on its
+   * reflow state. (This may involve resolving the inline dimension of
+   * aLogicalCBSize, too; hence, that variable is an in/outparam.)
+   *
+   * aKidSize, aMargin, aOffsets, and aLogicalCBSize are all expected to be
+   * represented in terms of the absolute containing block's writing-mode.
+   */
+  void ResolveSizeDependentOffsets(nsPresContext* aPresContext,
+                                   ReflowInput& aKidReflowInput,
+                                   const mozilla::LogicalSize& aKidSize,
+                                   const mozilla::LogicalMargin& aMargin,
+                                   mozilla::LogicalMargin* aOffsets,
+                                   mozilla::LogicalSize* aLogicalCBSize);
+
   void ReflowAbsoluteFrame(nsIFrame*                aDelegatingFrame,
                            nsPresContext*           aPresContext,
                            const ReflowInput& aReflowInput,
                            const nsRect&            aContainingBlockRect,
                            AbsPosReflowFlags        aFlags,
                            nsIFrame*                aKidFrame,
                            nsReflowStatus&          aStatus,
                            nsOverflowAreas*         aOverflowAreas);