mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +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)))
|
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> {
|
fn default_namespace(&self) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl> {
|
||||||
None
|
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.
|
/// Parse a simple selector other than a type selector.
|
||||||
///
|
///
|
||||||
/// * `Err(())`: Invalid selector, abort
|
/// * `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(Some(SimpleSelectorParseResult::SimpleSelector(attr)))
|
||||||
}
|
}
|
||||||
Ok(Token::Colon) => {
|
Ok(Token::Colon) => {
|
||||||
match input.next_including_whitespace()? {
|
let (is_single_colon, next_token) = match input.next_including_whitespace()? {
|
||||||
Token::Ident(name) => {
|
Token::Colon => (false, input.next_including_whitespace()?),
|
||||||
// Supported CSS 2.1 pseudo-elements only.
|
t => (true, t),
|
||||||
// ** Do not add to this list! **
|
};
|
||||||
if name.eq_ignore_ascii_case("before") ||
|
let (name, is_functional) = match next_token {
|
||||||
name.eq_ignore_ascii_case("after") ||
|
Token::Ident(name) => (name, false),
|
||||||
name.eq_ignore_ascii_case("first-line") ||
|
Token::Function(name) => (name, true),
|
||||||
name.eq_ignore_ascii_case("first-letter") {
|
t => return Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))),
|
||||||
let pseudo_element = P::parse_pseudo_element(parser, name)?;
|
};
|
||||||
Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo_element)))
|
let is_pseudo_element = !is_single_colon || is_css2_pseudo_element(&name);
|
||||||
} else {
|
if is_pseudo_element {
|
||||||
let pseudo_class = parse_simple_pseudo_class(parser, name)?;
|
let pseudo_element = if is_functional {
|
||||||
Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo_class)))
|
input.parse_nested_block(|input| {
|
||||||
}
|
P::parse_functional_pseudo_element(parser, name, input)
|
||||||
}
|
})?
|
||||||
Token::Function(name) => {
|
} else {
|
||||||
let pseudo = input.parse_nested_block(|input| {
|
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)
|
parse_functional_pseudo_class(parser, input, name, inside_negation)
|
||||||
})?;
|
})?
|
||||||
Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo)))
|
} else {
|
||||||
}
|
parse_simple_pseudo_class(parser, name)?
|
||||||
Token::Colon => {
|
};
|
||||||
match input.next_including_whitespace()? {
|
Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo_class)))
|
||||||
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))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue