From 51f3a16e193fc9a3f26c85966b4229740ab65b4a Mon Sep 17 00:00:00 2001 From: Brad Werth Date: Fri, 25 Aug 2017 13:53:23 -0700 Subject: [PATCH] Bug 1391169 Part 1: Servo-side change Selector to_css function to handle combinators in between universal selectors. MozReview-Commit-ID: EyVrSAICPm --- components/selectors/parser.rs | 28 +++++++++++++++------------ tests/unit/style/parsing/selectors.rs | 2 ++ 2 files changed, 18 insertions(+), 12 deletions(-) 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, "*|* + *", "* + *"); }