mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Add functional pseudo-element support to selectors crate.
This commit is contained in:
parent
d138fd1a32
commit
706d54401e
1 changed files with 45 additions and 30 deletions
|
@ -153,6 +153,13 @@ pub trait Parser<'i> {
|
|||
Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
|
||||
}
|
||||
|
||||
fn parse_functional_pseudo_element<'t>
|
||||
(&self, name: CompactCowStr<'i>, _arguments: &mut CssParser<'i, 't>)
|
||||
-> Result<<Self::Impl as SelectorImpl>::PseudoElement,
|
||||
ParseError<'i, SelectorParseError<'i, Self::Error>>> {
|
||||
Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
|
||||
}
|
||||
|
||||
fn default_namespace(&self) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl> {
|
||||
None
|
||||
}
|
||||
|
@ -1471,6 +1478,17 @@ where Impl: SelectorImpl, F: FnOnce(i32, i32) -> Component<Impl> {
|
|||
}
|
||||
|
||||
|
||||
/// Returns whether the name corresponds to a CSS2 pseudo-element that
|
||||
/// can be specified with the single colon syntax (in addition to the
|
||||
/// double-colon syntax, which can be used for all pseudo-elements).
|
||||
fn is_css2_pseudo_element<'i>(name: &CompactCowStr<'i>) -> bool {
|
||||
// ** Do not add to this list! **
|
||||
return name.eq_ignore_ascii_case("before") ||
|
||||
name.eq_ignore_ascii_case("after") ||
|
||||
name.eq_ignore_ascii_case("first-line") ||
|
||||
name.eq_ignore_ascii_case("first-letter");
|
||||
}
|
||||
|
||||
/// Parse a simple selector other than a type selector.
|
||||
///
|
||||
/// * `Err(())`: Invalid selector, abort
|
||||
|
@ -1503,37 +1521,34 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
|
|||
Ok(Some(SimpleSelectorParseResult::SimpleSelector(attr)))
|
||||
}
|
||||
Ok(Token::Colon) => {
|
||||
match input.next_including_whitespace()? {
|
||||
Token::Ident(name) => {
|
||||
// Supported CSS 2.1 pseudo-elements only.
|
||||
// ** Do not add to this list! **
|
||||
if name.eq_ignore_ascii_case("before") ||
|
||||
name.eq_ignore_ascii_case("after") ||
|
||||
name.eq_ignore_ascii_case("first-line") ||
|
||||
name.eq_ignore_ascii_case("first-letter") {
|
||||
let pseudo_element = P::parse_pseudo_element(parser, name)?;
|
||||
Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo_element)))
|
||||
} else {
|
||||
let pseudo_class = parse_simple_pseudo_class(parser, name)?;
|
||||
Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo_class)))
|
||||
}
|
||||
}
|
||||
Token::Function(name) => {
|
||||
let pseudo = input.parse_nested_block(|input| {
|
||||
let (is_single_colon, next_token) = match input.next_including_whitespace()? {
|
||||
Token::Colon => (false, input.next_including_whitespace()?),
|
||||
t => (true, t),
|
||||
};
|
||||
let (name, is_functional) = match next_token {
|
||||
Token::Ident(name) => (name, false),
|
||||
Token::Function(name) => (name, true),
|
||||
t => return Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))),
|
||||
};
|
||||
let is_pseudo_element = !is_single_colon || is_css2_pseudo_element(&name);
|
||||
if is_pseudo_element {
|
||||
let pseudo_element = if is_functional {
|
||||
input.parse_nested_block(|input| {
|
||||
P::parse_functional_pseudo_element(parser, name, input)
|
||||
})?
|
||||
} else {
|
||||
P::parse_pseudo_element(parser, name)?
|
||||
};
|
||||
Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo_element)))
|
||||
} else {
|
||||
let pseudo_class = if is_functional {
|
||||
input.parse_nested_block(|input| {
|
||||
parse_functional_pseudo_class(parser, input, name, inside_negation)
|
||||
})?;
|
||||
Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo)))
|
||||
}
|
||||
Token::Colon => {
|
||||
match input.next_including_whitespace()? {
|
||||
Token::Ident(name) => {
|
||||
let pseudo = P::parse_pseudo_element(parser, name)?;
|
||||
Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo)))
|
||||
}
|
||||
t => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))),
|
||||
}
|
||||
}
|
||||
t => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))),
|
||||
})?
|
||||
} else {
|
||||
parse_simple_pseudo_class(parser, name)?
|
||||
};
|
||||
Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo_class)))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue