style: Order keyframe rules by layer

@counter-style/@font-face/@scroll-timeline need similar fixes, but tests
for those haven't been synced yet so waiting for that before writing
them.

Differential Revision: https://phabricator.services.mozilla.com/D126616
This commit is contained in:
Emilio Cobos Álvarez 2023-05-27 15:03:43 +02:00 committed by Oriol Brufau
parent 6785ffea7b
commit b0a356e3b3
2 changed files with 32 additions and 15 deletions

View file

@ -14,6 +14,7 @@ use crate::properties::{PropertyDeclarationId, SourcePropertyDeclaration};
use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard}; use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard};
use crate::shared_lock::{Locked, ToCssWithGuard}; use crate::shared_lock::{Locked, ToCssWithGuard};
use crate::str::CssStringWriter; use crate::str::CssStringWriter;
use crate::stylesheets::layer_rule::LayerOrder;
use crate::stylesheets::rule_parser::VendorPrefix; use crate::stylesheets::rule_parser::VendorPrefix;
use crate::stylesheets::{CssRuleType, StylesheetContents}; use crate::stylesheets::{CssRuleType, StylesheetContents};
use crate::values::{serialize_percentage, KeyframesName}; use crate::values::{serialize_percentage, KeyframesName};
@ -357,6 +358,8 @@ pub struct KeyframesAnimation {
pub properties_changed: LonghandIdSet, pub properties_changed: LonghandIdSet,
/// Vendor prefix type the @keyframes has. /// Vendor prefix type the @keyframes has.
pub vendor_prefix: Option<VendorPrefix>, pub vendor_prefix: Option<VendorPrefix>,
/// The order of the cascade layer the keyframe rule was in.
pub layer_order: LayerOrder,
} }
/// Get all the animated properties in a keyframes animation. /// Get all the animated properties in a keyframes animation.
@ -409,12 +412,14 @@ impl KeyframesAnimation {
pub fn from_keyframes( pub fn from_keyframes(
keyframes: &[Arc<Locked<Keyframe>>], keyframes: &[Arc<Locked<Keyframe>>],
vendor_prefix: Option<VendorPrefix>, vendor_prefix: Option<VendorPrefix>,
layer_order: LayerOrder,
guard: &SharedRwLockReadGuard, guard: &SharedRwLockReadGuard,
) -> Self { ) -> Self {
let mut result = KeyframesAnimation { let mut result = KeyframesAnimation {
steps: vec![], steps: vec![],
properties_changed: LonghandIdSet::new(), properties_changed: LonghandIdSet::new(),
vendor_prefix, vendor_prefix,
layer_order,
}; };
if keyframes.is_empty() { if keyframes.is_empty() {

View file

@ -2265,23 +2265,35 @@ impl CascadeData {
self.rules_source_order += 1; self.rules_source_order += 1;
}, },
CssRule::Keyframes(ref keyframes_rule) => { CssRule::Keyframes(ref keyframes_rule) => {
use hashglobe::hash_map::Entry;
let keyframes_rule = keyframes_rule.read_with(guard); let keyframes_rule = keyframes_rule.read_with(guard);
debug!("Found valid keyframes rule: {:?}", *keyframes_rule); debug!("Found valid keyframes rule: {:?}", *keyframes_rule);
match self.animations.try_entry(keyframes_rule.name.as_atom().clone())? {
// Don't let a prefixed keyframes animation override a non-prefixed one. Entry::Vacant(e) => {
let needs_insertion = keyframes_rule.vendor_prefix.is_none() || e.insert(KeyframesAnimation::from_keyframes(
self.animations &keyframes_rule.keyframes,
.get(keyframes_rule.name.as_atom()) keyframes_rule.vendor_prefix.clone(),
.map_or(true, |rule| rule.vendor_prefix.is_some()); current_layer_order,
if needs_insertion { guard,
let animation = KeyframesAnimation::from_keyframes( ));
&keyframes_rule.keyframes, },
keyframes_rule.vendor_prefix.clone(), Entry::Occupied(mut e) => {
guard, // Don't let a prefixed keyframes animation override
); // a non-prefixed one on the same layer.
debug!("Found valid keyframe animation: {:?}", animation); let needs_insert =
self.animations current_layer_order > e.get().layer_order ||
.try_insert(keyframes_rule.name.as_atom().clone(), animation)?; (current_layer_order == e.get().layer_order &&
(keyframes_rule.vendor_prefix.is_none() || e.get().vendor_prefix.is_some()));
if needs_insert {
e.insert(KeyframesAnimation::from_keyframes(
&keyframes_rule.keyframes,
keyframes_rule.vendor_prefix.clone(),
current_layer_order,
guard,
));
}
},
} }
}, },
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]