Commit c0b42a3e authored by Morten Stenshorne's avatar Morten Stenshorne Committed by Commit Bot

[LayoutNG] Support column-span:all margins.

Collapse block margins between sibling spanners and add inline margins,
including auto margins.

We now position spanners correctly.

Bug: 829028
Change-Id: I07b5c1af92852d385cf558db6c20de61e88d87d1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1860419
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#706114}
parent b191d198
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h" #include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_fragment_geometry.h" #include "third_party/blink/renderer/core/layout/ng/geometry/ng_fragment_geometry.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
...@@ -212,6 +213,8 @@ base::Optional<MinMaxSize> NGColumnLayoutAlgorithm::ComputeMinMaxSize( ...@@ -212,6 +213,8 @@ base::Optional<MinMaxSize> NGColumnLayoutAlgorithm::ComputeMinMaxSize(
} }
void NGColumnLayoutAlgorithm::LayoutChildren() { void NGColumnLayoutAlgorithm::LayoutChildren() {
NGMarginStrut margin_strut;
// First extract incoming child break tokens. // First extract incoming child break tokens.
scoped_refptr<const NGBlockBreakToken> spanner_break_token; scoped_refptr<const NGBlockBreakToken> spanner_break_token;
scoped_refptr<const NGBlockBreakToken> next_column_token; scoped_refptr<const NGBlockBreakToken> next_column_token;
...@@ -257,7 +260,7 @@ void NGColumnLayoutAlgorithm::LayoutChildren() { ...@@ -257,7 +260,7 @@ void NGColumnLayoutAlgorithm::LayoutChildren() {
// resume now. // resume now.
spanner_break_token = spanner_break_token =
LayoutSpanner(To<NGBlockNode>(spanner_break_token->InputNode()), LayoutSpanner(To<NGBlockNode>(spanner_break_token->InputNode()),
spanner_break_token.get()); spanner_break_token.get(), &margin_strut);
if (spanner_break_token) { if (spanner_break_token) {
// We broke at the spanner again! // We broke at the spanner again!
...@@ -277,7 +280,7 @@ void NGColumnLayoutAlgorithm::LayoutChildren() { ...@@ -277,7 +280,7 @@ void NGColumnLayoutAlgorithm::LayoutChildren() {
// child is a spanner. // child is a spanner.
do { do {
scoped_refptr<const NGLayoutResult> result = scoped_refptr<const NGLayoutResult> result =
LayoutRow(next_column_token.get()); LayoutRow(next_column_token.get(), &margin_strut);
next_column_token = next_column_token =
To<NGBlockBreakToken>(result->PhysicalFragment().BreakToken()); To<NGBlockBreakToken>(result->PhysicalFragment().BreakToken());
...@@ -289,7 +292,7 @@ void NGColumnLayoutAlgorithm::LayoutChildren() { ...@@ -289,7 +292,7 @@ void NGColumnLayoutAlgorithm::LayoutChildren() {
break; break;
// We found a spanner. Lay it out, and then resume column layout. // We found a spanner. Lay it out, and then resume column layout.
spanner_break_token = LayoutSpanner(spanner_node, nullptr); spanner_break_token = LayoutSpanner(spanner_node, nullptr, &margin_strut);
if (spanner_break_token) { if (spanner_break_token) {
// We broke before or inside the spanner. This may happen if we're nested // We broke before or inside the spanner. This may happen if we're nested
...@@ -312,12 +315,14 @@ void NGColumnLayoutAlgorithm::LayoutChildren() { ...@@ -312,12 +315,14 @@ void NGColumnLayoutAlgorithm::LayoutChildren() {
// context. In that case we must make sure to skip the contents when // context. In that case we must make sure to skip the contents when
// resuming. // resuming.
container_builder_.SetHasSeenAllChildren(); container_builder_.SetHasSeenAllChildren();
intrinsic_block_size_ += margin_strut.Sum();
} }
} }
scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow( scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
const NGBlockBreakToken* next_column_token) { const NGBlockBreakToken* next_column_token,
LayoutUnit column_block_offset = intrinsic_block_size_; NGMarginStrut* margin_strut) {
LogicalSize column_size(column_inline_size_, content_box_size_.block_size); LogicalSize column_size(column_inline_size_, content_box_size_.block_size);
// If block-size is non-auto, subtract the space for content we've consumed in // If block-size is non-auto, subtract the space for content we've consumed in
...@@ -347,6 +352,10 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow( ...@@ -347,6 +352,10 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
CalculateBalancedColumnBlockSize(column_size, next_column_token); CalculateBalancedColumnBlockSize(column_size, next_column_token);
} }
// Column rows have no representation in the DOM and have no margins, but
// there may be a trailing margin from a preceding spanner.
LayoutUnit column_block_offset = intrinsic_block_size_ + margin_strut->Sum();
bool needs_more_fragments_in_outer = false; bool needs_more_fragments_in_outer = false;
if (is_constrained_by_outer_fragmentation_context_) { if (is_constrained_by_outer_fragmentation_context_) {
LayoutUnit available_outer_space = LayoutUnit available_outer_space =
...@@ -502,20 +511,31 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow( ...@@ -502,20 +511,31 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
break; break;
} while (true); } while (true);
bool keep_margin = false;
// If there was no content inside to process, we don't want the resulting // If there was no content inside to process, we don't want the resulting
// empty column fragment. // empty column fragment.
if (new_columns.size() == 1u) { if (new_columns.size() == 1u) {
const NGPhysicalBoxFragment& column = const NGPhysicalBoxFragment& column =
*To<NGPhysicalBoxFragment>(new_columns[0].fragment.get()); *To<NGPhysicalBoxFragment>(new_columns[0].fragment.get());
// TODO(mstensho): Keeping the empty fragment, just so that out-of-flow
// descendants get propagated correctly isn't right. Find some other way of if (column.Children().size() == 0) {
// propagating them. // No content. Keep the trailing margin from any previous column spanner.
if (column.Children().size() == 0 && keep_margin = true;
!column.HasOutOfFlowPositionedDescendants())
return result; // TODO(mstensho): It's wrong to keep the empty fragment, just so that
// out-of-flow descendants get propagated correctly. Find some other way
// of propagating them.
if (!column.HasOutOfFlowPositionedDescendants())
return result;
}
} }
intrinsic_block_size_ += column_size.block_size; intrinsic_block_size_ = column_block_offset + column_size.block_size;
// We added a row. Reset the trailing margin from any previous column spanner.
if (!keep_margin)
*margin_strut = NGMarginStrut();
// Commit all column fragments to the fragment builder. // Commit all column fragments to the fragment builder.
for (auto column : new_columns) { for (auto column : new_columns) {
...@@ -528,12 +548,21 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow( ...@@ -528,12 +548,21 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
scoped_refptr<const NGBlockBreakToken> NGColumnLayoutAlgorithm::LayoutSpanner( scoped_refptr<const NGBlockBreakToken> NGColumnLayoutAlgorithm::LayoutSpanner(
NGBlockNode spanner_node, NGBlockNode spanner_node,
const NGBlockBreakToken* break_token) { const NGBlockBreakToken* break_token,
// TODO(mstensho): Margins (including margin collapsing), inline alignment, NGMarginStrut* margin_strut) {
// and outer fragmentainer breaks between spanners and rows (the spanner may const ComputedStyle& spanner_style = spanner_node.Style();
// be unbreakable inside, and we may be in a nested fragmentation context and NGBoxStrut margins = ComputeMarginsFor(
// out of space). spanner_style, content_box_size_.inline_size,
LayoutUnit block_offset = intrinsic_block_size_; ConstraintSpace().GetWritingMode(), ConstraintSpace().Direction());
// Collapse the block-start margin of this spanner with the block-end margin
// of an immediately preceding spanner, if any.
margin_strut->Append(margins.block_start, /* is_quirky */ false);
// TODO(mstensho): outer fragmentainer breaks between spanners and rows (the
// spanner may be unbreakable inside, and we may be in a nested fragmentation
// context and out of space).
LayoutUnit block_offset = intrinsic_block_size_ + margin_strut->Sum();
auto spanner_space = CreateConstraintSpaceForSpanner(block_offset); auto spanner_space = CreateConstraintSpaceForSpanner(block_offset);
// TODO(mstensho): Passing a break-before token shouldn't be a problem, but it // TODO(mstensho): Passing a break-before token shouldn't be a problem, but it
// would cause problems for the NGPaintFragment code. Just pass nullptr. Won't // would cause problems for the NGPaintFragment code. Just pass nullptr. Won't
...@@ -541,10 +570,20 @@ scoped_refptr<const NGBlockBreakToken> NGColumnLayoutAlgorithm::LayoutSpanner( ...@@ -541,10 +570,20 @@ scoped_refptr<const NGBlockBreakToken> NGColumnLayoutAlgorithm::LayoutSpanner(
if (break_token && break_token->IsBreakBefore()) if (break_token && break_token->IsBreakBefore())
break_token = nullptr; break_token = nullptr;
auto result = spanner_node.Layout(spanner_space, break_token); auto result = spanner_node.Layout(spanner_space, break_token);
LogicalOffset offset(border_scrollbar_padding_.inline_start, NGFragment fragment(ConstraintSpace().GetWritingMode(),
intrinsic_block_size_); result->PhysicalFragment());
ResolveInlineMargins(spanner_style, Style(), content_box_size_.inline_size,
fragment.InlineSize(), &margins);
LogicalOffset offset(
border_scrollbar_padding_.inline_start + margins.inline_start,
block_offset);
container_builder_.AddResult(*result, offset); container_builder_.AddResult(*result, offset);
*margin_strut = NGMarginStrut();
margin_strut->Append(margins.block_end, /* is_quirky */ false);
// TODO(mstensho): The correct thing would be to weigh any break inside // TODO(mstensho): The correct thing would be to weigh any break inside
// against the appeal of breaking before the spanner, like we do in // against the appeal of breaking before the spanner, like we do in
// BreakBeforeChildIfNeeded() for the block layout algorithm. Just setting the // BreakBeforeChildIfNeeded() for the block layout algorithm. Just setting the
...@@ -554,7 +593,6 @@ scoped_refptr<const NGBlockBreakToken> NGColumnLayoutAlgorithm::LayoutSpanner( ...@@ -554,7 +593,6 @@ scoped_refptr<const NGBlockBreakToken> NGColumnLayoutAlgorithm::LayoutSpanner(
if (ConstraintSpace().HasBlockFragmentation()) if (ConstraintSpace().HasBlockFragmentation())
container_builder_.SetBreakAppeal(kBreakAppealPerfect); container_builder_.SetBreakAppeal(kBreakAppealPerfect);
NGFragment fragment(Style().GetWritingMode(), result->PhysicalFragment());
intrinsic_block_size_ = offset.block_offset + fragment.BlockSize(); intrinsic_block_size_ = offset.block_offset + fragment.BlockSize();
return To<NGBlockBreakToken>(result->PhysicalFragment().BreakToken()); return To<NGBlockBreakToken>(result->PhysicalFragment().BreakToken());
......
...@@ -14,6 +14,7 @@ class NGBlockNode; ...@@ -14,6 +14,7 @@ class NGBlockNode;
class NGBlockBreakToken; class NGBlockBreakToken;
class NGConstraintSpace; class NGConstraintSpace;
struct LogicalSize; struct LogicalSize;
struct NGMarginStrut;
class CORE_EXPORT NGColumnLayoutAlgorithm class CORE_EXPORT NGColumnLayoutAlgorithm
: public NGLayoutAlgorithm<NGBlockNode, : public NGLayoutAlgorithm<NGBlockNode,
...@@ -34,14 +35,16 @@ class CORE_EXPORT NGColumnLayoutAlgorithm ...@@ -34,14 +35,16 @@ class CORE_EXPORT NGColumnLayoutAlgorithm
// Lay out one row of columns. The layout result returned is for the last // Lay out one row of columns. The layout result returned is for the last
// column that was laid out. The rows themselves don't create fragments. // column that was laid out. The rows themselves don't create fragments.
scoped_refptr<const NGLayoutResult> LayoutRow( scoped_refptr<const NGLayoutResult> LayoutRow(
const NGBlockBreakToken* next_column_token); const NGBlockBreakToken* next_column_token,
NGMarginStrut*);
// Lay out a column spanner. Will return a break token if we break before or // Lay out a column spanner. Will return a break token if we break before or
// inside the spanner. If no break token is returned, it means that we can // inside the spanner. If no break token is returned, it means that we can
// proceed to the next row of columns. // proceed to the next row of columns.
scoped_refptr<const NGBlockBreakToken> LayoutSpanner( scoped_refptr<const NGBlockBreakToken> LayoutSpanner(
NGBlockNode spanner_node, NGBlockNode spanner_node,
const NGBlockBreakToken* break_token); const NGBlockBreakToken* break_token,
NGMarginStrut*);
LayoutUnit CalculateBalancedColumnBlockSize( LayoutUnit CalculateBalancedColumnBlockSize(
const LogicalSize& column_size, const LogicalSize& column_size,
......
...@@ -4374,6 +4374,77 @@ TEST_F(NGColumnLayoutAlgorithmTest, SpannerInBlockWithSiblings) { ...@@ -4374,6 +4374,77 @@ TEST_F(NGColumnLayoutAlgorithmTest, SpannerInBlockWithSiblings) {
EXPECT_EQ(expectation, dump); EXPECT_EQ(expectation, dump);
} }
TEST_F(NGColumnLayoutAlgorithmTest, SpannerMargins) {
SetBodyInnerHTML(R"HTML(
<style>
#parent {
columns: 3;
column-gap: 10px;
width: 320px;
}
.content { break-inside:avoid; height:20px; }
</style>
<div id="container">
<div id="parent">
<div style="column-span:all; margin:10px; width:33px; height:10px;"></div>
<div class="content"></div>
<div style="column-span:all; margin:10px auto; width:44px; height:10px;"></div>
<div style="column-span:all; margin:20px; width:55px;"></div>
<div style="column-span:all; margin:10px; width:66px; height:10px;"></div>
</div>
</div>
)HTML");
String dump = DumpFragmentTree(GetElementById("container"));
String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
offset:unplaced size:1000x130
offset:0,0 size:320x130
offset:10,10 size:33x10
offset:0,30 size:100x20
offset:0,0 size:100x20
offset:138,60 size:44x10
offset:20,90 size:55x0
offset:10,110 size:66x10
)DUMP";
EXPECT_EQ(expectation, dump);
}
TEST_F(NGColumnLayoutAlgorithmTest, SpannerMarginsRtl) {
SetBodyInnerHTML(R"HTML(
<style>
#parent {
columns: 3;
column-gap: 10px;
width: 320px;
direction: rtl;
}
.content { break-inside:avoid; height:20px; }
</style>
<div id="container">
<div id="parent">
<div style="column-span:all; margin:10px; width:33px; height:10px;"></div>
<div class="content"></div>
<div style="column-span:all; margin:10px auto; width:44px; height:10px;"></div>
<div style="column-span:all; margin:20px; width:55px;"></div>
<div style="column-span:all; margin:10px; width:66px; height:10px;"></div>
</div>
</div>
)HTML");
String dump = DumpFragmentTree(GetElementById("container"));
String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
offset:unplaced size:1000x130
offset:0,0 size:320x130
offset:277,10 size:33x10
offset:220,30 size:100x20
offset:0,0 size:100x20
offset:138,60 size:44x10
offset:245,90 size:55x0
offset:244,110 size:66x10
)DUMP";
EXPECT_EQ(expectation, dump);
}
TEST_F(NGColumnLayoutAlgorithmTest, InvalidSpanners) { TEST_F(NGColumnLayoutAlgorithmTest, InvalidSpanners) {
// Spanners cannot exist inside new formatting context roots. They will just // Spanners cannot exist inside new formatting context roots. They will just
// be treated as normal column content then. // be treated as normal column content then.
......
...@@ -1078,7 +1078,6 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/composited-with-ov ...@@ -1078,7 +1078,6 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/composited-with-ov
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/doubly-nested-with-top-padding-crossing-row-boundaries.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/doubly-nested-with-top-padding-crossing-row-boundaries.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/abspos-becomes-spanner.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/abspos-becomes-spanner.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/abspos-multicol-with-spanner-becomes-spanner.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/abspos-multicol-with-spanner-becomes-spanner.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/block-becomes-spanner.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/change-second-row-height.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/change-second-row-height.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/change-spanner-display.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/change-spanner-display.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/change-spanner-parent-display.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/change-spanner-parent-display.html [ Failure ]
...@@ -1212,7 +1211,6 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/scrolling-overflow ...@@ -1212,7 +1211,6 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/scrolling-overflow
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/shadow-breaking.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/shadow-breaking.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/single-line.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/single-line.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/abspos-containing-block-outside-spanner.html [ Crash Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/abspos-containing-block-outside-spanner.html [ Crash Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/adjacent-spanners-with-margin.html [ Failure ]
crbug.com/829028 virtual/layout_ng_experimental/fast/multicol/span/after-float.html [ Failure ] crbug.com/829028 virtual/layout_ng_experimental/fast/multicol/span/after-float.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/after-row-with-uneven-height-nested-multicol.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/after-row-with-uneven-height-nested-multicol.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/as-inner-multicol.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/as-inner-multicol.html [ Failure ]
...@@ -1226,8 +1224,6 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/block-with-to ...@@ -1226,8 +1224,6 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/block-with-to
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/block-with-top-border-and-margin-around-spanner-extra-space.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/block-with-top-border-and-margin-around-spanner-extra-space.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/change-multicol-writing-mode.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/change-multicol-writing-mode.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/change-spanner-margins.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/change-spanner-margins.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/empty-block-between-spanners-with-margins.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/empty-spanner-between-spanners-with-margins.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/fill-after-spanner-exact-fit.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/fill-after-spanner-exact-fit.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/fill-after-spanner-extra-height.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/fill-after-spanner-extra-height.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/float.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/float.html [ Failure ]
...@@ -1237,7 +1233,6 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/in-nested-mul ...@@ -1237,7 +1233,6 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/in-nested-mul
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/inside-block-with-fixed-height.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/inside-block-with-fixed-height.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/invalid-spanner-in-abspos.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/invalid-spanner-in-abspos.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/invalid-spanner-in-transform.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/invalid-spanner-in-transform.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/margin-on-multicol.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/multicol-with-padding.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/multicol-with-padding.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/nested-multicol.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/nested-multicol.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/offset-properties-empty-content.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/span/offset-properties-empty-content.html [ Failure ]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment