Changeset 182780 in webkit


Ignore:
Timestamp:
Apr 13, 2015 9:59:09 PM (9 years ago)
Author:
Manuel Rego Casasnovas
Message:

[CSS Grid Layout] Columns set in percentages collapse to auto width
https://bugs.webkit.org/show_bug.cgi?id=141435

Reviewed by David Hyatt.

Source/WebCore:

Based on a patch by Sergio Villar Senin <svillar@igalia.com>.

This patch adds 2 new new methods in RenderBox to determine if the grid
has a definite size or not.

RenderGrid::gridTrackSize() was not checking properly if the grid has or
not an indefinite size.
The condition was including auto which is not indefinite per se. For
example, auto is definite if the containing block is definite.
As the new method is more expensive, we just call it when it's really
needed to avoid performance regressions.

Finally we were setting the override logical width/height to -1 (no
possible resolution) for all the items regardless if they've a relative
width/height or a fixed one.
Added the condition, including not only items with percentage logical
width/height but also relative, to avoid overriding the value for items
with fixed width/height as it's not needed.

Tests: fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution.html

fast/css-grid-layout/percent-intrinsic-track-breadth.html
fast/css-grid-layout/percent-track-breadths-regarding-container-size.html

  • rendering/RenderBox.cpp:

(WebCore::logicalWidthIsResolvable):
(WebCore::RenderBox::hasDefiniteLogicalWidth):
(WebCore::RenderBox::percentageLogicalHeightIsResolvableFromBlock):
(WebCore::RenderBox::hasRelativeLogicalWidth):

  • rendering/RenderBox.h:
  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::hasDefiniteLogicalSize):
(WebCore::RenderGrid::gridTrackSize):
(WebCore::RenderGrid::logicalContentHeightForChild):
(WebCore::RenderGrid::minContentForChild):
(WebCore::RenderGrid::maxContentForChild):

  • rendering/RenderGrid.h:

LayoutTests:

Added new tests to check that percentage track breadths are properly
calculated under different sizing conditions.
Modified one test to include relative sizes too.

  • fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution-expected.txt:
  • fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution.html:
  • fast/css-grid-layout/percent-intrinsic-track-breadth-expected.txt: Added.
  • fast/css-grid-layout/percent-intrinsic-track-breadth.html: Added.
  • fast/css-grid-layout/percent-track-breadths-regarding-container-size-expected.txt: Added.
  • fast/css-grid-layout/percent-track-breadths-regarding-container-size.html: Added.
Location:
trunk
Files:
4 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r182768 r182780  
     12015-04-13  Manuel Rego Casasnovas  <rego@igalia.com>
     2
     3        [CSS Grid Layout] Columns set in percentages collapse to auto width
     4        https://bugs.webkit.org/show_bug.cgi?id=141435
     5
     6        Reviewed by David Hyatt.
     7
     8        Added new tests to check that percentage track breadths are properly
     9        calculated under different sizing conditions.
     10        Modified one test to include relative sizes too.
     11
     12        * fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution-expected.txt:
     13        * fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution.html:
     14        * fast/css-grid-layout/percent-intrinsic-track-breadth-expected.txt: Added.
     15        * fast/css-grid-layout/percent-intrinsic-track-breadth.html: Added.
     16        * fast/css-grid-layout/percent-track-breadths-regarding-container-size-expected.txt: Added.
     17        * fast/css-grid-layout/percent-track-breadths-regarding-container-size.html: Added.
     18
    1192015-04-10  Brent Fulgham  <bfulgham@apple.com>
    220
  • trunk/LayoutTests/fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution-expected.txt

    r164609 r182780  
    2121XXXXX XXXXX XXXXX XXXXXX
    2222PASS
     23XXXXX XXXXXX
     24XXXXX XXXXXX
     25XXXXX XXXXXX
     26XXXXX XXXXXX
     27PASS
     28XXXXX XXXXXX
     29XXXXX XXXXXX
     30XXXXX XXXXXX
     31XXXXX XXXXXX
     32PASS
     33XXXXX XXXXXX
     34XXXXX XXXXXX
     35XXXXX XXXXXX
     36XXXXX XXXXXX
     37PASS
     38XXXXX XXXXXX
     39XXXXX XXXXX XXXXXX
     40XXXXX XXXXXX
     41XXXXX XXXXX XXXXX XXXXXX
     42PASS
  • trunk/LayoutTests/fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution.html

    r168416 r182780  
    1111    -webkit-grid-template-columns: 50px 100px;
    1212    -webkit-grid-template-rows: auto auto;
     13}
     14
     15.sizedToGridAreaMinSizes {
     16    font: 10px/1 Ahem;
     17    min-width: 100%;
     18    min-height: 100%;
    1319}
    1420</style>
     
    5460</div>
    5561
     62<div class="unconstrainedContainer" style="position: relative">
     63<div class="grid gridMinMaxMinMax">
     64    <div class="sizedToGridAreaMinSizes firstRowFirstColumn" data-expected-width="50" data-expected-height="20">XXXXX XXXXXX</div>
     65    <div class="sizedToGridAreaMinSizes firstRowSecondColumn" data-expected-width="100" data-expected-height="20">XXXXX XXXXXX</div>
     66    <div class="sizedToGridAreaMinSizes secondRowFirstColumn" data-expected-width="50" data-expected-height="100">XXXXX XXXXXX</div>
     67    <div class="sizedToGridAreaMinSizes secondRowSecondColumn" data-expected-width="100" data-expected-height="100">XXXXX XXXXXX</div>
     68</div>
     69</div>
     70
     71<div style="position: relative; height: 100px;">
     72<div class="grid gridMinMaxMinMax">
     73    <div class="sizedToGridAreaMinSizes firstRowFirstColumn" data-expected-width="50" data-expected-height="20">XXXXX XXXXXX</div>
     74    <div class="sizedToGridAreaMinSizes firstRowSecondColumn" data-expected-width="100" data-expected-height="20">XXXXX XXXXXX</div>
     75    <div class="sizedToGridAreaMinSizes secondRowFirstColumn" data-expected-width="50" data-expected-height="100">XXXXX XXXXXX</div>
     76    <div class="sizedToGridAreaMinSizes secondRowSecondColumn" data-expected-width="100" data-expected-height="100">XXXXX XXXXXX</div>
     77</div>
     78</div>
     79
     80<div style="position: relative;">
     81<div class="grid gridMinMaxMinMax" style="height: 100px;">
     82    <div class="sizedToGridAreaMinSizes firstRowFirstColumn" data-expected-width="50" data-expected-height="20">XXXXX XXXXXX</div>
     83    <div class="sizedToGridAreaMinSizes firstRowSecondColumn" data-expected-width="100" data-expected-height="20">XXXXX XXXXXX</div>
     84    <div class="sizedToGridAreaMinSizes secondRowFirstColumn" data-expected-width="50" data-expected-height="80">XXXXX XXXXXX</div>
     85    <div class="sizedToGridAreaMinSizes secondRowSecondColumn" data-expected-width="100" data-expected-height="80">XXXXX XXXXXX</div>
     86</div>
     87</div>
     88
     89<div class="unconstrainedContainer" style="position: relative">
     90<div class="grid gridAutoAuto">
     91    <div class="sizedToGridAreaMinSizes firstRowFirstColumn" data-expected-width="50" data-expected-height="30">XXXXX XXXXXX</div>
     92    <div class="sizedToGridAreaMinSizes firstRowSecondColumn" data-expected-width="100" data-expected-height="30">XXXXX XXXXX XXXXXX</div>
     93    <div class="sizedToGridAreaMinSizes secondRowFirstColumn" data-expected-width="50" data-expected-height="40">XXXXX XXXXXX</div>
     94    <div class="sizedToGridAreaMinSizes secondRowSecondColumn" data-expected-width="100" data-expected-height="40">XXXXX XXXXX XXXXX XXXXXX</div>
     95</div>
     96</div>
     97
    5698</body>
    5799</html>
  • trunk/Source/WebCore/ChangeLog

    r182773 r182780  
     12015-04-13  Manuel Rego Casasnovas  <rego@igalia.com>
     2
     3        [CSS Grid Layout] Columns set in percentages collapse to auto width
     4        https://bugs.webkit.org/show_bug.cgi?id=141435
     5
     6        Reviewed by David Hyatt.
     7
     8        Based on a patch by Sergio Villar Senin  <svillar@igalia.com>.
     9
     10        This patch adds 2 new new methods in RenderBox to determine if the grid
     11        has a definite size or not.
     12
     13        RenderGrid::gridTrackSize() was not checking properly if the grid has or
     14        not an indefinite size.
     15        The condition was including auto which is not indefinite per se. For
     16        example, auto is definite if the containing block is definite.
     17        As the new method is more expensive, we just call it when it's really
     18        needed to avoid performance regressions.
     19
     20        Finally we were setting the override logical width/height to -1 (no
     21        possible resolution) for all the items regardless if they've a relative
     22        width/height or a fixed one.
     23        Added the condition, including not only items with percentage logical
     24        width/height but also relative, to avoid overriding the value for items
     25        with fixed width/height as it's not needed.
     26
     27        Tests: fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution.html
     28               fast/css-grid-layout/percent-intrinsic-track-breadth.html
     29               fast/css-grid-layout/percent-track-breadths-regarding-container-size.html
     30
     31        * rendering/RenderBox.cpp:
     32        (WebCore::logicalWidthIsResolvable):
     33        (WebCore::RenderBox::hasDefiniteLogicalWidth):
     34        (WebCore::RenderBox::percentageLogicalHeightIsResolvableFromBlock):
     35        (WebCore::RenderBox::hasRelativeLogicalWidth):
     36        * rendering/RenderBox.h:
     37        * rendering/RenderGrid.cpp:
     38        (WebCore::RenderGrid::hasDefiniteLogicalSize):
     39        (WebCore::RenderGrid::gridTrackSize):
     40        (WebCore::RenderGrid::logicalContentHeightForChild):
     41        (WebCore::RenderGrid::minContentForChild):
     42        (WebCore::RenderGrid::maxContentForChild):
     43        * rendering/RenderGrid.h:
     44
    1452015-04-13  Chris Dumez  <cdumez@apple.com>
    246
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r182674 r182780  
    44534453}
    44544454
     4455static bool logicalWidthIsResolvable(const RenderBox& renderBox)
     4456{
     4457    const RenderBox* box = &renderBox;
     4458    while (!box->isRenderView() && !box->isOutOfFlowPositioned()
     4459#if ENABLE(CSS_GRID_LAYOUT)
     4460        && !box->hasOverrideContainingBlockLogicalWidth()
     4461#endif
     4462        && (box->style().logicalWidth().isAuto() || box->isAnonymousBlock()))
     4463        box = box->containingBlock();
     4464
     4465    if (box->style().logicalWidth().isFixed())
     4466        return true;
     4467    if (box->isRenderView())
     4468        return true;
     4469    // The size of the containing block of an absolutely positioned element is always definite with respect to that
     4470    // element (http://dev.w3.org/csswg/css-sizing-3/#definite).
     4471    if (box->isOutOfFlowPositioned())
     4472        return true;
     4473#if ENABLE(CSS_GRID_LAYOUT)
     4474    if (box->hasOverrideContainingBlockLogicalWidth())
     4475        return box->overrideContainingBlockContentLogicalWidth() != -1;
     4476#endif
     4477    if (box->style().logicalWidth().isPercent())
     4478        return logicalWidthIsResolvable(*box->containingBlock());
     4479
     4480    return false;
     4481}
     4482
     4483bool RenderBox::hasDefiniteLogicalWidth() const
     4484{
     4485    return logicalWidthIsResolvable(*this);
     4486}
     4487
    44554488inline static bool percentageLogicalHeightIsResolvable(const RenderBox* box)
    44564489{
     
    44704503        if (!inQuirksMode && !cb->isAnonymousBlock())
    44714504            break;
     4505#if ENABLE(CSS_GRID_LAYOUT)
     4506        if (cb->hasOverrideContainingBlockLogicalHeight())
     4507            return cb->overrideContainingBlockContentLogicalHeight() != -1;
     4508#endif
     4509
    44724510        cb = cb->containingBlock();
    44734511    }
     
    45004538
    45014539    return false;
     4540}
     4541
     4542bool RenderBox::hasDefiniteLogicalHeight() const
     4543{
     4544    const Length& logicalHeight = style().logicalHeight();
     4545    if (logicalHeight.isIntrinsicOrAuto())
     4546        return false;
     4547    if (logicalHeight.isFixed())
     4548        return true;
     4549    // The size of the containing block of an absolutely positioned element is always definite with respect to that
     4550    // element (http://dev.w3.org/csswg/css-sizing-3/#definite).
     4551    if (isOutOfFlowPositioned())
     4552        return true;
     4553#if ENABLE(CSS_GRID_LAYOUT)
     4554    if (hasOverrideContainingBlockLogicalHeight())
     4555        return overrideContainingBlockContentLogicalHeight() != -1;
     4556#endif
     4557
     4558    return percentageLogicalHeightIsResolvable(this);
    45024559}
    45034560
     
    47824839}
    47834840
     4841bool RenderBox::hasRelativeLogicalWidth() const
     4842{
     4843    return style().logicalWidth().isPercent()
     4844        || style().logicalMinWidth().isPercent()
     4845        || style().logicalMaxWidth().isPercent();
     4846}
     4847
    47844848static void markBoxForRelayoutAfterSplit(RenderBox& box)
    47854849{
  • trunk/Source/WebCore/rendering/RenderBox.h

    r182127 r182780  
    443443    virtual LayoutUnit computeReplacedLogicalHeight() const;
    444444
     445    bool hasDefiniteLogicalWidth() const;
    445446    static bool percentageLogicalHeightIsResolvableFromBlock(const RenderBlock* containingBlock, bool outOfFlowPositioned);
     447    bool hasDefiniteLogicalHeight() const;
    446448    LayoutUnit computePercentageLogicalHeight(const Length& height) const;
    447449
     
    570572    virtual bool hasRelativeDimensions() const;
    571573    virtual bool hasRelativeLogicalHeight() const;
     574    virtual bool hasRelativeLogicalWidth() const;
    572575
    573576    bool hasHorizontalLayoutOverflow() const
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r182726 r182780  
    519519}
    520520
     521bool RenderGrid::hasDefiniteLogicalSize(GridTrackSizingDirection direction) const
     522{
     523    return (direction == ForRows) ? hasDefiniteLogicalHeight() : hasDefiniteLogicalWidth();
     524}
     525
    521526GridTrackSize RenderGrid::gridTrackSize(GridTrackSizingDirection direction, unsigned i) const
    522527{
     
    525530    auto& trackSize = (i >= trackStyles.size()) ? (isForColumns ? style().gridAutoColumns() : style().gridAutoRows()) : trackStyles[i];
    526531
    527     // If the logical width/height of the grid container is indefinite, percentage values are treated as <auto> (or in
    528     // the case of minmax() as min-content for the first position and max-content for the second).
    529     Length logicalSize = isForColumns ? style().logicalWidth() : style().logicalHeight();
    530     if (logicalSize.isIntrinsicOrAuto()) {
    531         const GridLength& oldMinTrackBreadth = trackSize.minTrackBreadth();
    532         const GridLength& oldMaxTrackBreadth = trackSize.maxTrackBreadth();
    533         return GridTrackSize(oldMinTrackBreadth.isPercentage() ? Length(MinContent) : oldMinTrackBreadth, oldMaxTrackBreadth.isPercentage() ? Length(MaxContent) : oldMaxTrackBreadth);
    534     }
    535 
    536     return trackSize;
     532    GridLength minTrackBreadth = trackSize.minTrackBreadth();
     533    GridLength maxTrackBreadth = trackSize.maxTrackBreadth();
     534
     535    if (minTrackBreadth.isPercentage() || maxTrackBreadth.isPercentage()) {
     536        if (!hasDefiniteLogicalSize(direction)) {
     537            if (minTrackBreadth.isPercentage())
     538                minTrackBreadth = Length(MinContent);
     539            if (maxTrackBreadth.isPercentage())
     540                maxTrackBreadth = Length(MaxContent);
     541        }
     542    }
     543
     544    return GridTrackSize(minTrackBreadth, maxTrackBreadth);
    537545}
    538546
     
    541549    LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child.hasOverrideContainingBlockLogicalWidth() ? child.overrideContainingBlockContentLogicalWidth() : LayoutUnit();
    542550    LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForChild(child, ForColumns, columnTracks);
    543     if (child.style().logicalHeight().isPercent() || oldOverrideContainingBlockContentLogicalWidth != overrideContainingBlockContentLogicalWidth)
     551    if (child.hasRelativeLogicalHeight() || oldOverrideContainingBlockContentLogicalWidth != overrideContainingBlockContentLogicalWidth)
    544552        child.setNeedsLayout(MarkOnlyThis);
    545553
    546554    child.setOverrideContainingBlockContentLogicalWidth(overrideContainingBlockContentLogicalWidth);
    547     // If |child| has a percentage logical height, we shouldn't let it override its intrinsic height, which is
     555    // If |child| has a relative logical height, we shouldn't let it override its intrinsic height, which is
    548556    // what we are interested in here. Thus we need to set the override logical height to -1 (no possible resolution).
    549     child.setOverrideContainingBlockContentLogicalHeight(-1);
     557    if (child.hasRelativeLogicalHeight())
     558        child.setOverrideContainingBlockContentLogicalHeight(-1);
    550559    child.layoutIfNeeded();
    551560    return child.logicalHeight() + child.marginLogicalHeight();
     
    560569
    561570    if (direction == ForColumns) {
     571        // If |child| has a relative logical width, we shouldn't let it override its intrinsic width, which is
     572        // what we are interested in here. Thus we need to set the override logical width to -1 (no possible resolution).
     573        if (child.hasRelativeLogicalWidth())
     574            child.setOverrideContainingBlockContentLogicalWidth(-1);
     575
    562576        // FIXME: It's unclear if we should return the intrinsic width or the preferred width.
    563577        // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
     
    576590
    577591    if (direction == ForColumns) {
     592        // If |child| has a relative logical width, we shouldn't let it override its intrinsic width, which is
     593        // what we are interested in here. Thus we need to set the override logical width to -1 (no possible resolution).
     594        if (child.hasRelativeLogicalWidth())
     595            child.setOverrideContainingBlockContentLogicalWidth(-1);
     596
    578597        // FIXME: It's unclear if we should return the intrinsic width or the preferred width.
    579598        // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
  • trunk/Source/WebCore/rendering/RenderGrid.h

    r182704 r182780  
    144144    }
    145145
     146    bool hasDefiniteLogicalSize(GridTrackSizingDirection) const;
     147
    146148    Vector<Vector<Vector<RenderBox*, 1>>> m_grid;
    147149    Vector<LayoutUnit> m_columnPositions;
Note: See TracChangeset for help on using the changeset viewer.