mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
layout: Refactor establishes_containing_block_for_all_descendants()
(#36725)
Instead of grouping all the `will-change` conditions together, move each one of them next to the condition for the relevant property. This avoids the need to call `is_transformable()` multiple times, and will also be needed for #35391. Testing: unneeded (no change in behavior) Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
b1d0b6a37b
commit
cf41012257
2 changed files with 52 additions and 30 deletions
|
@ -530,7 +530,7 @@ impl StackingContext {
|
|||
if effects.filter.0.is_empty() &&
|
||||
effects.opacity == 1.0 &&
|
||||
effects.mix_blend_mode == ComputedMixBlendMode::Normal &&
|
||||
!style.has_transform_or_perspective(FragmentFlags::empty()) &&
|
||||
!style.has_effective_transform_or_perspective(FragmentFlags::empty()) &&
|
||||
style.clone_clip_path() == ClipPath::None
|
||||
{
|
||||
return false;
|
||||
|
@ -1584,7 +1584,10 @@ impl BoxFragment {
|
|||
&self,
|
||||
containing_block_rect: &PhysicalRect<Au>,
|
||||
) -> Option<ReferenceFrameData> {
|
||||
if !self.style.has_transform_or_perspective(self.base.flags) {
|
||||
if !self
|
||||
.style
|
||||
.has_effective_transform_or_perspective(self.base.flags)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
@ -320,7 +320,8 @@ pub(crate) trait ComputedValuesExt {
|
|||
containing_block_writing_mode: WritingMode,
|
||||
) -> LogicalSides<LengthPercentageOrAuto<'_>>;
|
||||
fn is_transformable(&self, fragment_flags: FragmentFlags) -> bool;
|
||||
fn has_transform_or_perspective(&self, fragment_flags: FragmentFlags) -> bool;
|
||||
fn has_transform_or_perspective_style(&self) -> bool;
|
||||
fn has_effective_transform_or_perspective(&self, fragment_flags: FragmentFlags) -> bool;
|
||||
fn z_index_applies(&self, fragment_flags: FragmentFlags) -> bool;
|
||||
fn effective_z_index(&self, fragment_flags: FragmentFlags) -> i32;
|
||||
fn effective_overflow(&self, fragment_flags: FragmentFlags) -> AxesOverflow;
|
||||
|
@ -522,15 +523,20 @@ impl ComputedValuesExt for ComputedValues {
|
|||
!self.is_inline_box(fragment_flags)
|
||||
}
|
||||
|
||||
/// Returns true if this style has a transform, or perspective property set and
|
||||
/// Returns true if this style has a transform or perspective property set.
|
||||
fn has_transform_or_perspective_style(&self) -> bool {
|
||||
!self.get_box().transform.0.is_empty() ||
|
||||
self.get_box().scale != GenericScale::None ||
|
||||
self.get_box().rotate != GenericRotate::None ||
|
||||
self.get_box().translate != GenericTranslate::None ||
|
||||
self.get_box().perspective != Perspective::None
|
||||
}
|
||||
|
||||
/// Returns true if this style has a transform or perspective property set, and
|
||||
/// it applies to this element.
|
||||
fn has_transform_or_perspective(&self, fragment_flags: FragmentFlags) -> bool {
|
||||
self.is_transformable(fragment_flags) &&
|
||||
(!self.get_box().transform.0.is_empty() ||
|
||||
self.get_box().scale != GenericScale::None ||
|
||||
self.get_box().rotate != GenericRotate::None ||
|
||||
self.get_box().translate != GenericTranslate::None ||
|
||||
self.get_box().perspective != Perspective::None)
|
||||
#[inline]
|
||||
fn has_effective_transform_or_perspective(&self, fragment_flags: FragmentFlags) -> bool {
|
||||
self.is_transformable(fragment_flags) && self.has_transform_or_perspective_style()
|
||||
}
|
||||
|
||||
/// Whether the `z-index` property applies to this fragment.
|
||||
|
@ -705,7 +711,6 @@ impl ComputedValuesExt for ComputedValues {
|
|||
if self.is_transformable(fragment_flags) &&
|
||||
(!self.get_box().transform.0.is_empty() ||
|
||||
self.get_box().transform_style == ComputedTransformStyle::Preserve3d ||
|
||||
self.get_box().perspective != Perspective::None ||
|
||||
will_change_bits
|
||||
.intersects(WillChangeBits::TRANSFORM | WillChangeBits::PERSPECTIVE))
|
||||
{
|
||||
|
@ -795,29 +800,43 @@ impl ComputedValuesExt for ComputedValues {
|
|||
&self,
|
||||
fragment_flags: FragmentFlags,
|
||||
) -> bool {
|
||||
if self.has_transform_or_perspective(fragment_flags) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if !self.get_effects().filter.0.is_empty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// See <https://drafts.csswg.org/css-transforms-2/#transform-style-property>.
|
||||
if self.is_transformable(fragment_flags) &&
|
||||
self.get_box().transform_style == ComputedTransformStyle::Preserve3d
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// From <https://www.w3.org/TR/css-will-change/#valdef-will-change-custom-ident>:
|
||||
// > If any non-initial value of a property would cause the element to generate a
|
||||
// > containing block for fixed positioned elements, specifying that property in will-change
|
||||
// > must cause the element to generate a containing block for fixed positioned elements.
|
||||
let will_change_bits = self.clone_will_change().bits;
|
||||
if will_change_bits.intersects(WillChangeBits::FIXPOS_CB_NON_SVG) ||
|
||||
(will_change_bits
|
||||
.intersects(WillChangeBits::TRANSFORM | WillChangeBits::PERSPECTIVE) &&
|
||||
self.is_transformable(fragment_flags))
|
||||
|
||||
// From <https://drafts.csswg.org/css-transforms-1/#transform-rendering>:
|
||||
// > any value other than `none` for the `transform` property also causes the element
|
||||
// > to establish a containing block for all descendants.
|
||||
//
|
||||
// From <https://www.w3.org/TR/css-transforms-2/#individual-transforms>
|
||||
// > all other values […] create a stacking context and containing block for all
|
||||
// > descendants, per usual for transforms.
|
||||
//
|
||||
// From <https://drafts.csswg.org/css-transforms-2/#perspective-property>:
|
||||
// > The use of this property with any value other than `none` […] establishes a
|
||||
// > containing block for all descendants, just like the `transform` property does.
|
||||
//
|
||||
// From <https://drafts.csswg.org/css-transforms-2/#transform-style-property>:
|
||||
// > A computed value of `preserve-3d` for `transform-style` on a transformable element
|
||||
// > establishes both a stacking context and a containing block for all descendants.
|
||||
if self.is_transformable(fragment_flags) &&
|
||||
(self.has_transform_or_perspective_style() ||
|
||||
self.get_box().transform_style == ComputedTransformStyle::Preserve3d ||
|
||||
will_change_bits
|
||||
.intersects(WillChangeBits::TRANSFORM | WillChangeBits::PERSPECTIVE))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// From <https://www.w3.org/TR/filter-effects-1/#propdef-filter>:
|
||||
// > A value other than none for the filter property results in the creation of a containing
|
||||
// > block for absolute and fixed positioned descendants unless the element it applies to is
|
||||
// > a document root element in the current browsing context.
|
||||
// FIXME(#35391): Need to check if this is the root element.
|
||||
if !self.get_effects().filter.0.is_empty() ||
|
||||
will_change_bits.intersects(WillChangeBits::FIXPOS_CB_NON_SVG)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue