layout: support CSS will-change (#35787)

* support CSS `will-change`



* update wpt-test result



* Enable css-will-change test



* Update css-will-change test results



* Check transformable before will-change; update wpt-results



* Solve merge conflict



* Update Cargo.toml and Cargo.lock



* Mark new failing test-cases


---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
This commit is contained in:
Euclid Ye 2025-03-10 00:15:28 +08:00 committed by GitHub
parent 66583ce3c9
commit 4d73de3dde
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 84 additions and 71 deletions

View file

@ -25,7 +25,7 @@ use style::values::computed::{AlignItems, BorderStyle, Color, Inset, LengthPerce
use style::values::generics::box_::Perspective;
use style::values::generics::position::{GenericAspectRatio, PreferredRatio};
use style::values::specified::align::AlignFlags;
use style::values::specified::{Overflow, box_ as stylo};
use style::values::specified::{Overflow, WillChangeBits, box_ as stylo};
use webrender_api as wr;
use crate::dom_traversal::Contents;
@ -639,6 +639,21 @@ impl ComputedValuesExt for ComputedValues {
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 create a stacking context on the element,
// > specifying that property in will-change must create a stacking context on the element.
let will_change_bits = self.clone_will_change().bits;
if will_change_bits.intersects(
WillChangeBits::OPACITY |
WillChangeBits::STACKING_CONTEXT_UNCONDITIONAL |
WillChangeBits::Z_INDEX,
) || (will_change_bits
.intersects(WillChangeBits::PERSPECTIVE | WillChangeBits::TRANSFORM) &&
self.is_transformable(fragment_flags))
{
return true;
}
// Statically positioned fragments don't establish stacking contexts if the previous
// conditions are not fulfilled. Furthermore, z-index doesn't apply to statically
// positioned fragments (except for flex items, see below).
@ -674,6 +689,18 @@ impl ComputedValuesExt for ComputedValues {
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 absolutely positioned elements, specifying that property in
// > will-change must cause the element to generate a containing block for absolutely positioned elements.
if self
.clone_will_change()
.bits
.intersects(WillChangeBits::POSITION)
{
return true;
}
self.clone_position() != ComputedPosition::Static
}
@ -699,6 +726,18 @@ impl ComputedValuesExt for ComputedValues {
{
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))
{
return true;
}
// TODO: We need to handle CSS Contain here.
false