diff options
-rw-r--r-- | components/style/gecko/selector_parser.rs | 8 | ||||
-rw-r--r-- | components/style/gecko/snapshot.rs | 7 | ||||
-rw-r--r-- | components/style/restyle_hints.rs | 23 | ||||
-rw-r--r-- | components/style/servo/selector_parser.rs | 6 |
4 files changed, 42 insertions, 2 deletions
diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs index 90d503f58ab..bbf2142ffc6 100644 --- a/components/style/gecko/selector_parser.rs +++ b/components/style/gecko/selector_parser.rs @@ -206,6 +206,14 @@ impl NonTSPseudoClass { } apply_non_ts_list!(pseudo_class_geckotype) } + + /// Returns true if the evaluation of the pseudo-class depends on the + /// element's attributes. + pub fn is_attr_based(&self) -> bool { + matches!(*self, + NonTSPseudoClass::MozTableBorderNonzero | + NonTSPseudoClass::MozBrowserFrame) + } } /// The dummy struct we use to implement our selector parsing. diff --git a/components/style/gecko/snapshot.rs b/components/style/gecko/snapshot.rs index 4a79b492996..4c8fe00e602 100644 --- a/components/style/gecko/snapshot.rs +++ b/components/style/gecko/snapshot.rs @@ -55,6 +55,13 @@ impl GeckoElementSnapshot { self } + /// Returns true if the snapshot has stored state for pseudo-classes + /// that depend on things other than `ElementState`. + #[inline] + pub fn has_other_pseudo_class_state(&self) -> bool { + self.has_any(Flags::OtherPseudoClassState) + } + /// selectors::Element::attr_matches pub fn attr_matches(&self, ns: &NamespaceConstraint<&Namespace>, diff --git a/components/style/restyle_hints.rs b/components/style/restyle_hints.rs index fdce4a87d60..53e33608967 100644 --- a/components/style/restyle_hints.rs +++ b/components/style/restyle_hints.rs @@ -679,6 +679,24 @@ impl<'a, E> Element for ElementWrapper<'a, E> return relevant_link.is_visited(self, context); } + #[cfg(feature = "gecko")] + NonTSPseudoClass::MozTableBorderNonzero => { + if let Some(snapshot) = self.snapshot() { + if snapshot.has_other_pseudo_class_state() { + return snapshot.mIsTableBorderNonzero(); + } + } + } + + #[cfg(feature = "gecko")] + NonTSPseudoClass::MozBrowserFrame => { + if let Some(snapshot) = self.snapshot() { + if snapshot.has_other_pseudo_class_state() { + return snapshot.mIsMozBrowserFrame(); + } + } + } + _ => {} } @@ -807,13 +825,14 @@ fn selector_to_state(sel: &Component<SelectorImpl>) -> ElementState { } } -fn is_attr_selector(sel: &Component<SelectorImpl>) -> bool { +fn is_attr_based_selector(sel: &Component<SelectorImpl>) -> bool { match *sel { Component::ID(_) | Component::Class(_) | Component::AttributeInNoNamespaceExists { .. } | Component::AttributeInNoNamespace { .. } | Component::AttributeOther(_) => true, + Component::NonTSPseudoClass(ref pc) => pc.is_attr_based(), _ => false, } } @@ -902,7 +921,7 @@ impl SelectorVisitor for SensitivitiesVisitor { type Impl = SelectorImpl; fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool { self.sensitivities.states.insert(selector_to_state(s)); - self.sensitivities.attrs |= is_attr_selector(s); + self.sensitivities.attrs |= is_attr_based_selector(s); true } } diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index c6f56a09b12..dbc0e7c1eee 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -268,6 +268,12 @@ impl NonTSPseudoClass { pub fn needs_cache_revalidation(&self) -> bool { self.state_flag().is_empty() } + + /// Returns true if the evaluation of the pseudo-class depends on the + /// element's attributes. + pub fn is_attr_based(&self) -> bool { + false + } } /// The abstract struct we implement the selector parser implementation on top |