fix(layout): preserve flex baseline semantics across logical flows

Use typed alphabetic/central baseline context from Stylo and preserve sideways writing modes at the Taffy boundary. Pin Taffy's independent baseline-sharing groups, physical first/last baseline export, and stretch fallback fix.

Add 324 Chromium-backed geometry and pixel checks, retaining static-margin and reversed-inset regressions. Required fmt, workspace Clippy and all 17184 Nextest tests pass; focused release WPT comparison improves 35 to 47 of 96 cases without pass-to-fail regressions.
This commit is contained in:
ldm0
2026-09-09 04:45:31 +08:00
parent 428c5bd2f4
commit ede8a90a58
7 changed files with 196 additions and 22 deletions
Generated
+12 -12
View File
@@ -4266,7 +4266,7 @@ dependencies = [
[[package]]
name = "selectors"
version = "0.40.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"bitflags",
"cssparser",
@@ -4398,7 +4398,7 @@ dependencies = [
[[package]]
name = "servo_arc"
version = "0.4.3"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"serde",
"stable_deref_trait",
@@ -4645,7 +4645,7 @@ dependencies = [
[[package]]
name = "stylo"
version = "0.20.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"app_units",
"arrayvec",
@@ -4701,7 +4701,7 @@ dependencies = [
[[package]]
name = "stylo_atoms"
version = "0.20.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"string_cache",
"string_cache_codegen",
@@ -4710,7 +4710,7 @@ dependencies = [
[[package]]
name = "stylo_derive"
version = "0.20.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"darling",
"proc-macro2",
@@ -4722,7 +4722,7 @@ dependencies = [
[[package]]
name = "stylo_dom"
version = "0.20.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"bitflags",
"stylo_malloc_size_of",
@@ -4731,7 +4731,7 @@ dependencies = [
[[package]]
name = "stylo_malloc_size_of"
version = "0.20.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"app_units",
"cssparser",
@@ -4748,7 +4748,7 @@ dependencies = [
[[package]]
name = "stylo_static_prefs"
version = "0.20.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"toml",
]
@@ -4766,7 +4766,7 @@ dependencies = [
[[package]]
name = "stylo_traits"
version = "0.20.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"app_units",
"bitflags",
@@ -4842,7 +4842,7 @@ dependencies = [
[[package]]
name = "taffy"
version = "0.13.0"
source = "git+https://github.com/ldm0/taffy?rev=082327a5cb0d2ee1fed4c0ac5f339e1c1a51b576#082327a5cb0d2ee1fed4c0ac5f339e1c1a51b576"
source = "git+https://github.com/ldm0/taffy?rev=4922df49ff9eba488de9c5c44d3c4a1cf54876f9#4922df49ff9eba488de9c5c44d3c4a1cf54876f9"
dependencies = [
"arrayvec",
"serde",
@@ -5053,7 +5053,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "to_shmem"
version = "0.5.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"cssparser",
"servo_arc",
@@ -5066,7 +5066,7 @@ dependencies = [
[[package]]
name = "to_shmem_derive"
version = "0.1.0"
source = "git+https://github.com/ldm0/stylo?rev=e6cdff0a2eb7e51a313dabe8dc48a13a08314493#e6cdff0a2eb7e51a313dabe8dc48a13a08314493"
source = "git+https://github.com/ldm0/stylo?rev=cfa170da90c467e93786ec0fa5526bd83f201933#cfa170da90c467e93786ec0fa5526bd83f201933"
dependencies = [
"darling",
"proc-macro2",
+8 -8
View File
@@ -95,14 +95,14 @@ curl-sys = { git = "https://github.com/ldm0/curl-rust", branch = "moli" }
cookie = { git = "https://github.com/ldm0/cookie-rs", branch = "priority" }
v8 = { path = "vendor/v8-152.2.0" }
deno_v8 = { path = "vendor/deno_v8-0.3.0" }
selectors = { git = "https://github.com/ldm0/stylo", rev = "e6cdff0a2eb7e51a313dabe8dc48a13a08314493" }
servo_arc = { git = "https://github.com/ldm0/stylo", rev = "e6cdff0a2eb7e51a313dabe8dc48a13a08314493" }
stylo = { git = "https://github.com/ldm0/stylo", rev = "e6cdff0a2eb7e51a313dabe8dc48a13a08314493" }
stylo_atoms = { git = "https://github.com/ldm0/stylo", rev = "e6cdff0a2eb7e51a313dabe8dc48a13a08314493" }
stylo_dom = { git = "https://github.com/ldm0/stylo", rev = "e6cdff0a2eb7e51a313dabe8dc48a13a08314493" }
stylo_static_prefs = { git = "https://github.com/ldm0/stylo", rev = "e6cdff0a2eb7e51a313dabe8dc48a13a08314493" }
stylo_traits = { git = "https://github.com/ldm0/stylo", rev = "e6cdff0a2eb7e51a313dabe8dc48a13a08314493" }
taffy = { git = "https://github.com/ldm0/taffy", rev = "082327a5cb0d2ee1fed4c0ac5f339e1c1a51b576" }
selectors = { git = "https://github.com/ldm0/stylo", rev = "cfa170da90c467e93786ec0fa5526bd83f201933" }
servo_arc = { git = "https://github.com/ldm0/stylo", rev = "cfa170da90c467e93786ec0fa5526bd83f201933" }
stylo = { git = "https://github.com/ldm0/stylo", rev = "cfa170da90c467e93786ec0fa5526bd83f201933" }
stylo_atoms = { git = "https://github.com/ldm0/stylo", rev = "cfa170da90c467e93786ec0fa5526bd83f201933" }
stylo_dom = { git = "https://github.com/ldm0/stylo", rev = "cfa170da90c467e93786ec0fa5526bd83f201933" }
stylo_static_prefs = { git = "https://github.com/ldm0/stylo", rev = "cfa170da90c467e93786ec0fa5526bd83f201933" }
stylo_traits = { git = "https://github.com/ldm0/stylo", rev = "cfa170da90c467e93786ec0fa5526bd83f201933" }
taffy = { git = "https://github.com/ldm0/taffy", rev = "4922df49ff9eba488de9c5c44d3c4a1cf54876f9" }
[workspace.lints.clippy]
disallowed_methods = "deny"
+6
View File
@@ -137,6 +137,8 @@ pub(crate) enum LayoutWritingMode {
HorizontalTb,
VerticalRl,
VerticalLr,
SidewaysRl,
SidewaysLr,
}
impl LayoutWritingMode {
@@ -145,6 +147,8 @@ impl LayoutWritingMode {
StyloWritingMode::HorizontalTb => Self::HorizontalTb,
StyloWritingMode::VerticalRl => Self::VerticalRl,
StyloWritingMode::VerticalLr => Self::VerticalLr,
StyloWritingMode::SidewaysRl => Self::SidewaysRl,
StyloWritingMode::SidewaysLr => Self::SidewaysLr,
}
}
@@ -158,6 +162,8 @@ impl LayoutWritingMode {
Self::HorizontalTb => taffy::WritingMode::HorizontalTb,
Self::VerticalRl => taffy::WritingMode::VerticalRl,
Self::VerticalLr => taffy::WritingMode::VerticalLr,
Self::SidewaysRl => taffy::WritingMode::SidewaysRl,
Self::SidewaysLr => taffy::WritingMode::SidewaysLr,
}
}
}
+20
View File
@@ -1501,6 +1501,26 @@ where
}
}
fn get_baseline_type(&self, node_id: NodeId) -> taffy::BaselineType {
if self.is_viewport_taffy_node(node_id) {
return taffy::BaselineType::Alphabetic;
}
let style = &self.boxes[LayoutBoxId::from_taffy(node_id).index()].style;
style.stylo_computed_values().map_or_else(
|| taffy::BaselineType::for_writing_mode(style.writing_mode()),
|computed| {
// Stylo's writing direction includes text-orientation as well
// as writing-mode. Sideways text uses an alphabetic baseline;
// upright vertical text uses a central baseline, like Blink.
if computed.writing_mode.is_text_vertical() {
taffy::BaselineType::Central
} else {
taffy::BaselineType::Alphabetic
}
},
)
}
fn get_scrollbar_insets(&self, node_id: NodeId) -> taffy::Rect<f32> {
if self.is_viewport_taffy_node(node_id) {
// The synthetic viewport expresses its gutters as non-painted
@@ -1,5 +1,16 @@
use super::*;
#[tokio::test(flavor = "current_thread")]
async fn screenshot_resolves_flex_baselines_across_logical_flows() {
assert_flex_geometry_fixture(
include_str!("../../../../tests/fixtures/flex-baseline-flows.html"),
"collectFlexBaselineChecks()",
324,
1980,
)
.await;
}
#[tokio::test(flavor = "current_thread")]
async fn screenshot_resolves_flex_static_margin_boxes_across_containing_blocks() {
assert_flex_geometry_fixture(
@@ -74,9 +85,12 @@ async fn assert_flex_geometry_fixture(
let x = check["pixel"][0].as_f64().expect("pixel x") as usize;
let y = check["pixel"][1].as_f64().expect("pixel y") as usize;
let offset = (y * image.width as usize + x) * 4;
let color: [u8; 4] = check.get("color").map_or([31, 127, 63, 255], |color| {
std::array::from_fn(|index| color[index].as_u64().expect("color channel") as u8)
});
assert_eq!(
&image.rgba[offset..offset + 4],
&[31, 127, 63, 255],
&color,
"{} paint",
check["id"]
);
@@ -124,7 +124,7 @@ mod element_toggle_event;
mod fetch_xhr;
mod file_entry_file_callback;
mod file_system_directory_reader;
mod flex_static_position;
mod flex_geometry;
mod grid_item_box_generation;
mod grid_item_paint_order;
mod grid_resolved_track_values;
+134
View File
@@ -0,0 +1,134 @@
<!doctype html>
<meta charset="utf-8">
<title>Flex baseline synthesis across logical flows</title>
<link rel="help" href="https://drafts.csswg.org/css-align-3/#generate-baselines">
<style>
html,body { margin:0; padding:0; font:0/0 sans-serif; }
html { overflow:hidden; }
.slot { position:absolute; width:160px; height:180px; }
.flex { position:absolute; left:25px; top:30px; display:flex; width:100px; height:100px; align-items:baseline; }
.item { flex-shrink:0; }
</style>
<body>
<script>
// Literal Chromium 145 rectangle expectations; no expected coordinate depends
// on measured Moli geometry. Slots do not overlap, including overflow.
const cases = [
{"id":"horizontal-tb/ltr/row/wrap","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,100,50,20]]},
{"id":"horizontal-tb/ltr/row/wrap-reverse","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,30,50,20]]},
{"id":"horizontal-tb/ltr/column/wrap","children":[[0,0,50,50],[0,50,30,50],[50,0,40,70],[50,70,50,20]]},
{"id":"horizontal-tb/ltr/column/wrap-reverse","children":[[50,0,50,50],[50,50,30,50],[0,0,40,70],[0,70,50,20]]},
{"id":"horizontal-tb/ltr/row-reverse/wrap","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,100,50,20]]},
{"id":"horizontal-tb/ltr/row-reverse/wrap-reverse","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,30,50,20]]},
{"id":"horizontal-tb/ltr/column-reverse/wrap","children":[[0,50,50,50],[0,0,30,50],[50,30,40,70],[50,10,50,20]]},
{"id":"horizontal-tb/ltr/column-reverse/wrap-reverse","children":[[50,50,50,50],[50,0,30,50],[0,30,40,70],[0,10,50,20]]},
{"id":"horizontal-tb/rtl/row/wrap","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,100,50,20]]},
{"id":"horizontal-tb/rtl/row/wrap-reverse","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,30,50,20]]},
{"id":"horizontal-tb/rtl/column/wrap","children":[[50,0,50,50],[50,50,30,50],[0,0,40,70],[0,70,50,20]]},
{"id":"horizontal-tb/rtl/column/wrap-reverse","children":[[0,0,50,50],[0,50,30,50],[50,0,40,70],[50,70,50,20]]},
{"id":"horizontal-tb/rtl/row-reverse/wrap","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,100,50,20]]},
{"id":"horizontal-tb/rtl/row-reverse/wrap-reverse","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,30,50,20]]},
{"id":"horizontal-tb/rtl/column-reverse/wrap","children":[[50,50,50,50],[50,0,30,50],[0,30,40,70],[0,10,50,20]]},
{"id":"horizontal-tb/rtl/column-reverse/wrap-reverse","children":[[0,50,50,50],[0,0,30,50],[50,30,40,70],[50,10,50,20]]},
{"id":"vertical-rl/ltr/row/wrap","children":[[50,0,50,50],[60,50,30,50],[5,0,40,70],[0,70,50,20]]},
{"id":"vertical-rl/ltr/row/wrap-reverse","children":[[0,0,50,50],[10,50,30,50],[55,0,40,70],[50,70,50,20]]},
{"id":"vertical-rl/ltr/column/wrap","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,75,50,20]]},
{"id":"vertical-rl/ltr/column/wrap-reverse","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,5,50,20]]},
{"id":"vertical-rl/ltr/row-reverse/wrap","children":[[50,50,50,50],[60,0,30,50],[5,30,40,70],[0,10,50,20]]},
{"id":"vertical-rl/ltr/row-reverse/wrap-reverse","children":[[0,50,50,50],[10,0,30,50],[55,30,40,70],[50,10,50,20]]},
{"id":"vertical-rl/ltr/column-reverse/wrap","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,75,50,20]]},
{"id":"vertical-rl/ltr/column-reverse/wrap-reverse","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,5,50,20]]},
{"id":"vertical-rl/rtl/row/wrap","children":[[50,50,50,50],[60,0,30,50],[5,30,40,70],[0,10,50,20]]},
{"id":"vertical-rl/rtl/row/wrap-reverse","children":[[0,50,50,50],[10,0,30,50],[55,30,40,70],[50,10,50,20]]},
{"id":"vertical-rl/rtl/column/wrap","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,5,50,20]]},
{"id":"vertical-rl/rtl/column/wrap-reverse","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,75,50,20]]},
{"id":"vertical-rl/rtl/row-reverse/wrap","children":[[50,0,50,50],[60,50,30,50],[5,0,40,70],[0,70,50,20]]},
{"id":"vertical-rl/rtl/row-reverse/wrap-reverse","children":[[0,0,50,50],[10,50,30,50],[55,0,40,70],[50,70,50,20]]},
{"id":"vertical-rl/rtl/column-reverse/wrap","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,5,50,20]]},
{"id":"vertical-rl/rtl/column-reverse/wrap-reverse","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,75,50,20]]},
{"id":"vertical-lr/ltr/row/wrap","children":[[0,0,50,50],[10,50,30,50],[55,0,40,70],[50,70,50,20]]},
{"id":"vertical-lr/ltr/row/wrap-reverse","children":[[50,0,50,50],[60,50,30,50],[5,0,40,70],[0,70,50,20]]},
{"id":"vertical-lr/ltr/column/wrap","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,75,50,20]]},
{"id":"vertical-lr/ltr/column/wrap-reverse","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,5,50,20]]},
{"id":"vertical-lr/ltr/row-reverse/wrap","children":[[0,50,50,50],[10,0,30,50],[55,30,40,70],[50,10,50,20]]},
{"id":"vertical-lr/ltr/row-reverse/wrap-reverse","children":[[50,50,50,50],[60,0,30,50],[5,30,40,70],[0,10,50,20]]},
{"id":"vertical-lr/ltr/column-reverse/wrap","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,75,50,20]]},
{"id":"vertical-lr/ltr/column-reverse/wrap-reverse","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,5,50,20]]},
{"id":"vertical-lr/rtl/row/wrap","children":[[0,50,50,50],[10,0,30,50],[55,30,40,70],[50,10,50,20]]},
{"id":"vertical-lr/rtl/row/wrap-reverse","children":[[50,50,50,50],[60,0,30,50],[5,30,40,70],[0,10,50,20]]},
{"id":"vertical-lr/rtl/column/wrap","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,5,50,20]]},
{"id":"vertical-lr/rtl/column/wrap-reverse","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,75,50,20]]},
{"id":"vertical-lr/rtl/row-reverse/wrap","children":[[0,0,50,50],[10,50,30,50],[55,0,40,70],[50,70,50,20]]},
{"id":"vertical-lr/rtl/row-reverse/wrap-reverse","children":[[50,0,50,50],[60,50,30,50],[5,0,40,70],[0,70,50,20]]},
{"id":"vertical-lr/rtl/column-reverse/wrap","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,5,50,20]]},
{"id":"vertical-lr/rtl/column-reverse/wrap-reverse","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,75,50,20]]},
{"id":"sideways-rl/ltr/row/wrap","children":[[50,0,50,50],[50,50,30,50],[0,0,40,70],[0,70,50,20]]},
{"id":"sideways-rl/ltr/row/wrap-reverse","children":[[0,0,50,50],[0,50,30,50],[50,0,40,70],[50,70,50,20]]},
{"id":"sideways-rl/ltr/column/wrap","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,100,50,20]]},
{"id":"sideways-rl/ltr/column/wrap-reverse","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,30,50,20]]},
{"id":"sideways-rl/ltr/row-reverse/wrap","children":[[50,50,50,50],[50,0,30,50],[0,30,40,70],[0,10,50,20]]},
{"id":"sideways-rl/ltr/row-reverse/wrap-reverse","children":[[0,50,50,50],[0,0,30,50],[50,30,40,70],[50,10,50,20]]},
{"id":"sideways-rl/ltr/column-reverse/wrap","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,100,50,20]]},
{"id":"sideways-rl/ltr/column-reverse/wrap-reverse","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,30,50,20]]},
{"id":"sideways-rl/rtl/row/wrap","children":[[50,50,50,50],[50,0,30,50],[0,30,40,70],[0,10,50,20]]},
{"id":"sideways-rl/rtl/row/wrap-reverse","children":[[0,50,50,50],[0,0,30,50],[50,30,40,70],[50,10,50,20]]},
{"id":"sideways-rl/rtl/column/wrap","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,30,50,20]]},
{"id":"sideways-rl/rtl/column/wrap-reverse","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,100,50,20]]},
{"id":"sideways-rl/rtl/row-reverse/wrap","children":[[50,0,50,50],[50,50,30,50],[0,0,40,70],[0,70,50,20]]},
{"id":"sideways-rl/rtl/row-reverse/wrap-reverse","children":[[0,0,50,50],[0,50,30,50],[50,0,40,70],[50,70,50,20]]},
{"id":"sideways-rl/rtl/column-reverse/wrap","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,30,50,20]]},
{"id":"sideways-rl/rtl/column-reverse/wrap-reverse","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,100,50,20]]},
{"id":"sideways-lr/ltr/row/wrap","children":[[0,50,50,50],[20,0,30,50],[60,30,40,70],[50,10,50,20]]},
{"id":"sideways-lr/ltr/row/wrap-reverse","children":[[50,50,50,50],[70,0,30,50],[10,30,40,70],[0,10,50,20]]},
{"id":"sideways-lr/ltr/column/wrap","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,-20,50,20]]},
{"id":"sideways-lr/ltr/column/wrap-reverse","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,50,50,20]]},
{"id":"sideways-lr/ltr/row-reverse/wrap","children":[[0,0,50,50],[20,50,30,50],[60,0,40,70],[50,70,50,20]]},
{"id":"sideways-lr/ltr/row-reverse/wrap-reverse","children":[[50,0,50,50],[70,50,30,50],[10,0,40,70],[0,70,50,20]]},
{"id":"sideways-lr/ltr/column-reverse/wrap","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,-20,50,20]]},
{"id":"sideways-lr/ltr/column-reverse/wrap-reverse","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,50,50,20]]},
{"id":"sideways-lr/rtl/row/wrap","children":[[0,0,50,50],[20,50,30,50],[60,0,40,70],[50,70,50,20]]},
{"id":"sideways-lr/rtl/row/wrap-reverse","children":[[50,0,50,50],[70,50,30,50],[10,0,40,70],[0,70,50,20]]},
{"id":"sideways-lr/rtl/column/wrap","children":[[0,0,50,50],[50,0,30,50],[0,50,40,70],[40,50,50,20]]},
{"id":"sideways-lr/rtl/column/wrap-reverse","children":[[0,50,50,50],[50,50,30,50],[0,-20,40,70],[40,-20,50,20]]},
{"id":"sideways-lr/rtl/row-reverse/wrap","children":[[0,50,50,50],[20,0,30,50],[60,30,40,70],[50,10,50,20]]},
{"id":"sideways-lr/rtl/row-reverse/wrap-reverse","children":[[50,50,50,50],[70,0,30,50],[10,30,40,70],[0,10,50,20]]},
{"id":"sideways-lr/rtl/column-reverse/wrap","children":[[50,0,50,50],[20,0,30,50],[60,50,40,70],[10,50,50,20]]},
{"id":"sideways-lr/rtl/column-reverse/wrap-reverse","children":[[50,50,50,50],[20,50,30,50],[60,-20,40,70],[10,-20,50,20]]}
];
cases.push(
{id:'vertical-rl/ltr/row/wrap/sideways-text', textOrientation:'sideways', sizes:[[40,30],[20,30]], children:[[60,0,40,30],[60,30,20,30]]},
{id:'vertical-rl/ltr/row/wrap/upright-text', textOrientation:'upright', sizes:[[40,30],[20,30]], children:[[60,0,40,30],[70,30,20,30]]}
);
const colors = [[31,127,63,255],[191,47,31,255],[47,79,191,255],[159,63,159,255]];
for (const [index,test] of cases.entries()) {
const [mode,direction,flexDirection,wrap] = test.id.split('/');
const slot = document.createElement('div');
slot.className = 'slot';
slot.style.left = (index % 8) * 160 + 'px';
slot.style.top = Math.floor(index / 8) * 180 + 'px';
const flex = document.createElement('div');
flex.className = 'flex';
flex.style.cssText = 'writing-mode:'+mode+';direction:'+direction+';flex-direction:'+flexDirection+';flex-wrap:'+wrap;
if (test.textOrientation) flex.style.textOrientation = test.textOrientation;
for (const [i,[width,height]] of (test.sizes || [[50,50],[30,50],[40,70],[50,20]]).entries()) {
const child = document.createElement('div');
child.className = 'item';
child.style.cssText = 'width:'+width+'px;height:'+height+'px;background:rgb('+colors[i].slice(0,3).join(',')+')';
flex.append(child);
}
slot.append(flex);
document.body.append(slot);
}
function collectFlexBaselineChecks() {
return cases.flatMap((test,index) => {
const flex = document.querySelectorAll('.flex')[index];
const origin = flex.getBoundingClientRect();
return Array.from(flex.children,(child,i) => {
const rect=child.getBoundingClientRect(), expected=test.children[i];
return {id:test.id+'/'+i,
actual:[rect.x-origin.x,rect.y-origin.y,rect.width,rect.height], expected,
pixel:[origin.x+expected[0]+2,origin.y+expected[1]+2], color:colors[i]};
});
});
}
</script>