diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 8c9fef0c8f6..ac1a5dc581f 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1127,7 +1127,7 @@ fn static_assert() { ${impl_copy_animation_value(ident, gecko_ffi_name)} -<% skip_box_longhands= """display""" %> +<% skip_box_longhands= """display contain""" %> <%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}"> #[inline] pub fn set_display(&mut self, v: longhands::display::computed_value::T) { @@ -1137,8 +1137,7 @@ fn static_assert() { #[inline] pub fn copy_display_from(&mut self, other: &Self) { - self.gecko.mDisplay = other.gecko.mDisplay; - self.gecko.mOriginalDisplay = other.gecko.mDisplay; + self.set_display(other.gecko.mDisplay); } #[inline] @@ -1159,6 +1158,40 @@ fn static_assert() { pub fn clone_display(&self) -> longhands::display::computed_value::T { self.gecko.mDisplay } + + #[inline] + pub fn set_contain(&mut self, v: longhands::contain::computed_value::T) { + self.gecko.mContain = v; + self.gecko.mEffectiveContainment = v; + } + + #[inline] + pub fn copy_contain_from(&mut self, other: &Self) { + self.set_contain(other.gecko.mContain); + } + + #[inline] + pub fn reset_contain(&mut self, other: &Self) { + self.copy_contain_from(other) + } + + #[inline] + pub fn clone_contain(&self) -> longhands::contain::computed_value::T { + self.gecko.mContain + } + + #[inline] + pub fn set_effective_containment( + &mut self, + v: longhands::contain::computed_value::T + ) { + self.gecko.mEffectiveContainment = v; + } + + #[inline] + pub fn clone_effective_containment(&self) -> longhands::contain::computed_value::T { + self.gecko.mEffectiveContainment + } <%def name="simple_image_array_property(name, shorthand, field_name)"> diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index 2912f0676b6..ddfbeb60cee 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -7,8 +7,9 @@ use crate::computed_value_flags::ComputedValueFlags; use crate::dom::TElement; -#[cfg(feature = "gecko")] -use crate::properties::longhands::contain::SpecifiedValue; +use crate::properties::longhands::contain::computed_value::T as Contain; +use crate::properties::longhands::container_type::computed_value::T as ContainerType; +use crate::properties::longhands::content_visibility::computed_value::T as ContentVisibility; use crate::properties::longhands::display::computed_value::T as Display; use crate::properties::longhands::float::computed_value::T as Float; use crate::properties::longhands::position::computed_value::T as Position; @@ -465,6 +466,47 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { } } + fn adjust_for_contain(&mut self) { + let box_style = self.style.get_box(); + debug_assert_eq!(box_style.clone_contain(), box_style.clone_effective_containment()); + let container_type = box_style.clone_container_type(); + let content_visibility = box_style.clone_content_visibility(); + if container_type == ContainerType::Normal && + content_visibility == ContentVisibility::Visible + { + return; + } + let old_contain = box_style.clone_contain(); + let mut new_contain = old_contain; + match content_visibility { + ContentVisibility::Visible => {}, + // `content-visibility:auto` also applies size containment when content + // is not relevant (and therefore skipped). This is checked in + // nsIFrame::GetContainSizeAxes. + ContentVisibility::Auto => new_contain.insert( + Contain::LAYOUT | Contain::PAINT | Contain::STYLE), + ContentVisibility::Hidden => new_contain.insert( + Contain::LAYOUT | Contain::PAINT | Contain::SIZE | Contain::STYLE), + } + match container_type { + ContainerType::Normal => {}, + // https://drafts.csswg.org/css-contain-3/#valdef-container-type-inline-size: + // Applies layout containment, style containment, and inline-size + // containment to the principal box. + ContainerType::InlineSize => new_contain.insert( + Contain::LAYOUT | Contain::STYLE | Contain::INLINE_SIZE), + // https://drafts.csswg.org/css-contain-3/#valdef-container-type-size: + // Applies layout containment, style containment, and size + // containment to the principal box. + ContainerType::Size => new_contain.insert( + Contain::LAYOUT | Contain::STYLE | Contain::SIZE), + } + if new_contain == old_contain { + return; + } + self.style.mutate_box().set_effective_containment(new_contain); + } + /// Handles the relevant sections in: /// /// https://drafts.csswg.org/css-display/#unbox-html @@ -899,6 +941,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { self.adjust_for_webkit_line_clamp(); self.adjust_for_position(); self.adjust_for_overflow(); + self.adjust_for_contain(); #[cfg(feature = "gecko")] { self.adjust_for_table_text_align();