diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/style/selector_matching.rs | 2 | ||||
-rw-r--r-- | src/components/style/selectors.rs | 69 | ||||
-rw-r--r-- | src/components/style/stylesheets.rs | 2 |
3 files changed, 35 insertions, 38 deletions
diff --git a/src/components/style/selector_matching.rs b/src/components/style/selector_matching.rs index 9800007c1ab..0747495b14f 100644 --- a/src/components/style/selector_matching.rs +++ b/src/components/style/selector_matching.rs @@ -925,7 +925,7 @@ mod tests { let namespaces = NamespaceMap::new(); css_selectors.iter().enumerate().map(|(i, selectors)| { - parse_selector_list(tokenize(*selectors).map(|(c, _)| c).collect(), &namespaces) + parse_selector_list(tokenize(*selectors).map(|(c, _)| c), &namespaces) .unwrap().move_iter().map(|s| { Rule { selector: s.compound_selectors.clone(), diff --git a/src/components/style/selectors.rs b/src/components/style/selectors.rs index 00dca908c6b..44b098fa329 100644 --- a/src/components/style/selectors.rs +++ b/src/components/style/selectors.rs @@ -4,7 +4,6 @@ use std::{cmp, iter}; use std::ascii::{StrAsciiExt, OwnedStrAsciiExt}; -use std::vec; use sync::Arc; use cssparser::ast::*; @@ -113,13 +112,10 @@ pub enum NamespaceConstraint { } -type Iter = iter::Peekable<ComponentValue, vec::MoveItems<ComponentValue>>; - - pub fn parse_selector_list_from_str(input: &str) -> Result<SelectorList, ()> { let namespaces = NamespaceMap::new(); - let input = tokenize(input).map(|(token, _)| token).collect(); - parse_selector_list(input, &namespaces).map(|s| SelectorList { selectors: s }) + let iter = tokenize(input).map(|(token, _)| token); + parse_selector_list(iter, &namespaces).map(|s| SelectorList { selectors: s }) } /// Re-exported to script, but opaque. @@ -136,9 +132,10 @@ pub fn get_selector_list_selectors<'a>(selector_list: &'a SelectorList) -> &'a [ /// aka Selector Group in http://www.w3.org/TR/css3-selectors/#grouping /// /// Return the Selectors or None if there is an invalid selector. -pub fn parse_selector_list(input: Vec<ComponentValue>, namespaces: &NamespaceMap) +pub fn parse_selector_list<I: Iterator<ComponentValue>>( + iter: I, namespaces: &NamespaceMap) -> Result<Vec<Selector>, ()> { - let iter = &mut input.move_iter().peekable(); + let iter = &mut iter.peekable(); let mut results = vec![try!(parse_selector(iter, namespaces))]; loop { @@ -156,11 +153,14 @@ pub fn parse_selector_list(input: Vec<ComponentValue>, namespaces: &NamespaceMap } +type Iter<I> = iter::Peekable<ComponentValue, I>; + /// Build up a Selector. /// selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ; /// -/// None means invalid selector. -fn parse_selector(iter: &mut Iter, namespaces: &NamespaceMap) +/// `Err` means invalid selector. +fn parse_selector<I: Iterator<ComponentValue>>( + iter: &mut Iter<I>, namespaces: &NamespaceMap) -> Result<Selector, ()> { let (first, mut pseudo_element) = try!(parse_simple_selectors(iter, namespaces)); let mut compound = CompoundSelector{ simple_selectors: first, next: None }; @@ -253,8 +253,9 @@ fn compute_specificity(mut selector: &CompoundSelector, /// | [ HASH | class | attrib | pseudo | negation ]+ /// /// `Err(())` means invalid selector -fn parse_simple_selectors(iter: &mut Iter, namespaces: &NamespaceMap) - -> Result<(Vec<SimpleSelector>, Option<PseudoElement>), ()> { +fn parse_simple_selectors<I: Iterator<ComponentValue>>( + iter: &mut Iter<I>, namespaces: &NamespaceMap) + -> Result<(Vec<SimpleSelector>, Option<PseudoElement>), ()> { let mut empty = true; let mut simple_selectors = match try!(parse_type_selector(iter, namespaces)) { None => vec![], @@ -277,7 +278,8 @@ fn parse_simple_selectors(iter: &mut Iter, namespaces: &NamespaceMap) /// * `Err(())`: Invalid selector, abort /// * `Ok(None)`: Not a type selector, could be something else. `iter` was not consumed. /// * `Ok(Some(vec))`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`) -fn parse_type_selector(iter: &mut Iter, namespaces: &NamespaceMap) +fn parse_type_selector<I: Iterator<ComponentValue>>( + iter: &mut Iter<I>, namespaces: &NamespaceMap) -> Result<Option<Vec<SimpleSelector>>, ()> { skip_whitespace(iter); match try!(parse_qualified_name(iter, /* in_attr_selector = */ false, namespaces)) { @@ -313,8 +315,9 @@ enum SimpleSelectorParseResult { /// * `Err(())`: Invalid selector, abort /// * `Ok(None)`: Not a simple selector, could be something else. `iter` was not consumed. /// * `Ok(Some(_))`: Parsed a simple selector or pseudo-element -fn parse_one_simple_selector(iter: &mut Iter, namespaces: &NamespaceMap, inside_negation: bool) - -> Result<Option<SimpleSelectorParseResult>, ()> { +fn parse_one_simple_selector<I: Iterator<ComponentValue>>( + iter: &mut Iter<I>, namespaces: &NamespaceMap, inside_negation: bool) + -> Result<Option<SimpleSelectorParseResult>, ()> { match iter.peek() { Some(&IDHash(_)) => match iter.next() { Some(IDHash(id)) => Ok(Some(SimpleSelectorResult( @@ -372,21 +375,18 @@ fn parse_one_simple_selector(iter: &mut Iter, namespaces: &NamespaceMap, inside_ /// * `Err(())`: Invalid selector, abort /// * `Ok(None)`: Not a simple selector, could be something else. `iter` was not consumed. /// * `Ok(Some((namespace, local_name)))`: `None` for the local name means a `*` universal selector -fn parse_qualified_name(iter: &mut Iter, in_attr_selector: bool, namespaces: &NamespaceMap) - -> Result<Option<(NamespaceConstraint, Option<String>)>, ()> { - #[inline] - fn default_namespace(namespaces: &NamespaceMap, local_name: Option<String>) - -> Result<Option<(NamespaceConstraint, Option<String>)>, ()> { +fn parse_qualified_name<I: Iterator<ComponentValue>>( + iter: &mut Iter<I>, in_attr_selector: bool, namespaces: &NamespaceMap) + -> Result<Option<(NamespaceConstraint, Option<String>)>, ()> { + let default_namespace = |local_name| { let namespace = match namespaces.default { Some(ref ns) => SpecificNamespace(ns.clone()), None => AnyNamespace, }; Ok(Some((namespace, local_name))) - } + }; - #[inline] - fn explicit_namespace(iter: &mut Iter, in_attr_selector: bool, namespace: NamespaceConstraint) - -> Result<Option<(NamespaceConstraint, Option<String>)>, ()> { + let explicit_namespace = |iter: &mut Iter<I>, namespace| { assert!(iter.next() == Some(Delim('|')), "Implementation error, this should not happen."); match iter.peek() { @@ -400,7 +400,7 @@ fn parse_qualified_name(iter: &mut Iter, in_attr_selector: bool, namespaces: &Na }, _ => Err(()), } - } + }; match iter.peek() { Some(&Ident(_)) => { @@ -411,25 +411,24 @@ fn parse_qualified_name(iter: &mut Iter, in_attr_selector: bool, namespaces: &Na None => return Err(()), // Undeclared namespace prefix Some(ref ns) => (*ns).clone(), }; - explicit_namespace(iter, in_attr_selector, SpecificNamespace(namespace)) + explicit_namespace(iter, SpecificNamespace(namespace)) }, _ if in_attr_selector => Ok(Some( (SpecificNamespace(namespace::Null), Some(value)))), - _ => default_namespace(namespaces, Some(value)), + _ => default_namespace(Some(value)), } }, Some(&Delim('*')) => { iter.next(); // Consume '*' match iter.peek() { - Some(&Delim('|')) => explicit_namespace(iter, in_attr_selector, AnyNamespace), + Some(&Delim('|')) => explicit_namespace(iter, AnyNamespace), _ => { - if !in_attr_selector { default_namespace(namespaces, None) } + if !in_attr_selector { default_namespace(None) } else { Err(()) } }, } }, - Some(&Delim('|')) => explicit_namespace( - iter, in_attr_selector, SpecificNamespace(namespace::Null)), + Some(&Delim('|')) => explicit_namespace(iter, SpecificNamespace(namespace::Null)), _ => Ok(None), } } @@ -553,7 +552,7 @@ fn parse_negation(arguments: Vec<ComponentValue>, namespaces: &NamespaceMap) /// Assuming the next token is an ident, consume it and return its value #[inline] -fn get_next_ident(iter: &mut Iter) -> String { +fn get_next_ident<I: Iterator<ComponentValue>>(iter: &mut Iter<I>) -> String { match iter.next() { Some(Ident(value)) => value, _ => fail!("Implementation error, this should not happen."), @@ -562,7 +561,7 @@ fn get_next_ident(iter: &mut Iter) -> String { #[inline] -fn skip_whitespace(iter: &mut Iter) -> bool { +fn skip_whitespace<I: Iterator<ComponentValue>>(iter: &mut Iter<I>) -> bool { let mut any_whitespace = false; loop { if iter.peek() != Some(&WhiteSpace) { return any_whitespace } @@ -586,9 +585,7 @@ mod tests { } fn parse_ns(input: &str, namespaces: &NamespaceMap) -> Result<Vec<Selector>, ()> { - parse_selector_list( - cssparser::tokenize(input).map(|(v, _)| v).collect(), - namespaces) + parse_selector_list(cssparser::tokenize(input).map(|(v, _)| v), namespaces) } fn specificity(a: u32, b: u32, c: u32) -> u32 { diff --git a/src/components/style/stylesheets.rs b/src/components/style/stylesheets.rs index 790206001d7..cc2f1945ca9 100644 --- a/src/components/style/stylesheets.rs +++ b/src/components/style/stylesheets.rs @@ -129,7 +129,7 @@ pub fn parse_style_rule(rule: QualifiedRule, parent_rules: &mut Vec<CSSRule>, let QualifiedRule{location: location, prelude: prelude, block: block} = rule; // FIXME: avoid doing this for valid selectors let serialized = prelude.iter().to_css(); - match selectors::parse_selector_list(prelude, namespaces) { + match selectors::parse_selector_list(prelude.move_iter(), namespaces) { Ok(selectors) => parent_rules.push(CSSStyleRule(StyleRule{ selectors: selectors, declarations: properties::parse_property_declaration_list(block.move_iter(), base_url) |