mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
style: Document the keyframes module.
This commit is contained in:
parent
3f7f914e16
commit
0b3c1a8924
1 changed files with 33 additions and 11 deletions
|
@ -2,6 +2,10 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Keyframes: https://drafts.csswg.org/css-animations/#keyframes
|
||||||
|
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser};
|
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser};
|
||||||
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule};
|
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -14,8 +18,8 @@ use std::sync::Arc;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use stylesheets::{MemoryHoleReporter, Stylesheet};
|
use stylesheets::{MemoryHoleReporter, Stylesheet};
|
||||||
|
|
||||||
/// A number from 0 to 1, indicating the percentage of the animation where
|
/// A number from 0 to 1, indicating the percentage of the animation when this
|
||||||
/// this keyframe should run.
|
/// keyframe should run.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct KeyframePercentage(pub f32);
|
pub struct KeyframePercentage(pub f32);
|
||||||
|
@ -37,6 +41,7 @@ impl ToCss for KeyframePercentage {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyframePercentage {
|
impl KeyframePercentage {
|
||||||
|
/// Trivially constructs a new `KeyframePercentage`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(value: f32) -> KeyframePercentage {
|
pub fn new(value: f32) -> KeyframePercentage {
|
||||||
debug_assert!(value >= 0. && value <= 1.);
|
debug_assert!(value >= 0. && value <= 1.);
|
||||||
|
@ -67,6 +72,7 @@ impl KeyframePercentage {
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct KeyframeSelector(Vec<KeyframePercentage>);
|
pub struct KeyframeSelector(Vec<KeyframePercentage>);
|
||||||
impl KeyframeSelector {
|
impl KeyframeSelector {
|
||||||
|
/// Return the list of percentages this selector contains.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn percentages(&self) -> &[KeyframePercentage] {
|
pub fn percentages(&self) -> &[KeyframePercentage] {
|
||||||
&self.0
|
&self.0
|
||||||
|
@ -77,6 +83,7 @@ impl KeyframeSelector {
|
||||||
KeyframeSelector(percentages)
|
KeyframeSelector(percentages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a keyframe selector from CSS input.
|
||||||
pub fn parse(input: &mut Parser) -> Result<Self, ()> {
|
pub fn parse(input: &mut Parser) -> Result<Self, ()> {
|
||||||
input.parse_comma_separated(KeyframePercentage::parse)
|
input.parse_comma_separated(KeyframePercentage::parse)
|
||||||
.map(KeyframeSelector)
|
.map(KeyframeSelector)
|
||||||
|
@ -87,12 +94,13 @@ impl KeyframeSelector {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct Keyframe {
|
pub struct Keyframe {
|
||||||
|
/// The selector this keyframe was specified from.
|
||||||
pub selector: KeyframeSelector,
|
pub selector: KeyframeSelector,
|
||||||
|
|
||||||
/// `!important` is not allowed in keyframe declarations,
|
/// The declaration block that was declared inside this keyframe.
|
||||||
/// so the second value of these tuples is always `Importance::Normal`.
|
///
|
||||||
/// But including them enables `compute_style_for_animation_step` to create a `ApplicableDeclarationBlock`
|
/// Note that `!important` rules in keyframes don't apply, but we keep this
|
||||||
/// by cloning an `Arc<_>` (incrementing a reference count) rather than re-creating a `Vec<_>`.
|
/// `Arc` just for convenience.
|
||||||
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
|
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
|
||||||
pub block: Arc<RwLock<PropertyDeclarationBlock>>,
|
pub block: Arc<RwLock<PropertyDeclarationBlock>>,
|
||||||
}
|
}
|
||||||
|
@ -114,7 +122,10 @@ impl ToCss for Keyframe {
|
||||||
|
|
||||||
|
|
||||||
impl Keyframe {
|
impl Keyframe {
|
||||||
pub fn parse(css: &str, parent_stylesheet: &Stylesheet, extra_data: ParserContextExtraData)
|
/// Parse a CSS keyframe.
|
||||||
|
pub fn parse(css: &str,
|
||||||
|
parent_stylesheet: &Stylesheet,
|
||||||
|
extra_data: ParserContextExtraData)
|
||||||
-> Result<Arc<RwLock<Self>>, ()> {
|
-> Result<Arc<RwLock<Self>>, ()> {
|
||||||
let error_reporter = Box::new(MemoryHoleReporter);
|
let error_reporter = Box::new(MemoryHoleReporter);
|
||||||
let context = ParserContext::new_with_extra_data(parent_stylesheet.origin,
|
let context = ParserContext::new_with_extra_data(parent_stylesheet.origin,
|
||||||
|
@ -133,15 +144,19 @@ impl Keyframe {
|
||||||
/// A keyframes step value. This can be a synthetised keyframes animation, that
|
/// A keyframes step value. This can be a synthetised keyframes animation, that
|
||||||
/// is, one autogenerated from the current computed values, or a list of
|
/// is, one autogenerated from the current computed values, or a list of
|
||||||
/// declarations to apply.
|
/// declarations to apply.
|
||||||
// TODO: Find a better name for this?
|
///
|
||||||
|
/// TODO: Find a better name for this?
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum KeyframesStepValue {
|
pub enum KeyframesStepValue {
|
||||||
/// See `Keyframe::declarations`’s docs about the presence of `Importance`.
|
/// A step formed by a declaration block specified by the CSS.
|
||||||
Declarations {
|
Declarations {
|
||||||
|
/// The declaration block per se.
|
||||||
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
|
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
|
||||||
block: Arc<RwLock<PropertyDeclarationBlock>>
|
block: Arc<RwLock<PropertyDeclarationBlock>>
|
||||||
},
|
},
|
||||||
|
/// A synthetic step computed from the current computed values at the time
|
||||||
|
/// of the animation.
|
||||||
ComputedValues,
|
ComputedValues,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +177,6 @@ pub struct KeyframesStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyframesStep {
|
impl KeyframesStep {
|
||||||
#[allow(unsafe_code)]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new(percentage: KeyframePercentage,
|
fn new(percentage: KeyframePercentage,
|
||||||
value: KeyframesStepValue) -> Self {
|
value: KeyframesStepValue) -> Self {
|
||||||
|
@ -193,6 +207,7 @@ impl KeyframesStep {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct KeyframesAnimation {
|
pub struct KeyframesAnimation {
|
||||||
|
/// The difference steps of the animation.
|
||||||
pub steps: Vec<KeyframesStep>,
|
pub steps: Vec<KeyframesStep>,
|
||||||
/// The properties that change in this animation.
|
/// The properties that change in this animation.
|
||||||
pub properties_changed: Vec<TransitionProperty>,
|
pub properties_changed: Vec<TransitionProperty>,
|
||||||
|
@ -204,7 +219,6 @@ pub struct KeyframesAnimation {
|
||||||
///
|
///
|
||||||
/// In practice, browsers seem to try to do their best job at it, so we might
|
/// In practice, browsers seem to try to do their best job at it, so we might
|
||||||
/// want to go through all the actual keyframes and deduplicate properties.
|
/// want to go through all the actual keyframes and deduplicate properties.
|
||||||
#[allow(unsafe_code)]
|
|
||||||
fn get_animated_properties(keyframe: &Keyframe) -> Vec<TransitionProperty> {
|
fn get_animated_properties(keyframe: &Keyframe) -> Vec<TransitionProperty> {
|
||||||
let mut ret = vec![];
|
let mut ret = vec![];
|
||||||
// NB: declarations are already deduplicated, so we don't have to check for
|
// NB: declarations are already deduplicated, so we don't have to check for
|
||||||
|
@ -219,6 +233,13 @@ fn get_animated_properties(keyframe: &Keyframe) -> Vec<TransitionProperty> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyframesAnimation {
|
impl KeyframesAnimation {
|
||||||
|
/// Create a keyframes animation from a given list of keyframes.
|
||||||
|
///
|
||||||
|
/// This will return `None` if the list of keyframes is empty, or there are
|
||||||
|
/// no animated properties obtained from the keyframes.
|
||||||
|
///
|
||||||
|
/// Otherwise, this will compute and sort the steps used for the animation,
|
||||||
|
/// and return the animation object.
|
||||||
pub fn from_keyframes(keyframes: &[Arc<RwLock<Keyframe>>]) -> Option<Self> {
|
pub fn from_keyframes(keyframes: &[Arc<RwLock<Keyframe>>]) -> Option<Self> {
|
||||||
if keyframes.is_empty() {
|
if keyframes.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -273,6 +294,7 @@ struct KeyframeListParser<'a> {
|
||||||
context: &'a ParserContext<'a>,
|
context: &'a ParserContext<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses a keyframe list from CSS input.
|
||||||
pub fn parse_keyframe_list(context: &ParserContext, input: &mut Parser) -> Vec<Arc<RwLock<Keyframe>>> {
|
pub fn parse_keyframe_list(context: &ParserContext, input: &mut Parser) -> Vec<Arc<RwLock<Keyframe>>> {
|
||||||
RuleListParser::new_for_nested_rule(input, KeyframeListParser { context: context })
|
RuleListParser::new_for_nested_rule(input, KeyframeListParser { context: context })
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue