aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko/selector_parser.rs8
-rw-r--r--components/style/gecko/snapshot.rs7
-rw-r--r--components/style/restyle_hints.rs23
-rw-r--r--components/style/servo/selector_parser.rs6
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