diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index f5563800b931..9feab366478a 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -1004,11 +1004,13 @@ struct QueryContainerState { nscoord GetInlineSize() const { return LogicalSize(mWm, mSize).ISize(mWm); } bool Changed(const QueryContainerState& aNewState, StyleContainerType aType) { - if (aType & StyleContainerType::SIZE) { - return mSize != aNewState.mSize; - } - if (aType & StyleContainerType::INLINE_SIZE) { - return GetInlineSize() != aNewState.GetInlineSize(); + switch (aType) { + case StyleContainerType::Normal: + break; + case StyleContainerType::Size: + return mSize != aNewState.mSize; + case StyleContainerType::InlineSize: + return GetInlineSize() != aNewState.GetInlineSize(); } return false; } @@ -1041,7 +1043,8 @@ bool nsPresContext::UpdateContainerQueryStyles() { } auto type = frame->StyleDisplay()->mContainerType; - MOZ_ASSERT(type, "Non-container frames shouldn't be in this type"); + MOZ_ASSERT(type != StyleContainerType::Normal, + "Non-container frames shouldn't be in this type"); if (!mUpdatedContainerQueryContents.EnsureInserted(frame->GetContent())) { continue; diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp index f0944d956d70..3a20fc1b858f 100644 --- a/layout/generic/nsIFrame.cpp +++ b/layout/generic/nsIFrame.cpp @@ -721,7 +721,7 @@ void nsIFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED); } - if (disp->mContainerType) { + if (disp->mContainerType != StyleContainerType::Normal) { PresContext()->RegisterContainerQueryFrame(this); } @@ -811,7 +811,7 @@ void nsIFrame::DestroyFrom(nsIFrame* aDestructRoot, } } - if (disp->mContainerType) { + if (disp->mContainerType != StyleContainerType::Normal) { PresContext()->UnregisterContainerQueryFrame(this); } diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index ab9080490ae9..f1e313aa8bb1 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -2209,7 +2209,7 @@ nsStyleDisplay::nsStyleDisplay(const Document& aDocument) mOriginalDisplay(StyleDisplay::Inline), mContain(StyleContain::NONE), mContentVisibility(StyleContentVisibility::Visible), - mContainerType(StyleContainerType::NORMAL), + mContainerType(StyleContainerType::Normal), mAppearance(StyleAppearance::None), mDefaultAppearance(StyleAppearance::None), mPosition(StylePositionProperty::Static), diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 6128a5c9d978..b54210a15b17 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1705,7 +1705,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay { auto contain = mContain; // content-visibility and container-type implicitly enable some containment // flags. - if (MOZ_LIKELY(!mContainerType) && + if (MOZ_LIKELY(mContainerType == mozilla::StyleContainerType::Normal) && MOZ_LIKELY(mContentVisibility == StyleContentVisibility::Visible)) { return contain; } @@ -1726,18 +1726,24 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay { break; } - if (mContainerType & mozilla::StyleContainerType::SIZE) { - // https://drafts.csswg.org/css-contain-3/#valdef-container-type-size: - // Applies layout containment, style containment, and size containment - // to the principal box. - contain |= mozilla::StyleContain::LAYOUT | mozilla::StyleContain::STYLE | - mozilla::StyleContain::SIZE; - } else if (mContainerType & mozilla::StyleContainerType::INLINE_SIZE) { - // 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. - contain |= mozilla::StyleContain::LAYOUT | mozilla::StyleContain::STYLE | - mozilla::StyleContain::INLINE_SIZE; + switch (mContainerType) { + case mozilla::StyleContainerType::Normal: + break; + case mozilla::StyleContainerType::InlineSize: + // 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. + contain |= mozilla::StyleContain::LAYOUT | + mozilla::StyleContain::STYLE | + mozilla::StyleContain::INLINE_SIZE; + break; + case mozilla::StyleContainerType::Size: + // https://drafts.csswg.org/css-contain-3/#valdef-container-type-size: + // Applies layout containment, style containment, and size + // containment to the principal box. + contain |= mozilla::StyleContain::LAYOUT | + mozilla::StyleContain::STYLE | mozilla::StyleContain::SIZE; + break; } return contain; diff --git a/servo/components/style/matching.rs b/servo/components/style/matching.rs index a8b51bc20282..78d9d4d96269 100644 --- a/servo/components/style/matching.rs +++ b/servo/components/style/matching.rs @@ -907,7 +907,7 @@ pub trait MatchMethods: TElement { let is_container = !new_primary_style .get_box() .clone_container_type() - .is_empty(); + .is_normal(); if is_root || is_container { let new_font_size = new_primary_style.get_font().clone_font_size(); let old_font_size = old_styles diff --git a/servo/components/style/properties/longhands/box.mako.rs b/servo/components/style/properties/longhands/box.mako.rs index 19400a4d8809..cde50b6b3a4d 100644 --- a/servo/components/style/properties/longhands/box.mako.rs +++ b/servo/components/style/properties/longhands/box.mako.rs @@ -445,7 +445,7 @@ ${helpers.predefined_type( ${helpers.predefined_type( "container-type", "ContainerType", - "computed::ContainerType::NORMAL", + "computed::ContainerType::Normal", engines="gecko", animation_value_type="none", gecko_pref="layout.css.container-queries.enabled", diff --git a/servo/components/style/properties/shorthands/box.mako.rs b/servo/components/style/properties/shorthands/box.mako.rs index 53e6332349b2..64df89a3c4ad 100644 --- a/servo/components/style/properties/shorthands/box.mako.rs +++ b/servo/components/style/properties/shorthands/box.mako.rs @@ -40,19 +40,19 @@ ${helpers.two_properties_shorthand( gecko_pref="layout.css.container-queries.enabled", spec="https://drafts.csswg.org/css-contain-3/#container-shorthand" > + use crate::values::specified::box_::{ContainerName, ContainerType}; pub fn parse_value<'i>( context: &ParserContext, input: &mut Parser<'i, '_>, ) -> Result> { use crate::parser::Parse; - use crate::values::specified::box_::{ContainerName, ContainerType}; // See https://github.com/w3c/csswg-drafts/issues/7180 for why we don't // match the spec. let container_name = ContainerName::parse(context, input)?; let container_type = if input.try_parse(|input| input.expect_delim('/')).is_ok() { - ContainerType::parse(context, input)? + ContainerType::parse(input)? } else { - ContainerType::NORMAL + ContainerType::Normal }; Ok(expanded! { container_name: container_name, @@ -63,7 +63,7 @@ ${helpers.two_properties_shorthand( impl<'a> ToCss for LonghandsToSerialize<'a> { fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { self.container_name.to_css(dest)?; - if !self.container_type.is_empty() { + if !self.container_type.is_normal() { dest.write_str(" / ")?; self.container_type.to_css(dest)?; } diff --git a/servo/components/style/stylesheets/container_rule.rs b/servo/components/style/stylesheets/container_rule.rs index 991f06e2acb0..751636d10308 100644 --- a/servo/components/style/stylesheets/container_rule.rs +++ b/servo/components/style/stylesheets/container_rule.rs @@ -114,18 +114,18 @@ pub struct ContainerLookupResult { } fn container_type_axes(ty_: ContainerType, wm: WritingMode) -> FeatureFlags { - if ty_.contains(ContainerType::SIZE) { - return FeatureFlags::all_container_axes(); + match ty_ { + ContainerType::Size => FeatureFlags::all_container_axes(), + ContainerType::InlineSize => { + let physical_axis = if wm.is_vertical() { + FeatureFlags::CONTAINER_REQUIRES_HEIGHT_AXIS + } else { + FeatureFlags::CONTAINER_REQUIRES_WIDTH_AXIS + }; + FeatureFlags::CONTAINER_REQUIRES_INLINE_AXIS | physical_axis + }, + ContainerType::Normal => FeatureFlags::empty(), } - if ty_.contains(ContainerType::INLINE_SIZE) { - let physical_axis = if wm.is_vertical() { - FeatureFlags::CONTAINER_REQUIRES_HEIGHT_AXIS - } else { - FeatureFlags::CONTAINER_REQUIRES_WIDTH_AXIS - }; - return FeatureFlags::CONTAINER_REQUIRES_INLINE_AXIS | physical_axis; - } - FeatureFlags::empty() } enum TraversalResult { @@ -476,7 +476,7 @@ impl<'a> ContainerSizeQuery<'a> { let container_type = box_style.clone_container_type(); let size = e.primary_box_size(); match container_type { - ContainerType::SIZE => { + ContainerType::Size=> { TraversalResult::Done( ContainerSizeQueryResult { width: Some(size.width), @@ -484,7 +484,7 @@ impl<'a> ContainerSizeQuery<'a> { } ) }, - ContainerType::INLINE_SIZE => { + ContainerType::InlineSize => { if wm.is_horizontal() { TraversalResult::Done( ContainerSizeQueryResult { @@ -501,7 +501,7 @@ impl<'a> ContainerSizeQuery<'a> { ) } }, - _ => TraversalResult::InProgress, + ContainerType::Normal => TraversalResult::InProgress, } } diff --git a/servo/components/style/values/specified/box.rs b/servo/components/style/values/specified/box.rs index 0c9264c2e498..1e82f6454979 100644 --- a/servo/components/style/values/specified/box.rs +++ b/servo/components/style/values/specified/box.rs @@ -1515,30 +1515,28 @@ pub enum ContentVisibility { Visible, } -bitflags! { - #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToCss, Parse, ToResolvedValue, ToShmem)] - #[repr(C)] - #[allow(missing_docs)] - #[css(bitflags(single="normal", mixed="size,inline-size", overlapping_bits))] - /// https://drafts.csswg.org/css-contain-3/#container-type - /// - /// TODO: block-size is on the spec but it seems it was removed? WPTs don't - /// support it, see https://github.com/w3c/csswg-drafts/issues/7179. - pub struct ContainerType: u8 { - /// The `normal` variant. - const NORMAL = 0; - /// The `inline-size` variant. - const INLINE_SIZE = 1 << 0; - /// The `size` variant, exclusive with `inline-size` (they sharing bits - /// guarantees this). - const SIZE = 1 << 1 | Self::INLINE_SIZE.bits; - } +#[derive(Clone, Copy, Debug, PartialEq, Eq, MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToCss, Parse, ToResolvedValue, ToShmem)] +#[repr(u8)] +#[allow(missing_docs)] +/// https://drafts.csswg.org/css-contain-3/#container-type +pub enum ContainerType { + /// The `normal` variant. + Normal, + /// The `inline-size` variant. + InlineSize, + /// The `size` variant. + Size, } impl ContainerType { + /// Is this container-type: normal? + pub fn is_normal(self) -> bool { + self == Self::Normal + } + /// Is this type containing size in any way? - pub fn is_size_container_type(&self) -> bool { - self.intersects(ContainerType::SIZE | ContainerType::INLINE_SIZE) + pub fn is_size_container_type(self) -> bool { + !self.is_normal() } } diff --git a/testing/web-platform/meta/css/css-contain/container-queries/fieldset-legend-change.html.ini b/testing/web-platform/meta/css/css-contain/container-queries/fieldset-legend-change.html.ini deleted file mode 100644 index 9d5d377cd9c5..000000000000 --- a/testing/web-platform/meta/css/css-contain/container-queries/fieldset-legend-change.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[fieldset-legend-change.html] - expected: FAIL diff --git a/testing/web-platform/meta/css/css-contain/container-queries/inline-size-bfc-floats.html.ini b/testing/web-platform/meta/css/css-contain/container-queries/inline-size-bfc-floats.html.ini index 0efd1511e950..29e66efd5263 100644 --- a/testing/web-platform/meta/css/css-contain/container-queries/inline-size-bfc-floats.html.ini +++ b/testing/web-platform/meta/css/css-contain/container-queries/inline-size-bfc-floats.html.ini @@ -1,2 +1,2 @@ [inline-size-bfc-floats.html] - expected: FAIL + expected: TIMEOUT