mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
style: Add @keyframe rule parsing.
This commit is contained in:
parent
7b2080c5b7
commit
c1fd7432e9
5 changed files with 197 additions and 15 deletions
|
@ -9,6 +9,7 @@ use cssparser::{AtRuleType, RuleListParser};
|
|||
use encoding::EncodingRef;
|
||||
use error_reporting::ParseErrorReporter;
|
||||
use font_face::{FontFaceRule, parse_font_face_block};
|
||||
use keyframes::{Keyframe, parse_keyframe_list};
|
||||
use media_queries::{Device, MediaQueryList, parse_media_query_list};
|
||||
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
||||
use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
|
||||
|
@ -62,6 +63,14 @@ pub enum CSSRule<Impl: SelectorImpl> {
|
|||
Media(MediaRule<Impl>),
|
||||
FontFace(FontFaceRule),
|
||||
Viewport(ViewportRule),
|
||||
Keyframes(KeyframesRule),
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, HeapSizeOf, PartialEq)]
|
||||
pub struct KeyframesRule {
|
||||
pub name: String,
|
||||
pub keyframes: Vec<Keyframe>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -71,6 +80,7 @@ pub struct MediaRule<Impl: SelectorImpl> {
|
|||
pub rules: Vec<CSSRule<Impl>>,
|
||||
}
|
||||
|
||||
|
||||
impl<Impl: SelectorImpl> MediaRule<Impl> {
|
||||
#[inline]
|
||||
pub fn evaluate(&self, device: &Device) -> bool {
|
||||
|
@ -127,7 +137,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
|
|||
let mut input = Parser::new(css);
|
||||
input.look_for_viewport_percentages();
|
||||
|
||||
let mut rules = Vec::new();
|
||||
let mut rules = vec![];
|
||||
{
|
||||
let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
|
||||
while let Some(result) = iter.next() {
|
||||
|
@ -142,6 +152,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
|
|||
Some(namespace.clone());
|
||||
}
|
||||
}
|
||||
|
||||
rules.push(rule);
|
||||
}
|
||||
Err(range) => {
|
||||
|
@ -153,6 +164,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Stylesheet {
|
||||
origin: origin,
|
||||
rules: rules,
|
||||
|
@ -253,7 +265,7 @@ pub mod rule_filter {
|
|||
use std::marker::PhantomData;
|
||||
use super::super::font_face::FontFaceRule;
|
||||
use super::super::viewport::ViewportRule;
|
||||
use super::{CSSRule, MediaRule, StyleRule};
|
||||
use super::{CSSRule, KeyframesRule, MediaRule, StyleRule};
|
||||
|
||||
macro_rules! rule_filter {
|
||||
($variant:ident -> $value:ty) => {
|
||||
|
@ -266,6 +278,8 @@ pub mod rule_filter {
|
|||
|
||||
impl<'a, I, Impl: SelectorImpl + 'a> $variant<'a, I>
|
||||
where I: Iterator<Item=&'a CSSRule<Impl>> {
|
||||
|
||||
#[inline]
|
||||
pub fn new(iter: I) -> $variant<'a, I> {
|
||||
$variant {
|
||||
iter: iter,
|
||||
|
@ -300,6 +314,7 @@ pub mod rule_filter {
|
|||
rule_filter!(Style -> StyleRule<Impl>);
|
||||
rule_filter!(FontFace -> FontFaceRule);
|
||||
rule_filter!(Viewport -> ViewportRule);
|
||||
rule_filter!(Keyframes -> KeyframesRule);
|
||||
}
|
||||
|
||||
/// Extension methods for `CSSRule` iterators.
|
||||
|
@ -315,6 +330,9 @@ pub trait CSSRuleIteratorExt<'a, Impl: SelectorImpl + 'a>: Iterator<Item=&'a CSS
|
|||
|
||||
/// Yield only @viewport rules.
|
||||
fn viewport(self) -> rule_filter::Viewport<'a, Self>;
|
||||
|
||||
/// Yield only @keyframes rules.
|
||||
fn keyframes(self) -> rule_filter::Keyframes<'a, Self>;
|
||||
}
|
||||
|
||||
impl<'a, I, Impl: SelectorImpl + 'a> CSSRuleIteratorExt<'a, Impl> for I where I: Iterator<Item=&'a CSSRule<Impl>> {
|
||||
|
@ -337,6 +355,11 @@ impl<'a, I, Impl: SelectorImpl + 'a> CSSRuleIteratorExt<'a, Impl> for I where I:
|
|||
fn viewport(self) -> rule_filter::Viewport<'a, I> {
|
||||
rule_filter::Viewport::new(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn keyframes(self) -> rule_filter::Keyframes<'a, I> {
|
||||
rule_filter::Keyframes::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_nested_rules<Impl: SelectorImpl>(context: &ParserContext, input: &mut Parser) -> Vec<CSSRule<Impl>> {
|
||||
|
@ -376,9 +399,14 @@ enum State {
|
|||
|
||||
|
||||
enum AtRulePrelude {
|
||||
/// A @font-face rule prelude.
|
||||
FontFace,
|
||||
/// A @media rule prelude, with its media queries.
|
||||
Media(MediaQueryList),
|
||||
/// A @viewport rule prelude.
|
||||
Viewport,
|
||||
/// A @keyframes rule, with its animation name.
|
||||
Keyframes(String),
|
||||
}
|
||||
|
||||
|
||||
|
@ -478,6 +506,10 @@ impl<'a, 'b, Impl: SelectorImpl> AtRuleParser for NestedRuleParser<'a, 'b, Impl>
|
|||
Err(())
|
||||
}
|
||||
},
|
||||
"keyframes" => {
|
||||
let name = try!(input.expect_ident());
|
||||
Ok(AtRuleType::WithBlock(AtRulePrelude::Keyframes(name.into_owned())))
|
||||
},
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
@ -496,11 +528,16 @@ impl<'a, 'b, Impl: SelectorImpl> AtRuleParser for NestedRuleParser<'a, 'b, Impl>
|
|||
AtRulePrelude::Viewport => {
|
||||
ViewportRule::parse(input, self.context).map(CSSRule::Viewport)
|
||||
}
|
||||
AtRulePrelude::Keyframes(name) => {
|
||||
Ok(CSSRule::Keyframes(KeyframesRule {
|
||||
name: name,
|
||||
keyframes: try!(parse_keyframe_list(&self.context, input)),
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a, 'b, Impl: SelectorImpl> QualifiedRuleParser for NestedRuleParser<'a, 'b, Impl> {
|
||||
type Prelude = Vec<Selector<Impl>>;
|
||||
type QualifiedRule = CSSRule<Impl>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue