servo: Merge #14615 - Prepare for @import support (from servo:import); r=Ms2ger
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 16 Dec 2016 06:41:45 -0800
changeset 340363 55608c0db9f6cbad3c03140a285520e447089444
parent 340362 7420de79abae88af1513dbb2b1957299d34a4091
child 340364 4b742231b72e6aca1bab48b37fecdc937514fad2
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMs2ger
servo: Merge #14615 - Prepare for @import support (from servo:import); r=Ms2ger Source-Repo: https://github.com/servo/servo Source-Revision: e5d783c4542135e75cd86e1beedf42bf0ee35e5f
servo/components/style/media_queries.rs
servo/components/style/stylist.rs
--- a/servo/components/style/media_queries.rs
+++ b/servo/components/style/media_queries.rs
@@ -242,32 +242,34 @@ impl MediaQuery {
             }
             expressions.push(try!(Expression::parse(input)))
         }
     }
 }
 
 pub fn parse_media_query_list(input: &mut Parser) -> MediaList {
     if input.is_exhausted() {
-        Default::default()
-    } else {
-        let mut media_queries = vec![];
-        loop {
-            media_queries.push(
-                input.parse_until_before(Delimiter::Comma, MediaQuery::parse)
-                     .unwrap_or(MediaQuery::new(Some(Qualifier::Not),
-                                                MediaQueryType::All,
-                                                vec!())));
-            match input.next() {
-                Ok(Token::Comma) => continue,
-                Ok(_) => unreachable!(),
-                Err(()) => break,
-            }
+        return Default::default()
+    }
+
+    let mut media_queries = vec![];
+    loop {
+        media_queries.push(
+            input.parse_until_before(Delimiter::Comma, MediaQuery::parse)
+                 .unwrap_or(MediaQuery::new(Some(Qualifier::Not),
+                                            MediaQueryType::All,
+                                            vec!())));
+        match input.next() {
+            Ok(Token::Comma) => {},
+            Ok(_) => unreachable!(),
+            Err(()) => break,
         }
-        MediaList { media_queries: media_queries }
+    }
+    MediaList {
+        media_queries: media_queries,
     }
 }
 
 impl MediaList {
     pub fn evaluate(&self, device: &Device) -> bool {
         let viewport_size = device.au_viewport_size();
 
         // Check if it is an empty media query list or any queries match (OR condition)
--- a/servo/components/style/stylist.rs
+++ b/servo/components/style/stylist.rs
@@ -44,17 +44,17 @@ pub type FnvHashMap<K, V> = HashMap<K, V
 /// depending on the pseudo-element (see `PerPseudoElementSelectorMap`),
 /// and stylesheet origin (see the fields of `PerPseudoElementSelectorMap`).
 ///
 /// This structure is effectively created once per pipeline, in the
 /// LayoutThread corresponding to that pipeline.
 #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct Stylist {
     /// Device that the stylist is currently evaluating against.
-    pub device: Device,
+    pub device: Arc<Device>,
 
     /// Viewport constraints based on the current device.
     viewport_constraints: Option<ViewportConstraints>,
 
     /// If true, the quirks-mode stylesheet is applied.
     quirks_mode: bool,
 
     /// If true, the device has changed, and the stylist needs to be updated.
@@ -98,17 +98,17 @@ pub struct Stylist {
     non_common_style_affecting_attributes_selectors: Vec<Selector<SelectorImpl>>,
 }
 
 impl Stylist {
     #[inline]
     pub fn new(device: Device) -> Self {
         let mut stylist = Stylist {
             viewport_constraints: None,
-            device: device,
+            device: Arc::new(device),
             is_device_dirty: true,
             quirks_mode: false,
 
             element_map: PerPseudoElementSelectorMap::new(),
             pseudos_map: Default::default(),
             animations: Default::default(),
             precomputed_pseudo_element_decls: Default::default(),
             rules_source_order: 0,
@@ -169,101 +169,90 @@ impl Stylist {
         true
     }
 
     fn add_stylesheet(&mut self, stylesheet: &Stylesheet) {
         if stylesheet.disabled() || !stylesheet.is_effective_for_device(&self.device) {
             return;
         }
 
-        // Work around borrowing all of `self` if `self.something` is used in it
-        // instead of just `self.something`
-        macro_rules! borrow_self_field {
-            ($($x: ident),+) => {
-                $(
-                    let $x = &mut self.$x;
-                )+
-            }
-        }
-        borrow_self_field!(pseudos_map, element_map, state_deps, sibling_affecting_selectors,
-                           non_common_style_affecting_attributes_selectors, rules_source_order,
-                           animations, precomputed_pseudo_element_decls);
-        stylesheet.effective_rules(&self.device, |rule| {
+        // Cheap `Arc` clone so that the closure below can borrow `&mut Stylist`.
+        let device = self.device.clone();
+
+        stylesheet.effective_rules(&device, |rule| {
             match *rule {
                 CssRule::Style(ref style_rule) => {
                     let guard = style_rule.read();
                     for selector in &guard.selectors.0 {
                         let map = if let Some(ref pseudo) = selector.pseudo_element {
-                            pseudos_map
+                            self.pseudos_map
                                 .entry(pseudo.clone())
                                 .or_insert_with(PerPseudoElementSelectorMap::new)
                                 .borrow_for_origin(&stylesheet.origin)
                         } else {
-                            element_map.borrow_for_origin(&stylesheet.origin)
+                            self.element_map.borrow_for_origin(&stylesheet.origin)
                         };
 
                         map.insert(Rule {
                             selector: selector.complex_selector.clone(),
                             style_rule: style_rule.clone(),
                             specificity: selector.specificity,
-                            source_order: *rules_source_order,
+                            source_order: self.rules_source_order,
                         });
                     }
-                    *rules_source_order += 1;
+                    self.rules_source_order += 1;
 
                     for selector in &guard.selectors.0 {
-                        state_deps.note_selector(&selector.complex_selector);
+                        self.state_deps.note_selector(&selector.complex_selector);
                         if selector.affects_siblings() {
-                            sibling_affecting_selectors.push(selector.clone());
+                            self.sibling_affecting_selectors.push(selector.clone());
                         }
 
                         if selector.matches_non_common_style_affecting_attribute() {
-                            non_common_style_affecting_attributes_selectors.push(selector.clone());
+                            self.non_common_style_affecting_attributes_selectors.push(selector.clone());
                         }
                     }
                 }
                 CssRule::Keyframes(ref keyframes_rule) => {
                     let keyframes_rule = keyframes_rule.read();
                     debug!("Found valid keyframes rule: {:?}", *keyframes_rule);
                     if let Some(animation) = KeyframesAnimation::from_keyframes(&keyframes_rule.keyframes) {
                         debug!("Found valid keyframe animation: {:?}", animation);
-                        animations.insert(keyframes_rule.name.clone(),
+                        self.animations.insert(keyframes_rule.name.clone(),
                                                animation);
                     } else {
                         // If there's a valid keyframes rule, even if it doesn't
                         // produce an animation, should shadow other animations
                         // with the same name.
-                        animations.remove(&keyframes_rule.name);
+                        self.animations.remove(&keyframes_rule.name);
                     }
                 }
                 // We don't care about any other rule.
                 _ => {}
             }
         });
 
         debug!("Stylist stats:");
         debug!(" - Got {} sibling-affecting selectors",
-               sibling_affecting_selectors.len());
+               self.sibling_affecting_selectors.len());
         debug!(" - Got {} non-common-style-attribute-affecting selectors",
-               non_common_style_affecting_attributes_selectors.len());
+               self.non_common_style_affecting_attributes_selectors.len());
         debug!(" - Got {} deps for style-hint calculation",
-               state_deps.len());
+               self.state_deps.len());
 
         SelectorImpl::each_precomputed_pseudo_element(|pseudo| {
             // TODO: Consider not doing this and just getting the rules on the
             // fly. It should be a bit slower, but we'd take rid of the
             // extra field, and avoid this precomputation entirely.
-            if let Some(map) = pseudos_map.remove(&pseudo) {
+            if let Some(map) = self.pseudos_map.remove(&pseudo) {
                 let mut declarations = vec![];
-
                 map.user_agent.get_universal_rules(&mut declarations);
-
-                precomputed_pseudo_element_decls.insert(pseudo, declarations);
+                self.precomputed_pseudo_element_decls.insert(pseudo, declarations);
             }
-        })
+        });
     }
 
     /// Computes the style for a given "precomputed" pseudo-element, taking the
     /// universal rules and applying them.
     ///
     /// If `inherit_all` is true, then all properties are inherited from the parent; otherwise,
     /// non-inherited properties are reset to their initial values. The flow constructor uses this
     /// flag when constructing anonymous flows.
@@ -387,17 +376,17 @@ impl Stylist {
                 }
             }
             false
         }
         self.is_device_dirty |= stylesheets.iter().any(|stylesheet| {
             mq_eval_changed(&stylesheet.rules.read().0, &self.device, &device)
         });
 
-        self.device = device;
+        self.device = Arc::new(device);
     }
 
     pub fn viewport_constraints(&self) -> &Option<ViewportConstraints> {
         &self.viewport_constraints
     }
 
     pub fn set_quirks_mode(&mut self, enabled: bool) {
         self.quirks_mode = enabled;