mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
style: Fix style containment not triggered by 'contain'
'container-type' and 'content-visibility' can trigger various kinds of containment, but this was done via nsStyleDisplay::EffectiveContainment, to avoid affecting the computed value of 'contain'. This was fine except for style containment, which needs to set the flag SELF_OR_ANCESTOR_HAS_CONTAIN_STYLE in order to really work, but this was only done with 'contain: style'. So this patch removes nsStyleDisplay::EffectiveContainment, and instead uses two fields for containment: mContain and mEffectiveContainment. This is somewhat analogous to mDisplay and mOriginalDisplay, though in that case the computed value is the modified display. Also fixes a typo in IsContainStyle() that made it return true for any kind of containment, not just for style containment. Differential Revision: https://phabricator.services.mozilla.com/D163779
This commit is contained in:
parent
60bd00980d
commit
7ec4c53266
2 changed files with 81 additions and 5 deletions
|
@ -1127,7 +1127,7 @@ fn static_assert() {
|
|||
${impl_copy_animation_value(ident, gecko_ffi_name)}
|
||||
</%def>
|
||||
|
||||
<% 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
|
||||
}
|
||||
</%self:impl_trait>
|
||||
|
||||
<%def name="simple_image_array_property(name, shorthand, field_name)">
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue