Bug 1144096 part 14 - [css-grid] Make ReflowInFlowChild() deal with a constrained available block-size. r=dholbert

This commit is contained in:
Mats Palmgren 2016-03-11 17:39:26 +01:00
Родитель 1dbca39b11
Коммит bbd8687f0d
2 изменённых файлов: 46 добавлений и 9 удалений

Просмотреть файл

@ -4076,23 +4076,43 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
MOZ_ASSERT(isGridItem == (aChild->GetType() != nsGkAtoms::placeholderFrame)); MOZ_ASSERT(isGridItem == (aChild->GetType() != nsGkAtoms::placeholderFrame));
LogicalRect cb(wm); LogicalRect cb(wm);
WritingMode childWM = aChild->GetWritingMode(); WritingMode childWM = aChild->GetWritingMode();
bool isConstrainedBSize = false;
nscoord toFragmentainerEnd;
if (MOZ_LIKELY(isGridItem)) { if (MOZ_LIKELY(isGridItem)) {
MOZ_ASSERT(aGridItemInfo->mFrame == aChild); MOZ_ASSERT(aGridItemInfo->mFrame == aChild);
const GridArea& area = aGridItemInfo->mArea; const GridArea& area = aGridItemInfo->mArea;
MOZ_ASSERT(area.IsDefinite()); MOZ_ASSERT(area.IsDefinite());
cb = aState.ContainingBlockFor(area); cb = aState.ContainingBlockFor(area);
isConstrainedBSize = aFragmentainer && !wm.IsOrthogonalTo(childWM);
if (isConstrainedBSize) {
nscoord fragCBOffset = cb.BStart(wm) - aState.mFragBStart;
if (fragCBOffset < 0) {
// Subtract the "consumed" part of the grid area.
cb.BSize(wm) = std::max(fragCBOffset + cb.BSize(wm), 0);
}
cb.BStart(wm) = std::max(fragCBOffset, 0);
toFragmentainerEnd = aFragmentainer->mToFragmentainerEnd -
aState.mFragBStart - cb.BStart(wm);
toFragmentainerEnd = std::max(toFragmentainerEnd, 0);
}
cb += aContentArea.Origin(wm); cb += aContentArea.Origin(wm);
} else { } else {
cb = aContentArea; cb = aContentArea;
} }
LogicalSize childCBSize = cb.Size(wm).ConvertTo(childWM, wm);
LogicalSize percentBasis(childCBSize);
// XXX temporary workaround to avoid being INCOMPLETE until we have
// support for fragmentation (bug 1144096)
childCBSize.BSize(childWM) = NS_UNCONSTRAINEDSIZE;
LogicalSize reflowSize(cb.Size(wm));
if (isConstrainedBSize) {
reflowSize.BSize(wm) = toFragmentainerEnd;
}
LogicalSize childCBSize = reflowSize.ConvertTo(childWM, wm);
if (!isConstrainedBSize) {
childCBSize.BSize(childWM) = NS_UNCONSTRAINEDSIZE;
}
LogicalSize percentBasis(cb.Size(wm).ConvertTo(childWM, wm));
Maybe<nsHTMLReflowState> childRS; // Maybe<> so we can reuse the space Maybe<nsHTMLReflowState> childRS; // Maybe<> so we can reuse the space
childRS.emplace(pc, *aState.mReflowState, aChild, childCBSize, &percentBasis); childRS.emplace(pc, *aState.mReflowState, aChild, childCBSize, &percentBasis);
childRS->mFlags.mIsTopOfPage = aFragmentainer ? aFragmentainer->mIsTopOfPage : false;
// We need the width of the child before we can correctly convert // We need the width of the child before we can correctly convert
// the writing-mode of its origin, so we reflow at (0, 0) using a dummy // the writing-mode of its origin, so we reflow at (0, 0) using a dummy
// aContainerSize, and then pass the correct position to FinishReflowChild. // aContainerSize, and then pass the correct position to FinishReflowChild.
@ -4105,12 +4125,15 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
cb.Origin(wm).ConvertTo(childWM, wm, cb.Origin(wm).ConvertTo(childWM, wm,
aContainerSize - childSize->PhysicalSize()); aContainerSize - childSize->PhysicalSize());
// Apply align/justify-self and reflow again if that affects the size. // Apply align/justify-self and reflow again if that affects the size.
if (isGridItem) { if (MOZ_LIKELY(isGridItem)) {
LogicalSize oldSize = childSize->Size(childWM); // from the ReflowChild() LogicalSize oldSize = childSize->Size(childWM); // from the ReflowChild()
LogicalSize newContentSize(childWM); LogicalSize newContentSize(childWM);
auto align = childRS->mStylePosition->ComputedAlignSelf(containerSC); auto align = childRS->mStylePosition->ComputedAlignSelf(containerSC);
Maybe<LogicalAxis> alignResize = Maybe<LogicalAxis> alignResize;
if (NS_FRAME_IS_COMPLETE(aStatus)) {
alignResize =
AlignSelf(align, cb, wm, *childRS, oldSize, &newContentSize, &childPos); AlignSelf(align, cb, wm, *childRS, oldSize, &newContentSize, &childPos);
}
auto justify = childRS->mStylePosition->ComputedJustifySelf(containerSC); auto justify = childRS->mStylePosition->ComputedJustifySelf(containerSC);
Maybe<LogicalAxis> justifyResize = Maybe<LogicalAxis> justifyResize =
JustifySelf(justify, cb, wm, *childRS, oldSize, &newContentSize, &childPos); JustifySelf(justify, cb, wm, *childRS, oldSize, &newContentSize, &childPos);
@ -4121,9 +4144,17 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
childSize.reset(); // In reverse declaration order since it runs childSize.reset(); // In reverse declaration order since it runs
childRS.reset(); // destructors. childRS.reset(); // destructors.
childRS.emplace(pc, *aState.mReflowState, aChild, childCBSize, &percentBasis); childRS.emplace(pc, *aState.mReflowState, aChild, childCBSize, &percentBasis);
childRS->mFlags.mIsTopOfPage = aFragmentainer ? aFragmentainer->mIsTopOfPage : false;
if ((alignResize && alignResize.value() == eLogicalAxisBlock) || if ((alignResize && alignResize.value() == eLogicalAxisBlock) ||
(justifyResize && justifyResize.value() == eLogicalAxisBlock)) { (justifyResize && justifyResize.value() == eLogicalAxisBlock)) {
childRS->SetComputedBSize(newContentSize.BSize(childWM)); nscoord childConsumedBSize = 0;
if (isConstrainedBSize) {
// XXX use aChild->GetConsumedBSize() instead after bug 1232194 is fixed
for (auto prev = aChild->GetPrevInFlow(); prev; prev = prev->GetPrevInFlow()) {
childConsumedBSize += prev->ContentBSize(childWM);
}
}
childRS->SetComputedBSize(childConsumedBSize + newContentSize.BSize(childWM));
childRS->SetBResize(true); childRS->SetBResize(true);
} }
if ((alignResize && alignResize.value() == eLogicalAxisInline) || if ((alignResize && alignResize.value() == eLogicalAxisInline) ||

Просмотреть файл

@ -713,6 +713,12 @@ public:
nscoord BSize(mozilla::WritingMode aWritingMode) const { nscoord BSize(mozilla::WritingMode aWritingMode) const {
return GetLogicalSize(aWritingMode).BSize(aWritingMode); return GetLogicalSize(aWritingMode).BSize(aWritingMode);
} }
nscoord ContentBSize() const { return ContentBSize(GetWritingMode()); }
nscoord ContentBSize(mozilla::WritingMode aWritingMode) const {
auto bp = GetLogicalUsedBorderAndPadding(aWritingMode);
bp.ApplySkipSides(GetLogicalSkipSides());
return std::max(0, BSize(aWritingMode) - bp.BStartEnd(aWritingMode));
}
/** /**
* When we change the size of the frame's border-box rect, we may need to * When we change the size of the frame's border-box rect, we may need to