[GridNG] Opposite direction auto track subgrid fixes
This CL fixes several issues with opposite-direction nested subgrids in
auto-sized tracks. First, the `last_indefinite_index` array needs to be
reversed. We can't simply reverse the array, since it's an array of
prior indices that need to span the subgrid's index range. We also can't
simply offset the values, as this will be incorrect in reversed
scenarios, due to their stateful nature.
Ethan suggested a clever idea, which is to rebuild the array by looking
at when the parent array changed in subsequent values, as that's how
it's originally built up.
The second issue this fixes is that the extra margin for contribution
sizes needs to swap the start and end offsets for opposite directions.
A new test was added that's a variation of
`writing-directions-001.html` but with auto track sizes.
Bug: 618969
Change-Id: I495daa34e3c0c0cadd5f25d7a9212641c05bb81d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4506078
Commit-Queue: Kurt Catti-Schmidt <kschmi@microsoft.com>
Reviewed-by: Alison Maher <almaher@microsoft.com>
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: Ethan Jimenez <ethavar@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1146118}
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
index 73deef85..370223c 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
@@ -2592,8 +2592,13 @@
? subgrid_layout_data.Columns()
: subgrid_layout_data.Rows();
- AccomodateSubgridExtraMargins(subgrid_track_collection.StartExtraMargin(),
- subgrid_track_collection.EndExtraMargin(),
+ auto start_extra_margin = subgrid_track_collection.StartExtraMargin();
+ auto end_extra_margin = subgrid_track_collection.EndExtraMargin();
+ if (grid_item.IsOppositeDirectionInRootGrid(track_direction)) {
+ std::swap(start_extra_margin, end_extra_margin);
+ }
+
+ AccomodateSubgridExtraMargins(start_extra_margin, end_extra_margin,
grid_item.SetIndices(track_direction),
&track_collection);
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc
index 505054c5..898b2ba 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc
@@ -767,17 +767,29 @@
subgrid_last_indefinite_index.ReserveInitialCapacity(set_span_size + 1);
subgrid_last_indefinite_index.push_back(kNotFound);
- for (wtf_size_t i = begin_set_index + 1; i <= end_set_index; ++i) {
- subgrid_last_indefinite_index.push_back(
- (last_indefinite_index_[i] == kNotFound ||
- last_indefinite_index_[i] < begin_set_index)
- ? kNotFound
- : last_indefinite_index_[i] - begin_set_index);
- }
+ wtf_size_t last_indefinite_index = kNotFound;
+ for (wtf_size_t i = 1; i <= set_span_size; ++i) {
+ // Opposite direction subgrids need to iterate backwards.
+ const wtf_size_t current_index = is_opposite_direction_in_root_grid
+ ? end_set_index - i
+ : begin_set_index + i;
+ const wtf_size_t next_index = is_opposite_direction_in_root_grid
+ ? current_index - 1
+ : current_index + 1;
- // TODO(kschmi): Handle `subgrid_last_indefinite_index` when
- // `is_opposite_direction_to_parent`. This can be done by looking at the
- // difference between subsequent entries.
+ if (last_indefinite_index_[current_index] == kNotFound ||
+ next_index == last_indefinite_index_.size()) {
+ subgrid_last_indefinite_index.push_back(kNotFound);
+ } else {
+ // Map the last indefinite index from the parent track collection by
+ // looking for a change in subsequent entries.
+ if (last_indefinite_index_[current_index] !=
+ last_indefinite_index_[next_index]) {
+ last_indefinite_index = i;
+ }
+ subgrid_last_indefinite_index.push_back(last_indefinite_index);
+ }
+ }
}
// Copy the major and minor baselines in the subgrid's span.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/writing-directions-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/writing-directions-002-ref.html
new file mode 100644
index 0000000..cd1ee52
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/writing-directions-002-ref.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML>
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference: nested subgrids map margin/border/padding according to writing direction</title>
+ <link rel="author" title="Kurt Catti-Schmidt" href="mailto:kschmi@microsoft.com">
+ <link rel="help" href="https://drafts.csswg.org/css-grid-2">
+ <style>
+html,body {
+ font:12px/1 monospace;
+}
+
+.grid {
+ display: grid;
+ grid: 0.2em 1.4em / repeat(10, auto);
+ border: 1px solid;
+ padding: 0 0 0 0;
+}
+
+div > div {
+ display: grid;
+ grid-column: 1 / span 3;
+ grid: auto / subgrid;
+ border: 1px solid;
+ background: grey;
+}
+
+n {
+ grid-row: 1;
+ counter-increment: n;
+}
+n::before { content: counter(n, decimal); }
+
+x {
+ background: silver;
+}
+
+ </style>
+</head>
+<body>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div style="grid-template-columns: subgrid; padding: 0 0 0 10px;">
+ <div style="grid-template-columns: subgrid; grid-column: 1 /span 3;">
+ <x style="grid-column: 1; ">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div style="grid-template-columns: subgrid;">
+ <div style="grid-template-columns: subgrid; grid-column: 1 /span 3; padding-left: 10px;">
+ <x style="grid-column: 1; ">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div style="grid-template-columns: subgrid; border-right: 20px solid; border-left: 10px solid;">
+ <div style="grid-template-columns: subgrid; grid-column-start:span 3;">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div style="grid-template-columns: subgrid;">
+ <div style="grid-template-columns: subgrid; grid-column-start:span 3; border-right: 20px solid; border-left: 10px solid;">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div style="grid-template-columns: subgrid; margin: 0 20px 0 0;">
+ <div style="grid-template-columns: subgrid; grid-column-start:span 3;">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div style="grid-template-columns: subgrid;">
+ <div style="grid-template-columns: subgrid; grid-column-start:span 3; margin: 0 20px 0 0;">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/writing-directions-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/writing-directions-002.html
new file mode 100644
index 0000000..078d580
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/writing-directions-002.html
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML>
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Test: nested subgrids map margin/border/padding according to writing direction</title>
+ <link rel="author" title="Kurt Catti-Schmidt" href="mailto:kschmi@microsoft.com">
+ <link rel="help" href="https://drafts.csswg.org/css-grid-2">
+ <link rel="match" href="writing-directions-002-ref.html">
+ <style>
+html,body {
+ font:12px/1 monospace;
+}
+
+.grid {
+ display: grid;
+ grid: 0.2em 1.4em / repeat(10, auto);
+ border: 1px solid;
+ padding: 0 0 0 0;
+}
+
+div > div {
+ display: grid;
+ grid-column: 1 / span 3;
+ grid: auto / subgrid;
+ border: 1px solid;
+ background: grey;
+}
+
+n {
+ grid-row: 1;
+ counter-increment: n;
+}
+n::before { content: counter(n, decimal); }
+
+x {
+ background: silver;
+}
+
+.rtl { direction:rtl; }
+.ltr { direction:ltr; }
+
+ </style>
+</head>
+<body>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div class="rtl" style="grid-template-columns: subgrid; padding: 0 0 0 10px;">
+ <div class="ltr" style="grid-template-columns: subgrid;">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div class="rtl" style="grid-template-columns: subgrid; ">
+ <div class="ltr" style="grid-template-columns: subgrid; padding: 0 0 0 10px;">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div class="rtl" style="grid-template-columns: subgrid; border-right: 20px solid; border-left: 10px solid;">
+ <div class="ltr" style="grid-template-columns: subgrid; ">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div class="rtl" style="grid-template-columns: subgrid;">
+ <div class="ltr" style="grid-template-columns: subgrid; border-right: 20px solid; border-left: 10px solid;">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div class="rtl" style="grid-template-columns: subgrid; margin: 0 20px 0 0;">
+ <div class="ltr" style="grid-template-columns: subgrid; ">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+<div class="grid">
+ <n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n><n></n>
+ <div class="rtl" style="grid-template-columns: subgrid;">
+ <div class="ltr" style="grid-template-columns: subgrid; margin: 0 20px 0 0;">
+ <x style="grid-column: 1;">x</x>
+ </div>
+ </div>
+</div>
+
+</body>
+</html>