Bug 1269046 part 2: Spin out a helper function to hold nsAbsoluteContainingBlock's code for resolving abspos offsets. r?mats
MozReview-Commit-ID: 5tvCIEhAsPH
--- 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);