Bug 1402219 - Store custom properties in keyframes into servo's PropertyDeclarationBlock. r?emilio,birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Wed, 27 Sep 2017 12:46:08 +0900
changeset 670900 709c4d80f25c5d3c716e3c0be55fdd05ede4fdea
parent 670899 b85a3a32860452833873d62cf236660cef82711f
child 670901 e717d4a3bef9dfafece01e8bb404f15fa1b60d01
push id81761
push userhikezoe@mozilla.com
push dateWed, 27 Sep 2017 04:24:49 +0000
reviewersemilio, birtles
bugs1402219
milestone58.0a1
Bug 1402219 - Store custom properties in keyframes into servo's PropertyDeclarationBlock. r?emilio,birtles MozReview-Commit-ID: FtkwRNtRJHS
servo/Cargo.lock
servo/components/style/properties/properties.mako.rs
servo/ports/geckolib/Cargo.toml
servo/ports/geckolib/glue.rs
servo/ports/geckolib/lib.rs
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/rust/Cargo.lock
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -1063,16 +1063,17 @@ dependencies = [
  "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "nsstring_vendor 0.1.0",
  "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.0.1",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
  "stylo_tests 0.0.1",
 ]
 
 [[package]]
 name = "getopts"
 version = "0.2.14"
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -1509,16 +1509,22 @@ impl PropertyDeclaration {
                     % endif
                 }
                 % endfor
             },
             PropertyDeclaration::Custom(..) => false,
         }
     }
 
+    /// Returns true if this property is a custom property, false
+    /// otherwise.
+    pub fn is_custom(&self) -> bool {
+        matches!(*self, PropertyDeclaration::Custom(_, _))
+    }
+
     /// The `context` parameter controls this:
     ///
     /// https://drafts.csswg.org/css-animations/#keyframes
     /// > The <declaration-list> inside of <keyframe-block> accepts any CSS property
     /// > except those defined in this specification,
     /// > but does accept the `animation-play-state` property and interprets it specially.
     ///
     /// This will not actually parse Importance values, and will always set things
--- a/servo/ports/geckolib/Cargo.toml
+++ b/servo/ports/geckolib/Cargo.toml
@@ -23,13 +23,14 @@ malloc_size_of = {path = "../../componen
 nsstring_vendor = {path = "../../components/style/gecko_bindings/nsstring_vendor"}
 parking_lot = "0.4"
 # Turn on gecko_like_types because of so that crates which use this
 # crate and also dev-depend on stylo_tests get reasonable behavior
 # during rebuilds.  See https://github.com/rust-lang/cargo/issues/3923
 # for the cargo problem behind this.
 selectors = {path = "../../components/selectors", features = ["gecko_like_types"]}
 servo_arc = {path = "../../components/servo_arc"}
+smallvec = "0.4"
 style = {path = "../../components/style", features = ["gecko"]}
 style_traits = {path = "../../components/style_traits"}
 
 [dev-dependencies]
 stylo_tests = {path = "../../tests/unit/stylo"}
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -3547,16 +3547,18 @@ fn fill_in_missing_keyframe_values(all_p
     }
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleSet_GetKeyframesForName(raw_data: RawServoStyleSetBorrowed,
                                                      name: *const nsACString,
                                                      inherited_timing_function: nsTimingFunctionBorrowed,
                                                      keyframes: RawGeckoKeyframeListBorrowedMut) -> bool {
+    use smallvec::SmallVec;
+
     debug_assert!(keyframes.len() == 0,
                   "keyframes should be initially empty");
 
     let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
     let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) };
 
     let animation = match data.stylist.get_animation(&name) {
         Some(animation) => animation,
@@ -3618,16 +3620,35 @@ pub extern "C" fn Servo_StyleSet_GetKeyf
             },
             KeyframesStepValue::Declarations { ref block } => {
                 let guard = block.read_with(&guard);
                 // Filter out non-animatable properties and properties with !important.
                 let animatable =
                     guard.normal_declaration_iter()
                          .filter(|declaration| declaration.is_animatable());
 
+                let custom_properties: SmallVec<[&PropertyDeclaration; 1]> =
+                    guard.normal_declaration_iter()
+                         .filter(|declaration| declaration.is_custom())
+                         .collect();
+
+                if custom_properties.len() > 0 {
+                    let mut pdb = PropertyDeclarationBlock::new();
+                    for custom in custom_properties.iter() {
+                        pdb.push((*custom).clone(), Importance::Normal);
+                    }
+                    unsafe {
+                        let pair =
+                            Gecko_AppendPropertyValuePair(&mut (*keyframe).mPropertyValues,
+                                                          nsCSSPropertyID::eCSSPropertyExtra_variable);
+                        (*pair).mServoDeclarationBlock.set_arc_leaky(
+                            Arc::new(global_style_data.shared_lock.wrap(pdb)));
+                    }
+                }
+
                 for declaration in animatable {
                     let property = AnimatableLonghand::from_declaration(declaration).unwrap();
                     // Skip the 'display' property because although it is animatable from SMIL,
                     // it should not be animatable from CSS Animations.
                     if property != AnimatableLonghand::Display &&
                         !properties_set_at_current_offset.has_animatable_longhand_bit(&property) {
                         properties_set_at_current_offset.set_animatable_longhand_bit(&property);
                         if current_offset == 0.0 {
--- a/servo/ports/geckolib/lib.rs
+++ b/servo/ports/geckolib/lib.rs
@@ -6,16 +6,17 @@
 
 extern crate cssparser;
 extern crate env_logger;
 extern crate libc;
 #[macro_use] extern crate log;
 extern crate malloc_size_of;
 extern crate selectors;
 extern crate servo_arc;
+extern crate smallvec;
 #[macro_use] extern crate style;
 extern crate style_traits;
 
 mod error_reporter;
 #[allow(non_snake_case)]
 pub mod glue;
 mod stylesheet_loader;
 
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -551,16 +551,17 @@ dependencies = [
  "env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "nsstring_vendor 0.1.0",
  "parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.0.1",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
 ]
 
 [[package]]
 name = "gkrust-shared"
 version = "0.1.0"
 dependencies = [
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -549,16 +549,17 @@ dependencies = [
  "env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "nsstring_vendor 0.1.0",
  "parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.0.1",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
 ]
 
 [[package]]
 name = "gkrust-shared"
 version = "0.1.0"
 dependencies = [