mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Fix selector parsing.
This commit is contained in:
parent
de06249408
commit
b9d964bcf1
1 changed files with 76 additions and 8 deletions
|
@ -8,7 +8,7 @@ use cssparser::*;
|
|||
use namespaces::NamespaceMap;
|
||||
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[deriving(Eq, Clone)]
|
||||
pub struct Selector {
|
||||
compound_selectors: CompoundSelector,
|
||||
pseudo_element: Option<PseudoElement>,
|
||||
|
@ -27,7 +27,7 @@ pub enum PseudoElement {
|
|||
}
|
||||
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[deriving(Eq, Clone)]
|
||||
pub struct CompoundSelector {
|
||||
simple_selectors: ~[SimpleSelector],
|
||||
next: Option<(~CompoundSelector, Combinator)>, // c.next is left of c
|
||||
|
@ -41,7 +41,7 @@ pub enum Combinator {
|
|||
LaterSibling, // ~
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[deriving(Eq, Clone)]
|
||||
pub enum SimpleSelector {
|
||||
IDSelector(~str),
|
||||
ClassSelector(~str),
|
||||
|
@ -66,7 +66,7 @@ pub enum SimpleSelector {
|
|||
// ...
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[deriving(Eq, Clone)]
|
||||
pub struct AttrSelector {
|
||||
name: ~str,
|
||||
namespace: Option<~str>,
|
||||
|
@ -192,7 +192,7 @@ fn compute_specificity(mut selector: &CompoundSelector,
|
|||
static MAX_10BIT: u32 = (1u32 << 10) - 1;
|
||||
specificity.id_selectors.min(&MAX_10BIT) << 20
|
||||
| specificity.class_like_selectors.min(&MAX_10BIT) << 10
|
||||
| specificity.id_selectors.min(&MAX_10BIT)
|
||||
| specificity.element_selectors.min(&MAX_10BIT)
|
||||
}
|
||||
|
||||
|
||||
|
@ -211,7 +211,7 @@ fn parse_simple_selectors(iter: &mut Iter, namespaces: &NamespaceMap)
|
|||
match parse_one_simple_selector(iter, namespaces, /* inside_negation = */ false) {
|
||||
None => return None, // invalid selector
|
||||
Some(None) => break,
|
||||
Some(Some(Left(s))) => simple_selectors.push(s),
|
||||
Some(Some(Left(s))) => { simple_selectors.push(s); empty = false },
|
||||
Some(Some(Right(p))) => { pseudo_element = Some(p); break },
|
||||
}
|
||||
}
|
||||
|
@ -359,8 +359,7 @@ fn parse_qualified_name(iter: &mut Iter, allow_universal: bool, namespaces: &Nam
|
|||
}
|
||||
},
|
||||
Some(&Delim('|')) => explicit_namespace(iter, allow_universal, Some(~"")),
|
||||
Some(&IDHash(*)) => default_namespace(namespaces, None),
|
||||
_ => return None,
|
||||
_ => Some(None),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -492,3 +491,72 @@ fn skip_whitespace(iter: &mut Iter) -> bool {
|
|||
iter.next();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use cssparser;
|
||||
use namespaces::NamespaceMap;
|
||||
use super::*;
|
||||
|
||||
fn parse(input: &str) -> Option<~[Selector]> {
|
||||
parse_selector_list(
|
||||
cssparser::tokenize(input).map(|(v, _)| v).to_owned_vec(),
|
||||
&NamespaceMap::new())
|
||||
}
|
||||
|
||||
fn specificity(a: u32, b: u32, c: u32) -> u32 {
|
||||
a << 20 | b << 10 | c
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parsing() {
|
||||
assert_eq!(parse(""), None)
|
||||
assert_eq!(parse("e"), Some(~[Selector{
|
||||
compound_selectors: CompoundSelector {
|
||||
simple_selectors: ~[LocalNameSelector(~"e")],
|
||||
next: None,
|
||||
},
|
||||
pseudo_element: None,
|
||||
specificity: specificity(0, 0, 1),
|
||||
}]))
|
||||
assert_eq!(parse(".foo"), Some(~[Selector{
|
||||
compound_selectors: CompoundSelector {
|
||||
simple_selectors: ~[ClassSelector(~"foo")],
|
||||
next: None,
|
||||
},
|
||||
pseudo_element: None,
|
||||
specificity: specificity(0, 1, 0),
|
||||
}]))
|
||||
assert_eq!(parse("#bar"), Some(~[Selector{
|
||||
compound_selectors: CompoundSelector {
|
||||
simple_selectors: ~[IDSelector(~"bar")],
|
||||
next: None,
|
||||
},
|
||||
pseudo_element: None,
|
||||
specificity: specificity(1, 0, 0),
|
||||
}]))
|
||||
assert_eq!(parse("e.foo#bar"), Some(~[Selector{
|
||||
compound_selectors: CompoundSelector {
|
||||
simple_selectors: ~[LocalNameSelector(~"e"),
|
||||
ClassSelector(~"foo"),
|
||||
IDSelector(~"bar")],
|
||||
next: None,
|
||||
},
|
||||
pseudo_element: None,
|
||||
specificity: specificity(1, 1, 1),
|
||||
}]))
|
||||
assert_eq!(parse("e.foo #bar"), Some(~[Selector{
|
||||
compound_selectors: CompoundSelector {
|
||||
simple_selectors: ~[IDSelector(~"bar")],
|
||||
next: Some((~CompoundSelector {
|
||||
simple_selectors: ~[LocalNameSelector(~"e"),
|
||||
ClassSelector(~"foo")],
|
||||
next: None,
|
||||
}, Descendant)),
|
||||
},
|
||||
pseudo_element: None,
|
||||
specificity: specificity(1, 1, 1),
|
||||
}]))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue