diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index ec2247e1896..edb8758344c 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -1573,7 +1573,7 @@ impl Fragment { } // If this fragment takes up no space, we don't need to build any display items for it. - if self.has_non_invertible_transform() { + if self.has_non_invertible_transform_or_zero_scale() { return; } @@ -2419,7 +2419,7 @@ impl BlockFlow { flags: StackingContextCollectionFlags, ) { // This block flow produces no stacking contexts if it takes up no space. - if self.has_non_invertible_transform() { + if self.has_non_invertible_transform_or_zero_scale() { return; } diff --git a/components/layout/flow.rs b/components/layout/flow.rs index f1e10aa485e..5b0ea08b5b4 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -277,7 +277,7 @@ pub trait Flow: HasBaseFlow + fmt::Debug + Sync + Send + 'static { might_have_floats_in_or_out } - fn has_non_invertible_transform(&self) -> bool { + fn has_non_invertible_transform_or_zero_scale(&self) -> bool { if !self.class().is_block_like() || self.as_block() .fragment @@ -290,7 +290,9 @@ pub trait Flow: HasBaseFlow + fmt::Debug + Sync + Send + 'static { return false; } - self.as_block().fragment.has_non_invertible_transform() + self.as_block() + .fragment + .has_non_invertible_transform_or_zero_scale() } fn get_overflow_in_parent_coordinates(&self) -> Overflow { @@ -1176,7 +1178,7 @@ impl BaseFlow { state: &mut StackingContextCollectionState, ) { for kid in self.children.iter_mut() { - if !kid.has_non_invertible_transform() { + if !kid.has_non_invertible_transform_or_zero_scale() { kid.collect_stacking_contexts(state); } } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 10afbf341f6..1c04bc2ad6e 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -2760,9 +2760,11 @@ impl Fragment { } /// Returns true if this fragment has a transform applied that causes it to take up no space. - pub fn has_non_invertible_transform(&self) -> bool { + pub fn has_non_invertible_transform_or_zero_scale(&self) -> bool { self.transform_matrix(&Rect::default()) - .map_or(false, |matrix| !matrix.is_invertible()) + .map_or(false, |matrix| { + !matrix.is_invertible() || matrix.m11 == 0. || matrix.m22 == 0. + }) } /// Returns true if this fragment establishes a new stacking context and false otherwise. diff --git a/components/layout/inline.rs b/components/layout/inline.rs index c112a8acdc5..e9ca463090e 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -1882,7 +1882,7 @@ impl Flow for InlineFlow { for fragment in self.fragments.fragments.iter_mut() { // If a particular fragment would establish a stacking context but has a transform // applied that causes it to take up no space, we can skip it entirely. - if fragment.has_non_invertible_transform() { + if fragment.has_non_invertible_transform_or_zero_scale() { continue; } state.containing_block_clipping_and_scrolling = previous_cb_clipping_and_scrolling; diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index a9527f01a67..16868356736 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -345,7 +345,7 @@ pub struct BuildDisplayList<'a> { impl<'a> BuildDisplayList<'a> { #[inline] pub fn traverse(&mut self, flow: &mut dyn Flow) { - if flow.has_non_invertible_transform() { + if flow.has_non_invertible_transform_or_zero_scale() { return; } diff --git a/components/layout_2020/display_list/stacking_context.rs b/components/layout_2020/display_list/stacking_context.rs index 2ee572a805d..42d61f03c2f 100644 --- a/components/layout_2020/display_list/stacking_context.rs +++ b/components/layout_2020/display_list/stacking_context.rs @@ -787,8 +787,10 @@ impl Fragment { // If this fragment has a transform applied that makes it take up no space // then we don't need to create any stacking contexts for it. - let has_non_invertible_transform = - fragment.has_non_invertible_transform(&containing_block.rect.to_untyped()); + let has_non_invertible_transform = fragment + .has_non_invertible_transform_or_zero_scale( + &containing_block.rect.to_untyped(), + ); if has_non_invertible_transform { return; } @@ -1258,10 +1260,10 @@ impl BoxFragment { } /// Returns true if the given style contains a transform that is not invertible. - fn has_non_invertible_transform(&self, containing_block: &Rect) -> bool { + fn has_non_invertible_transform_or_zero_scale(&self, containing_block: &Rect) -> bool { let list = &self.style.get_box().transform; match list.to_transform_3d_matrix(Some(containing_block)) { - Ok(t) => !t.0.is_invertible(), + Ok(t) => !t.0.is_invertible() || t.0.m11 == 0. || t.0.m22 == 0., Err(_) => false, } } diff --git a/tests/wpt/meta/css/css-transforms/crashtests/preserve3d-scene-001.html.ini b/tests/wpt/meta/css/css-transforms/crashtests/preserve3d-scene-001.html.ini deleted file mode 100644 index 376b626e352..00000000000 --- a/tests/wpt/meta/css/css-transforms/crashtests/preserve3d-scene-001.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[preserve3d-scene-001.html] - expected: CRASH diff --git a/tests/wpt/meta/css/css-transforms/crashtests/preserve3d-scene-002.html.ini b/tests/wpt/meta/css/css-transforms/crashtests/preserve3d-scene-002.html.ini deleted file mode 100644 index e2f99f70289..00000000000 --- a/tests/wpt/meta/css/css-transforms/crashtests/preserve3d-scene-002.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[preserve3d-scene-002.html] - expected: CRASH