зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #15813 - Implement parsing/serialization and glue for will-change property (from canaltinova:will-change); r=upsuper,emilio
Implement parsing/serialization and glue for will-change property --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #15706 (github issue number if applicable). <!-- Either: --> - [x] There are tests for these changes <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: cb1438e44f0550378867a308494e4f84b1e00478 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : caf2bb046a96cc073eace38d7c14a3a819d8a111
This commit is contained in:
Родитель
16207207f1
Коммит
7eea9c3295
|
@ -781,6 +781,17 @@ extern "C" {
|
|||
*mut ::std::os::raw::c_void,
|
||||
len: usize);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_ClearWillChange(display: *mut nsStyleDisplay, length: usize);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_AppendWillChange(display: *mut nsStyleDisplay,
|
||||
atom: *mut nsIAtom);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CopyWillChangeFrom(dest: *mut nsStyleDisplay,
|
||||
src: *mut nsStyleDisplay);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_AnimationAppendKeyframe(keyframes:
|
||||
RawGeckoKeyframeListBorrowedMut,
|
||||
|
|
|
@ -96,7 +96,8 @@ class Longhand(object):
|
|||
predefined_type=None, custom_cascade=False, experimental=False, internal=False,
|
||||
need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False,
|
||||
allowed_in_keyframe_block=True, complex_color=False, cast_type='u8',
|
||||
has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False):
|
||||
has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False,
|
||||
creates_stacking_context=False, fixpos_cb=False, abspos_cb=False):
|
||||
self.name = name
|
||||
if not spec:
|
||||
raise TypeError("Spec should be specified for %s" % name)
|
||||
|
@ -120,6 +121,9 @@ class Longhand(object):
|
|||
self.alias = alias.split() if alias else []
|
||||
self.extra_prefixes = extra_prefixes.split() if extra_prefixes else []
|
||||
self.boxed = arg_to_bool(boxed)
|
||||
self.creates_stacking_context = arg_to_bool(creates_stacking_context)
|
||||
self.fixpos_cb = arg_to_bool(fixpos_cb)
|
||||
self.abspos_cb = arg_to_bool(abspos_cb)
|
||||
|
||||
# https://drafts.csswg.org/css-animations/#keyframes
|
||||
# > The <declaration-list> inside of <keyframe-block> accepts any CSS property
|
||||
|
|
|
@ -1423,7 +1423,7 @@ fn static_assert() {
|
|||
page-break-before page-break-after
|
||||
scroll-snap-points-x scroll-snap-points-y transform
|
||||
scroll-snap-type-y scroll-snap-coordinate
|
||||
perspective-origin transform-origin -moz-binding""" %>
|
||||
perspective-origin transform-origin -moz-binding will-change""" %>
|
||||
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
|
||||
|
||||
// We manually-implement the |display| property until we get general
|
||||
|
@ -1918,6 +1918,92 @@ fn static_assert() {
|
|||
.expect("clone for Length failed"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_will_change(&mut self, v: longhands::will_change::computed_value::T) {
|
||||
use gecko_bindings::bindings::{Gecko_AppendWillChange, Gecko_ClearWillChange};
|
||||
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_OPACITY;
|
||||
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_SCROLL;
|
||||
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_TRANSFORM;
|
||||
use properties::PropertyId;
|
||||
use properties::longhands::will_change::computed_value::T;
|
||||
|
||||
fn will_change_bitfield_from_prop_flags(prop: &LonghandId) -> u8 {
|
||||
use properties::{ABSPOS_CB, CREATES_STACKING_CONTEXT, FIXPOS_CB};
|
||||
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_ABSPOS_CB;
|
||||
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_FIXPOS_CB;
|
||||
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_STACKING_CONTEXT;
|
||||
let servo_flags = prop.flags();
|
||||
let mut bitfield = 0;
|
||||
|
||||
if servo_flags.contains(CREATES_STACKING_CONTEXT) {
|
||||
bitfield |= NS_STYLE_WILL_CHANGE_STACKING_CONTEXT;
|
||||
}
|
||||
if servo_flags.contains(FIXPOS_CB) {
|
||||
bitfield |= NS_STYLE_WILL_CHANGE_FIXPOS_CB;
|
||||
}
|
||||
if servo_flags.contains(ABSPOS_CB) {
|
||||
bitfield |= NS_STYLE_WILL_CHANGE_ABSPOS_CB;
|
||||
}
|
||||
|
||||
bitfield as u8
|
||||
}
|
||||
|
||||
self.gecko.mWillChangeBitField = 0;
|
||||
|
||||
match v {
|
||||
T::AnimateableFeatures(features) => {
|
||||
unsafe {
|
||||
Gecko_ClearWillChange(&mut self.gecko, features.len());
|
||||
}
|
||||
|
||||
for feature in features.iter() {
|
||||
if feature == &atom!("scroll-position") {
|
||||
self.gecko.mWillChangeBitField |= NS_STYLE_WILL_CHANGE_SCROLL as u8;
|
||||
} else if feature == &atom!("opacity") {
|
||||
self.gecko.mWillChangeBitField |= NS_STYLE_WILL_CHANGE_OPACITY as u8;
|
||||
} else if feature == &atom!("transform") {
|
||||
self.gecko.mWillChangeBitField |= NS_STYLE_WILL_CHANGE_TRANSFORM as u8;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
Gecko_AppendWillChange(&mut self.gecko, feature.as_ptr());
|
||||
}
|
||||
|
||||
if let Ok(prop_id) = PropertyId::parse(feature.to_string().into()) {
|
||||
match prop_id.as_shorthand() {
|
||||
Ok(shorthand) => {
|
||||
for longhand in shorthand.longhands() {
|
||||
self.gecko.mWillChangeBitField |=
|
||||
will_change_bitfield_from_prop_flags(longhand);
|
||||
}
|
||||
},
|
||||
Err(longhand_or_custom) => {
|
||||
if let PropertyDeclarationId::Longhand(longhand)
|
||||
= longhand_or_custom {
|
||||
self.gecko.mWillChangeBitField |=
|
||||
will_change_bitfield_from_prop_flags(&longhand);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T::Auto => {
|
||||
unsafe {
|
||||
Gecko_ClearWillChange(&mut self.gecko, 0);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn copy_will_change_from(&mut self, other: &Self) {
|
||||
use gecko_bindings::bindings::Gecko_CopyWillChangeFrom;
|
||||
|
||||
self.gecko.mWillChangeBitField = other.gecko.mWillChangeBitField;
|
||||
unsafe {
|
||||
Gecko_CopyWillChangeFrom(&mut self.gecko, &other.gecko as *const _ as *mut _);
|
||||
}
|
||||
}
|
||||
</%self:impl_trait>
|
||||
|
||||
<%def name="simple_image_array_property(name, shorthand, field_name)">
|
||||
|
|
|
@ -108,6 +108,8 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
|
|||
need_clone="True"
|
||||
extra_gecko_values="sticky"
|
||||
animatable="False"
|
||||
creates_stacking_context="True"
|
||||
abspos_cb="True"
|
||||
spec="https://drafts.csswg.org/css-position/#position-property">
|
||||
impl SpecifiedValue {
|
||||
pub fn is_absolutely_positioned_style(&self) -> bool {
|
||||
|
@ -1116,6 +1118,8 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
|
||||
<%helpers:longhand name="transform" products="gecko servo" extra_prefixes="webkit"
|
||||
animatable="True"
|
||||
creates_stacking_context="True"
|
||||
fixpos_cb="True"
|
||||
spec="https://drafts.csswg.org/css-transforms/#propdef-transform">
|
||||
use app_units::Au;
|
||||
use style_traits::ToCss;
|
||||
|
@ -1672,6 +1676,7 @@ ${helpers.single_keyword("isolation",
|
|||
"auto isolate",
|
||||
products="gecko",
|
||||
spec="https://drafts.fxtf.org/compositing/#isolation",
|
||||
creates_stacking_context=True,
|
||||
animatable=False)}
|
||||
|
||||
// TODO add support for logical values recto and verso
|
||||
|
@ -1710,6 +1715,8 @@ ${helpers.predefined_type("perspective",
|
|||
spec="https://drafts.csswg.org/css-transforms/#perspective",
|
||||
extra_prefixes="moz webkit",
|
||||
boxed=True,
|
||||
creates_stacking_context=True,
|
||||
fixpos_cb=True,
|
||||
animatable=True)}
|
||||
|
||||
// FIXME: This prop should be animatable
|
||||
|
@ -1819,6 +1826,8 @@ ${helpers.single_keyword("transform-style",
|
|||
"flat preserve-3d",
|
||||
spec="https://drafts.csswg.org/css-transforms/#transform-style-property",
|
||||
extra_prefixes="moz webkit",
|
||||
creates_stacking_context=True,
|
||||
fixpos_cb=True,
|
||||
animatable=False)}
|
||||
|
||||
<%helpers:longhand name="transform-origin" animatable="True" extra_prefixes="moz webkit" boxed="True"
|
||||
|
@ -1973,3 +1982,67 @@ ${helpers.single_keyword("-moz-orient",
|
|||
gecko_enum_prefix="StyleOrient",
|
||||
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-orient)",
|
||||
animatable=False)}
|
||||
|
||||
<%helpers:longhand name="will-change" products="gecko" animatable="False"
|
||||
spec="https://drafts.csswg.org/css-will-change/#will-change">
|
||||
use cssparser::serialize_identifier;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::HasViewportPercentage;
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
|
||||
impl ComputedValueAsSpecified for SpecifiedValue {}
|
||||
no_viewport_percentage!(SpecifiedValue);
|
||||
|
||||
pub mod computed_value {
|
||||
pub use super::SpecifiedValue as T;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum SpecifiedValue {
|
||||
Auto,
|
||||
AnimateableFeatures(Vec<Atom>),
|
||||
}
|
||||
|
||||
impl ToCss for SpecifiedValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
SpecifiedValue::Auto => dest.write_str("auto"),
|
||||
SpecifiedValue::AnimateableFeatures(ref features) => {
|
||||
let (first, rest) = features.split_first().unwrap();
|
||||
// handle head element
|
||||
serialize_identifier(&*first.to_string(), dest)?;
|
||||
// handle tail, precede each with a delimiter
|
||||
for feature in rest {
|
||||
dest.write_str(", ")?;
|
||||
serialize_identifier(&*feature.to_string(), dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_initial_value() -> computed_value::T {
|
||||
computed_value::T::Auto
|
||||
}
|
||||
|
||||
/// auto | <animateable-feature>#
|
||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
|
||||
Ok(computed_value::T::Auto)
|
||||
} else {
|
||||
input.parse_comma_separated(|i| {
|
||||
let ident = i.expect_ident()?;
|
||||
match_ignore_ascii_case! { &ident,
|
||||
"will-change" | "none" | "all" | "auto" |
|
||||
"initial" | "inherit" | "unset" | "default" => return Err(()),
|
||||
_ => {},
|
||||
}
|
||||
Ok((Atom::from(ident)))
|
||||
}).map(SpecifiedValue::AnimateableFeatures)
|
||||
}
|
||||
}
|
||||
</%helpers:longhand>
|
||||
|
|
|
@ -11,6 +11,7 @@ ${helpers.predefined_type("opacity",
|
|||
"Opacity",
|
||||
"1.0",
|
||||
animatable=True,
|
||||
creates_stacking_context=True,
|
||||
spec="https://drafts.csswg.org/css-color/#opacity")}
|
||||
|
||||
<%helpers:vector_longhand name="box-shadow" allow_empty="True"
|
||||
|
@ -86,6 +87,8 @@ ${helpers.predefined_type("clip",
|
|||
|
||||
// FIXME: This prop should be animatable
|
||||
<%helpers:longhand name="filter" animatable="False" extra_prefixes="webkit"
|
||||
creates_stacking_context="True"
|
||||
fixpos_cb="True"
|
||||
spec="https://drafts.fxtf.org/filters/#propdef-filter">
|
||||
//pub use self::computed_value::T as SpecifiedValue;
|
||||
use cssparser;
|
||||
|
@ -516,4 +519,5 @@ ${helpers.single_keyword("mix-blend-mode",
|
|||
color-burn hard-light soft-light difference exclusion hue
|
||||
saturation color luminosity""", gecko_constant_prefix="NS_STYLE_BLEND",
|
||||
animatable=False,
|
||||
creates_stacking_context=True,
|
||||
spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode")}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
${helpers.predefined_type("z-index", "IntegerOrAuto",
|
||||
"Either::Second(Auto)",
|
||||
spec="https://www.w3.org/TR/CSS2/visuren.html#z-index",
|
||||
creates_stacking_context=True,
|
||||
animatable="True")}
|
||||
|
||||
// CSS Flexible Box Layout Module Level 1
|
||||
|
|
|
@ -59,6 +59,7 @@ ${helpers.single_keyword("mask-type", "luminance alpha",
|
|||
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-type")}
|
||||
|
||||
<%helpers:longhand name="clip-path" animatable="False" products="gecko" boxed="True"
|
||||
creates_stacking_context="True"
|
||||
spec="https://drafts.fxtf.org/css-masking/#propdef-clip-path">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
@ -189,7 +190,8 @@ ${helpers.single_keyword("mask-composite",
|
|||
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-composite")}
|
||||
|
||||
<%helpers:vector_longhand name="mask-image" products="gecko" animatable="False" extra_prefixes="webkit"
|
||||
has_uncacheable_values="${product == 'gecko'}",
|
||||
has_uncacheable_values="${product == 'gecko'}"
|
||||
creates_stacking_context="True"
|
||||
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-image">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
|
|
@ -420,6 +420,20 @@ impl Parse for CSSWideKeyword {
|
|||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// A set of flags for properties.
|
||||
pub flags PropertyFlags: u8 {
|
||||
/// This property requires a stacking context.
|
||||
const CREATES_STACKING_CONTEXT = 0x01,
|
||||
/// This property has values that can establish a containing block for
|
||||
/// fixed positioned and absolutely positioned elements.
|
||||
const FIXPOS_CB = 0x02,
|
||||
/// This property has values that can establish a containing block for
|
||||
/// absolutely positioned elements.
|
||||
const ABSPOS_CB = 0x04,
|
||||
}
|
||||
}
|
||||
|
||||
/// An identifier for a given longhand property.
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
@ -458,6 +472,25 @@ impl LonghandId {
|
|||
_ => *self
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns PropertyFlags for given property.
|
||||
pub fn flags(&self) -> PropertyFlags {
|
||||
match *self {
|
||||
% for property in data.longhands:
|
||||
LonghandId::${property.camel_case} =>
|
||||
%if property.creates_stacking_context:
|
||||
CREATES_STACKING_CONTEXT |
|
||||
%endif
|
||||
%if property.fixpos_cb:
|
||||
FIXPOS_CB |
|
||||
%endif
|
||||
%if property.abspos_cb:
|
||||
ABSPOS_CB |
|
||||
%endif
|
||||
PropertyFlags::empty(),
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An identifier for a given shorthand property.
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use cssparser::Parser;
|
||||
use media_queries::CSSErrorReporterTest;
|
||||
use parsing::parse;
|
||||
use style::parser::ParserContext;
|
||||
use style::stylesheets::Origin;
|
||||
use style_traits::ToCss;
|
||||
|
||||
#[test]
|
||||
fn test_will_change() {
|
||||
use style::properties::longhands::will_change;
|
||||
|
||||
assert_roundtrip_with_context!(will_change::parse, "auto");
|
||||
assert_roundtrip_with_context!(will_change::parse, "scroll-position");
|
||||
assert_roundtrip_with_context!(will_change::parse, "contents");
|
||||
assert_roundtrip_with_context!(will_change::parse, "transition");
|
||||
assert_roundtrip_with_context!(will_change::parse, "opacity, transform");
|
||||
|
||||
assert!(parse(will_change::parse, "will-change").is_err());
|
||||
assert!(parse(will_change::parse, "all").is_err());
|
||||
assert!(parse(will_change::parse, "none").is_err());
|
||||
assert!(parse(will_change::parse, "contents, auto").is_err());
|
||||
assert!(parse(will_change::parse, "contents, inherit, initial").is_err());
|
||||
assert!(parse(will_change::parse, "transform scroll-position").is_err());
|
||||
}
|
|
@ -85,6 +85,7 @@ mod animation;
|
|||
mod background;
|
||||
mod basic_shape;
|
||||
mod border;
|
||||
mod box_;
|
||||
mod column;
|
||||
mod effects;
|
||||
mod font;
|
||||
|
|
Загрузка…
Ссылка в новой задаче