style: Skip state pseudo-classes when finding a pseudo-element. r?heycam draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 18 Aug 2017 19:45:40 +0200
changeset 649126 f765606c29eec0d91a841b318edb7b6beef78f7b
parent 649125 94dbd3b4e5e5af03c38052afac6360462add039d
child 649127 373065afa18fa7032a515344b613c3e35daee231
push id74959
push userbmo:emilio+bugs@crisal.io
push dateFri, 18 Aug 2017 17:48:18 +0000
reviewersheycam
milestone57.0a1
style: Skip state pseudo-classes when finding a pseudo-element. r?heycam MozReview-Commit-ID: 1ICBijtcf2b
servo/components/style/invalidation/element/invalidator.rs
--- a/servo/components/style/invalidation/element/invalidator.rs
+++ b/servo/components/style/invalidation/element/invalidator.rs
@@ -590,25 +590,47 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator
                 invalidated_self = true;
             }
             CompoundSelectorMatchingResult::Matched { next_combinator_offset } => {
                 let next_combinator =
                     invalidation.selector.combinator_at(next_combinator_offset);
                 matched = true;
 
                 if matches!(next_combinator, Combinator::PseudoElement) {
-                    let pseudo_selector =
+                    // This will usually be the very next component, except for
+                    // the fact that we store compound selectors the other way
+                    // around, so there could also be state pseudo-classes.
+                    let pseudo =
                         invalidation.selector
                             .iter_raw_parse_order_from(next_combinator_offset - 1)
-                            .next()
-                            .unwrap();
-                    let pseudo = match *pseudo_selector {
-                        Component::PseudoElement(ref pseudo) => pseudo,
-                        _ => unreachable!("Someone seriously messed up selector parsing"),
-                    };
+                            .flat_map(|component| {
+                                match *component {
+                                    Component::PseudoElement(ref pseudo) => {
+                                        Some(pseudo)
+                                    },
+                                    Component::Combinator(ref combinator) => {
+                                        unreachable!(
+                                            "Someone seriously messed up selector parsing: \
+                                            {:?} at offset {:?}: {:?}",
+                                            invalidation.selector,
+                                            next_combinator_offset,
+                                            combinator,
+                                        )
+                                    },
+                                    ref other => {
+                                        debug_assert!(matches!(
+                                            *other,
+                                            Component::NonTSPseudoClass(..)
+                                        ));
+
+                                        None
+                                    }
+                                }
+                            })
+                            .next().unwrap();
 
                     // FIXME(emilio): This is not ideal, and could not be
                     // accurate if we ever have stateful element-backed eager
                     // pseudos.
                     //
                     // Ideally, we'd just remove element-backed eager pseudos
                     // altogether, given they work fine without it. Only gotcha
                     // is that we wouldn't style them in parallel, which may or