Bug 1407953 - style: Fix invalidation collection for XBL when quirks modes don't match. r=heycam, a=ritu
☠☠ backed out by 2504eb322881 ☠ ☠
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 11 Oct 2017 10:59:05 -0500
changeset 432462 7239feae77be01b4e5984ab5a2c8fc75b8f69f66
parent 432461 2b1e17caa3146e55e1a87b1c87e3a0a27a5c4439
child 432463 2b73168324dd5459547571d20cd40298d72e5fbd
push id7956
push userryanvm@gmail.com
push dateThu, 12 Oct 2017 19:12:45 +0000
treeherdermozilla-beta@bfa99221e3af [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam, ritu
bugs1407953
milestone57.0
Bug 1407953 - style: Fix invalidation collection for XBL when quirks modes don't match. r=heycam, a=ritu Source-Repo: https://github.com/servo/servo Source-Revision: 105c5d2a0692c6e09320c5d967b43f879c3cd00d
servo/components/style/invalidation/element/invalidator.rs
--- a/servo/components/style/invalidation/element/invalidator.rs
+++ b/servo/components/style/invalidation/element/invalidator.rs
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! The struct that takes care of encapsulating all the logic on where and how
 //! element styles need to be invalidated.
 
 use Atom;
-use context::{SharedStyleContext, StackLimitChecker};
+use context::{QuirksMode, SharedStyleContext, StackLimitChecker};
 use data::ElementData;
 use dom::{TElement, TNode};
 use element_state::{ElementState, IN_VISITED_OR_UNVISITED_STATE};
 use invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper};
 use invalidation::element::invalidation_map::*;
 use invalidation::element::restyle_hints::*;
 use selector_map::SelectorMap;
 use selector_parser::{SelectorImpl, Snapshot};
@@ -250,17 +250,17 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator
 
         let mut descendant_invalidations = InvalidationVector::new();
         let mut sibling_invalidations = InvalidationVector::new();
         let invalidated_self = {
             let mut collector = InvalidationCollector {
                 wrapper: wrapper,
                 element: self.element,
                 snapshot: &snapshot,
-                shared_context: self.shared_context,
+                quirks_mode: self.shared_context.quirks_mode(),
                 lookup_element: lookup_element,
                 removed_id: id_removed.as_ref(),
                 added_id: id_added.as_ref(),
                 classes_removed: &classes_removed,
                 classes_added: &classes_added,
                 state_changes: state_changes,
                 descendant_invalidations: &mut descendant_invalidations,
                 sibling_invalidations: &mut sibling_invalidations,
@@ -272,16 +272,20 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator
             });
 
             // TODO(emilio): Consider storing dependencies from the UA sheet in
             // a different map. If we do that, we can skip the stuff on the
             // shared stylist iff cut_off_inheritance is true, and we can look
             // just at that map.
             let _cut_off_inheritance =
                 self.element.each_xbl_stylist(|stylist| {
+                    // FIXME(emilio): Replace with assert / remove when we
+                    // figure out what to do with the quirks mode mismatches
+                    // (that is, when bug 1406875 is properly fixed).
+                    collector.quirks_mode = stylist.quirks_mode();
                     stylist.each_invalidation_map(|invalidation_map| {
                         collector.collect_dependencies_in_invalidation_map(invalidation_map);
                     });
                 });
 
             collector.invalidates_self
         };
 
@@ -810,17 +814,17 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator
 }
 
 struct InvalidationCollector<'a, 'b: 'a, E>
     where E: TElement,
 {
     element: E,
     wrapper: ElementWrapper<'b, E>,
     snapshot: &'a Snapshot,
-    shared_context: &'a SharedStyleContext<'b>,
+    quirks_mode: QuirksMode,
     lookup_element: E,
     removed_id: Option<&'a Atom>,
     added_id: Option<&'a Atom>,
     classes_removed: &'a SmallVec<[Atom; 8]>,
     classes_added: &'a SmallVec<[Atom; 8]>,
     state_changes: ElementState,
     descendant_invalidations: &'a mut InvalidationVector,
     sibling_invalidations: &'a mut InvalidationVector,
@@ -829,17 +833,17 @@ struct InvalidationCollector<'a, 'b: 'a,
 
 impl<'a, 'b: 'a, E> InvalidationCollector<'a, 'b, E>
     where E: TElement,
 {
     fn collect_dependencies_in_invalidation_map(
         &mut self,
         map: &InvalidationMap,
     ) {
-        let quirks_mode = self.shared_context.quirks_mode();
+        let quirks_mode = self.quirks_mode;
         let removed_id = self.removed_id;
         if let Some(ref id) = removed_id {
             if let Some(deps) = map.id_to_selector.get(id, quirks_mode) {
                 for dep in deps {
                     self.scan_dependency(dep, VisitedDependent::No);
                 }
             }
         }
@@ -882,34 +886,34 @@ impl<'a, 'b: 'a, E> InvalidationCollecto
     }
 
     fn collect_dependencies_in_map(
         &mut self,
         map: &SelectorMap<Dependency>,
     ) {
         map.lookup_with_additional(
             self.lookup_element,
-            self.shared_context.quirks_mode(),
+            self.quirks_mode,
             self.removed_id,
             self.classes_removed,
             &mut |dependency| {
                 self.scan_dependency(dependency, VisitedDependent::No);
                 true
             },
         );
     }
 
     fn collect_state_dependencies(
         &mut self,
         map: &SelectorMap<StateDependency>,
         state_changes: ElementState,
     ) {
         map.lookup_with_additional(
             self.lookup_element,
-            self.shared_context.quirks_mode(),
+            self.quirks_mode,
             self.removed_id,
             self.classes_removed,
             &mut |dependency| {
                 if !dependency.state.intersects(state_changes) {
                     return true;
                 }
                 let visited_dependent =
                     if dependency.state.intersects(IN_VISITED_OR_UNVISITED_STATE) {