Make tree pseudos not precomputed since they are not really anonymous boxes. draft
authorXidorn Quan <me@upsuper.org>
Thu, 19 Oct 2017 14:44:43 +1100
changeset 683743 22b992be067c02de310aa0ba5f1384d30790d9f0
parent 683742 2e684ce0e0b7ae169fbc47a9d4d9cf860eb61af9
child 683744 bbff59f2b23db52205af71f6751a580257d9ff63
push id85454
push userxquan@mozilla.com
push dateFri, 20 Oct 2017 05:32:42 +0000
milestone58.0a1
Make tree pseudos not precomputed since they are not really anonymous boxes. MozReview-Commit-ID: 81W9ZNqwW3W
servo/components/style/gecko/generated/pseudo_element_definition.rs
servo/components/style/gecko/pseudo_element.rs
servo/components/style/gecko/pseudo_element_definition.mako.rs
servo/components/style/stylist.rs
--- a/servo/components/style/gecko/generated/pseudo_element_definition.rs
+++ b/servo/components/style/gecko/generated/pseudo_element_definition.rs
@@ -541,16 +541,36 @@ impl PseudoElement {
 
     /// Whether this pseudo-element is eagerly-cascaded.
     #[inline]
     pub fn is_eager(&self) -> bool {
         matches!(*self,
                  PseudoElement::Before | PseudoElement::After | PseudoElement::FirstLine | PseudoElement::FirstLetter)
     }
 
+    /// Whether this pseudo-element is tree pseudo-element.
+    #[inline]
+    pub fn is_tree_pseudo_element(&self) -> bool {
+        match *self {
+            PseudoElement::MozTreeColumn(..) => true,
+            PseudoElement::MozTreeRow(..) => true,
+            PseudoElement::MozTreeSeparator(..) => true,
+            PseudoElement::MozTreeCell(..) => true,
+            PseudoElement::MozTreeIndentation(..) => true,
+            PseudoElement::MozTreeLine(..) => true,
+            PseudoElement::MozTreeTwisty(..) => true,
+            PseudoElement::MozTreeImage(..) => true,
+            PseudoElement::MozTreeCellText(..) => true,
+            PseudoElement::MozTreeCheckbox(..) => true,
+            PseudoElement::MozTreeProgressmeter(..) => true,
+            PseudoElement::MozTreeDropFeedback(..) => true,
+            _ => false,
+        }
+    }
+
     /// Gets the flags associated to this pseudo-element, or 0 if it's an
     /// anonymous box.
     pub fn flags(&self) -> u32 {
         match *self {
                 PseudoElement::After =>
                     structs::SERVO_CSS_PSEUDO_ELEMENT_FLAGS_after,
                 PseudoElement::Before =>
                     structs::SERVO_CSS_PSEUDO_ELEMENT_FLAGS_before,
--- a/servo/components/style/gecko/pseudo_element.rs
+++ b/servo/components/style/gecko/pseudo_element.rs
@@ -41,17 +41,17 @@ impl PseudoElement {
     ///
     /// We resolve the others lazily, see `Servo_ResolvePseudoStyle`.
     pub fn cascade_type(&self) -> PseudoElementCascadeType {
         if self.is_eager() {
             debug_assert!(!self.is_anon_box());
             return PseudoElementCascadeType::Eager
         }
 
-        if self.is_anon_box() {
+        if self.is_precomputed() {
             return PseudoElementCascadeType::Precomputed
         }
 
         PseudoElementCascadeType::Lazy
     }
 
     /// Whether the pseudo-element should inherit from the default computed
     /// values instead of from the parent element.
@@ -132,17 +132,17 @@ impl PseudoElement {
     #[inline]
     pub fn skip_item_based_display_fixup(&self) -> bool {
         (self.flags() & structs::CSS_PSEUDO_ELEMENT_IS_FLEX_OR_GRID_ITEM) == 0
     }
 
     /// Whether this pseudo-element is precomputed.
     #[inline]
     pub fn is_precomputed(&self) -> bool {
-        self.is_anon_box()
+        self.is_anon_box() && !self.is_tree_pseudo_element()
     }
 
     /// Covert non-canonical pseudo-element to canonical one, and keep a
     /// canonical one as it is.
     pub fn canonical(&self) -> PseudoElement {
         match *self {
             PseudoElement::MozPlaceholder => PseudoElement::Placeholder,
             _ => self.clone(),
--- a/servo/components/style/gecko/pseudo_element_definition.mako.rs
+++ b/servo/components/style/gecko/pseudo_element_definition.mako.rs
@@ -89,16 +89,27 @@ impl PseudoElement {
 
     /// Whether this pseudo-element is eagerly-cascaded.
     #[inline]
     pub fn is_eager(&self) -> bool {
         matches!(*self,
                  ${" | ".join(map(lambda name: "PseudoElement::{}".format(name), EAGER_PSEUDOS))})
     }
 
+    /// Whether this pseudo-element is tree pseudo-element.
+    #[inline]
+    pub fn is_tree_pseudo_element(&self) -> bool {
+        match *self {
+            % for pseudo in TREE_PSEUDOS:
+            ${pseudo_element_variant(pseudo)} => true,
+            % endfor
+            _ => false,
+        }
+    }
+
     /// Gets the flags associated to this pseudo-element, or 0 if it's an
     /// anonymous box.
     pub fn flags(&self) -> u32 {
         match *self {
             % for pseudo in PSEUDOS:
                 ${pseudo_element_variant(pseudo)} =>
                 % if pseudo.is_tree_pseudo_element():
                     0,
--- a/servo/components/style/stylist.rs
+++ b/servo/components/style/stylist.rs
@@ -1978,23 +1978,18 @@ impl CascadeData {
                     let style_rule = locked.read_with(&guard);
                     self.num_declarations +=
                         style_rule.block.read_with(&guard).len();
                     for selector in &style_rule.selectors.0 {
                         self.num_selectors += 1;
 
                         let map = match selector.pseudo_element() {
                             Some(pseudo) if pseudo.is_precomputed() => {
-                                if !selector.is_universal() ||
-                                   !matches!(origin, Origin::UserAgent) {
-                                    // ::-moz-tree selectors may appear in
-                                    // non-UA sheets (even though they never
-                                    // match).
-                                    continue;
-                                }
+                                debug_assert!(selector.is_universal());
+                                debug_assert!(matches!(origin, Origin::UserAgent));
 
                                 precomputed_pseudo_element_decls
                                     .as_mut()
                                     .expect("Expected precomputed declarations for the UA level")
                                     .get_or_insert_with(&pseudo.canonical(), Vec::new)
                                     .push(ApplicableDeclarationBlock::new(
                                         StyleSource::Style(locked.clone()),
                                         self.rules_source_order,