diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 5300b218bb561..b9c0c34d66fef 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations @@ -971,13 +971,17 @@ crbug.com/471824 imported/web-platform-tests/pointerevents/ [ Skip ] crbug.com/471824 virtual/pointerevent/imported/web-platform-tests/pointerevents/pointerevent_touch-action-illegal.html [ Skip ] crbug.com/471824 virtual/pointerevent/imported/web-platform-tests/pointerevents/pointerevent_touch-action-verification.html [ Skip ] -# Not implemented yet -crbug.com/336604 imported/csswg-test/css-flexbox-1/flexbox_visibility-collapse-line-wrapping.html [ Failure ] -crbug.com/336604 imported/csswg-test/css-flexbox-1/flexbox_visibility-collapse.html [ Failure ] +# These testcases are incorrect, mark them as failing until they're fixed in the testsuite. +# https://lists.w3.org/Archives/Public/www-style/2016Jan/0275.html +# https://lists.w3.org/Archives/Public/www-style/2016Jan/0276.html crbug.com/249112 imported/csswg-test/css-flexbox-1/flex-minimum-height-flex-items-005.xht [ Failure ] crbug.com/249112 imported/csswg-test/css-flexbox-1/flex-minimum-height-flex-items-007.xht [ Failure ] -crbug.com/249112 imported/csswg-test/css-flexbox-1/flex-minimum-height-flex-items-008.xht [ Failure ] crbug.com/249112 imported/csswg-test/css-flexbox-1/flex-minimum-width-flex-items-005.xht [ Failure ] +crbug.com/249112 imported/csswg-test/css-flexbox-1/flex-minimum-width-flex-items-007.xht [ Failure ] + +# Not implemented yet +crbug.com/336604 imported/csswg-test/css-flexbox-1/flexbox_visibility-collapse-line-wrapping.html [ Failure ] +crbug.com/336604 imported/csswg-test/css-flexbox-1/flexbox_visibility-collapse.html [ Failure ] crbug.com/249112 imported/csswg-test/css-flexbox-1/flex-minimum-width-flex-items-006.xht [ Failure ] crbug.com/467127 imported/csswg-test/css-flexbox-1/flex-grow-006.html [ Failure ] @@ -987,7 +991,6 @@ crbug.com/467127 imported/csswg-test/css-flexbox-1/getcomputedstyle/flexbox_comp crbug.com/467127 imported/csswg-test/css-flexbox-1/getcomputedstyle/flexbox_computedstyle_flex-basis-0percent.html [ Failure ] crbug.com/467127 imported/csswg-test/css-flexbox-1/getcomputedstyle/flexbox_computedstyle_flex-basis-percent.html [ Failure ] crbug.com/467127 imported/csswg-test/css-flexbox-1/getcomputedstyle/flexbox_computedstyle_flex-shorthand-number.html [ Failure ] -crbug.com/467127 [ Mac ] imported/csswg-test/css-flexbox-1/flex-minimum-width-flex-items-007.xht [ Failure ] crbug.com/467127 [ Mac Win ] imported/csswg-test/css-flexbox-1/ttwf-reftest-flex-wrap-reverse.html [ Failure ] crbug.com/467127 [ Mac Win ] imported/csswg-test/css-flexbox-1/ttwf-reftest-flex-wrap.html [ Failure ] diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/minimum-size-image.html b/third_party/WebKit/LayoutTests/css3/flexbox/minimum-size-image.html new file mode 100644 index 0000000000000..1840859dbad05 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/flexbox/minimum-size-image.html @@ -0,0 +1,70 @@ + + + + + + + + +
+ +
+ + +
+ +
+ + +
+ + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp index f735ab00a391d..f589bc10dd994 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp @@ -42,6 +42,11 @@ namespace blink { +static bool hasAspectRatio(const LayoutBox& child) +{ + return child.isImage() || child.isCanvas() || child.isVideo(); +} + struct LayoutFlexibleBox::LineContext { LineContext(LayoutUnit crossAxisOffset, LayoutUnit crossAxisExtent, size_t numberOfChildren, LayoutUnit maxAscent) : crossAxisOffset(crossAxisOffset) @@ -452,7 +457,7 @@ LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(const LayoutBox& chi // computeLogicalWidth always re-computes the intrinsic widths. However, when our logical width is auto, // we can just use our cached value. So let's do that here. (Compare code in LayoutBlock::computePreferredLogicalWidths) LayoutUnit borderAndPadding = child.borderAndPaddingLogicalWidth(); - if (child.styleRef().logicalWidth().isAuto()) { + if (child.styleRef().logicalWidth().isAuto() && !hasAspectRatio(child)) { if (size.type() == MinContent) return child.minPreferredLogicalWidth() - borderAndPadding; if (size.type() == MaxContent) @@ -625,6 +630,44 @@ LayoutPoint LayoutFlexibleBox::flowAwareLocationForChild(const LayoutBox& child) return isHorizontalFlow() ? child.location() : child.location().transposedPoint(); } +bool LayoutFlexibleBox::useChildAspectRatio(const LayoutBox& child) const +{ + if (!hasAspectRatio(child)) + return false; + if (child.intrinsicSize().height() == 0) { + // We can't compute a ratio in this case. + return false; + } + Length crossSize; + if (isHorizontalFlow()) + crossSize = child.styleRef().height(); + else + crossSize = child.styleRef().width(); + return crossAxisLengthIsDefinite(child, crossSize); +} + +LayoutUnit LayoutFlexibleBox::computeMainSizeFromAspectRatioUsing(const LayoutBox& child, Length crossSizeLength) const +{ + ASSERT(hasAspectRatio(child)); + ASSERT(child.intrinsicSize().height() != 0); + + LayoutUnit crossSize; + if (crossSizeLength.isFixed()) { + crossSize = crossSizeLength.value(); + } else { + ASSERT(crossSizeLength.hasPercent()); + crossSize = hasOrthogonalFlow(child) ? + adjustBorderBoxLogicalWidthForBoxSizing(valueForLength(crossSizeLength, contentWidth())) : + child.computePercentageLogicalHeight(crossSizeLength); + } + + const LayoutSize& childIntrinsicSize = child.intrinsicSize(); + double ratio = childIntrinsicSize.width().toFloat() / childIntrinsicSize.height().toFloat(); + if (isHorizontalFlow()) + return crossSize * ratio; + return crossSize / ratio; +} + void LayoutFlexibleBox::setFlowAwareLocationForChild(LayoutBox& child, const LayoutPoint& location) { if (isHorizontalFlow()) @@ -650,6 +693,20 @@ bool LayoutFlexibleBox::mainAxisLengthIsDefinite(const LayoutBox& child, const L return true; } +bool LayoutFlexibleBox::crossAxisLengthIsDefinite(const LayoutBox& child, const Length& length) const +{ + if (length.isAuto()) + return false; + if (length.hasPercent()) { + return hasOrthogonalFlow(child) ? + hasDefiniteLogicalWidth() : + child.computePercentageLogicalHeight(length) != -1; + } + // TODO(cbiesinger): Eventually we should support other types of sizes here. Requires updating + // computeMainSizeFromAspectRatioUsing. + return length.isFixed(); +} + bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(const LayoutBox& child) const { return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && ( @@ -919,6 +976,8 @@ LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(const LayoutBox& child // css-flexbox section 4.5 LayoutUnit contentSize = computeMainAxisExtentForChild(child, MinSize, Length(MinContent)); ASSERT(contentSize >= 0); + if (hasAspectRatio(child) && child.intrinsicSize().height() > 0) + contentSize = adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, contentSize); if (maxExtent != -1 && contentSize > maxExtent) contentSize = maxExtent; @@ -929,15 +988,38 @@ LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(const LayoutBox& child LayoutUnit specifiedSize = maxExtent != -1 ? std::min(resolvedMainSize, maxExtent) : resolvedMainSize; minExtent = std::min(specifiedSize, contentSize); + } else if (useChildAspectRatio(child)) { + Length crossSizeLength = isHorizontalFlow() ? child.styleRef().height() : child.styleRef().width(); + LayoutUnit transferredSize = computeMainSizeFromAspectRatioUsing(child, crossSizeLength); + transferredSize = adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, transferredSize); + minExtent = std::min(transferredSize, contentSize); } else { minExtent = contentSize; } - // TODO(cbiesinger): Implement aspect ratio handling (here, transferred size) - crbug.com/249112 } ASSERT(minExtent >= 0); return std::max(childSize, minExtent); } +LayoutUnit LayoutFlexibleBox::adjustChildSizeForAspectRatioCrossAxisMinAndMax(const LayoutBox& child, LayoutUnit childSize) +{ + Length crossMin = isHorizontalFlow() ? child.style()->minHeight() : child.style()->minWidth(); + Length crossMax = isHorizontalFlow() ? child.style()->maxHeight() : child.style()->maxWidth(); + + + if (crossAxisLengthIsDefinite(child, crossMax)) { + LayoutUnit maxValue = computeMainSizeFromAspectRatioUsing(child, crossMax); + childSize = std::min(maxValue, childSize); + } + + if (crossAxisLengthIsDefinite(child, crossMin)) { + LayoutUnit minValue = computeMainSizeFromAspectRatioUsing(child, crossMin); + childSize = std::max(minValue, childSize); + } + + return childSize; +} + bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayoutChildren) { orderedChildren.clear(); @@ -1177,6 +1259,7 @@ bool LayoutFlexibleBox::needToStretchChildLogicalHeight(const LayoutBox& child) if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) return false; + // TODO(cbiesinger): what about indefinite percentage heights? return isHorizontalFlow() ? child.styleRef().height().isAuto() : child.styleRef().width().isAuto(); } @@ -1206,6 +1289,7 @@ EOverflow LayoutFlexibleBox::crossAxisOverflowForChild(const LayoutBox& child) c return child.styleRef().overflowY(); return child.styleRef().overflowX(); } + void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const Vector& childSizes, LayoutUnit availableFreeSpace, bool relayoutChildren, SubtreeLayoutScope& layoutScope, Vector& lineContexts) { ASSERT(childSizes.size() == children.size()); diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h index a4948ca887e12..d2605bdb7c0a3 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h @@ -127,12 +127,15 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock { LayoutUnit crossAxisScrollbarExtent() const; LayoutUnit crossAxisScrollbarExtentForChild(const LayoutBox& child) const; LayoutPoint flowAwareLocationForChild(const LayoutBox& child) const; + bool useChildAspectRatio(const LayoutBox& child) const; + LayoutUnit computeMainSizeFromAspectRatioUsing(const LayoutBox& child, Length crossSizeLength) const; void setFlowAwareLocationForChild(LayoutBox& child, const LayoutPoint&); void adjustAlignmentForChild(LayoutBox& child, LayoutUnit); ItemPosition alignmentForChild(const LayoutBox& child) const; LayoutUnit mainAxisBorderAndPaddingExtentForChild(const LayoutBox& child) const; LayoutUnit computeInnerFlexBaseSizeForChild(LayoutBox& child, ChildLayoutType = LayoutIfNeeded); bool mainAxisLengthIsDefinite(const LayoutBox& child, const Length& flexBasis) const; + bool crossAxisLengthIsDefinite(const LayoutBox& child, const Length& flexBasis) const; bool childFlexBaseSizeRequiresLayout(const LayoutBox& child) const; bool needToStretchChildLogicalHeight(const LayoutBox& child) const; bool childHasIntrinsicMainAxisSize(const LayoutBox& child) const; @@ -154,6 +157,7 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock { LayoutUnit computeChildMarginValue(Length margin); void prepareOrderIteratorAndMargins(); LayoutUnit adjustChildSizeForMinAndMax(const LayoutBox& child, LayoutUnit childSize); + LayoutUnit adjustChildSizeForAspectRatioCrossAxisMinAndMax(const LayoutBox& child, LayoutUnit childSize); // The hypothetical main size of an item is the flex base size clamped according to its min and max main size properties bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayoutChildren);