Backed out 5 changesets (bug 1864736, bug 1877383) for causing build bustages with `is_parsed` CLOSED TREE

Backed out changeset 230e45fd2ece (bug 1877383)
Backed out changeset 3f19bcf6a34f (bug 1864736)
Backed out changeset cc6c51d8d712 (bug 1864736)
Backed out changeset eefa88f79557 (bug 1864736)
Backed out changeset 7cddfe0bce3a (bug 1864736)
This commit is contained in:
Cristian Tuns 2024-03-11 01:11:17 -04:00
Родитель 45d3aedb0d
Коммит e4866809a2
41 изменённых файлов: 470 добавлений и 350 удалений

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

@ -15,10 +15,7 @@ use crate::properties::{
};
use crate::properties_and_values::{
registry::PropertyRegistrationData,
value::{
AllowComputationallyDependent, ComputedValue as ComputedRegisteredValue,
SpecifiedValue as SpecifiedRegisteredValue,
},
value::{AllowComputationallyDependent, SpecifiedValue as SpecifiedRegisteredValue},
};
use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet};
use crate::stylesheets::UrlExtraData;
@ -253,7 +250,7 @@ impl ComputedCustomProperties {
}
/// Return the name and value of the property at specified index, if any.
pub fn property_at(&self, index: usize) -> Option<(&Name, &Option<ComputedRegisteredValue>)> {
pub fn property_at(&self, index: usize) -> Option<(&Name, &Option<Arc<VariableValue>>)> {
// Just expose the custom property items from custom_properties.inherited, followed
// by custom property items from custom_properties.non_inherited.
self.inherited
@ -267,7 +264,7 @@ impl ComputedCustomProperties {
&mut self,
registration: &PropertyRegistrationData,
name: &Name,
value: ComputedRegisteredValue,
value: Arc<VariableValue>,
) {
self.map_mut(registration).insert(name, value)
}
@ -296,7 +293,7 @@ impl ComputedCustomProperties {
&self,
registration: &PropertyRegistrationData,
name: &Name,
) -> Option<&ComputedRegisteredValue> {
) -> Option<&Arc<VariableValue>> {
if registration.inherits() {
self.inherited.get(name)
} else {
@ -677,9 +674,7 @@ fn parse_declaration_value_block<'i, 't>(
let mut prev_reference_index: Option<usize> = None;
loop {
let token_start = input.position();
let Ok(token) = input.next_including_whitespace_and_comments() else {
break;
};
let Ok(token) = input.next_including_whitespace_and_comments() else { break };
let prev_token_type = last_token_type;
let serialization_type = token.serialization_type();
@ -819,8 +814,7 @@ fn parse_declaration_value_block<'i, 't>(
check_closed!(")");
prev_reference_index = Some(our_ref_index);
let reference = &mut references.refs[our_ref_index];
reference.end = input.position().byte_index() - input_start.byte_index() +
missing_closing_characters.len();
reference.end = input.position().byte_index() - input_start.byte_index() + missing_closing_characters.len();
reference.fallback = fallback;
if is_var {
references.any_var = true;
@ -896,11 +890,7 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
/// Create a new builder, inheriting from a given custom properties map.
///
/// We expose this publicly mostly for @keyframe blocks.
pub fn new_with_properties(
stylist: &'a Stylist,
custom_properties: ComputedCustomProperties,
computed_context: &'a mut computed::Context<'b>,
) -> Self {
pub fn new_with_properties(stylist: &'a Stylist, custom_properties: ComputedCustomProperties, computed_context: &'a mut computed::Context<'b>) -> Self {
Self {
seen: PrecomputedHashSet::default(),
reverted: Default::default(),
@ -930,9 +920,7 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
// Reuse flags from computing registered custom properties initial values, such as
// whether they depend on viewport units.
context
.style()
.add_flags(stylist.get_custom_property_initial_values_flags());
context.style().add_flags(stylist.get_custom_property_initial_values_flags());
Self::new_with_properties(stylist, properties, context)
}
@ -960,8 +948,8 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
let map = &mut self.custom_properties;
let registration = self.stylist.get_custom_property_registration(&name);
match value {
CustomDeclarationValue::Value(unparsed_value) => {
match *value {
CustomDeclarationValue::Value(ref unparsed_value) => {
let has_custom_property_references = unparsed_value.references.any_var;
let registered_length_property =
registration.syntax.may_reference_font_relative_length();
@ -987,19 +975,21 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
self.computed_context,
);
}
let value = ComputedRegisteredValue::universal(Arc::clone(unparsed_value));
map.insert(registration, name, value);
map.insert(registration, name, Arc::clone(unparsed_value));
},
CustomDeclarationValue::CSSWideKeyword(keyword) => match keyword {
CSSWideKeyword::RevertLayer | CSSWideKeyword::Revert => {
let origin_revert = matches!(keyword, CSSWideKeyword::Revert);
let origin_revert = keyword == CSSWideKeyword::Revert;
self.seen.remove(name);
self.reverted.insert(name, (priority, origin_revert));
},
CSSWideKeyword::Initial => {
// For non-inherited custom properties, 'initial' was handled in value_may_affect_style.
debug_assert!(registration.inherits(), "Should've been handled earlier");
remove_and_insert_initial_value(name, registration, map);
map.remove(registration, name);
if let Some(ref initial_value) = registration.initial_value {
map.insert(registration, name, initial_value.clone());
}
},
CSSWideKeyword::Inherit => {
// For inherited custom properties, 'inherit' was handled in value_may_affect_style.
@ -1021,11 +1011,7 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
/// Note a non-custom property with variable reference that may in turn depend on that property.
/// e.g. `font-size` depending on a custom property that may be a registered property using `em`.
pub fn note_potentially_cyclic_non_custom_dependency(
&mut self,
id: LonghandId,
decl: &VariableDeclaration,
) {
pub fn note_potentially_cyclic_non_custom_dependency(&mut self, id: LonghandId, decl: &VariableDeclaration) {
// With unit algebra in `calc()`, references aren't limited to `font-size`.
// For example, `--foo: 100ex; font-weight: calc(var(--foo) / 1ex);`,
// or `--foo: 1em; zoom: calc(var(--foo) * 30px / 2em);`
@ -1039,7 +1025,8 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
},
LonghandId::LineHeight => {
if self.computed_context.is_root_element() {
NonCustomReferences::ROOT_LH_UNITS | NonCustomReferences::ROOT_FONT_UNITS
NonCustomReferences::ROOT_LH_UNITS |
NonCustomReferences::ROOT_FONT_UNITS
} else {
NonCustomReferences::LH_UNITS | NonCustomReferences::FONT_UNITS
}
@ -1051,24 +1038,15 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
return;
}
let variables: Vec<Atom> = refs
.refs
.iter()
.filter_map(|reference| {
if !reference.is_var {
return None;
}
if !self
.stylist
.get_custom_property_registration(&reference.name)
.syntax
.may_compute_length()
{
return None;
}
Some(reference.name.clone())
})
.collect();
let variables: Vec<Atom> = refs.refs.iter().filter_map(|reference| {
if !reference.is_var {
return None;
}
if !self.stylist.get_custom_property_registration(&reference.name).syntax.may_compute_length() {
return None;
}
Some(reference.name.clone())
}).collect();
references.for_each(|idx| {
let entry = &mut self.references_from_non_custom_properties[idx];
let was_none = entry.is_none();
@ -1125,12 +1103,8 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
debug_assert!(registration.inherits(), "Should've been handled earlier");
// Don't bother overwriting an existing value with the initial value specified in
// the registration.
if let Some(initial_value) = self
.stylist
.get_custom_property_initial_values()
.get(registration, name)
{
return existing_value != initial_value;
if Some(existing_value) == registration.initial_value.as_ref() {
return false;
}
},
(Some(_), &CustomDeclarationValue::CSSWideKeyword(CSSWideKeyword::Inherit)) => {
@ -1151,16 +1125,8 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
(Some(existing_value), &CustomDeclarationValue::Value(ref value)) => {
// Don't bother overwriting an existing value with the same
// specified value.
if let Some(existing_value) = existing_value.as_universal() {
return existing_value != value;
}
if let Ok(value) = compute_value(
&value.css,
&value.url_data,
registration,
self.computed_context,
) {
return existing_value.v != value.v;
if existing_value == value {
return false;
}
},
_ => {},
@ -1203,8 +1169,7 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
self.stylist,
self.computed_context,
);
self.computed_context.builder.invalid_non_custom_properties =
invalid_non_custom_properties;
self.computed_context.builder.invalid_non_custom_properties = invalid_non_custom_properties;
}
self.custom_properties.shrink_to_fit();
@ -1218,8 +1183,7 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
inherited: if self
.computed_context
.inherited_custom_properties()
.inherited ==
self.custom_properties.inherited
.inherited == self.custom_properties.inherited
{
self.computed_context
.inherited_custom_properties()
@ -1258,9 +1222,6 @@ impl<'a, 'b: 'a> CustomPropertiesBuilder<'a, 'b> {
// have to worry about resolving in a wrong order.
for (k, v) in deferred.iter() {
let Some(v) = v else { continue };
let Some(v) = v.as_universal() else {
unreachable!("Computing should have been deferred!")
};
substitute_references_if_needed_and_apply(
k,
v,
@ -1384,7 +1345,6 @@ fn substitute_all(
VarType::Custom(ref name) => {
let registration = context.stylist.get_custom_property_registration(name);
let value = context.map.get(registration, name)?;
let value = value.as_universal()?;
let non_custom_references = value
.references
@ -1521,16 +1481,22 @@ fn substitute_all(
.invalid_non_custom_properties
.insert(LonghandId::FontSize);
}
if context
.non_custom_references
.intersects(NonCustomReferences::LH_UNITS | NonCustomReferences::ROOT_LH_UNITS)
{
if context.non_custom_references.intersects(
NonCustomReferences::LH_UNITS |
NonCustomReferences::ROOT_LH_UNITS,
) {
context
.invalid_non_custom_properties
.insert(LonghandId::LineHeight);
}
// This variable is in loop. Resolve to invalid.
handle_invalid_at_computed_value_time(name, context.map, context.computed_context);
handle_invalid_at_computed_value_time(
name,
context.map,
context.computed_context.inherited_custom_properties(),
context.stylist,
context.computed_context.is_root_element(),
);
};
loop {
let var_index = context
@ -1573,7 +1539,7 @@ fn substitute_all(
return None;
}
if let Some(ref v) = value {
if let Some(ref v) = value.as_ref() {
let registration = context.stylist.get_custom_property_registration(&name);
let registered_length_property =
registration.syntax.may_reference_font_relative_length();
@ -1581,8 +1547,7 @@ fn substitute_all(
if !context.non_custom_references.is_empty() && registered_length_property {
if let Some(deferred) = &mut context.deferred_properties {
// This property directly depends on a non-custom property, defer resolving it.
let deferred_property = ComputedRegisteredValue::universal(Arc::clone(v));
deferred.insert(registration, &name, deferred_property);
deferred.insert(registration, &name, (*v).clone());
context.map.remove(registration, &name);
defer = true;
}
@ -1593,14 +1558,11 @@ fn substitute_all(
continue;
}
if let Some(deferred) = &mut context.deferred_properties {
let registration = context
.stylist
.get_custom_property_registration(&reference.name);
let registration =
context.stylist.get_custom_property_registration(&reference.name);
if deferred.get(registration, &reference.name).is_some() {
// This property depends on a custom property that depends on a non-custom property, defer.
let deferred_property =
ComputedRegisteredValue::universal(Arc::clone(v));
deferred.insert(registration, &name, deferred_property);
deferred.insert(registration, &name, Arc::clone(v));
context.map.remove(registration, &name);
defer = true;
break;
@ -1653,27 +1615,22 @@ fn substitute_all(
fn handle_invalid_at_computed_value_time(
name: &Name,
custom_properties: &mut ComputedCustomProperties,
computed_context: &computed::Context,
inherited: &ComputedCustomProperties,
stylist: &Stylist,
is_root_element: bool,
) {
let stylist = computed_context.style().stylist.unwrap();
let registration = stylist.get_custom_property_registration(&name);
if !registration.syntax.is_universal() {
// For the root element, inherited maps are empty. We should just
// use the initial value if any, rather than removing the name.
if registration.inherits() && !computed_context.is_root_element() {
let inherited = computed_context.inherited_custom_properties();
if registration.inherits() && !is_root_element {
if let Some(value) = inherited.get(registration, name) {
custom_properties.insert(registration, name, value.clone());
custom_properties.insert(registration, name, Arc::clone(value));
return;
}
} else if let Some(ref initial_value) = registration.initial_value {
if let Ok(initial_value) = compute_value(
&initial_value.css,
&initial_value.url_data,
registration,
computed_context,
) {
custom_properties.insert(registration, name, initial_value);
} else {
if let Some(ref initial_value) = registration.initial_value {
custom_properties.insert(registration, name, Arc::clone(initial_value));
return;
}
}
@ -1692,43 +1649,35 @@ fn substitute_references_if_needed_and_apply(
let registration = stylist.get_custom_property_registration(&name);
if !value.has_references() && registration.syntax.is_universal() {
// Trivial path: no references and no need to compute the value, just apply it directly.
let computed_value = ComputedRegisteredValue::universal(Arc::clone(value));
custom_properties.insert(registration, name, computed_value);
custom_properties.insert(registration, name, Arc::clone(value));
return;
}
let inherited = computed_context.inherited_custom_properties();
let url_data = &value.url_data;
let value = match substitute_internal(
value,
custom_properties,
stylist,
registration,
computed_context,
) {
let value = match substitute_internal(value, custom_properties, stylist, registration, computed_context) {
Ok(v) => v,
Err(..) => {
handle_invalid_at_computed_value_time(name, custom_properties, computed_context);
handle_invalid_at_computed_value_time(
name,
custom_properties,
inherited,
stylist,
computed_context.is_root_element(),
);
return;
},
}
.into_value(url_data);
}.into_value(&value.url_data);
// If variable fallback results in a wide keyword, deal with it now.
{
let css = value.to_variable_value().css;
let mut input = ParserInput::new(&css);
let mut input = ParserInput::new(&value.css);
let mut input = Parser::new(&mut input);
if let Ok(kw) = input.try_parse(CSSWideKeyword::parse) {
// TODO: It's unclear what this should do for revert / revert-layer, see
// https://github.com/w3c/csswg-drafts/issues/9131. For now treating as unset
// seems fine?
match (
kw,
registration.inherits(),
computed_context.is_root_element(),
) {
match (kw, registration.inherits(), computed_context.is_root_element()) {
(CSSWideKeyword::Initial, _, _) |
(CSSWideKeyword::Revert, false, _) |
(CSSWideKeyword::RevertLayer, false, _) |
@ -1737,7 +1686,10 @@ fn substitute_references_if_needed_and_apply(
(CSSWideKeyword::RevertLayer, true, true) |
(CSSWideKeyword::Unset, true, true) |
(CSSWideKeyword::Inherit, _, true) => {
remove_and_insert_initial_value(name, registration, custom_properties);
custom_properties.remove(registration, name);
if let Some(ref initial_value) = registration.initial_value {
custom_properties.insert(registration, name, Arc::clone(initial_value));
}
},
(CSSWideKeyword::Revert, true, false) |
(CSSWideKeyword::RevertLayer, true, false) |
@ -1745,7 +1697,7 @@ fn substitute_references_if_needed_and_apply(
(CSSWideKeyword::Unset, true, false) => {
match inherited.get(registration, name) {
Some(value) => {
custom_properties.insert(registration, name, value.clone());
custom_properties.insert(registration, name, Arc::clone(value));
},
None => {
custom_properties.remove(registration, name);
@ -1757,81 +1709,45 @@ fn substitute_references_if_needed_and_apply(
}
}
custom_properties.insert(registration, name, value);
}
enum Substitution<'a> {
Universal(UniversalSubstitution<'a>),
Computed(ComputedRegisteredValue),
}
impl<'a> Default for Substitution<'a> {
fn default() -> Self {
Self::Universal(UniversalSubstitution::default())
}
custom_properties.insert(registration, name, Arc::new(value));
}
#[derive(Default)]
struct UniversalSubstitution<'a> {
struct Substitution<'a> {
css: Cow<'a, str>,
first_token_type: TokenSerializationType,
last_token_type: TokenSerializationType,
}
impl<'a> UniversalSubstitution<'a> {
fn from_value(v: VariableValue) -> Self {
UniversalSubstitution {
css: Cow::from(v.css),
first_token_type: v.first_token_type,
last_token_type: v.last_token_type,
}
}
}
impl<'a> Substitution<'a> {
fn new(
css: &'a str,
first_token_type: TokenSerializationType,
last_token_type: TokenSerializationType,
) -> Self {
Self::Universal(UniversalSubstitution {
Self {
css: Cow::Borrowed(css),
first_token_type,
last_token_type,
})
}
fn into_universal(self) -> UniversalSubstitution<'a> {
match self {
Substitution::Universal(substitution) => substitution,
Substitution::Computed(computed) => {
UniversalSubstitution::from_value(computed.to_variable_value())
},
}
}
fn from_value(v: VariableValue) -> Self {
debug_assert!(
!v.has_references(),
"Computed values shouldn't have references"
);
let substitution = UniversalSubstitution::from_value(v);
Self::Universal(substitution)
fn from_value(v: VariableValue) -> Substitution<'static> {
debug_assert!(!v.has_references(), "Computed values shouldn't have references");
Substitution {
css: Cow::from(v.css),
first_token_type: v.first_token_type,
last_token_type: v.last_token_type,
}
}
fn into_value(self, url_data: &UrlExtraData) -> ComputedRegisteredValue {
match self {
Substitution::Universal(substitution) => {
let value = Arc::new(VariableValue {
css: substitution.css.into_owned(),
first_token_type: substitution.first_token_type,
last_token_type: substitution.last_token_type,
url_data: url_data.clone(),
references: Default::default(),
});
ComputedRegisteredValue::universal(value)
},
Substitution::Computed(computed) => computed,
fn into_value(self, url_data: &UrlExtraData) -> VariableValue {
VariableValue {
css: self.css.into_owned(),
first_token_type: self.first_token_type,
last_token_type: self.last_token_type,
url_data: url_data.clone(),
references: Default::default(),
}
}
}
@ -1841,32 +1757,20 @@ fn compute_value(
url_data: &UrlExtraData,
registration: &PropertyRegistrationData,
computed_context: &computed::Context,
) -> Result<ComputedRegisteredValue, ()> {
) -> Result<Substitution<'static>, ()> {
debug_assert!(!registration.syntax.is_universal());
let mut input = ParserInput::new(&css);
let mut input = Parser::new(&mut input);
SpecifiedRegisteredValue::compute(
let value = SpecifiedRegisteredValue::compute(
&mut input,
registration,
url_data,
computed_context,
AllowComputationallyDependent::Yes,
)
}
/// Removes the named registered custom property and inserts its uncomputed initial value.
fn remove_and_insert_initial_value(
name: &Name,
registration: &PropertyRegistrationData,
custom_properties: &mut ComputedCustomProperties,
) {
custom_properties.remove(registration, name);
if let Some(ref initial_value) = registration.initial_value {
let value = ComputedRegisteredValue::universal(Arc::clone(initial_value));
custom_properties.insert(registration, name, value);
}
)?;
Ok(Substitution::from_value(value))
}
fn do_substitute_chunk<'a>(
@ -1893,8 +1797,7 @@ fn do_substitute_chunk<'a>(
{
let result = &css[start..end];
if !registration.syntax.is_universal() {
let computed_value = compute_value(result, url_data, registration, computed_context)?;
return Ok(Substitution::Computed(computed_value));
return compute_value(result, url_data, registration, computed_context);
}
return Ok(Substitution::new(result, first_token_type, last_token_type));
}
@ -1926,7 +1829,6 @@ fn do_substitute_chunk<'a>(
return Ok(substitution);
}
let substitution = substitution.into_universal();
substituted.push(
&substitution.css,
substitution.first_token_type,
@ -1940,9 +1842,7 @@ fn do_substitute_chunk<'a>(
substituted.push(&css[cur_pos..end], next_token_type, last_token_type)?;
}
if !registration.syntax.is_universal() {
let computed_value =
compute_value(&substituted.css, url_data, registration, computed_context)?;
return Ok(Substitution::Computed(computed_value));
return compute_value(&substituted.css, url_data, registration, computed_context);
}
Ok(Substitution::from_value(substituted))
}
@ -1960,7 +1860,7 @@ fn substitute_one_reference<'a>(
if reference.is_var {
registration = stylist.get_custom_property_registration(&reference.name);
if let Some(v) = custom_properties.get(registration, &reference.name) {
debug_assert!(v.is_parsed(registration), "Should be already computed");
debug_assert!(!v.has_references(), "Should be already computed");
if registration.syntax.is_universal() {
// Skip references that are inside the outer variable (in fallback for example).
while references
@ -1986,7 +1886,11 @@ fn substitute_one_reference<'a>(
)?;
}
}
return Ok(Substitution::Computed(v.clone()));
return Ok(Substitution {
css: Cow::from(&v.css),
first_token_type: v.first_token_type,
last_token_type: v.last_token_type,
});
}
} else {
registration = PropertyRegistrationData::unregistered();
@ -2000,9 +1904,7 @@ fn substitute_one_reference<'a>(
}
}
let Some(ref fallback) = reference.fallback else {
return Err(());
};
let Some(ref fallback) = reference.fallback else { return Err(()) };
do_substitute_chunk(
css,
@ -2058,6 +1960,5 @@ pub fn substitute<'a>(
PropertyRegistrationData::unregistered(),
computed_context,
)?;
let v = v.into_universal();
Ok(v.css)
}

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

@ -4,8 +4,7 @@
//! The structure that contains the custom properties of a given element.
use crate::custom_properties::Name;
use crate::properties_and_values::value::ComputedValue as ComputedRegisteredValue;
use crate::custom_properties::{Name, VariableValue};
use crate::selector_map::PrecomputedHasher;
use indexmap::IndexMap;
use servo_arc::Arc;
@ -23,8 +22,7 @@ impl Default for CustomPropertiesMap {
}
/// We use None in the value to represent a removed entry.
type OwnMap =
IndexMap<Name, Option<ComputedRegisteredValue>, BuildHasherDefault<PrecomputedHasher>>;
type OwnMap = IndexMap<Name, Option<Arc<VariableValue>>, BuildHasherDefault<PrecomputedHasher>>;
// IndexMap equality doesn't consider ordering, which we want to account for. Also, for the same
// reason, IndexMap equality comparisons are slower than needed.
@ -71,12 +69,12 @@ const ANCESTOR_COUNT_LIMIT: usize = 4;
/// An iterator over the custom properties.
pub struct Iter<'a> {
current: &'a Inner,
current_iter: indexmap::map::Iter<'a, Name, Option<ComputedRegisteredValue>>,
current_iter: indexmap::map::Iter<'a, Name, Option<Arc<VariableValue>>>,
descendants: smallvec::SmallVec<[&'a Inner; ANCESTOR_COUNT_LIMIT]>,
}
impl<'a> Iterator for Iter<'a> {
type Item = (&'a Name, &'a Option<ComputedRegisteredValue>);
type Item = (&'a Name, &'a Option<Arc<VariableValue>>);
fn next(&mut self) -> Option<Self::Item> {
loop {
@ -143,14 +141,14 @@ impl Inner {
self.len
}
fn get(&self, name: &Name) -> Option<&ComputedRegisteredValue> {
fn get(&self, name: &Name) -> Option<&Arc<VariableValue>> {
if let Some(p) = self.own_properties.get(name) {
return p.as_ref();
}
self.parent.as_ref()?.get(name)
}
fn insert(&mut self, name: &Name, value: Option<ComputedRegisteredValue>) {
fn insert(&mut self, name: &Name, value: Option<Arc<VariableValue>>) {
let new = self.own_properties.insert(name.clone(), value).is_none();
if new && self.parent.as_ref().map_or(true, |p| p.get(name).is_none()) {
self.len += 1;
@ -179,7 +177,7 @@ impl CustomPropertiesMap {
}
/// Returns the property name and value at a given index.
pub fn get_index(&self, index: usize) -> Option<(&Name, &Option<ComputedRegisteredValue>)> {
pub fn get_index(&self, index: usize) -> Option<(&Name, &Option<Arc<VariableValue>>)> {
if index >= self.len() {
return None;
}
@ -188,11 +186,11 @@ impl CustomPropertiesMap {
}
/// Returns a given property value by name.
pub fn get(&self, name: &Name) -> Option<&ComputedRegisteredValue> {
pub fn get(&self, name: &Name) -> Option<&Arc<VariableValue>> {
self.0.get(name)
}
fn do_insert(&mut self, name: &Name, value: Option<ComputedRegisteredValue>) {
fn do_insert(&mut self, name: &Name, value: Option<Arc<VariableValue>>) {
if let Some(inner) = Arc::get_mut(&mut self.0) {
return inner.insert(name, value);
}
@ -216,7 +214,7 @@ impl CustomPropertiesMap {
}
/// Inserts an element in the map.
pub fn insert(&mut self, name: &Name, value: ComputedRegisteredValue) {
pub fn insert(&mut self, name: &Name, value: Arc<VariableValue>) {
self.do_insert(name, Some(value))
}

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

@ -9,10 +9,7 @@
use super::{
registry::{PropertyRegistration, PropertyRegistrationData},
syntax::Descriptor,
value::{
AllowComputationallyDependent, ComputedValue as ComputedRegisteredValue,
SpecifiedValue as SpecifiedRegisteredValue,
},
value::{AllowComputationallyDependent, SpecifiedValue as SpecifiedRegisteredValue},
};
use crate::custom_properties::{Name as CustomPropertyName, SpecifiedValue};
use crate::error_reporting::ContextualParseError;
@ -219,13 +216,13 @@ impl PropertyRegistration {
pub fn compute_initial_value(
&self,
computed_context: &computed::Context,
) -> Result<ComputedRegisteredValue, ()> {
) -> Result<InitialValue, ()> {
let Some(ref initial) = self.data.initial_value else {
return Err(());
};
if self.data.syntax.is_universal() {
return Ok(ComputedRegisteredValue::universal(Arc::clone(initial)));
return Ok(Arc::clone(initial));
}
let mut input = ParserInput::new(initial.css_text());
@ -239,7 +236,7 @@ impl PropertyRegistration {
computed_context,
AllowComputationallyDependent::No,
) {
Ok(computed) => Ok(computed),
Ok(computed) => Ok(Arc::new(computed)),
Err(_) => Err(()),
}
}

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

@ -131,13 +131,11 @@ pub enum GenericValueComponent<
/// A <resolution> value
Resolution(Resolution),
/// A <transform-function> value
/// TODO(bug 1884606): <transform-function> `none` should not interpolate.
TransformFunction(TransformFunction),
/// A <custom-ident> value
#[animation(error)]
CustomIdent(CustomIdent),
/// A <transform-list> value, equivalent to <transform-function>+
/// TODO(bug 1884606): <transform-list> `none` should not interpolate.
TransformList(ComponentList<Self>),
/// A <string> value
#[animation(error)]
@ -158,11 +156,7 @@ impl<Component: Animate> Animate for ComponentList<Component> {
if self.multiplier != other.multiplier {
return Err(());
}
let components = animated::lists::by_computed_value::animate(
&self.components,
&other.components,
procedure,
)?;
let components = animated::lists::by_computed_value::animate(&self.components, &other.components, procedure)?;
Ok(Self {
multiplier: self.multiplier,
components,
@ -196,45 +190,9 @@ impl<Component: ToCss> ToCss for ComponentList<Component> {
}
}
/// A struct for a single specified registered custom property value that includes its original URL
// data so the value can be uncomputed later.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
pub struct Value<Component> {
/// The registered custom property value.
pub(crate) v: ValueInner<Component>,
/// The URL data of the registered custom property from before it was computed. This is
/// necessary to uncompute registered custom properties.
#[css(skip)]
url_data: UrlExtraData,
}
impl<Component: Animate> Animate for Value<Component> {
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
let v = self.v.animate(&other.v, procedure)?;
Ok(Value {
v,
url_data: self.url_data.clone(),
})
}
}
impl<Component> Value<Component> {
/// Creates a new registered custom property value.
pub fn new(v: ValueInner<Component>, url_data: UrlExtraData) -> Self {
Self { v, url_data }
}
/// Creates a new registered custom property value presumed to have universal syntax.
pub fn universal(var: Arc<ComputedPropertyValue>) -> Self {
let url_data = var.url_data.clone();
let v = ValueInner::Universal(var);
Self { v, url_data }
}
}
/// A specified registered custom property value.
#[derive(Animate, ToComputedValue, ToCss, Clone, Debug, MallocSizeOf, PartialEq)]
pub enum ValueInner<Component> {
pub enum Value<Component> {
/// A single specified component value whose syntax descriptor component did not have a
/// multiplier.
Component(Component),
@ -248,31 +206,31 @@ pub enum ValueInner<Component> {
/// Specified custom property value.
pub type SpecifiedValue = Value<SpecifiedValueComponent>;
impl ToComputedValue for SpecifiedValue {
type ComputedValue = ComputedValue;
fn to_computed_value(&self, context: &computed::Context) -> Self::ComputedValue {
Self::ComputedValue {
v: self.v.to_computed_value(context),
url_data: self.url_data.clone(),
}
}
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
Self {
v: ToComputedValue::from_computed_value(&computed.v),
url_data: computed.url_data.clone(),
}
}
}
/// Computed custom property value.
pub type ComputedValue = Value<ComputedValueComponent>;
impl SpecifiedValue {
/// Convert a Computed custom property value to a VariableValue.
pub fn compute<'i, 't>(
input: &mut CSSParser<'i, 't>,
registration: &PropertyRegistrationData,
url_data: &UrlExtraData,
context: &computed::Context,
allow_computationally_dependent: AllowComputationallyDependent,
) -> Result<ComputedPropertyValue, ()> {
let value = Self::get_computed_value(
input,
registration,
url_data,
context,
allow_computationally_dependent,
)?;
Ok(value.to_variable_value(url_data))
}
/// Convert a registered custom property to a Computed custom property value, given input and a
/// property registration.
pub fn compute<'i, 't>(
fn get_computed_value<'i, 't>(
input: &mut CSSParser<'i, 't>,
registration: &PropertyRegistrationData,
url_data: &UrlExtraData,
@ -301,11 +259,9 @@ impl SpecifiedValue {
allow_computationally_dependent: AllowComputationallyDependent,
) -> Result<Self, StyleParseError<'i>> {
if syntax.is_universal() {
let parsed = ComputedPropertyValue::parse(&mut input, url_data)?;
return Ok(SpecifiedValue {
v: ValueInner::Universal(Arc::new(parsed)),
url_data: url_data.clone(),
});
return Ok(Self::Universal(Arc::new(ComputedPropertyValue::parse(
&mut input, url_data,
)?)));
}
let mut values = SmallComponentVec::new();
@ -314,64 +270,45 @@ impl SpecifiedValue {
let mut parser = Parser::new(syntax, &mut values, &mut multiplier);
parser.parse(&mut input, url_data, allow_computationally_dependent)?;
}
let v = if let Some(multiplier) = multiplier {
ValueInner::List(ComponentList {
let computed_value = if let Some(multiplier) = multiplier {
Self::List(ComponentList {
multiplier,
components: values.to_vec().into(),
})
} else {
ValueInner::Component(values[0].clone())
Self::Component(values[0].clone())
};
Ok(Self {
v,
url_data: url_data.clone(),
})
Ok(computed_value)
}
}
impl ComputedValue {
fn serialization_types(&self) -> (TokenSerializationType, TokenSerializationType) {
match &self.v {
ValueInner::Component(component) => component.serialization_types(),
ValueInner::Universal(_) => unreachable!(),
ValueInner::List(list) => list
match self {
Self::Component(component) => component.serialization_types(),
Self::Universal(_) => unreachable!(),
Self::List(list) => list
.components
.first()
.map_or(Default::default(), |f| f.serialization_types()),
}
}
fn to_declared_value(&self) -> Arc<ComputedPropertyValue> {
if let ValueInner::Universal(ref var) = self.v {
fn to_declared_value(&self, url_data: &UrlExtraData) -> Arc<ComputedPropertyValue> {
if let Self::Universal(var) = self {
return Arc::clone(var);
}
Arc::new(self.to_variable_value())
Arc::new(self.to_variable_value(url_data))
}
/// Returns the contained variable value if it exists, otherwise `None`.
pub fn as_universal(&self) -> Option<&Arc<ComputedPropertyValue>> {
if let ValueInner::Universal(ref var) = self.v {
Some(var)
} else {
None
}
}
/// Returns whether the the property is computed.
#[cfg(debug_assertions)]
pub fn is_parsed(&self, registration: &PropertyRegistrationData) -> bool {
registration.syntax.is_universal() || !matches!(self.v, ValueInner::Universal(_))
}
/// Convert to an untyped variable value.
pub fn to_variable_value(&self) -> ComputedPropertyValue {
if let ValueInner::Universal(ref value) = self.v {
return (**value).clone();
}
fn to_variable_value(&self, url_data: &UrlExtraData) -> ComputedPropertyValue {
debug_assert!(!matches!(self, Self::Universal(..)), "Shouldn't be needed");
// TODO(zrhoffman, 1864736): Preserve the computed type instead of converting back to a
// string.
let serialization_types = self.serialization_types();
ComputedPropertyValue::new(
self.to_css_string(),
&self.url_data,
url_data,
serialization_types.0,
serialization_types.1,
)
@ -593,6 +530,7 @@ impl<'a> Parser<'a> {
}
}
/// An animated value for custom property.
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
pub struct CustomAnimatedValue {
@ -600,17 +538,25 @@ pub struct CustomAnimatedValue {
pub(crate) name: crate::custom_properties::Name,
/// The computed value of the custom property.
value: ComputedValue,
/// The url data where the value came from.
/// FIXME: This seems like it should not be needed: registered properties don't need it, and
/// unregistered properties animate discretely. But we need it so far because the computed
/// value representation isn't typed.
url_data: UrlExtraData,
}
impl Animate for CustomAnimatedValue {
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
if self.name != other.name {
return Err(());
return Err(())
}
let value = self.value.animate(&other.value, procedure)?;
Ok(Self {
name: self.name.clone(),
value,
// NOTE: This is sketchy AF, but it's ~fine, since values that can animate (non-universal)
// don't need it.
url_data: self.url_data.clone(),
})
}
}
@ -618,11 +564,13 @@ impl Animate for CustomAnimatedValue {
impl CustomAnimatedValue {
pub(crate) fn from_computed(
name: &crate::custom_properties::Name,
value: &ComputedValue,
value: &Arc<ComputedPropertyValue>,
) -> Self {
Self {
name: name.clone(),
value: value.clone(),
// FIXME: Should probably preserve type-ness in ComputedPropertyValue.
value: ComputedValue::Universal(value.clone()),
url_data: value.url_data.clone(),
}
}
@ -642,11 +590,8 @@ impl CustomAnimatedValue {
context.builder.stylist.is_some(),
"Need a Stylist to get property registration!"
);
let registration = context
.builder
.stylist
.unwrap()
.get_custom_property_registration(&declaration.name);
let registration =
context.builder.stylist.unwrap().get_custom_property_registration(&declaration.name);
// FIXME: Do we need to perform substitution here somehow?
let computed_value = if registration.syntax.is_universal() {
@ -654,22 +599,20 @@ impl CustomAnimatedValue {
} else {
let mut input = cssparser::ParserInput::new(&value.css);
let mut input = CSSParser::new(&mut input);
SpecifiedValue::compute(
SpecifiedValue::get_computed_value(
&mut input,
registration,
&value.url_data,
context,
AllowComputationallyDependent::Yes,
)
.ok()
).ok()
};
let value = computed_value.unwrap_or_else(|| ComputedValue {
v: ValueInner::Universal(Arc::clone(value)),
url_data: value.url_data.clone(),
});
let url_data = value.url_data.clone();
let value = computed_value.unwrap_or_else(|| ComputedValue::Universal(Arc::clone(value)));
Some(Self {
name: declaration.name.clone(),
url_data,
value,
})
}
@ -677,7 +620,7 @@ impl CustomAnimatedValue {
pub(crate) fn to_declaration(&self) -> properties::PropertyDeclaration {
properties::PropertyDeclaration::Custom(properties::CustomDeclaration {
name: self.name.clone(),
value: properties::CustomDeclarationValue::Value(self.value.to_declared_value()),
value: properties::CustomDeclarationValue::Value(self.value.to_declared_value(&self.url_data)),
})
}
}

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

@ -6215,8 +6215,8 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(
let mut seen = PropertyDeclarationIdSet::default();
let mut iter = PrioritizedPropertyIter::new(&keyframe.mPropertyValues);
// FIXME (bug 1883255): This is pretty much a hack. Instead, the AnimatedValue should be
// better integrated in the cascade.
// FIXME: This is pretty much a hack. Instead, the AnimatedValue should be better
// integrated in the cascade. This would allow us to fix revert() too.
{
let mut builder = CustomPropertiesBuilder::new_with_properties(
&data.stylist,

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

@ -0,0 +1,2 @@
[revert-layer-011.html]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-angle-comma-list.html]
[Animating a custom property of type <angle># with a single keyframe]
expected: FAIL
[Animating a custom property of type <angle># with additivity]
expected: FAIL
[Animating a custom property of type <angle># with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-angle-space-list.html]
[Animating a custom property of type <angle>+ with a single keyframe]
expected: FAIL
[Animating a custom property of type <angle>+ with additivity]
expected: FAIL
[Animating a custom property of type <angle>+ with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-angle.html]
[Animating a custom property of type <angle> with a single keyframe]
expected: FAIL
[Animating a custom property of type <angle> with additivity]
expected: FAIL
[Animating a custom property of type <angle> with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-color-comma-list.html]
[Animating a custom property of type <color># with a single keyframe]
expected: FAIL
[Animating a custom property of type <color># with additivity]
expected: FAIL
[Animating a custom property of type <color># with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-color-space-list.html]
[Animating a custom property of type <color>+ with a single keyframe]
expected: FAIL
[Animating a custom property of type <color>+ with additivity]
expected: FAIL
[Animating a custom property of type <color>+ with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-color.html]
[Animating a custom property of type <color> with a single keyframe]
expected: FAIL
[Animating a custom property of type <color> with additivity]
expected: FAIL
[Animating a custom property of type <color> with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,3 @@
[custom-property-animation-inherited-used-by-standard-property.html]
[Animating an inherited CSS variable on a parent is reflected on a standard property using that variable as a value on a child]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-integer-comma-list.html]
[Animating a custom property of type <integer># with a single keyframe]
expected: FAIL
[Animating a custom property of type <integer># with additivity]
expected: FAIL
[Animating a custom property of type <integer># with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-integer-space-list.html]
[Animating a custom property of type <integer>+ with a single keyframe]
expected: FAIL
[Animating a custom property of type <integer>+ with additivity]
expected: FAIL
[Animating a custom property of type <integer>+ with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-integer.html]
[Animating a custom property of type <integer> with a single keyframe]
expected: FAIL
[Animating a custom property of type <integer> with additivity]
expected: FAIL
[Animating a custom property of type <integer> with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-length-comma-list.html]
[Animating a custom property of type <length># with a single keyframe]
expected: FAIL
[Animating a custom property of type <length># with additivity]
expected: FAIL
[Animating a custom property of type <length># with a single keyframe and additivity]
expected: FAIL

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

@ -1,3 +1,12 @@
[custom-property-animation-length-percentage-comma-list.html]
[Animating a custom property of type <length-percentage># with a single keyframe]
expected: FAIL
[Animating a custom property of type <length-percentage># with additivity]
expected: FAIL
[Animating a custom property of type <length-percentage># with a single keyframe and additivity]
expected: FAIL
[Animating a custom property of type <length-percentage># with iterationComposite]
expected: FAIL

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

@ -1,3 +1,12 @@
[custom-property-animation-length-percentage-space-list.html]
[Animating a custom property of type <length-percentage>+ with a single keyframe]
expected: FAIL
[Animating a custom property of type <length-percentage>+ with additivity]
expected: FAIL
[Animating a custom property of type <length-percentage>+ with a single keyframe and additivity]
expected: FAIL
[Animating a custom property of type <length-percentage>+ with iterationComposite]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-length-percentage.html]
[Animating a custom property of type <length-percentage> with a single keyframe]
expected: FAIL
[Animating a custom property of type <length-percentage> with additivity]
expected: FAIL
[Animating a custom property of type <length-percentage> with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-length-space-list.html]
[Animating a custom property of type <length>+ with a single keyframe]
expected: FAIL
[Animating a custom property of type <length>+ with additivity]
expected: FAIL
[Animating a custom property of type <length>+ with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-length.html]
[Animating a custom property of type <length> with a single keyframe]
expected: FAIL
[Animating a custom property of type <length> with additivity]
expected: FAIL
[Animating a custom property of type <length> with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,3 @@
[custom-property-animation-non-inherited-used-by-standard-property.html]
[Animating a non-inherited CSS variable is reflected on a standard property using that variable as a value]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-number-comma-list.html]
[Animating a custom property of type <number># with a single keyframe]
expected: FAIL
[Animating a custom property of type <number># with additivity]
expected: FAIL
[Animating a custom property of type <number># with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-number-space-list.html]
[Animating a custom property of type <number>+ with a single keyframe]
expected: FAIL
[Animating a custom property of type <number>+ with additivity]
expected: FAIL
[Animating a custom property of type <number>+ with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-number.html]
[Animating a custom property of type <number> with a single keyframe]
expected: FAIL
[Animating a custom property of type <number> with additivity]
expected: FAIL
[Animating a custom property of type <number> with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-percentage-comma-list.html]
[Animating a custom property of type <percentage># with a single keyframe]
expected: FAIL
[Animating a custom property of type <percentage># with additivity]
expected: FAIL
[Animating a custom property of type <percentage># with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-percentage-space-list.html]
[Animating a custom property of type <percentage>+ with a single keyframe]
expected: FAIL
[Animating a custom property of type <percentage>+ with additivity]
expected: FAIL
[Animating a custom property of type <percentage>+ with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-percentage.html]
[Animating a custom property of type <percentage> with a single keyframe]
expected: FAIL
[Animating a custom property of type <percentage> with additivity]
expected: FAIL
[Animating a custom property of type <percentage> with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-resolution-comma-list.html]
[Animating a custom property of type <resolution># with a single keyframe]
expected: FAIL
[Animating a custom property of type <resolution># with additivity]
expected: FAIL
[Animating a custom property of type <resolution># with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-resolution-space-list.html]
[Animating a custom property of type <resolution>+ with a single keyframe]
expected: FAIL
[Animating a custom property of type <resolution>+ with additivity]
expected: FAIL
[Animating a custom property of type <resolution>+ with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-resolution.html]
[Animating a custom property of type <resolution> with a single keyframe]
expected: FAIL
[Animating a custom property of type <resolution> with additivity]
expected: FAIL
[Animating a custom property of type <resolution> with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-time-comma-list.html]
[Animating a custom property of type <time># with a single keyframe]
expected: FAIL
[Animating a custom property of type <time># with additivity]
expected: FAIL
[Animating a custom property of type <time># with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-time-space-list.html]
[Animating a custom property of type <time>+ with a single keyframe]
expected: FAIL
[Animating a custom property of type <time>+ with additivity]
expected: FAIL
[Animating a custom property of type <time>+ with a single keyframe and additivity]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-time.html]
[Animating a custom property of type <time> with a single keyframe]
expected: FAIL
[Animating a custom property of type <time> with additivity]
expected: FAIL
[Animating a custom property of type <time> with a single keyframe and additivity]
expected: FAIL

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

@ -1,4 +1,7 @@
[custom-property-animation-transform-function.html]
[Animating a custom property of type <transform-function> with a single keyframe]
expected: FAIL
[Animating a custom property of type <transform-function> with additivity]
expected: FAIL

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

@ -1,4 +1,13 @@
[custom-property-animation-transform-list-multiple-values.html]
[Animating a custom property of type <transform-list> containing multiple values with a single keyframe]
expected: FAIL
[Animating a custom property of type <transform-list> containing multiple values with additivity]
expected: FAIL
[Animating a custom property of type <transform-list> containing multiple values with a single keyframe and additivity]
expected: FAIL
[Animating a custom property of type <transform-list> containing multiple values with iterationComposite]
expected: FAIL

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

@ -0,0 +1,9 @@
[custom-property-animation-transform-list-single-values.html]
[Animating a custom property of type <transform-list> containing a single value with a single keyframe]
expected: FAIL
[Animating a custom property of type <transform-list> containing a single value with additivity]
expected: FAIL
[Animating a custom property of type <transform-list> containing a single value with a single keyframe and additivity]
expected: FAIL

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

@ -1,6 +0,0 @@
[custom-property-animation-transform-none.tentative.html]
[Animating a custom property of type "<transform-list>|none" from "none" to <transform-list> value]
expected: FAIL
[Animating a custom property of type "<transform-function>|none" from "none" to <transform-function> value]
expected: FAIL

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

@ -1,4 +1,13 @@
[at-property-animation.html]
[Ongoing animation picks up redeclared intial value]
expected: FAIL
[Ongoing animation picks up redeclared inherits flag]
expected: FAIL
[Ongoing animation picks up redeclared meaning of 'unset']
expected: FAIL
[Transition triggered by initial value change]
expected: FAIL

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

@ -0,0 +1,6 @@
[registered-property-revert.html]
[Non-inherited registered custom property can be reverted in animation]
expected: FAIL
[Inherited registered custom property can be reverted in animation]
expected: FAIL