⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 201516 in webkit


Ignore:
Timestamp:
May 31, 2016, 11:42:17 AM (10 years ago)
Author:
hyatt@apple.com
Message:

REGRESSION (r189567): Elements with aspect ratios not handled correctly inside flexbox.
https://bugs.webkit.org/show_bug.cgi?id=158040

Reviewed by Zalan Bujtas.

Source/WebCore:

Added new tests in fast/flexbox.

  • rendering/RenderFlexibleBox.cpp:

(WebCore::RenderFlexibleBox::clientLogicalBottomAfterRepositioning):
(WebCore::RenderFlexibleBox::hasOrthogonalFlow):
(WebCore::RenderFlexibleBox::mainAxisContentExtent):
(WebCore::RenderFlexibleBox::computeMainAxisExtentForChild):
(WebCore::RenderFlexibleBox::mainAxisBorderAndPaddingExtentForChild):
(WebCore::RenderFlexibleBox::mainAxisLengthIsDefinite):
(WebCore::RenderFlexibleBox::mainAxisScrollbarExtentForChild):
(WebCore::RenderFlexibleBox::prepareOrderIteratorAndMargins):
(WebCore::RenderFlexibleBox::crossAxisLengthIsDefinite):
(WebCore::RenderFlexibleBox::computeMainSizeFromAspectRatioUsing):
(WebCore::RenderFlexibleBox::adjustChildSizeForAspectRatioCrossAxisMinAndMax):
(WebCore::RenderFlexibleBox::useChildAspectRatio):
(WebCore::RenderFlexibleBox::adjustChildSizeForMinAndMax):
(WebCore::RenderFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis):
(WebCore::RenderFlexibleBox::mainAxisOverflowForChild):
(WebCore::RenderFlexibleBox::mainAxisExtentIsDefinite): Deleted.
(WebCore::RenderFlexibleBox::mainAxisLengthIsIndefinite): Deleted.

  • rendering/RenderFlexibleBox.h:

(WebCore::RenderFlexibleBox::isFlexibleBoxImpl):

LayoutTests:

  • fast/flexbox/aspect-ratio-intrinsic-adjust-expected.html: Added.
  • fast/flexbox/aspect-ratio-intrinsic-adjust.html: Added.
  • fast/flexbox/resources/subjects_sm.png: Added.
Location:
trunk
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r201510 r201516  
     12016-05-31  Dave Hyatt  <hyatt@apple.com>
     2
     3        REGRESSION (r189567): Elements with aspect ratios not handled correctly inside flexbox.
     4        https://bugs.webkit.org/show_bug.cgi?id=158040
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        * fast/flexbox/aspect-ratio-intrinsic-adjust-expected.html: Added.
     9        * fast/flexbox/aspect-ratio-intrinsic-adjust.html: Added.
     10        * fast/flexbox/resources/subjects_sm.png: Added.
     11
    1122016-05-25  Sergio Villar Senin  <svillar@igalia.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r201515 r201516  
     12016-05-31  Dave Hyatt  <hyatt@apple.com>
     2
     3        REGRESSION (r189567): Elements with aspect ratios not handled correctly inside flexbox.
     4        https://bugs.webkit.org/show_bug.cgi?id=158040
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        Added new tests in fast/flexbox.
     9
     10        * rendering/RenderFlexibleBox.cpp:
     11        (WebCore::RenderFlexibleBox::clientLogicalBottomAfterRepositioning):
     12        (WebCore::RenderFlexibleBox::hasOrthogonalFlow):
     13        (WebCore::RenderFlexibleBox::mainAxisContentExtent):
     14        (WebCore::RenderFlexibleBox::computeMainAxisExtentForChild):
     15        (WebCore::RenderFlexibleBox::mainAxisBorderAndPaddingExtentForChild):
     16        (WebCore::RenderFlexibleBox::mainAxisLengthIsDefinite):
     17        (WebCore::RenderFlexibleBox::mainAxisScrollbarExtentForChild):
     18        (WebCore::RenderFlexibleBox::prepareOrderIteratorAndMargins):
     19        (WebCore::RenderFlexibleBox::crossAxisLengthIsDefinite):
     20        (WebCore::RenderFlexibleBox::computeMainSizeFromAspectRatioUsing):
     21        (WebCore::RenderFlexibleBox::adjustChildSizeForAspectRatioCrossAxisMinAndMax):
     22        (WebCore::RenderFlexibleBox::useChildAspectRatio):
     23        (WebCore::RenderFlexibleBox::adjustChildSizeForMinAndMax):
     24        (WebCore::RenderFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis):
     25        (WebCore::RenderFlexibleBox::mainAxisOverflowForChild):
     26        (WebCore::RenderFlexibleBox::mainAxisExtentIsDefinite): Deleted.
     27        (WebCore::RenderFlexibleBox::mainAxisLengthIsIndefinite): Deleted.
     28        * rendering/RenderFlexibleBox.h:
     29        (WebCore::RenderFlexibleBox::isFlexibleBoxImpl):
     30
    1312016-05-31  Alex Christensen  <achristensen@webkit.org>
    232
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp

    r201498 r201516  
    368368}
    369369
    370 bool RenderFlexibleBox::hasOrthogonalFlow(RenderBox& child) const
     370bool RenderFlexibleBox::hasOrthogonalFlow(const RenderBox& child) const
    371371{
    372372    // FIXME: If the child is a flexbox, then we need to check isHorizontalFlow.
     
    455455}
    456456
    457 Optional<LayoutUnit> RenderFlexibleBox::computeMainAxisExtentForChild(RenderBox& child, SizeType sizeType, const Length& size)
     457Optional<LayoutUnit> RenderFlexibleBox::computeMainAxisExtentForChild(const RenderBox& child, SizeType sizeType, const Length& size)
    458458{
    459459    // FIXME: This is wrong for orthogonal flows. It should use the flexbox's writing-mode, not the child's in order
     
    462462        // We don't have to check for "auto" here - computeContentLogicalHeight will just return Nullopt for that case anyway.
    463463        if (size.isIntrinsic())
    464             child.layoutIfNeeded();
     464            const_cast<RenderBox&>(child).layoutIfNeeded(); // FIXME: Should not need to do a layout here.
    465465        return child.computeContentLogicalHeight(sizeType, size, child.logicalHeight() - child.borderAndPaddingLogicalHeight());
    466466    }
     
    653653    return isHorizontalFlow() ? child.horizontalBorderAndPaddingExtent() : child.verticalBorderAndPaddingExtent();
    654654}
    655 
    656 bool RenderFlexibleBox::mainAxisExtentIsDefinite() const
    657 {
    658     return isColumnFlow() ? hasDefiniteLogicalHeight() : hasDefiniteLogicalWidth();
    659 }
    660 
    661 bool RenderFlexibleBox::mainAxisLengthIsIndefinite(const Length& flexBasis) const
    662 {
    663     return flexBasis.isAuto() || (flexBasis.isPercentOrCalculated() && !mainAxisExtentIsDefinite());
     655   
     656bool RenderFlexibleBox::mainAxisLengthIsDefinite(const RenderBox& child, const Length& flexBasis) const
     657{
     658    if (flexBasis.isAuto())
     659        return false;
     660    if (flexBasis.isPercentOrCalculated())
     661        return isColumnFlow() ? bool(child.computePercentageLogicalHeight(flexBasis)) : hasDefiniteLogicalWidth();
     662    return true;
    664663}
    665664
     
    860859}
    861860
    862 LayoutUnit RenderFlexibleBox::adjustChildSizeForMinAndMax(RenderBox& child, LayoutUnit childSize)
     861bool RenderFlexibleBox::crossAxisLengthIsDefinite(const RenderBox& child, const Length& length) const
     862{
     863    if (length.isAuto())
     864        return false;
     865    if (length.isPercentOrCalculated())
     866        return hasOrthogonalFlow(child) ? hasDefiniteLogicalWidth() : bool(child.computePercentageLogicalHeight(length));
     867    return length.isFixed();
     868}
     869
     870   
     871Optional<LayoutUnit> RenderFlexibleBox::computeMainSizeFromAspectRatioUsing(const RenderBox& child, Length crossSizeLength) const
     872{
     873    ASSERT(child.hasAspectRatio());
     874    ASSERT(child.intrinsicSize().height() > 0);
     875   
     876    Optional<LayoutUnit> crossSize;
     877    if (crossSizeLength.isFixed())
     878        crossSize = LayoutUnit(crossSizeLength.value());
     879    else {
     880        ASSERT(crossSizeLength.isPercentOrCalculated());
     881        crossSize = hasOrthogonalFlow(child) ?
     882        adjustBorderBoxLogicalWidthForBoxSizing(valueForLength(crossSizeLength, contentWidth())) :
     883        child.computePercentageLogicalHeight(crossSizeLength);
     884    }
     885   
     886    if (!crossSize)
     887        return crossSize;
     888
     889    const LayoutSize& childIntrinsicSize = child.intrinsicSize();
     890    double ratio = childIntrinsicSize.width().toFloat() / childIntrinsicSize.height().toFloat();
     891    if (isHorizontalFlow())
     892        return LayoutUnit(crossSize.value() * ratio);
     893    return LayoutUnit(crossSize.value() / ratio);
     894}
     895
     896LayoutUnit RenderFlexibleBox::adjustChildSizeForAspectRatioCrossAxisMinAndMax(const RenderBox& child, LayoutUnit childSize)
     897{
     898    Length crossMin = isHorizontalFlow() ? child.style().minHeight() : child.style().minWidth();
     899    Length crossMax = isHorizontalFlow() ? child.style().maxHeight() : child.style().maxWidth();
     900
     901    if (crossAxisLengthIsDefinite(child, crossMax)) {
     902        Optional<LayoutUnit> maxValue = computeMainSizeFromAspectRatioUsing(child, crossMax);
     903        if (maxValue)
     904            childSize = std::min(maxValue.value(), childSize);
     905    }
     906   
     907    if (crossAxisLengthIsDefinite(child, crossMin)) {
     908        Optional<LayoutUnit> minValue = computeMainSizeFromAspectRatioUsing(child, crossMin);
     909        if (minValue)
     910            childSize = std::max(minValue.value(), childSize);
     911    }
     912   
     913    return childSize;
     914}
     915
     916bool RenderFlexibleBox::useChildAspectRatio(const RenderBox& child) const
     917{
     918    if (!child.hasAspectRatio())
     919        return false;
     920    if (!child.intrinsicSize().height())
     921        return false;
     922    Length crossSize = isHorizontalFlow() ? child.style().height() : child.style().width();
     923    return crossAxisLengthIsDefinite(child, crossSize);
     924}
     925
     926LayoutUnit RenderFlexibleBox::adjustChildSizeForMinAndMax(const RenderBox& child, LayoutUnit childSize)
    863927{
    864928    Length max = isHorizontalFlow() ? child.style().maxWidth() : child.style().maxHeight();
     
    868932        childSize = std::min(childSize, maxExtent.valueOr(childSize));
    869933    }
    870 
     934   
    871935    Length min = isHorizontalFlow() ? child.style().minWidth() : child.style().minHeight();
    872936    if (min.isSpecifiedOrIntrinsic())
    873937        return std::max(childSize, computeMainAxisExtentForChild(child, MinSize, min).valueOr(childSize));
    874 
     938   
    875939    if (!isFlexibleBoxImpl() && min.isAuto() && mainAxisOverflowForChild(child) == OVISIBLE && !(isColumnFlow() && is<RenderFlexibleBox>(child))) {
    876940        // This is the implementation of CSS flexbox section 4.5 which defines the minimum size of "pure" flex
     
    881945        LayoutUnit contentSize = computeMainAxisExtentForChild(child, MinSize, Length(MinContent)).value();
    882946        ASSERT(contentSize >= 0);
     947        if (child.hasAspectRatio() && child.intrinsicSize().height() > 0)
     948            contentSize = adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, contentSize);
    883949        contentSize = std::min(contentSize, maxExtent.valueOr(contentSize));
    884 
     950       
    885951        Length mainSize = isHorizontalFlow() ? child.style().width() : child.style().height();
    886         if (!mainAxisLengthIsIndefinite(mainSize)) {
     952        if (mainAxisLengthIsDefinite(child, mainSize)) {
    887953            LayoutUnit resolvedMainSize = computeMainAxisExtentForChild(child, MainOrPreferredSize, mainSize).value();
    888954            ASSERT(resolvedMainSize >= 0);
    889955            LayoutUnit specifiedSize = std::min(resolvedMainSize, maxExtent.valueOr(resolvedMainSize));
    890 
    891956            return std::max(childSize, std::min(specifiedSize, contentSize));
     957        } else if (useChildAspectRatio(child)) {
     958            Length crossSizeLength = isHorizontalFlow() ? child.style().height() : child.style().width();
     959            Optional<LayoutUnit> transferredSize = computeMainSizeFromAspectRatioUsing(child, crossSizeLength);
     960            if (transferredSize) {
     961                transferredSize = adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, transferredSize.value());
     962                return std::max(childSize, std::min(transferredSize.value(), contentSize));
     963            }
    892964        }
    893965        return std::max(childSize, contentSize);
     
    10921164}
    10931165
    1094 EOverflow RenderFlexibleBox::mainAxisOverflowForChild(RenderBox& child) const
     1166EOverflow RenderFlexibleBox::mainAxisOverflowForChild(const RenderBox& child) const
    10951167{
    10961168    if (isHorizontalFlow())
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.h

    r200041 r201516  
    8787
    8888    bool isFlexibleBox() const final { return true; }
    89     bool hasOrthogonalFlow(RenderBox& child) const;
     89    bool hasOrthogonalFlow(const RenderBox& child) const;
    9090    bool isColumnFlow() const;
    9191    bool isLeftToRightFlow() const;
     
    9999    LayoutUnit crossAxisContentExtent() const;
    100100    LayoutUnit mainAxisContentExtent(LayoutUnit contentLogicalHeight);
    101     Optional<LayoutUnit> computeMainAxisExtentForChild(RenderBox& child, SizeType, const Length& size);
     101    Optional<LayoutUnit> computeMainAxisExtentForChild(const RenderBox& child, SizeType, const Length& size);
    102102    WritingMode transformedWritingMode() const;
    103103    LayoutUnit flowAwareBorderStart() const;
     
    123123    LayoutUnit mainAxisScrollbarExtentForChild(RenderBox& child) const;
    124124    LayoutUnit preferredMainAxisContentExtentForChild(RenderBox& child, bool hasInfiniteLineLength);
    125     EOverflow mainAxisOverflowForChild(RenderBox&) const;
     125    EOverflow mainAxisOverflowForChild(const RenderBox&) const;
    126126
    127127    void layoutFlexItems(bool relayoutChildren, Vector<LineContext>&);
     
    140140    LayoutUnit computeChildMarginValue(const Length& margin);
    141141    void prepareOrderIteratorAndMargins();
    142     LayoutUnit adjustChildSizeForMinAndMax(RenderBox&, LayoutUnit childSize);
     142    LayoutUnit adjustChildSizeForMinAndMax(const RenderBox&, LayoutUnit childSize);
     143    LayoutUnit adjustChildSizeForAspectRatioCrossAxisMinAndMax(const RenderBox&, LayoutUnit childSize);
    143144    bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent, bool& hasInfiniteLineLength);
    144145
     
    159160    void flipForWrapReverse(const Vector<LineContext>&, LayoutUnit crossAxisStartEdge);
    160161
    161     bool mainAxisExtentIsDefinite() const;
    162     bool mainAxisLengthIsIndefinite(const Length& flexBasis) const;
    163 
     162    bool mainAxisLengthIsDefinite(const RenderBox&, const Length&) const;
     163    bool crossAxisLengthIsDefinite(const RenderBox&, const Length&) const;
     164    bool useChildAspectRatio(const RenderBox&) const;
     165    Optional<LayoutUnit> computeMainSizeFromAspectRatioUsing(const RenderBox& child, Length crossSizeLength) const;
     166   
    164167    virtual bool isFlexibleBoxImpl() const { return false; };
    165168
Note: See TracChangeset for help on using the changeset viewer.