Bug 1794040 - Simplify container-type implementation. r=dshin

It was made a bitfield so that we could include style. But then style
containment was removed and the bitfield keeps causing us to do wrong
check (since INLINE_SIZE intersects SIZE).

So just make it an enum. This causes a progression and a test that
failed now times out (which is a pre-existing issue, just like the
pseudo-elements test that times out).

Differential Revision: https://phabricator.services.mozilla.com/D160371
This commit is contained in:
Emilio Cobos Álvarez 2022-10-26 16:56:07 +00:00
Родитель 420ba200c7
Коммит 3a328a3ef8
11 изменённых файлов: 70 добавлений и 65 удалений

Просмотреть файл

@ -1004,11 +1004,13 @@ struct QueryContainerState {
nscoord GetInlineSize() const { return LogicalSize(mWm, mSize).ISize(mWm); } nscoord GetInlineSize() const { return LogicalSize(mWm, mSize).ISize(mWm); }
bool Changed(const QueryContainerState& aNewState, StyleContainerType aType) { bool Changed(const QueryContainerState& aNewState, StyleContainerType aType) {
if (aType & StyleContainerType::SIZE) { switch (aType) {
return mSize != aNewState.mSize; case StyleContainerType::Normal:
} break;
if (aType & StyleContainerType::INLINE_SIZE) { case StyleContainerType::Size:
return GetInlineSize() != aNewState.GetInlineSize(); return mSize != aNewState.mSize;
case StyleContainerType::InlineSize:
return GetInlineSize() != aNewState.GetInlineSize();
} }
return false; return false;
} }
@ -1041,7 +1043,8 @@ bool nsPresContext::UpdateContainerQueryStyles() {
} }
auto type = frame->StyleDisplay()->mContainerType; 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())) { if (!mUpdatedContainerQueryContents.EnsureInserted(frame->GetContent())) {
continue; continue;

Просмотреть файл

@ -721,7 +721,7 @@ void nsIFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED); AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
} }
if (disp->mContainerType) { if (disp->mContainerType != StyleContainerType::Normal) {
PresContext()->RegisterContainerQueryFrame(this); PresContext()->RegisterContainerQueryFrame(this);
} }
@ -811,7 +811,7 @@ void nsIFrame::DestroyFrom(nsIFrame* aDestructRoot,
} }
} }
if (disp->mContainerType) { if (disp->mContainerType != StyleContainerType::Normal) {
PresContext()->UnregisterContainerQueryFrame(this); PresContext()->UnregisterContainerQueryFrame(this);
} }

Просмотреть файл

@ -2209,7 +2209,7 @@ nsStyleDisplay::nsStyleDisplay(const Document& aDocument)
mOriginalDisplay(StyleDisplay::Inline), mOriginalDisplay(StyleDisplay::Inline),
mContain(StyleContain::NONE), mContain(StyleContain::NONE),
mContentVisibility(StyleContentVisibility::Visible), mContentVisibility(StyleContentVisibility::Visible),
mContainerType(StyleContainerType::NORMAL), mContainerType(StyleContainerType::Normal),
mAppearance(StyleAppearance::None), mAppearance(StyleAppearance::None),
mDefaultAppearance(StyleAppearance::None), mDefaultAppearance(StyleAppearance::None),
mPosition(StylePositionProperty::Static), mPosition(StylePositionProperty::Static),

Просмотреть файл

@ -1705,7 +1705,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
auto contain = mContain; auto contain = mContain;
// content-visibility and container-type implicitly enable some containment // content-visibility and container-type implicitly enable some containment
// flags. // flags.
if (MOZ_LIKELY(!mContainerType) && if (MOZ_LIKELY(mContainerType == mozilla::StyleContainerType::Normal) &&
MOZ_LIKELY(mContentVisibility == StyleContentVisibility::Visible)) { MOZ_LIKELY(mContentVisibility == StyleContentVisibility::Visible)) {
return contain; return contain;
} }
@ -1726,18 +1726,24 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
break; break;
} }
if (mContainerType & mozilla::StyleContainerType::SIZE) { switch (mContainerType) {
// https://drafts.csswg.org/css-contain-3/#valdef-container-type-size: case mozilla::StyleContainerType::Normal:
// Applies layout containment, style containment, and size containment break;
// to the principal box. case mozilla::StyleContainerType::InlineSize:
contain |= mozilla::StyleContain::LAYOUT | mozilla::StyleContain::STYLE | // https://drafts.csswg.org/css-contain-3/#valdef-container-type-inline-size:
mozilla::StyleContain::SIZE; // Applies layout containment, style containment, and inline-size
} else if (mContainerType & mozilla::StyleContainerType::INLINE_SIZE) { // containment to the principal box.
// https://drafts.csswg.org/css-contain-3/#valdef-container-type-inline-size: contain |= mozilla::StyleContain::LAYOUT |
// Applies layout containment, style containment, and inline-size mozilla::StyleContain::STYLE |
// containment to the principal box. mozilla::StyleContain::INLINE_SIZE;
contain |= mozilla::StyleContain::LAYOUT | mozilla::StyleContain::STYLE | break;
mozilla::StyleContain::INLINE_SIZE; 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; return contain;

Просмотреть файл

@ -907,7 +907,7 @@ pub trait MatchMethods: TElement {
let is_container = !new_primary_style let is_container = !new_primary_style
.get_box() .get_box()
.clone_container_type() .clone_container_type()
.is_empty(); .is_normal();
if is_root || is_container { if is_root || is_container {
let new_font_size = new_primary_style.get_font().clone_font_size(); let new_font_size = new_primary_style.get_font().clone_font_size();
let old_font_size = old_styles let old_font_size = old_styles

Просмотреть файл

@ -445,7 +445,7 @@ ${helpers.predefined_type(
${helpers.predefined_type( ${helpers.predefined_type(
"container-type", "container-type",
"ContainerType", "ContainerType",
"computed::ContainerType::NORMAL", "computed::ContainerType::Normal",
engines="gecko", engines="gecko",
animation_value_type="none", animation_value_type="none",
gecko_pref="layout.css.container-queries.enabled", gecko_pref="layout.css.container-queries.enabled",

Просмотреть файл

@ -40,19 +40,19 @@ ${helpers.two_properties_shorthand(
gecko_pref="layout.css.container-queries.enabled", gecko_pref="layout.css.container-queries.enabled",
spec="https://drafts.csswg.org/css-contain-3/#container-shorthand" spec="https://drafts.csswg.org/css-contain-3/#container-shorthand"
> >
use crate::values::specified::box_::{ContainerName, ContainerType};
pub fn parse_value<'i>( pub fn parse_value<'i>(
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, '_>, input: &mut Parser<'i, '_>,
) -> Result<Longhands, ParseError<'i>> { ) -> Result<Longhands, ParseError<'i>> {
use crate::parser::Parse; 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 // See https://github.com/w3c/csswg-drafts/issues/7180 for why we don't
// match the spec. // match the spec.
let container_name = ContainerName::parse(context, input)?; let container_name = ContainerName::parse(context, input)?;
let container_type = if input.try_parse(|input| input.expect_delim('/')).is_ok() { let container_type = if input.try_parse(|input| input.expect_delim('/')).is_ok() {
ContainerType::parse(context, input)? ContainerType::parse(input)?
} else { } else {
ContainerType::NORMAL ContainerType::Normal
}; };
Ok(expanded! { Ok(expanded! {
container_name: container_name, container_name: container_name,
@ -63,7 +63,7 @@ ${helpers.two_properties_shorthand(
impl<'a> ToCss for LonghandsToSerialize<'a> { impl<'a> ToCss for LonghandsToSerialize<'a> {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
self.container_name.to_css(dest)?; self.container_name.to_css(dest)?;
if !self.container_type.is_empty() { if !self.container_type.is_normal() {
dest.write_str(" / ")?; dest.write_str(" / ")?;
self.container_type.to_css(dest)?; self.container_type.to_css(dest)?;
} }

Просмотреть файл

@ -114,18 +114,18 @@ pub struct ContainerLookupResult<E> {
} }
fn container_type_axes(ty_: ContainerType, wm: WritingMode) -> FeatureFlags { fn container_type_axes(ty_: ContainerType, wm: WritingMode) -> FeatureFlags {
if ty_.contains(ContainerType::SIZE) { match ty_ {
return FeatureFlags::all_container_axes(); 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<T> { enum TraversalResult<T> {
@ -476,7 +476,7 @@ impl<'a> ContainerSizeQuery<'a> {
let container_type = box_style.clone_container_type(); let container_type = box_style.clone_container_type();
let size = e.primary_box_size(); let size = e.primary_box_size();
match container_type { match container_type {
ContainerType::SIZE => { ContainerType::Size=> {
TraversalResult::Done( TraversalResult::Done(
ContainerSizeQueryResult { ContainerSizeQueryResult {
width: Some(size.width), width: Some(size.width),
@ -484,7 +484,7 @@ impl<'a> ContainerSizeQuery<'a> {
} }
) )
}, },
ContainerType::INLINE_SIZE => { ContainerType::InlineSize => {
if wm.is_horizontal() { if wm.is_horizontal() {
TraversalResult::Done( TraversalResult::Done(
ContainerSizeQueryResult { ContainerSizeQueryResult {
@ -501,7 +501,7 @@ impl<'a> ContainerSizeQuery<'a> {
) )
} }
}, },
_ => TraversalResult::InProgress, ContainerType::Normal => TraversalResult::InProgress,
} }
} }

Просмотреть файл

@ -1515,30 +1515,28 @@ pub enum ContentVisibility {
Visible, Visible,
} }
bitflags! { #[derive(Clone, Copy, Debug, PartialEq, Eq, MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToCss, Parse, ToResolvedValue, ToShmem)]
#[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToCss, Parse, ToResolvedValue, ToShmem)] #[repr(u8)]
#[repr(C)] #[allow(missing_docs)]
#[allow(missing_docs)] /// https://drafts.csswg.org/css-contain-3/#container-type
#[css(bitflags(single="normal", mixed="size,inline-size", overlapping_bits))] pub enum ContainerType {
/// https://drafts.csswg.org/css-contain-3/#container-type /// The `normal` variant.
/// Normal,
/// TODO: block-size is on the spec but it seems it was removed? WPTs don't /// The `inline-size` variant.
/// support it, see https://github.com/w3c/csswg-drafts/issues/7179. InlineSize,
pub struct ContainerType: u8 { /// The `size` variant.
/// The `normal` variant. Size,
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;
}
} }
impl ContainerType { impl ContainerType {
/// Is this container-type: normal?
pub fn is_normal(self) -> bool {
self == Self::Normal
}
/// Is this type containing size in any way? /// Is this type containing size in any way?
pub fn is_size_container_type(&self) -> bool { pub fn is_size_container_type(self) -> bool {
self.intersects(ContainerType::SIZE | ContainerType::INLINE_SIZE) !self.is_normal()
} }
} }

Просмотреть файл

@ -1,2 +0,0 @@
[fieldset-legend-change.html]
expected: FAIL

Просмотреть файл

@ -1,2 +1,2 @@
[inline-size-bfc-floats.html] [inline-size-bfc-floats.html]
expected: FAIL expected: TIMEOUT