diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 8cacbe6f3a2..cb149e16e5c 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -787,8 +787,8 @@ impl ToCss for Selector { // something like `... > ::before`, because we store `>` and `::` // both as combinators internally. // - // If we are in this case, we continue to the next iteration of the - // `for compound in compound_selectors` loop. + // If we are in this case, after we have serialized the universal + // selector, we skip Step 2 and continue with the algorithm. let (can_elide_namespace, first_non_namespace) = match &compound[0] { &Component::ExplicitAnyNamespace | &Component::ExplicitNoNamespace | @@ -796,6 +796,7 @@ impl ToCss for Selector { &Component::DefaultNamespace(_) => (true, 1), _ => (true, 0), }; + let mut perform_step_2 = true; if first_non_namespace == compound.len() - 1 { match (combinators.peek(), &compound[first_non_namespace]) { // We have to be careful here, because if there is a pseudo @@ -811,7 +812,8 @@ impl ToCss for Selector { for simple in compound.iter() { simple.to_css(dest)?; } - continue + // Skip step 2, which is an "otherwise". + perform_step_2 = false; } (_, _) => (), } @@ -826,17 +828,19 @@ impl ToCss for Selector { // proposing to change this to match up with the behavior asserted // in cssom/serialize-namespaced-type-selectors.html, which the // following code tries to match. - for simple in compound.iter() { - if let Component::ExplicitUniversalType = *simple { - // Can't have a namespace followed by a pseudo-element - // selector followed by a universal selector in the same - // compound selector, so we don't have to worry about the - // real namespace being in a different `compound`. - if can_elide_namespace { - continue + if perform_step_2 { + for simple in compound.iter() { + if let Component::ExplicitUniversalType = *simple { + // Can't have a namespace followed by a pseudo-element + // selector followed by a universal selector in the same + // compound selector, so we don't have to worry about the + // real namespace being in a different `compound`. + if can_elide_namespace { + continue + } } + simple.to_css(dest)?; } - simple.to_css(dest)?; } } diff --git a/tests/unit/style/parsing/selectors.rs b/tests/unit/style/parsing/selectors.rs index 8d6e94fd471..9efe7f1d2e3 100644 --- a/tests/unit/style/parsing/selectors.rs +++ b/tests/unit/style/parsing/selectors.rs @@ -25,4 +25,6 @@ fn test_selectors() { assert_roundtrip!(parse_selector, "svg|circle"); assert_roundtrip!(parse_selector, "p:before", "p::before"); assert_roundtrip!(parse_selector, "[border=\"0\"]:-servo-nonzero-border ~ ::-servo-details-summary"); + assert_roundtrip!(parse_selector, "* > *"); + assert_roundtrip!(parse_selector, "*|* + *", "* + *"); }