mirror of
https://github.com/servo/servo.git
synced 2025-06-18 05:14:28 +00:00
format components/selectors
This commit is contained in:
parent
9667298d29
commit
a28c642fc7
4 changed files with 342 additions and 401 deletions
|
@ -318,8 +318,9 @@ fn create_and_insert_some_stuff() {
|
||||||
assert!(bf.might_contain_hash(hash_as_str(i)));
|
assert!(bf.might_contain_hash(hash_as_str(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let false_positives =
|
let false_positives = (1001_usize..2000)
|
||||||
(1001_usize..2000).filter(|i| bf.might_contain_hash(hash_as_str(*i))).count();
|
.filter(|i| bf.might_contain_hash(hash_as_str(*i)))
|
||||||
|
.count();
|
||||||
|
|
||||||
assert!(false_positives < 190, "{} is not < 190", false_positives); // 19%.
|
assert!(false_positives < 190, "{} is not < 190", false_positives); // 19%.
|
||||||
|
|
||||||
|
@ -331,7 +332,9 @@ fn create_and_insert_some_stuff() {
|
||||||
assert!(bf.might_contain_hash(hash_as_str(i)));
|
assert!(bf.might_contain_hash(hash_as_str(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let false_positives = (0_usize..100).filter(|i| bf.might_contain_hash(hash_as_str(*i))).count();
|
let false_positives = (0_usize..100)
|
||||||
|
.filter(|i| bf.might_contain_hash(hash_as_str(*i)))
|
||||||
|
.count();
|
||||||
|
|
||||||
assert!(false_positives < 20, "{} is not < 20", false_positives); // 20%.
|
assert!(false_positives < 20, "{} is not < 20", false_positives); // 20%.
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,8 @@ struct SelectorBuilderIter<'a, Impl: SelectorImpl> {
|
||||||
|
|
||||||
impl<'a, Impl: SelectorImpl> ExactSizeIterator for SelectorBuilderIter<'a, Impl> {
|
impl<'a, Impl: SelectorImpl> ExactSizeIterator for SelectorBuilderIter<'a, Impl> {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.current_simple_selectors.len() + self.rest_of_simple_selectors.len() +
|
self.current_simple_selectors.len() +
|
||||||
|
self.rest_of_simple_selectors.len() +
|
||||||
self.combinators.len()
|
self.combinators.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +229,6 @@ struct Specificity {
|
||||||
element_selectors: u32,
|
element_selectors: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl AddAssign for Specificity {
|
impl AddAssign for Specificity {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_assign(&mut self, rhs: Self) {
|
fn add_assign(&mut self, rhs: Self) {
|
||||||
|
@ -306,10 +306,9 @@ where
|
||||||
Component::Combinator(ref combinator) => {
|
Component::Combinator(ref combinator) => {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
"Found combinator {:?} in simple selectors vector? {:?}",
|
"Found combinator {:?} in simple selectors vector? {:?}",
|
||||||
combinator,
|
combinator, builder,
|
||||||
builder,
|
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
Component::PseudoElement(..) | Component::LocalName(..) => {
|
Component::PseudoElement(..) | Component::LocalName(..) => {
|
||||||
specificity.element_selectors += 1
|
specificity.element_selectors += 1
|
||||||
},
|
},
|
||||||
|
@ -329,7 +328,7 @@ where
|
||||||
// See: https://github.com/w3c/csswg-drafts/issues/1915
|
// See: https://github.com/w3c/csswg-drafts/issues/1915
|
||||||
*specificity += Specificity::from(selector.specificity());
|
*specificity += Specificity::from(selector.specificity());
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
Component::ID(..) => {
|
Component::ID(..) => {
|
||||||
specificity.id_selectors += 1;
|
specificity.id_selectors += 1;
|
||||||
},
|
},
|
||||||
|
|
|
@ -261,8 +261,7 @@ where
|
||||||
let iter = selector.iter_from(selector.len() - from_offset);
|
let iter = selector.iter_from(selector.len() - from_offset);
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
iter.clone().next().is_some() ||
|
iter.clone().next().is_some() ||
|
||||||
(from_offset != selector.len() &&
|
(from_offset != selector.len() && matches!(
|
||||||
matches!(
|
|
||||||
selector.combinator_at_parse_order(from_offset),
|
selector.combinator_at_parse_order(from_offset),
|
||||||
Combinator::SlotAssignment | Combinator::PseudoElement
|
Combinator::SlotAssignment | Combinator::PseudoElement
|
||||||
)),
|
)),
|
||||||
|
@ -663,8 +662,9 @@ where
|
||||||
Component::Combinator(_) => unreachable!(),
|
Component::Combinator(_) => unreachable!(),
|
||||||
Component::Slotted(ref selector) => {
|
Component::Slotted(ref selector) => {
|
||||||
// <slots> are never flattened tree slottables.
|
// <slots> are never flattened tree slottables.
|
||||||
!element.is_html_slot_element() && element.assigned_slot().is_some() &&
|
!element.is_html_slot_element() && element.assigned_slot().is_some() && context
|
||||||
context.shared.nest(|context| {
|
.shared
|
||||||
|
.nest(|context| {
|
||||||
matches_complex_selector(selector.iter(), element, context, flags_setter)
|
matches_complex_selector(selector.iter(), element, context, flags_setter)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -729,7 +729,7 @@ where
|
||||||
None => {
|
None => {
|
||||||
empty_string = ::parser::namespace_empty_string::<E::Impl>();
|
empty_string = ::parser::namespace_empty_string::<E::Impl>();
|
||||||
NamespaceConstraint::Specific(&empty_string)
|
NamespaceConstraint::Specific(&empty_string)
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
element.attr_matches(
|
element.attr_matches(
|
||||||
&namespace,
|
&namespace,
|
||||||
|
@ -750,7 +750,8 @@ where
|
||||||
},
|
},
|
||||||
Component::NonTSPseudoClass(ref pc) => {
|
Component::NonTSPseudoClass(ref pc) => {
|
||||||
if context.matches_hover_and_active_quirk == MatchesHoverAndActiveQuirk::Yes &&
|
if context.matches_hover_and_active_quirk == MatchesHoverAndActiveQuirk::Yes &&
|
||||||
!context.shared.is_nested() && pc.is_active_or_hover() &&
|
!context.shared.is_nested() &&
|
||||||
|
pc.is_active_or_hover() &&
|
||||||
!element.is_link()
|
!element.is_link()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -231,9 +231,10 @@ impl<Impl: SelectorImpl> SelectorList<Impl> {
|
||||||
{
|
{
|
||||||
let mut values = SmallVec::new();
|
let mut values = SmallVec::new();
|
||||||
loop {
|
loop {
|
||||||
values
|
values.push(
|
||||||
.push(input
|
input
|
||||||
.parse_until_before(Delimiter::Comma, |input| parse_selector(parser, input))?);
|
.parse_until_before(Delimiter::Comma, |input| parse_selector(parser, input))?,
|
||||||
|
);
|
||||||
match input.next() {
|
match input.next() {
|
||||||
Err(_) => return Ok(SelectorList(values)),
|
Err(_) => return Ok(SelectorList(values)),
|
||||||
Ok(&Token::Comma) => continue,
|
Ok(&Token::Comma) => continue,
|
||||||
|
@ -434,7 +435,8 @@ where
|
||||||
ref local_name,
|
ref local_name,
|
||||||
never_matches,
|
never_matches,
|
||||||
..
|
..
|
||||||
} if !never_matches =>
|
}
|
||||||
|
if !never_matches =>
|
||||||
{
|
{
|
||||||
if !visitor.visit_attribute_selector(
|
if !visitor.visit_attribute_selector(
|
||||||
&NamespaceConstraint::Specific(&namespace_empty_string::<Impl>()),
|
&NamespaceConstraint::Specific(&namespace_empty_string::<Impl>()),
|
||||||
|
@ -451,7 +453,7 @@ where
|
||||||
None => {
|
None => {
|
||||||
empty_string = ::parser::namespace_empty_string::<Impl>();
|
empty_string = ::parser::namespace_empty_string::<Impl>();
|
||||||
NamespaceConstraint::Specific(&empty_string)
|
NamespaceConstraint::Specific(&empty_string)
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
if !visitor.visit_attribute_selector(
|
if !visitor.visit_attribute_selector(
|
||||||
&namespace,
|
&namespace,
|
||||||
|
@ -536,7 +538,8 @@ impl<Impl: SelectorImpl> Selector<Impl> {
|
||||||
self.iter_raw_match_order().all(|c| {
|
self.iter_raw_match_order().all(|c| {
|
||||||
matches!(
|
matches!(
|
||||||
*c,
|
*c,
|
||||||
Component::ExplicitUniversalType | Component::ExplicitAnyNamespace |
|
Component::ExplicitUniversalType |
|
||||||
|
Component::ExplicitAnyNamespace |
|
||||||
Component::Combinator(Combinator::PseudoElement) |
|
Component::Combinator(Combinator::PseudoElement) |
|
||||||
Component::PseudoElement(..)
|
Component::PseudoElement(..)
|
||||||
)
|
)
|
||||||
|
@ -571,7 +574,7 @@ impl<Impl: SelectorImpl> Selector<Impl> {
|
||||||
None => return false,
|
None => return false,
|
||||||
Some(combinator) => {
|
Some(combinator) => {
|
||||||
debug_assert_eq!(combinator, Combinator::PseudoElement);
|
debug_assert_eq!(combinator, Combinator::PseudoElement);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
iter.is_featureless_host_selector()
|
iter.is_featureless_host_selector()
|
||||||
|
@ -785,7 +788,9 @@ impl Combinator {
|
||||||
pub fn is_ancestor(&self) -> bool {
|
pub fn is_ancestor(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
*self,
|
*self,
|
||||||
Combinator::Child | Combinator::Descendant | Combinator::PseudoElement |
|
Combinator::Child |
|
||||||
|
Combinator::Descendant |
|
||||||
|
Combinator::PseudoElement |
|
||||||
Combinator::SlotAssignment
|
Combinator::SlotAssignment
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -976,7 +981,8 @@ impl<Impl: SelectorImpl> ToCss for SelectorList<Impl> {
|
||||||
W: fmt::Write,
|
W: fmt::Write,
|
||||||
{
|
{
|
||||||
let mut iter = self.0.iter();
|
let mut iter = self.0.iter();
|
||||||
let first = iter.next()
|
let first = iter
|
||||||
|
.next()
|
||||||
.expect("Empty SelectorList, should contain at least one selector");
|
.expect("Empty SelectorList, should contain at least one selector");
|
||||||
first.to_css(dest)?;
|
first.to_css(dest)?;
|
||||||
for selector in iter {
|
for selector in iter {
|
||||||
|
@ -1004,10 +1010,12 @@ impl<Impl: SelectorImpl> ToCss for Selector<Impl> {
|
||||||
// which we need for |split|. So we split by combinators on a match-order
|
// which we need for |split|. So we split by combinators on a match-order
|
||||||
// sequence and then reverse.
|
// sequence and then reverse.
|
||||||
|
|
||||||
let mut combinators = self.iter_raw_match_order()
|
let mut combinators = self
|
||||||
|
.iter_raw_match_order()
|
||||||
.rev()
|
.rev()
|
||||||
.filter_map(|x| x.as_combinator());
|
.filter_map(|x| x.as_combinator());
|
||||||
let compound_selectors = self.iter_raw_match_order()
|
let compound_selectors = self
|
||||||
|
.iter_raw_match_order()
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.split(|x| x.is_combinator())
|
.split(|x| x.is_combinator())
|
||||||
.rev();
|
.rev();
|
||||||
|
@ -1261,7 +1269,7 @@ impl<Impl: SelectorImpl> ToCss for AttrSelectorWithOptionalNamespace<Impl> {
|
||||||
dest.write_char('|')?
|
dest.write_char('|')?
|
||||||
},
|
},
|
||||||
Some(NamespaceConstraint::Any) => dest.write_str("*|")?,
|
Some(NamespaceConstraint::Any) => dest.write_str("*|")?,
|
||||||
None => {}
|
None => {},
|
||||||
}
|
}
|
||||||
display_to_css_identifier(&self.local_name, dest)?;
|
display_to_css_identifier(&self.local_name, dest)?;
|
||||||
match self.operation {
|
match self.operation {
|
||||||
|
@ -1701,8 +1709,7 @@ where
|
||||||
{
|
{
|
||||||
let local_name_lower_cow = to_ascii_lowercase(&local_name);
|
let local_name_lower_cow = to_ascii_lowercase(&local_name);
|
||||||
if let ParsedCaseSensitivity::CaseSensitive = case_sensitivity {
|
if let ParsedCaseSensitivity::CaseSensitive = case_sensitivity {
|
||||||
if namespace.is_none() &&
|
if namespace.is_none() && include!(concat!(
|
||||||
include!(concat!(
|
|
||||||
env!("OUT_DIR"),
|
env!("OUT_DIR"),
|
||||||
"/ascii_case_insensitive_html_attributes.rs"
|
"/ascii_case_insensitive_html_attributes.rs"
|
||||||
)).contains(&*local_name_lower_cow)
|
)).contains(&*local_name_lower_cow)
|
||||||
|
@ -1798,7 +1805,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success.
|
// Success.
|
||||||
Ok(Component::Negation(sequence.into_vec().into_boxed_slice().into()))
|
Ok(Component::Negation(
|
||||||
|
sequence.into_vec().into_boxed_slice().into(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// simple_selector_sequence
|
/// simple_selector_sequence
|
||||||
|
@ -2041,9 +2050,7 @@ where
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SimpleSelectorParseResult::PseudoElement(P::parse_pseudo_element(
|
SimpleSelectorParseResult::PseudoElement(P::parse_pseudo_element(
|
||||||
parser,
|
parser, location, name,
|
||||||
location,
|
|
||||||
name,
|
|
||||||
)?)
|
)?)
|
||||||
};
|
};
|
||||||
Ok(Some(parse_result))
|
Ok(Some(parse_result))
|
||||||
|
@ -2363,22 +2370,17 @@ pub mod tests {
|
||||||
assert!(parse(":lang(en US)").is_err());
|
assert!(parse(":lang(en US)").is_err());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("EeÉ"),
|
parse("EeÉ"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::LocalName(LocalName {
|
||||||
vec![
|
|
||||||
Component::LocalName(LocalName {
|
|
||||||
name: DummyAtom::from("EeÉ"),
|
name: DummyAtom::from("EeÉ"),
|
||||||
lower_name: DummyAtom::from("eeÉ"),
|
lower_name: DummyAtom::from("eeÉ"),
|
||||||
}),
|
}), ],
|
||||||
],
|
|
||||||
specificity(0, 0, 1),
|
specificity(0, 0, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("|e"),
|
parse("|e"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::ExplicitNoNamespace,
|
Component::ExplicitNoNamespace,
|
||||||
Component::LocalName(LocalName {
|
Component::LocalName(LocalName {
|
||||||
|
@ -2387,24 +2389,19 @@ pub mod tests {
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
specificity(0, 0, 1),
|
specificity(0, 0, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
// When the default namespace is not set, *| should be elided.
|
// When the default namespace is not set, *| should be elided.
|
||||||
// https://github.com/servo/servo/pull/17537
|
// https://github.com/servo/servo/pull/17537
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_expected("*|e", Some("e")),
|
parse_expected("*|e", Some("e")),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::LocalName(LocalName {
|
||||||
vec![
|
|
||||||
Component::LocalName(LocalName {
|
|
||||||
name: DummyAtom::from("e"),
|
name: DummyAtom::from("e"),
|
||||||
lower_name: DummyAtom::from("e"),
|
lower_name: DummyAtom::from("e"),
|
||||||
}),
|
}), ],
|
||||||
],
|
|
||||||
specificity(0, 0, 1),
|
specificity(0, 0, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
// When the default namespace is set, *| should _not_ be elided (as foo
|
// When the default namespace is set, *| should _not_ be elided (as foo
|
||||||
// is no longer equivalent to *|foo--the former is only for foo in the
|
// is no longer equivalent to *|foo--the former is only for foo in the
|
||||||
|
@ -2415,8 +2412,7 @@ pub mod tests {
|
||||||
"*|e",
|
"*|e",
|
||||||
&DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org"))
|
&DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org"))
|
||||||
),
|
),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::ExplicitAnyNamespace,
|
Component::ExplicitAnyNamespace,
|
||||||
Component::LocalName(LocalName {
|
Component::LocalName(LocalName {
|
||||||
|
@ -2425,73 +2421,65 @@ pub mod tests {
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
specificity(0, 0, 1),
|
specificity(0, 0, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("*"),
|
parse("*"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(vec![Component::ExplicitUniversalType], specificity(0, 0, 0)),
|
vec![Component::ExplicitUniversalType],
|
||||||
]))
|
specificity(0, 0, 0)
|
||||||
|
), ]))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("|*"),
|
parse("|*"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::ExplicitNoNamespace,
|
Component::ExplicitNoNamespace,
|
||||||
Component::ExplicitUniversalType,
|
Component::ExplicitUniversalType,
|
||||||
],
|
],
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_expected("*|*", Some("*")),
|
parse_expected("*|*", Some("*")),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(vec![Component::ExplicitUniversalType], specificity(0, 0, 0)),
|
vec![Component::ExplicitUniversalType],
|
||||||
]))
|
specificity(0, 0, 0)
|
||||||
|
), ]))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns(
|
parse_ns(
|
||||||
"*|*",
|
"*|*",
|
||||||
&DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org"))
|
&DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org"))
|
||||||
),
|
),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::ExplicitAnyNamespace,
|
Component::ExplicitAnyNamespace,
|
||||||
Component::ExplicitUniversalType,
|
Component::ExplicitUniversalType,
|
||||||
],
|
],
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(".foo:lang(en-US)"),
|
parse(".foo:lang(en-US)"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::Class(DummyAtom::from("foo")),
|
Component::Class(DummyAtom::from("foo")),
|
||||||
Component::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned())),
|
Component::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned())),
|
||||||
],
|
],
|
||||||
specificity(0, 2, 0),
|
specificity(0, 2, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("#bar"),
|
parse("#bar"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![Component::ID(DummyAtom::from("bar"))],
|
vec![Component::ID(DummyAtom::from("bar"))],
|
||||||
specificity(1, 0, 0),
|
specificity(1, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("e.foo#bar"),
|
parse("e.foo#bar"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::LocalName(LocalName {
|
Component::LocalName(LocalName {
|
||||||
name: DummyAtom::from("e"),
|
name: DummyAtom::from("e"),
|
||||||
|
@ -2501,13 +2489,11 @@ pub mod tests {
|
||||||
Component::ID(DummyAtom::from("bar")),
|
Component::ID(DummyAtom::from("bar")),
|
||||||
],
|
],
|
||||||
specificity(1, 1, 1),
|
specificity(1, 1, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("e.foo #bar"),
|
parse("e.foo #bar"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::LocalName(LocalName {
|
Component::LocalName(LocalName {
|
||||||
name: DummyAtom::from("e"),
|
name: DummyAtom::from("e"),
|
||||||
|
@ -2518,25 +2504,20 @@ pub mod tests {
|
||||||
Component::ID(DummyAtom::from("bar")),
|
Component::ID(DummyAtom::from("bar")),
|
||||||
],
|
],
|
||||||
specificity(1, 1, 1),
|
specificity(1, 1, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
// Default namespace does not apply to attribute selectors
|
// Default namespace does not apply to attribute selectors
|
||||||
// https://github.com/mozilla/servo/pull/1652
|
// https://github.com/mozilla/servo/pull/1652
|
||||||
let mut parser = DummyParser::default();
|
let mut parser = DummyParser::default();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns("[Foo]", &parser),
|
parse_ns("[Foo]", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::AttributeInNoNamespaceExists {
|
||||||
vec![
|
|
||||||
Component::AttributeInNoNamespaceExists {
|
|
||||||
local_name: DummyAtom::from("Foo"),
|
local_name: DummyAtom::from("Foo"),
|
||||||
local_name_lower: DummyAtom::from("foo"),
|
local_name_lower: DummyAtom::from("foo"),
|
||||||
},
|
}, ],
|
||||||
],
|
|
||||||
specificity(0, 1, 0),
|
specificity(0, 1, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert!(parse_ns("svg|circle", &parser).is_err());
|
assert!(parse_ns("svg|circle", &parser).is_err());
|
||||||
parser
|
parser
|
||||||
|
@ -2544,8 +2525,7 @@ pub mod tests {
|
||||||
.insert(DummyAtom("svg".into()), DummyAtom(SVG.into()));
|
.insert(DummyAtom("svg".into()), DummyAtom(SVG.into()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns("svg|circle", &parser),
|
parse_ns("svg|circle", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::Namespace(DummyAtom("svg".into()), SVG.into()),
|
Component::Namespace(DummyAtom("svg".into()), SVG.into()),
|
||||||
Component::LocalName(LocalName {
|
Component::LocalName(LocalName {
|
||||||
|
@ -2554,20 +2534,17 @@ pub mod tests {
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
specificity(0, 0, 1),
|
specificity(0, 0, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns("svg|*", &parser),
|
parse_ns("svg|*", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::Namespace(DummyAtom("svg".into()), SVG.into()),
|
Component::Namespace(DummyAtom("svg".into()), SVG.into()),
|
||||||
Component::ExplicitUniversalType,
|
Component::ExplicitUniversalType,
|
||||||
],
|
],
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
// Default namespace does not apply to attribute selectors
|
// Default namespace does not apply to attribute selectors
|
||||||
// https://github.com/mozilla/servo/pull/1652
|
// https://github.com/mozilla/servo/pull/1652
|
||||||
|
@ -2576,8 +2553,7 @@ pub mod tests {
|
||||||
parser.default_ns = Some(MATHML.into());
|
parser.default_ns = Some(MATHML.into());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns("[Foo]", &parser),
|
parse_ns("[Foo]", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::DefaultNamespace(MATHML.into()),
|
Component::DefaultNamespace(MATHML.into()),
|
||||||
Component::AttributeInNoNamespaceExists {
|
Component::AttributeInNoNamespaceExists {
|
||||||
|
@ -2586,14 +2562,12 @@ pub mod tests {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
specificity(0, 1, 0),
|
specificity(0, 1, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
// Default namespace does apply to type selectors
|
// Default namespace does apply to type selectors
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns("e", &parser),
|
parse_ns("e", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::DefaultNamespace(MATHML.into()),
|
Component::DefaultNamespace(MATHML.into()),
|
||||||
Component::LocalName(LocalName {
|
Component::LocalName(LocalName {
|
||||||
|
@ -2602,70 +2576,63 @@ pub mod tests {
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
specificity(0, 0, 1),
|
specificity(0, 0, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns("*", &parser),
|
parse_ns("*", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::DefaultNamespace(MATHML.into()),
|
Component::DefaultNamespace(MATHML.into()),
|
||||||
Component::ExplicitUniversalType,
|
Component::ExplicitUniversalType,
|
||||||
],
|
],
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns("*|*", &parser),
|
parse_ns("*|*", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::ExplicitAnyNamespace,
|
Component::ExplicitAnyNamespace,
|
||||||
Component::ExplicitUniversalType,
|
Component::ExplicitUniversalType,
|
||||||
],
|
],
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
// Default namespace applies to universal and type selectors inside :not and :matches,
|
// Default namespace applies to universal and type selectors inside :not and :matches,
|
||||||
// but not otherwise.
|
// but not otherwise.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns(":not(.cl)", &parser),
|
parse_ns(":not(.cl)", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::DefaultNamespace(MATHML.into()),
|
Component::DefaultNamespace(MATHML.into()),
|
||||||
Component::Negation(
|
Component::Negation(
|
||||||
vec![Component::Class(DummyAtom::from("cl"))].into_boxed_slice().into(),
|
vec![Component::Class(DummyAtom::from("cl"))]
|
||||||
|
.into_boxed_slice()
|
||||||
|
.into(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
specificity(0, 1, 0),
|
specificity(0, 1, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns(":not(*)", &parser),
|
parse_ns(":not(*)", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::DefaultNamespace(MATHML.into()),
|
Component::DefaultNamespace(MATHML.into()),
|
||||||
Component::Negation(
|
Component::Negation(
|
||||||
vec![
|
vec![
|
||||||
Component::DefaultNamespace(MATHML.into()),
|
Component::DefaultNamespace(MATHML.into()),
|
||||||
Component::ExplicitUniversalType,
|
Component::ExplicitUniversalType,
|
||||||
].into_boxed_slice().into(),
|
].into_boxed_slice()
|
||||||
|
.into(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns(":not(e)", &parser),
|
parse_ns(":not(e)", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::DefaultNamespace(MATHML.into()),
|
Component::DefaultNamespace(MATHML.into()),
|
||||||
Component::Negation(
|
Component::Negation(
|
||||||
|
@ -2675,64 +2642,54 @@ pub mod tests {
|
||||||
name: DummyAtom::from("e"),
|
name: DummyAtom::from("e"),
|
||||||
lower_name: DummyAtom::from("e"),
|
lower_name: DummyAtom::from("e"),
|
||||||
}),
|
}),
|
||||||
].into_boxed_slice().into(),
|
].into_boxed_slice()
|
||||||
|
.into(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
specificity(0, 0, 1),
|
specificity(0, 0, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("[attr|=\"foo\"]"),
|
parse("[attr|=\"foo\"]"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::AttributeInNoNamespace {
|
||||||
vec![
|
|
||||||
Component::AttributeInNoNamespace {
|
|
||||||
local_name: DummyAtom::from("attr"),
|
local_name: DummyAtom::from("attr"),
|
||||||
operator: AttrSelectorOperator::DashMatch,
|
operator: AttrSelectorOperator::DashMatch,
|
||||||
value: DummyAtom::from("foo"),
|
value: DummyAtom::from("foo"),
|
||||||
never_matches: false,
|
never_matches: false,
|
||||||
case_sensitivity: ParsedCaseSensitivity::CaseSensitive,
|
case_sensitivity: ParsedCaseSensitivity::CaseSensitive,
|
||||||
},
|
}, ],
|
||||||
],
|
|
||||||
specificity(0, 1, 0),
|
specificity(0, 1, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
// https://github.com/mozilla/servo/issues/1723
|
// https://github.com/mozilla/servo/issues/1723
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("::before"),
|
parse("::before"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![Component::PseudoElement(PseudoElement::Before)],
|
vec![Component::PseudoElement(PseudoElement::Before)],
|
||||||
specificity(0, 0, 1) | HAS_PSEUDO_BIT,
|
specificity(0, 0, 1) | HAS_PSEUDO_BIT,
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("::before:hover"),
|
parse("::before:hover"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::PseudoElement(PseudoElement::Before),
|
Component::PseudoElement(PseudoElement::Before),
|
||||||
Component::NonTSPseudoClass(PseudoClass::Hover),
|
Component::NonTSPseudoClass(PseudoClass::Hover),
|
||||||
],
|
],
|
||||||
specificity(0, 1, 1) | HAS_PSEUDO_BIT,
|
specificity(0, 1, 1) | HAS_PSEUDO_BIT,
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("::before:hover:hover"),
|
parse("::before:hover:hover"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::PseudoElement(PseudoElement::Before),
|
Component::PseudoElement(PseudoElement::Before),
|
||||||
Component::NonTSPseudoClass(PseudoClass::Hover),
|
Component::NonTSPseudoClass(PseudoClass::Hover),
|
||||||
Component::NonTSPseudoClass(PseudoClass::Hover),
|
Component::NonTSPseudoClass(PseudoClass::Hover),
|
||||||
],
|
],
|
||||||
specificity(0, 2, 1) | HAS_PSEUDO_BIT,
|
specificity(0, 2, 1) | HAS_PSEUDO_BIT,
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert!(parse("::before:hover:active").is_err());
|
assert!(parse("::before:hover:active").is_err());
|
||||||
assert!(parse("::before:hover .foo").is_err());
|
assert!(parse("::before:hover .foo").is_err());
|
||||||
|
@ -2744,8 +2701,7 @@ pub mod tests {
|
||||||
assert!(parse(":: before").is_err());
|
assert!(parse(":: before").is_err());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("div ::after"),
|
parse("div ::after"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::LocalName(LocalName {
|
Component::LocalName(LocalName {
|
||||||
name: DummyAtom::from("div"),
|
name: DummyAtom::from("div"),
|
||||||
|
@ -2756,21 +2712,18 @@ pub mod tests {
|
||||||
Component::PseudoElement(PseudoElement::After),
|
Component::PseudoElement(PseudoElement::After),
|
||||||
],
|
],
|
||||||
specificity(0, 0, 2) | HAS_PSEUDO_BIT,
|
specificity(0, 0, 2) | HAS_PSEUDO_BIT,
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("#d1 > .ok"),
|
parse("#d1 > .ok"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
|
||||||
vec![
|
vec![
|
||||||
Component::ID(DummyAtom::from("d1")),
|
Component::ID(DummyAtom::from("d1")),
|
||||||
Component::Combinator(Combinator::Child),
|
Component::Combinator(Combinator::Child),
|
||||||
Component::Class(DummyAtom::from("ok")),
|
Component::Class(DummyAtom::from("ok")),
|
||||||
],
|
],
|
||||||
(1 << 20) + (1 << 10) + (0 << 0),
|
(1 << 20) + (1 << 10) + (0 << 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
parser.default_ns = None;
|
parser.default_ns = None;
|
||||||
assert!(parse(":not(#provel.old)").is_err());
|
assert!(parse(":not(#provel.old)").is_err());
|
||||||
|
@ -2778,96 +2731,81 @@ pub mod tests {
|
||||||
assert!(parse("table[rules]:not([rules=\"none\"]):not([rules=\"\"])").is_ok());
|
assert!(parse("table[rules]:not([rules=\"none\"]):not([rules=\"\"])").is_ok());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(":not(#provel)"),
|
parse(":not(#provel)"),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::Negation(
|
||||||
vec![
|
vec![Component::ID(DummyAtom::from("provel"))]
|
||||||
Component::Negation(
|
.into_boxed_slice()
|
||||||
vec![Component::ID(DummyAtom::from("provel"))].into_boxed_slice().into(),
|
.into(),
|
||||||
),
|
), ],
|
||||||
],
|
|
||||||
specificity(1, 0, 0),
|
specificity(1, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns(":not(svg|circle)", &parser),
|
parse_ns(":not(svg|circle)", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::Negation(
|
||||||
vec![
|
|
||||||
Component::Negation(
|
|
||||||
vec![
|
vec![
|
||||||
Component::Namespace(DummyAtom("svg".into()), SVG.into()),
|
Component::Namespace(DummyAtom("svg".into()), SVG.into()),
|
||||||
Component::LocalName(LocalName {
|
Component::LocalName(LocalName {
|
||||||
name: DummyAtom::from("circle"),
|
name: DummyAtom::from("circle"),
|
||||||
lower_name: DummyAtom::from("circle"),
|
lower_name: DummyAtom::from("circle"),
|
||||||
}),
|
}),
|
||||||
].into_boxed_slice().into(),
|
].into_boxed_slice()
|
||||||
),
|
.into(),
|
||||||
],
|
), ],
|
||||||
specificity(0, 0, 1),
|
specificity(0, 0, 1),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
// https://github.com/servo/servo/issues/16017
|
// https://github.com/servo/servo/issues/16017
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns(":not(*)", &parser),
|
parse_ns(":not(*)", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::Negation(
|
||||||
vec![
|
vec![Component::ExplicitUniversalType]
|
||||||
Component::Negation(
|
.into_boxed_slice()
|
||||||
vec![Component::ExplicitUniversalType].into_boxed_slice().into(),
|
.into(),
|
||||||
),
|
), ],
|
||||||
],
|
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns(":not(|*)", &parser),
|
parse_ns(":not(|*)", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::Negation(
|
||||||
vec![
|
|
||||||
Component::Negation(
|
|
||||||
vec![
|
vec![
|
||||||
Component::ExplicitNoNamespace,
|
Component::ExplicitNoNamespace,
|
||||||
Component::ExplicitUniversalType,
|
Component::ExplicitUniversalType,
|
||||||
].into_boxed_slice().into(),
|
].into_boxed_slice()
|
||||||
),
|
.into(),
|
||||||
],
|
), ],
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
// *| should be elided if there is no default namespace.
|
// *| should be elided if there is no default namespace.
|
||||||
// https://github.com/servo/servo/pull/17537
|
// https://github.com/servo/servo/pull/17537
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns_expected(":not(*|*)", &parser, Some(":not(*)")),
|
parse_ns_expected(":not(*|*)", &parser, Some(":not(*)")),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::Negation(
|
||||||
vec![
|
vec![Component::ExplicitUniversalType]
|
||||||
Component::Negation(
|
.into_boxed_slice()
|
||||||
vec![Component::ExplicitUniversalType].into_boxed_slice().into(),
|
.into(),
|
||||||
),
|
), ],
|
||||||
],
|
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ns(":not(svg|*)", &parser),
|
parse_ns(":not(svg|*)", &parser),
|
||||||
Ok(SelectorList::from_vec(vec![
|
Ok(SelectorList::from_vec(vec![Selector::from_vec(
|
||||||
Selector::from_vec(
|
vec![Component::Negation(
|
||||||
vec![
|
|
||||||
Component::Negation(
|
|
||||||
vec![
|
vec![
|
||||||
Component::Namespace(DummyAtom("svg".into()), SVG.into()),
|
Component::Namespace(DummyAtom("svg".into()), SVG.into()),
|
||||||
Component::ExplicitUniversalType,
|
Component::ExplicitUniversalType,
|
||||||
].into_boxed_slice().into(),
|
].into_boxed_slice()
|
||||||
),
|
.into(),
|
||||||
],
|
), ],
|
||||||
specificity(0, 0, 0),
|
specificity(0, 0, 0),
|
||||||
),
|
), ]))
|
||||||
]))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(parse("::slotted()").is_err());
|
assert!(parse("::slotted()").is_err());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue