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

Changeset 283439 in webkit


Ignore:
Timestamp:
Oct 2, 2021, 5:38:36 AM (5 years ago)
Author:
Ziran Sun
Message:

[css-grid] Accommodate spanning items crossing flexible tracks
https://bugs.webkit.org/show_bug.cgi?id=230252

Reviewed by Sergio Villar Senin.

LayoutTests/imported/w3c:

Three tests are passing and the test expectation files are updated.

  • web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt:
  • web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt:
  • web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-003-expected.txt:

Source/WebCore:

CSS spec has added one more step at https://drafts.csswg.org/css-grid/#algo-spanning-flex-items
for resolving intrinsic track sizes. Basically, increasing sizes to accommodate spanning items
crossing flexible tracks instead of ignoring their contents completely.

This patch is an import of obrufau's work in chromium. Initial CL is at
https://chromium-review.googlesource.com/c/chromium/src/+/1492337/16..20.
The performance issue caused by the patch were fixed at https://bugs.webkit.org/show_bug.cgi?id=207852
for webkit and https://bugs.chromium.org/p/chromium/issues/detail?id=1021929 for chromium.
This change also addresses web compat issue raised at https://github.com/w3c/csswg-drafts/issues/4783.

  • rendering/GridTrackSizingAlgorithm.cpp:

(WebCore::GridTrackSizingAlgorithm::initialGrowthLimit const):
(WebCore::GridTrackSizingAlgorithm::spanningItemCrossesFlexibleSizedTracks const):
(WebCore::GridTrackSizingAlgorithm::increaseSizesToAccommodateSpanningItems):
(WebCore::getSizeDistributionWeight):
(WebCore::distributeItemIncurredIncreaseToTrack):
(WebCore::distributeItemIncurredIncreases):
(WebCore::GridTrackSizingAlgorithm::distributeSpaceToTracks const):
(WebCore::GridTrackSizingAlgorithmStrategy::minSizeForChild const):
(WebCore::GridTrackSizingAlgorithm::resolveIntrinsicTrackSizes):

  • rendering/GridTrackSizingAlgorithm.h:

(WebCore::GridTrackSizingAlgorithmStrategy::distributeSpaceToTracks const):

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r283438 r283439  
     12021-10-02  Ziran Sun  <zsun@igalia.com>
     2
     3        [css-grid] Accommodate spanning items crossing flexible tracks
     4        https://bugs.webkit.org/show_bug.cgi?id=230252
     5
     6        Reviewed by Sergio Villar Senin.
     7
     8        Three tests are passing and the test expectation files are updated.
     9
     10        * web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt:
     11        * web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt:
     12        * web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-003-expected.txt:
     13
    1142021-10-02  Youenn Fablet  <youenn@apple.com>
    215
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt

    r279269 r283439  
    88PASS 'grid' with: grid-template-columns: minmax(0, 2fr); and grid-template-rows: minmax(0, 2fr);
    99PASS 'grid' with: grid-template-columns: minmax(75px, 1fr); and grid-template-rows: minmax(75px, 1fr);
    10 FAIL 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 50px"]
    11 FAIL 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["0px 100px"]
    12 FAIL 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
    13 FAIL 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr; assert_in_array: gridTemplateColumns value "25px 25px" not in array ["50px 50px"]
    14 FAIL 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr; assert_in_array: gridTemplateColumns value "12.5px 37.5px" not in array ["25px 75px"]
    15 FAIL 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 0px 50px" not in array ["50px 50px 0px"]
     10PASS 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr;
     11PASS 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr;
     12PASS 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr;
     13PASS 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr;
     14PASS 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr;
     15PASS 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr;
    1616PASS 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 0fr);
    1717PASS 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 1fr);
     
    1919PASS 'grid' with: grid-template-columns: minmax(20px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(20px, 1fr) minmax(0, 1fr);
    2020PASS 'grid' with: grid-template-columns: minmax(30px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(30px, 1fr) minmax(0, 1fr);
    21 FAIL 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr); assert_in_array: gridTemplateColumns value "0px 0px" not in array ["100px 0px"]
    22 FAIL 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
    23 FAIL 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["100px 0px"]
    24 FAIL 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["75px 25px"]
    25 FAIL 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
    26 FAIL 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
    27 FAIL 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
     21PASS 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr);
     22PASS 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr);
     23PASS 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr);
     24PASS 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr);
     25PASS 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto;
     26PASS 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto;
     27PASS 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content;
    2828PASS 'grid' with: grid-template-columns: minmax(0, 0fr) auto; and grid-template-rows: minmax(0, 0fr) auto;
    2929PASS 'grid' with: grid-template-columns: minmax(0, 1fr) auto; and grid-template-rows: minmax(0, 1fr) auto;
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt

    r279269 r283439  
    11
    2 FAIL 'grid' with: grid-template-columns: 1fr auto auto auto; and grid-template-rows: 1fr auto auto auto; assert_in_array: gridTemplateColumns value "0px 50px 50px 50px" not in array ["10px 50px 50px 50px"]
     2PASS 'grid' with: grid-template-columns: 1fr auto auto auto; and grid-template-rows: 1fr auto auto auto;
    33PASS 'grid' with: grid-template-columns: minmax(0, 1fr) auto auto auto; and grid-template-rows: minmax(0, 1fr) auto auto auto;
    4 FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr 1fr; assert_in_array: gridTemplateColumns value "12.5px 12.5px 12.5px 12.5px" not in array ["30px 50px 50px 50px"]
    5 FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr 4fr; and grid-template-rows: 1fr 1fr 1fr 4fr; assert_in_array: gridTemplateColumns value "7.140625px 7.140625px 7.140625px 28.5625px" not in array ["30px 30px 25px 100px"]
    6 FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr; assert_in_array: gridTemplateColumns value "60px 0px 0px" not in array ["60px 50px 50px"]
     4PASS 'grid' with: grid-template-columns: 1fr 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr 1fr;
     5PASS 'grid' with: grid-template-columns: 1fr 1fr 1fr 4fr; and grid-template-rows: 1fr 1fr 1fr 4fr;
     6PASS 'grid' with: grid-template-columns: 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr;
    77
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-003-expected.txt

    r267650 r283439  
    4242PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 2fr); and grid-template-rows: minmax(0, 2fr);
    4343PASS min-content min item 'grid' with: grid-template-columns: minmax(75px, 1fr); and grid-template-rows: minmax(75px, 1fr);
    44 FAIL min-content min item 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 50px"]
    45 FAIL min-content min item 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 60px" not in array ["0px 100px"]
    46 FAIL min-content min item 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr; assert_in_array: gridTemplateColumns value "60px 0px" not in array ["100px 0px"]
    47 FAIL min-content min item 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr; assert_in_array: gridTemplateColumns value "30px 30px" not in array ["50px 50px"]
    48 FAIL min-content min item 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr; assert_in_array: gridTemplateColumns value "15px 45px" not in array ["25px 75px"]
    49 FAIL min-content min item 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 0px 60px" not in array ["50px 50px 0px"]
     44PASS min-content min item 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr;
     45PASS min-content min item 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr;
     46PASS min-content min item 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr;
     47PASS min-content min item 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr;
     48PASS min-content min item 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr;
     49PASS min-content min item 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr;
    5050PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 0fr);
    5151PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 1fr);
     
    5353PASS min-content min item 'grid' with: grid-template-columns: minmax(20px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(20px, 1fr) minmax(0, 1fr);
    5454PASS min-content min item 'grid' with: grid-template-columns: minmax(40px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(40px, 1fr) minmax(0, 1fr);
    55 FAIL min-content min item 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr); assert_in_array: gridTemplateColumns value "0px 0px" not in array ["100px 0px"]
    56 FAIL min-content min item 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "0px 60px" not in array ["100px 0px"]
    57 FAIL min-content min item 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "30px 30px" not in array ["100px 0px"]
    58 FAIL min-content min item 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr); assert_in_array: gridTemplateColumns value "30px 30px" not in array ["75px 25px"]
    59 FAIL min-content min item 'grid' with: grid-template-columns: 0fr min-content; and grid-template-rows: 0fr min-content; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["100px 0px"]
    60 FAIL min-content min item 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto; assert_in_array: gridTemplateColumns value "0px 60px" not in array ["100px 0px"]
    61 FAIL min-content min item 'grid' with: grid-template-columns: 0.5fr auto; and grid-template-rows: 0.5fr auto; assert_in_array: gridTemplateColumns value "30px 30px" not in array ["100px 0px"]
    62 FAIL min-content min item 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto; assert_in_array: gridTemplateColumns value "60px 0px" not in array ["100px 0px"]
    63 FAIL min-content min item 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content; assert_in_array: gridTemplateColumns value "60px 0px" not in array ["100px 0px"]
    64 FAIL min-content min item 'grid' with: grid-template-columns: 1fr min-content; and grid-template-rows: 1fr min-content; assert_in_array: gridTemplateColumns value "60px 0px" not in array ["100px 0px"]
     55PASS min-content min item 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr);
     56PASS min-content min item 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr);
     57PASS min-content min item 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr);
     58PASS min-content min item 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr);
     59PASS min-content min item 'grid' with: grid-template-columns: 0fr min-content; and grid-template-rows: 0fr min-content;
     60PASS min-content min item 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto;
     61PASS min-content min item 'grid' with: grid-template-columns: 0.5fr auto; and grid-template-rows: 0.5fr auto;
     62PASS min-content min item 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto;
     63PASS min-content min item 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content;
     64PASS min-content min item 'grid' with: grid-template-columns: 1fr min-content; and grid-template-rows: 1fr min-content;
    6565PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 0fr) min-content; and grid-template-rows: minmax(0, 0fr) min-content;
    6666PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 0fr) auto; and grid-template-rows: minmax(0, 0fr) auto;
     
    7676PASS 50px min item 'grid' with: grid-template-columns: minmax(0, 2fr); and grid-template-rows: minmax(0, 2fr);
    7777PASS 50px min item 'grid' with: grid-template-columns: minmax(75px, 1fr); and grid-template-rows: minmax(75px, 1fr);
    78 FAIL 50px min item 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["25px 25px"]
     78PASS 50px min item 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr;
    7979PASS 50px min item 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr;
    8080PASS 50px min item 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr;
    8181PASS 50px min item 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr;
    8282PASS 50px min item 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr;
    83 FAIL 50px min item 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 0px 60px" not in array ["25px 25px 10px"]
     83PASS 50px min item 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr;
    8484PASS 50px min item 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 0fr);
    8585PASS 50px min item 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 1fr);
     
    8787PASS 50px min item 'grid' with: grid-template-columns: minmax(20px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(20px, 1fr) minmax(0, 1fr);
    8888PASS 50px min item 'grid' with: grid-template-columns: minmax(40px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(40px, 1fr) minmax(0, 1fr);
    89 FAIL 50px min item 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr); assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 0px"]
    90 FAIL 50px min item 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "0px 60px" not in array ["50px 10px"]
    91 FAIL 50px min item 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "30px 30px" not in array ["50px 10px"]
     89PASS 50px min item 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr);
     90PASS 50px min item 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr);
     91PASS 50px min item 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr);
    9292PASS 50px min item 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr);
    93 FAIL 50px min item 'grid' with: grid-template-columns: 0fr min-content; and grid-template-rows: 0fr min-content; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 0px"]
    94 FAIL 50px min item 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto; assert_in_array: gridTemplateColumns value "0px 60px" not in array ["50px 10px"]
    95 FAIL 50px min item 'grid' with: grid-template-columns: 0.5fr auto; and grid-template-rows: 0.5fr auto; assert_in_array: gridTemplateColumns value "30px 30px" not in array ["50px 10px"]
     93PASS 50px min item 'grid' with: grid-template-columns: 0fr min-content; and grid-template-rows: 0fr min-content;
     94PASS 50px min item 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto;
     95PASS 50px min item 'grid' with: grid-template-columns: 0.5fr auto; and grid-template-rows: 0.5fr auto;
    9696PASS 50px min item 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto;
    9797PASS 50px min item 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content;
  • trunk/Source/WebCore/ChangeLog

    r283438 r283439  
     12021-10-02  Ziran Sun  <zsun@igalia.com>
     2
     3        [css-grid] Accommodate spanning items crossing flexible tracks
     4        https://bugs.webkit.org/show_bug.cgi?id=230252
     5
     6        Reviewed by Sergio Villar Senin.
     7
     8        CSS spec has added one more step at https://drafts.csswg.org/css-grid/#algo-spanning-flex-items
     9        for resolving intrinsic track sizes. Basically, increasing sizes to accommodate spanning items
     10        crossing flexible tracks instead of ignoring their contents completely.
     11
     12        This patch is an import of obrufau's work in chromium. Initial CL is at
     13        https://chromium-review.googlesource.com/c/chromium/src/+/1492337/16..20.
     14        The performance issue caused by the patch were fixed at https://bugs.webkit.org/show_bug.cgi?id=207852
     15        for webkit and https://bugs.chromium.org/p/chromium/issues/detail?id=1021929 for chromium.
     16        This change also addresses web compat issue raised at https://github.com/w3c/csswg-drafts/issues/4783.       
     17
     18        * rendering/GridTrackSizingAlgorithm.cpp:
     19        (WebCore::GridTrackSizingAlgorithm::initialGrowthLimit const):
     20        (WebCore::GridTrackSizingAlgorithm::spanningItemCrossesFlexibleSizedTracks const):
     21        (WebCore::GridTrackSizingAlgorithm::increaseSizesToAccommodateSpanningItems):
     22        (WebCore::getSizeDistributionWeight):
     23        (WebCore::distributeItemIncurredIncreaseToTrack):
     24        (WebCore::distributeItemIncurredIncreases):
     25        (WebCore::GridTrackSizingAlgorithm::distributeSpaceToTracks const):
     26        (WebCore::GridTrackSizingAlgorithmStrategy::minSizeForChild const):
     27        (WebCore::GridTrackSizingAlgorithm::resolveIntrinsicTrackSizes):
     28        * rendering/GridTrackSizingAlgorithm.h:
     29        (WebCore::GridTrackSizingAlgorithmStrategy::distributeSpaceToTracks const):
     30
    1312021-10-02  Youenn Fablet  <youenn@apple.com>
    232
  • trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp

    r282801 r283439  
    228228    const GridLength& gridLength = trackSize.maxTrackBreadth();
    229229    if (gridLength.isFlex())
    230         return baseSize;
     230        return trackSize.minTrackBreadth().isContentSized() ? LayoutUnit(infinity) : baseSize;
    231231
    232232    const Length& trackLength = gridLength.length();
     
    266266    for (auto trackPosition : itemSpan) {
    267267        const auto& trackSize = trackList[trackPosition].cachedTrackSize();
    268         if (trackSize.maxTrackBreadth().isFlex())
     268        if (trackSize.minTrackBreadth().isFlex() || trackSize.maxTrackBreadth().isFlex())
    269269            return true;
    270270    }
     
    423423}
    424424
    425 template <TrackSizeComputationPhase phase>
     425template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase>
    426426void GridTrackSizingAlgorithm::increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan)
    427427{
     
    436436    for (auto it = gridItemsWithSpan.rangeStart; it != gridItemsWithSpan.rangeEnd; ++it) {
    437437        GridItemWithSpan& gridItemWithSpan = *it;
    438         ASSERT(gridItemWithSpan.span().integerSpan() > 1);
    439438        const GridSpan& itemSpan = gridItemWithSpan.span();
     439        ASSERT(variant == TrackSizeComputationVariant::CrossingFlexibleTracks || itemSpan.integerSpan() > 1u);
    440440
    441441        filteredTracks.shrink(0);
     
    446446            const auto& trackSize = track.cachedTrackSize();
    447447            spanningTracksSize += trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity);
     448            if (variant == TrackSizeComputationVariant::CrossingFlexibleTracks && !trackSize.maxTrackBreadth().isFlex())
     449                continue;
    448450            if (!shouldProcessTrackForTrackSizeComputationPhase(phase, trackSize))
    449451                continue;
     
    463465        extraSpace = std::max<LayoutUnit>(extraSpace, 0);
    464466        auto& tracksToGrowBeyondGrowthLimits = growBeyondGrowthLimitsTracks.isEmpty() ? filteredTracks : growBeyondGrowthLimitsTracks;
    465         distributeSpaceToTracks<phase>(filteredTracks, &tracksToGrowBeyondGrowthLimits, extraSpace);
     467        distributeSpaceToTracks<variant, phase>(filteredTracks, &tracksToGrowBeyondGrowthLimits, extraSpace);
    466468    }
    467469
     
    473475}
    474476
     477template <TrackSizeComputationVariant variant>
     478void GridTrackSizingAlgorithm::increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan)
     479{
     480    increaseSizesToAccommodateSpanningItems<variant, ResolveIntrinsicMinimums>(gridItemsWithSpan);
     481    increaseSizesToAccommodateSpanningItems<variant, ResolveContentBasedMinimums>(gridItemsWithSpan);
     482    increaseSizesToAccommodateSpanningItems<variant, ResolveMaxContentMinimums>(gridItemsWithSpan);
     483    increaseSizesToAccommodateSpanningItems<variant, ResolveIntrinsicMaximums>(gridItemsWithSpan);
     484    increaseSizesToAccommodateSpanningItems<variant, ResolveMaxContentMaximums>(gridItemsWithSpan);
     485}
     486
     487template <TrackSizeComputationVariant variant>
     488static double getSizeDistributionWeight(const GridTrack& track)
     489{
     490    if (variant != TrackSizeComputationVariant::CrossingFlexibleTracks)
     491        return 0;
     492    ASSERT(track.cachedTrackSize().maxTrackBreadth().isFlex());
     493    return track.cachedTrackSize().maxTrackBreadth().flex();
     494}
     495
    475496static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTrack* track2)
    476497{
     
    503524}
    504525
    505 template <TrackSizeComputationPhase phase>
     526template <TrackSizeComputationPhase phase, SpaceDistributionLimit limit>
     527static void distributeItemIncurredIncreaseToTrack(GridTrack& track, LayoutUnit& freeSpace, double shareFraction)
     528{
     529    LayoutUnit freeSpaceShare(freeSpace / shareFraction);
     530    LayoutUnit growthShare = limit == SpaceDistributionLimit::BeyondGrowthLimit || track.infiniteGrowthPotential() ? freeSpaceShare : std::min(freeSpaceShare, track.growthLimit() - trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity));
     531    clampGrowthShareIfNeeded(phase, track, growthShare);
     532    ASSERT_WITH_MESSAGE(growthShare >= 0, "We must never shrink any grid track or else we can't guarantee we abide by our min-sizing function.");
     533    track.growTempSize(growthShare);
     534    freeSpace -= growthShare;
     535}
     536
     537template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase, SpaceDistributionLimit limit>
     538static void distributeItemIncurredIncreases(Vector<GridTrack*>& tracks, LayoutUnit& freeSpace)
     539{
     540    uint32_t tracksSize = tracks.size();
     541    if (!tracksSize)
     542        return;
     543    if (variant == TrackSizeComputationVariant::NotCrossingFlexibleTracks) {
     544        // We have to sort tracks according to their growth potential. This is necessary even when distributing beyond growth limits,
     545        // because there might be tracks with growth limit caps (like the ones with fit-content()) which cannot indefinitely grow over the limits.
     546        std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
     547        for (uint32_t i = 0; i < tracksSize; ++i) {
     548            ASSERT(!getSizeDistributionWeight<variant>(*tracks[i]));
     549            distributeItemIncurredIncreaseToTrack<phase, limit>(*tracks[i], freeSpace, tracksSize - i);
     550        }
     551        return;
     552    }
     553    // We never grow flex tracks beyond growth limits, since they are infinite.
     554    ASSERT(limit != SpaceDistributionLimit::BeyondGrowthLimit);
     555    // For TrackSizeComputationVariant::CrossingFlexibleTracks we don't distribute equally, we need to take the weights into account.
     556    Vector<double> fractionsOfRemainingSpace(tracksSize);
     557    double weightSum = 0;
     558    for (int32_t i = tracksSize - 1; i >= 0; --i) {
     559        double weight = getSizeDistributionWeight<variant>(*tracks[i]);
     560        weightSum += weight;
     561        fractionsOfRemainingSpace[i] = weightSum > 0 ? weightSum / weight : tracksSize - i;
     562    }
     563    for (uint32_t i = 0; i < tracksSize; ++i) {
     564        // Sorting is not needed for TrackSizeComputationVariant::CrossingFlexibleTracks, since all tracks have an infinite growth potential.
     565        ASSERT(tracks[i]->growthLimitIsInfinite()); 
     566        distributeItemIncurredIncreaseToTrack<phase, limit>(*tracks[i], freeSpace, fractionsOfRemainingSpace[i]);
     567    }
     568}
     569
     570template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase>
    506571void GridTrackSizingAlgorithm::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* growBeyondGrowthLimitsTracks, LayoutUnit& freeSpace) const
    507572{
     
    511576        track->setTempSize(trackSizeForTrackSizeComputationPhase(phase, *track, ForbidInfinity));
    512577
    513     if (freeSpace > 0) {
    514         std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
    515 
    516         unsigned tracksSize = tracks.size();
    517         for (unsigned i = 0; i < tracksSize; ++i) {
    518             GridTrack& track = *tracks[i];
    519             const LayoutUnit& trackBreadth = trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity);
    520             bool infiniteGrowthPotential = track.infiniteGrowthPotential();
    521             LayoutUnit trackGrowthPotential = infiniteGrowthPotential ? track.growthLimit() : track.growthLimit() - trackBreadth;
    522             // Let's avoid computing availableLogicalSpaceShare as much as possible as it's a hot spot in performance tests.
    523             if (trackGrowthPotential > 0 || infiniteGrowthPotential) {
    524                 LayoutUnit availableLogicalSpaceShare = freeSpace / (tracksSize - i);
    525                 LayoutUnit growthShare = infiniteGrowthPotential ? availableLogicalSpaceShare : std::min(availableLogicalSpaceShare, trackGrowthPotential);
    526                 clampGrowthShareIfNeeded(phase, track, growthShare);
    527                 ASSERT_WITH_MESSAGE(growthShare >= 0, "We should never shrink any grid track or else we can't guarantee we abide by our min-sizing function. We can still have 0 as growthShare if the amount of tracks greatly exceeds the freeSpace.");
    528                 track.growTempSize(growthShare);
    529                 freeSpace -= growthShare;
    530             }
    531         }
    532     }
    533 
    534     if (freeSpace > 0 && growBeyondGrowthLimitsTracks) {
    535         // We need to sort them because there might be tracks with growth limit caps (like the ones
    536         // with fit-content()) which cannot indefinitely grow over the limits.
    537         if (phase == ResolveMaxContentMaximums)
    538             std::sort(growBeyondGrowthLimitsTracks->begin(), growBeyondGrowthLimitsTracks->end(), sortByGridTrackGrowthPotential);
    539 
    540         unsigned tracksGrowingBeyondGrowthLimitsSize = growBeyondGrowthLimitsTracks->size();
    541         for (unsigned i = 0; i < tracksGrowingBeyondGrowthLimitsSize; ++i) {
    542             GridTrack* track = growBeyondGrowthLimitsTracks->at(i);
    543             LayoutUnit growthShare = freeSpace / (tracksGrowingBeyondGrowthLimitsSize - i);
    544             clampGrowthShareIfNeeded(phase, *track, growthShare);
    545             track->growTempSize(growthShare);
    546             freeSpace -= growthShare;
    547         }
    548     }
    549 
     578    if (freeSpace > 0)
     579        distributeItemIncurredIncreases<variant, phase, SpaceDistributionLimit::UpToGrowthLimit>(tracks, freeSpace);
     580
     581    if (freeSpace > 0 && growBeyondGrowthLimitsTracks)
     582        distributeItemIncurredIncreases<variant, phase, SpaceDistributionLimit::BeyondGrowthLimit>(*growBeyondGrowthLimitsTracks, freeSpace);
     583   
    550584    for (auto* track : tracks)
    551585        track->setPlannedSize(track->plannedSize() == infinity ? track->tempSize() : std::max(track->plannedSize(), track->tempSize()));
     
    811845    if (childMinSize.isAuto() && overflowIsVisible) {
    812846        auto minSize = minContentForChild(child);
     847        const GridSpan& span = m_algorithm.grid().gridItemSpan(child, direction());
     848
    813849        LayoutUnit maxBreadth;
    814850        auto allTracks = m_algorithm.tracks(direction());
    815         for (auto trackPosition : m_algorithm.grid().gridItemSpan(child, direction())) {
     851        bool allFixed = true;
     852        for (auto trackPosition : span) {
    816853            const auto& trackSize = allTracks[trackPosition].cachedTrackSize();
     854            if (trackSize.maxTrackBreadth().isFlex() && span.integerSpan() > 1)
     855                return { };
    817856            if (!trackSize.hasFixedMaxTrackBreadth())
    818                 return minSize;
    819             maxBreadth += valueForLength(trackSize.maxTrackBreadth().length(), availableSpace().value_or(0_lu));
     857                allFixed = false;
     858            else if (allFixed)
     859                maxBreadth += valueForLength(trackSize.maxTrackBreadth().length(), availableSpace().value_or(0_lu));
    820860        }
     861        if (!allFixed)
     862            return minSize;
    821863        if (minSize > maxBreadth) {
    822864            auto marginAndBorderAndPadding = GridLayoutFunctions::marginLogicalSizeForChild(*renderGrid(), direction(), child);
     
    11641206
    11651207    Vector<GridItemWithSpan> itemsSortedByIncreasingSpan;
     1208    Vector<GridItemWithSpan> itemsCrossingFlexibleTracks;
    11661209    HashSet<RenderBox*> itemsSet;
    11671210    if (m_grid.hasGridItems()) {
     
    11731216                if (itemsSet.add(gridItem).isNewEntry) {
    11741217                    const GridSpan& span = m_grid.gridItemSpan(*gridItem, m_direction);
    1175                     if (span.integerSpan() == 1)
     1218                    if (spanningItemCrossesFlexibleSizedTracks(span))
     1219                        itemsCrossingFlexibleTracks.append(GridItemWithSpan(*gridItem, span));
     1220                    else if (span.integerSpan() == 1)
    11761221                        sizeTrackToFitNonSpanningItem(span, *gridItem, track);
    1177                     else if (!spanningItemCrossesFlexibleSizedTracks(span))
     1222                    else
    11781223                        itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, span));
    11791224                }
     
    11871232    while (it != end) {
    11881233        GridItemsSpanGroupRange spanGroupRange = { it, std::upper_bound(it, end, *it) };
    1189         increaseSizesToAccommodateSpanningItems<ResolveIntrinsicMinimums>(spanGroupRange);
    1190         increaseSizesToAccommodateSpanningItems<ResolveContentBasedMinimums>(spanGroupRange);
    1191         increaseSizesToAccommodateSpanningItems<ResolveMaxContentMinimums>(spanGroupRange);
    1192         increaseSizesToAccommodateSpanningItems<ResolveIntrinsicMaximums>(spanGroupRange);
    1193         increaseSizesToAccommodateSpanningItems<ResolveMaxContentMaximums>(spanGroupRange);
     1234        increaseSizesToAccommodateSpanningItems<TrackSizeComputationVariant::NotCrossingFlexibleTracks>(spanGroupRange);
    11941235        it = spanGroupRange.rangeEnd;
    11951236    }
     1237    GridItemsSpanGroupRange tracksGroupRange = { itemsCrossingFlexibleTracks.begin(), itemsCrossingFlexibleTracks.end() };
     1238    increaseSizesToAccommodateSpanningItems<TrackSizeComputationVariant::CrossingFlexibleTracks>(tracksGroupRange);
    11961239    handleInfinityGrowthLimit();
    11971240}
  • trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h

    r278253 r283439  
    3636enum SizingOperation { TrackSizing, IntrinsicSizeComputation };
    3737
     38enum class TrackSizeComputationVariant : uint8_t {
     39    NotCrossingFlexibleTracks,
     40    CrossingFlexibleTracks,
     41};
     42
    3843enum TrackSizeComputationPhase {
    3944    ResolveIntrinsicMinimums,
     
    4550};
    4651
     52enum class SpaceDistributionLimit : uint8_t  {
     53    UpToGrowthLimit,
     54    BeyondGrowthLimit,
     55};
     56
    4757class GridTrackSizingAlgorithmStrategy;
    4858
     
    153163    bool spanningItemCrossesFlexibleSizedTracks(const GridSpan&) const;
    154164    typedef struct GridItemsSpanGroupRange GridItemsSpanGroupRange;
    155     template <TrackSizeComputationPhase phase> void increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan);
     165    template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase> void increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan);
     166    template <TrackSizeComputationVariant variant> void increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan);
    156167    LayoutUnit itemSizeForTrackSizeComputationPhase(TrackSizeComputationPhase, RenderBox&) const;
    157     template <TrackSizeComputationPhase phase> void distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* growBeyondGrowthLimitsTracks, LayoutUnit& availableLogicalSpace) const;
     168    template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase> void distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* growBeyondGrowthLimitsTracks, LayoutUnit& freeSpace) const;
     169
    158170    std::optional<LayoutUnit> gridAreaBreadthForChild(const RenderBox&, GridTrackSizingDirection) const;
    159171
     
    275287    GridTrackSizingDirection direction() const { return m_algorithm.m_direction; }
    276288    double findFrUnitSize(const GridSpan& tracksSpan, LayoutUnit leftOverSpace) const { return m_algorithm.findFrUnitSize(tracksSpan, leftOverSpace); }
    277     void distributeSpaceToTracks(Vector<GridTrack*>& tracks, LayoutUnit& availableLogicalSpace) const { m_algorithm.distributeSpaceToTracks<MaximizeTracks>(tracks, nullptr, availableLogicalSpace); }
     289    void distributeSpaceToTracks(Vector<GridTrack*>& tracks, LayoutUnit& availableLogicalSpace) const { m_algorithm.distributeSpaceToTracks<TrackSizeComputationVariant::NotCrossingFlexibleTracks, MaximizeTracks>(tracks, nullptr, availableLogicalSpace); }
    278290    const RenderGrid* renderGrid() const { return m_algorithm.m_renderGrid; }
    279291    std::optional<LayoutUnit> availableSpace() const { return m_algorithm.availableSpace(); }
Note: See TracChangeset for help on using the changeset viewer.