Bug 1269017 part 1 - [css-grid] Adjust OffsetToAlignedStaticPos() to use correct alignment container for abpsos children of grid containers. r=mats
MozReview-Commit-ID: LItIGLH5GJP
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -360,29 +360,31 @@ GetPlaceholderContainer(nsPresContext* a
* This function returns the offset of an abs/fixed-pos child's static
* position, with respect to the "start" corner of its alignment container,
* according to CSS Box Alignment. This function only operates in a single
* axis at a time -- callers can choose which axis via the |aAbsPosCBAxis|
* parameter.
*
* @param aKidReflowInput The ReflowInput for the to-be-aligned abspos child.
* @param aKidSizeInAbsPosCBWM The child frame's size (after it's been given
- * the opportunity to reflow), in terms of the
- * containing block's WritingMode.
+ * the opportunity to reflow), in terms of
+ * aAbsPosCBWM.
+ * @param aAbsPosCBSize The abspos CB size, in terms of aAbsPosCBWM.
* @param aPlaceholderContainer The parent of the child frame's corresponding
* placeholder frame, cast to a nsContainerFrame.
* (This will help us choose which alignment enum
* we should use for the child.)
* @param aAbsPosCBWM The child frame's containing block's WritingMode.
* @param aAbsPosCBAxis The axis (of the containing block) that we should
* be doing this computation for.
*/
static nscoord
OffsetToAlignedStaticPos(const ReflowInput& aKidReflowInput,
const LogicalSize& aKidSizeInAbsPosCBWM,
+ const LogicalSize& aAbsPosCBSize,
nsContainerFrame* aPlaceholderContainer,
WritingMode aAbsPosCBWM,
LogicalAxis aAbsPosCBAxis)
{
if (!aPlaceholderContainer) {
// (The placeholder container should be the thing that kicks this whole
// process off, by setting PLACEHOLDER_STATICPOS_NEEDS_CSSALIGN. So it
// should exist... but bail gracefully if it doesn't.)
@@ -405,20 +407,40 @@ OffsetToAlignedStaticPos(const ReflowInp
// writing-mode.
LogicalAxis pcAxis = (pcWM.IsOrthogonalTo(aAbsPosCBWM)
? GetOrthogonalAxis(aAbsPosCBAxis)
: aAbsPosCBAxis);
nsIAtom* parentType = aPlaceholderContainer->GetType();
LogicalSize alignAreaSize(pcWM);
if (parentType == nsGkAtoms::flexContainerFrame) {
+ // The alignment container is the flex container's content box:
alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
LogicalMargin pcBorderPadding =
aPlaceholderContainer->GetLogicalUsedBorderAndPadding(pcWM);
alignAreaSize -= pcBorderPadding.Size(pcWM);
+ } else if (parentType == nsGkAtoms::gridContainerFrame) {
+ // This abspos elem's parent is a grid container. Per CSS Grid 10.1 & 10.2:
+ // - If the grid container *also* generates the abspos containing block (a
+ // grid area) for this abspos child, we use that abspos containing block as
+ // the alignment container, too. (And its size is aAbsPosCBSize.)
+ // - Otherwise, we use the grid's padding box as the alignment container.
+ // https://drafts.csswg.org/css-grid/#static-position
+ if (aPlaceholderContainer == aKidReflowInput.mCBReflowInput->mFrame) {
+ // The alignment container is the grid area that we're using as the
+ // absolute containing block.
+ alignAreaSize = aAbsPosCBSize.ConvertTo(pcWM, aAbsPosCBWM);
+ } else {
+ // The alignment container is a the grid container's padding box (which
+ // we can get by subtracting away its border from frame's size):
+ alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
+ LogicalMargin pcBorder =
+ aPlaceholderContainer->GetLogicalUsedBorder(pcWM);
+ alignAreaSize -= pcBorder.Size(pcWM);
+ }
} else {
NS_ERROR("Unsupported container for abpsos CSS Box Alignment");
return 0; // (leave the child at the start of its alignment container)
}
nscoord alignAreaSizeInAxis = (pcAxis == eLogicalAxisInline)
? alignAreaSize.ISize(pcWM)
: alignAreaSize.BSize(pcWM);
@@ -517,16 +539,17 @@ nsAbsoluteContainingBlock::ResolveSizeDe
aOffsets->IStart(outerWM) =
logicalCBSizeOuterWM.ISize(outerWM) -
aOffsets->IEnd(outerWM) - aMargin.IStartEnd(outerWM) -
aKidSize.ISize(outerWM);
} else if (aKidReflowInput.mFlags.mIOffsetsNeedCSSAlign) {
placeholderContainer = GetPlaceholderContainer(aPresContext,
aKidReflowInput.mFrame);
nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize,
+ logicalCBSizeOuterWM,
placeholderContainer,
outerWM, eLogicalAxisInline);
// Shift IStart from its current position (at start corner of the
// alignment container) by the returned offset. And set IEnd to the
// distance between the kid's end edge to containing block's end edge.
aOffsets->IStart(outerWM) += offset;
aOffsets->IEnd(outerWM) =
logicalCBSizeOuterWM.ISize(outerWM) -
@@ -539,16 +562,17 @@ nsAbsoluteContainingBlock::ResolveSizeDe
aOffsets->BEnd(outerWM) - aMargin.BStartEnd(outerWM) -
aKidSize.BSize(outerWM);
} else if (aKidReflowInput.mFlags.mBOffsetsNeedCSSAlign) {
if (!placeholderContainer) {
placeholderContainer = GetPlaceholderContainer(aPresContext,
aKidReflowInput.mFrame);
}
nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize,
+ logicalCBSizeOuterWM,
placeholderContainer,
outerWM, eLogicalAxisBlock);
// Shift BStart from its current position (at start corner of the
// alignment container) by the returned offset. And set BEnd to the
// distance between the kid's end edge to containing block's end edge.
aOffsets->BStart(outerWM) += offset;
aOffsets->BEnd(outerWM) =
logicalCBSizeOuterWM.BSize(outerWM) -