servo: Merge #19984 - Use atom for identifier media features (from upsuper:media-ident-atom); r=emilio
authorXidorn Quan <me@upsuper.org>
Wed, 07 Feb 2018 21:43:36 -0500
changeset 457902 ba64db4fd491c98dd45b5a27e1aab1b4dbfff55f
parent 457901 579f806b99f83b72d3714b8e9670207bd5812d9a
child 457903 43a1e6e51a52fffbad6b7442857681ddc0bd2606
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1435944
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #19984 - Use atom for identifier media features (from upsuper:media-ident-atom); r=emilio This is the Servo side change of [bug 1435944](https://bugzilla.mozilla.org/show_bug.cgi?id=1435944). Source-Repo: https://github.com/servo/servo Source-Revision: 0d7c2271c284bcc2d4bd005bd0e89f9a87eba636
servo/components/style/gecko/media_queries.rs
--- a/servo/components/style/gecko/media_queries.rs
+++ b/servo/components/style/gecko/media_queries.rs
@@ -2,17 +2,17 @@
  * 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/. */
 
 //! Gecko's media-query device and expression representation.
 
 use app_units::AU_PER_PX;
 use app_units::Au;
 use context::QuirksMode;
-use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseErrorKind};
+use cssparser::{Parser, RGBA, Token, BasicParseErrorKind};
 use euclid::Size2D;
 use euclid::TypedScale;
 use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
 use gecko_bindings::bindings;
 use gecko_bindings::structs;
 use gecko_bindings::structs::{nsCSSKeyword, nsCSSProps_KTableEntry, nsCSSValue, nsCSSUnit};
 use gecko_bindings::structs::{nsMediaFeature, nsMediaFeature_ValueType, nsMediaFeature_RangeType};
 use gecko_bindings::structs::{nsPresContext, RawGeckoPresContextOwned};
@@ -23,17 +23,17 @@ use servo_arc::Arc;
 use std::fmt::{self, Write};
 use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering};
 use str::starts_with_ignore_ascii_case;
 use string_cache::Atom;
 use style_traits::{CSSPixel, CssWriter, DevicePixel};
 use style_traits::{ToCss, ParseError, StyleParseErrorKind};
 use style_traits::viewport::ViewportConstraints;
 use stylesheets::Origin;
-use values::{CSSFloat, CustomIdent, KeyframesName};
+use values::{CSSFloat, CustomIdent, KeyframesName, serialize_atom_identifier};
 use values::computed::{self, ToComputedValue};
 use values::computed::font::FontSize;
 use values::specified::{Integer, Length, Number};
 
 /// The `Device` in Gecko wraps a pres context, has a default values computed,
 /// and contains all the viewport rule state.
 pub struct Device {
     /// NB: The pres context lifetime is tied to the styleset, who owns the
@@ -347,25 +347,21 @@ pub enum MediaExpressionValue {
     /// of the '/'.
     IntRatio(u32, u32),
     /// A resolution.
     Resolution(Resolution),
     /// An enumerated value, defined by the variant keyword table in the
     /// feature's `mData` member.
     Enumerated(i16),
     /// An identifier.
-    ///
-    /// TODO(emilio): Maybe atomize?
-    Ident(String),
+    Ident(Atom),
 }
 
 impl MediaExpressionValue {
     fn from_css_value(for_expr: &Expression, css_value: &nsCSSValue) -> Option<Self> {
-        use gecko::conversions::string_from_chars_pointer;
-
         // NB: If there's a null value, that means that we don't support the
         // feature.
         if css_value.mUnit == nsCSSUnit::eCSSUnit_Null {
             return None;
         }
 
         match for_expr.feature.mValueType {
             nsMediaFeature_ValueType::eLength => {
@@ -392,23 +388,20 @@ impl MediaExpressionValue {
                 debug_assert_eq!(css_value.mUnit, nsCSSUnit::eCSSUnit_Pixel);
                 Some(MediaExpressionValue::Resolution(Resolution::Dppx(css_value.float_unchecked())))
             }
             nsMediaFeature_ValueType::eEnumerated => {
                 let value = css_value.integer_unchecked() as i16;
                 Some(MediaExpressionValue::Enumerated(value))
             }
             nsMediaFeature_ValueType::eIdent => {
-                debug_assert_eq!(css_value.mUnit, nsCSSUnit::eCSSUnit_Ident);
-                let string = unsafe {
-                    let buffer = *css_value.mValue.mString.as_ref();
-                    debug_assert!(!buffer.is_null());
-                    string_from_chars_pointer(buffer.offset(1) as *const u16)
-                };
-                Some(MediaExpressionValue::Ident(string))
+                debug_assert_eq!(css_value.mUnit, nsCSSUnit::eCSSUnit_AtomIdent);
+                Some(MediaExpressionValue::Ident(Atom::from(unsafe {
+                    *css_value.mValue.mAtom.as_ref()
+                })))
             }
             nsMediaFeature_ValueType::eIntRatio => {
                 let array = unsafe { css_value.array_unchecked() };
                 debug_assert_eq!(array.len(), 2);
                 let first = array[0].integer_unchecked();
                 let second = array[1].integer_unchecked();
 
                 debug_assert!(first >= 0 && second >= 0);
@@ -431,17 +424,17 @@ impl MediaExpressionValue {
             },
             MediaExpressionValue::IntRatio(a, b) => {
                 a.to_css(dest)?;
                 dest.write_char('/')?;
                 b.to_css(dest)
             },
             MediaExpressionValue::Resolution(ref r) => r.to_css(dest),
             MediaExpressionValue::Ident(ref ident) => {
-                CssStringWriter::new(dest).write_str(ident)
+                serialize_atom_identifier(ident, dest)
             }
             MediaExpressionValue::Enumerated(value) => unsafe {
                 use std::{slice, str};
                 use std::os::raw::c_char;
 
                 // NB: All the keywords on nsMediaFeatures are static,
                 // well-formed utf-8.
                 let mut length = 0;
@@ -556,17 +549,17 @@ fn parse_feature_value<'i, 't>(
             let value = match unsafe { find_in_table(first_table_entry, |kw, _| kw == keyword) } {
                 Some((_kw, value)) => value,
                 None => return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
             };
 
             MediaExpressionValue::Enumerated(value)
         }
         nsMediaFeature_ValueType::eIdent => {
-            MediaExpressionValue::Ident(input.expect_ident()?.as_ref().to_owned())
+            MediaExpressionValue::Ident(Atom::from(input.expect_ident()?.as_ref()))
         }
     };
 
     Ok(value)
 }
 
 impl Expression {
     /// Trivially construct a new expression.