servo: Merge #15893 - Support SVG presentation attributes (from Manishearth:stylo-svg-pres); r=bz
authorManish Goregaokar <manishearth@gmail.com>
Thu, 09 Mar 2017 15:02:06 -0800
changeset 346869 9646ef87ae12aa5f605c5f8587d3805b3f95b5eb
parent 346868 71e3443cdc4355ed59ea0ae565cbdb42da4c3236
child 346870 5a0c4791eef57a309aef794490c5ba394923de6a
push id31480
push usercbook@mozilla.com
push dateFri, 10 Mar 2017 10:37:06 +0000
treeherdermozilla-central@e18d3dd20e8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
milestone55.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 #15893 - Support SVG presentation attributes (from Manishearth:stylo-svg-pres); r=bz r=bz from https://bugzilla.mozilla.org/show_bug.cgi?id=1329093 Source-Repo: https://github.com/servo/servo Source-Revision: ee223798cc72bf81a4b2bb6849697de617c5f028
servo/components/style/build_gecko.rs
servo/components/style/gecko_bindings/bindings.rs
servo/components/style/gecko_bindings/structs_debug.rs
servo/components/style/gecko_bindings/structs_release.rs
servo/components/style/parser.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -312,16 +312,17 @@ mod bindings {
             "DOMIntersectionObserverEntry",
             "Element",
             "FontFamilyList",
             "FontFamilyListRefCnt",
             "FontFamilyName",
             "FontFamilyType",
             "FragmentOrURL",
             "FrameRequestCallback",
+            "GeckoParserExtraData",
             "gfxAlternateValue",
             "gfxFontFeature",
             "gfxFontVariation",
             "GridNamedArea",
             "HalfCorner",
             "Image",
             "ImageURL",
             "Keyframe",
@@ -533,16 +534,17 @@ mod bindings {
             "RawGeckoKeyframeList",
             "RawGeckoComputedKeyframeValuesList",
             "RawGeckoNode",
             "RawGeckoAnimationValueList",
             "RawServoAnimationValue",
             "RawServoDeclarationBlock",
             "RawGeckoPresContext",
             "RawGeckoPresContextOwned",
+            "GeckoParserExtraData",
             "RefPtr",
             "ThreadSafeURIHolder",
             "ThreadSafePrincipalHolder",
             "CSSPseudoClassType",
             "TraversalRootBehavior",
             "FontFamilyList",
             "FontFamilyType",
             "Keyframe",
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -9,16 +9,17 @@ use gecko_bindings::structs::RawGeckoEle
 use gecko_bindings::structs::RawGeckoKeyframeList;
 use gecko_bindings::structs::RawGeckoComputedKeyframeValuesList;
 use gecko_bindings::structs::RawGeckoNode;
 use gecko_bindings::structs::RawGeckoAnimationValueList;
 use gecko_bindings::structs::RawServoAnimationValue;
 use gecko_bindings::structs::RawServoDeclarationBlock;
 use gecko_bindings::structs::RawGeckoPresContext;
 use gecko_bindings::structs::RawGeckoPresContextOwned;
+use gecko_bindings::structs::GeckoParserExtraData;
 use gecko_bindings::structs::RefPtr;
 use gecko_bindings::structs::ThreadSafeURIHolder;
 use gecko_bindings::structs::ThreadSafePrincipalHolder;
 use gecko_bindings::structs::CSSPseudoClassType;
 use gecko_bindings::structs::TraversalRootBehavior;
 use gecko_bindings::structs::FontFamilyList;
 use gecko_bindings::structs::FontFamilyType;
 use gecko_bindings::structs::Keyframe;
@@ -1334,20 +1335,18 @@ extern "C" {
 }
 extern "C" {
     pub fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed,
                                            result: *mut nsAString_internal);
 }
 extern "C" {
     pub fn Servo_ParseProperty(property: *const nsACString_internal,
                                value: *const nsACString_internal,
-                               base_url: *const nsACString_internal,
-                               base: *mut ThreadSafeURIHolder,
-                               referrer: *mut ThreadSafeURIHolder,
-                               principal: *mut ThreadSafePrincipalHolder)
+                               base: *const nsACString_internal,
+                               data: *const GeckoParserExtraData)
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
     pub fn Servo_GetComputedKeyframeValues(keyframes:
                                                RawGeckoKeyframeListBorrowed,
                                            style: ServoComputedValuesBorrowed,
                                            parent_style:
                                                ServoComputedValuesBorrowedOrNull,
@@ -1459,26 +1458,37 @@ extern "C" {
                                                              *const nsACString_internal)
      -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_SetProperty(declarations:
                                                   RawServoDeclarationBlockBorrowed,
                                               property:
                                                   *const nsACString_internal,
-                                              value: *mut nsACString_internal,
-                                              is_important: bool) -> bool;
+                                              value:
+                                                  *const nsACString_internal,
+                                              is_important: bool,
+                                              base:
+                                                  *const nsACString_internal,
+                                              data:
+                                                  *const GeckoParserExtraData)
+     -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_SetPropertyById(declarations:
                                                       RawServoDeclarationBlockBorrowed,
                                                   property: nsCSSPropertyID,
                                                   value:
-                                                      *mut nsACString_internal,
-                                                  is_important: bool) -> bool;
+                                                      *const nsACString_internal,
+                                                  is_important: bool,
+                                                  base:
+                                                      *const nsACString_internal,
+                                                  data:
+                                                      *const GeckoParserExtraData)
+     -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_RemoveProperty(declarations:
                                                      RawServoDeclarationBlockBorrowed,
                                                  property:
                                                      *const nsACString_internal);
 }
 extern "C" {
--- a/servo/components/style/gecko_bindings/structs_debug.rs
+++ b/servo/components/style/gecko_bindings/structs_debug.rs
@@ -25744,16 +25744,50 @@ pub mod root {
                     & ( * ( 0 as * const ServoBundledURI ) ) . mPrincipal as *
                     const _ as usize } , 32usize , concat ! (
                     "Alignment of field: " , stringify ! ( ServoBundledURI ) ,
                     "::" , stringify ! ( mPrincipal ) ));
     }
     impl Clone for ServoBundledURI {
         fn clone(&self) -> Self { *self }
     }
+    #[repr(C)]
+    #[derive(Debug)]
+    pub struct GeckoParserExtraData {
+        pub mBaseURI: root::RefPtr<root::nsMainThreadPtrHolder<root::nsIURI>>,
+        pub mReferrer: root::RefPtr<root::nsMainThreadPtrHolder<root::nsIURI>>,
+        pub mPrincipal: root::RefPtr<root::nsMainThreadPtrHolder<root::nsIPrincipal>>,
+    }
+    #[test]
+    fn bindgen_test_layout_GeckoParserExtraData() {
+        assert_eq!(::std::mem::size_of::<GeckoParserExtraData>() , 24usize ,
+                   concat ! (
+                   "Size of: " , stringify ! ( GeckoParserExtraData ) ));
+        assert_eq! (::std::mem::align_of::<GeckoParserExtraData>() , 8usize ,
+                    concat ! (
+                    "Alignment of " , stringify ! ( GeckoParserExtraData ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const GeckoParserExtraData ) ) . mBaseURI
+                    as * const _ as usize } , 0usize , concat ! (
+                    "Alignment of field: " , stringify ! (
+                    GeckoParserExtraData ) , "::" , stringify ! ( mBaseURI )
+                    ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const GeckoParserExtraData ) ) . mReferrer
+                    as * const _ as usize } , 8usize , concat ! (
+                    "Alignment of field: " , stringify ! (
+                    GeckoParserExtraData ) , "::" , stringify ! ( mReferrer )
+                    ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const GeckoParserExtraData ) ) . mPrincipal
+                    as * const _ as usize } , 16usize , concat ! (
+                    "Alignment of field: " , stringify ! (
+                    GeckoParserExtraData ) , "::" , stringify ! ( mPrincipal )
+                    ));
+    }
     pub type nsMediaFeatureValueGetter =
         ::std::option::Option<unsafe extern "C" fn(aPresContext:
                                                        *mut root::nsPresContext,
                                                    aFeature:
                                                        *const root::nsMediaFeature,
                                                    aResult:
                                                        *mut root::nsCSSValue)>;
     #[repr(C)]
--- a/servo/components/style/gecko_bindings/structs_release.rs
+++ b/servo/components/style/gecko_bindings/structs_release.rs
@@ -25143,16 +25143,50 @@ pub mod root {
                     & ( * ( 0 as * const ServoBundledURI ) ) . mPrincipal as *
                     const _ as usize } , 32usize , concat ! (
                     "Alignment of field: " , stringify ! ( ServoBundledURI ) ,
                     "::" , stringify ! ( mPrincipal ) ));
     }
     impl Clone for ServoBundledURI {
         fn clone(&self) -> Self { *self }
     }
+    #[repr(C)]
+    #[derive(Debug)]
+    pub struct GeckoParserExtraData {
+        pub mBaseURI: root::RefPtr<root::nsMainThreadPtrHolder<root::nsIURI>>,
+        pub mReferrer: root::RefPtr<root::nsMainThreadPtrHolder<root::nsIURI>>,
+        pub mPrincipal: root::RefPtr<root::nsMainThreadPtrHolder<root::nsIPrincipal>>,
+    }
+    #[test]
+    fn bindgen_test_layout_GeckoParserExtraData() {
+        assert_eq!(::std::mem::size_of::<GeckoParserExtraData>() , 24usize ,
+                   concat ! (
+                   "Size of: " , stringify ! ( GeckoParserExtraData ) ));
+        assert_eq! (::std::mem::align_of::<GeckoParserExtraData>() , 8usize ,
+                    concat ! (
+                    "Alignment of " , stringify ! ( GeckoParserExtraData ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const GeckoParserExtraData ) ) . mBaseURI
+                    as * const _ as usize } , 0usize , concat ! (
+                    "Alignment of field: " , stringify ! (
+                    GeckoParserExtraData ) , "::" , stringify ! ( mBaseURI )
+                    ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const GeckoParserExtraData ) ) . mReferrer
+                    as * const _ as usize } , 8usize , concat ! (
+                    "Alignment of field: " , stringify ! (
+                    GeckoParserExtraData ) , "::" , stringify ! ( mReferrer )
+                    ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const GeckoParserExtraData ) ) . mPrincipal
+                    as * const _ as usize } , 16usize , concat ! (
+                    "Alignment of field: " , stringify ! (
+                    GeckoParserExtraData ) , "::" , stringify ! ( mPrincipal )
+                    ));
+    }
     pub type nsMediaFeatureValueGetter =
         ::std::option::Option<unsafe extern "C" fn(aPresContext:
                                                        *mut root::nsPresContext,
                                                    aFeature:
                                                        *const root::nsMediaFeature,
                                                    aResult:
                                                        *mut root::nsCSSValue)>;
     #[repr(C)]
--- a/servo/components/style/parser.rs
+++ b/servo/components/style/parser.rs
@@ -38,16 +38,32 @@ impl Default for ParserContextExtraData 
 
 #[cfg(feature = "gecko")]
 impl Default for ParserContextExtraData {
     fn default() -> Self {
         ParserContextExtraData { base: None, referrer: None, principal: None }
     }
 }
 
+#[cfg(feature = "gecko")]
+impl ParserContextExtraData {
+    /// Construct from a GeckoParserExtraData
+    ///
+    /// GeckoParserExtraData must live longer than this call
+    pub unsafe fn new(data: *const ::gecko_bindings::structs::GeckoParserExtraData) -> Self {
+        // the to_safe calls are safe since we trust that we have references to
+        // real Gecko refptrs. The dereferencing of data is safe because this function
+        // is expected to be called with a `data` living longer than this function.
+        unsafe { ParserContextExtraData {
+            base: Some((*data).mBaseURI.to_safe()),
+            referrer: Some((*data).mReferrer.to_safe()),
+            principal: Some((*data).mPrincipal.to_safe()),
+        }}
+    }
+}
 /// The data that the parser needs from outside in order to parse a stylesheet.
 pub struct ParserContext<'a> {
     /// The `Origin` of the stylesheet, whether it's a user, author or
     /// user-agent stylesheet.
     pub stylesheet_origin: Origin,
     /// The base url we're parsing this stylesheet as.
     pub base_url: &'a ServoUrl,
     /// An error reporter to report syntax errors.
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -676,38 +676,44 @@ pub extern "C" fn Servo_StyleSet_Rebuild
     data.reset_device();
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) -> () {
     let _ = data.into_box::<PerDocumentStyleData>();
 }
 
+// Must be a macro since we need to store the base_url on the stack somewhere
+/// Initializes the data needed for constructing a ParserContext from
+/// Gecko-side values
+macro_rules! make_context {
+    (($base:ident, $data:ident) => ($base_url:ident, $extra_data:ident)) => {
+        let base_str = unsafe { $base.as_ref().unwrap().as_str_unchecked() };
+        let $base_url = ServoUrl::parse(base_str).unwrap();
+        let $extra_data = unsafe { ParserContextExtraData::new($data) };
+    }
+}
+
 #[no_mangle]
 pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const nsACString,
-                                      base_url: *const nsACString, base: *mut ThreadSafeURIHolder,
-                                      referrer: *mut ThreadSafeURIHolder,
-                                      principal: *mut ThreadSafePrincipalHolder)
+                                      base: *const nsACString,
+                                      data: *const structs::GeckoParserExtraData)
                                       -> RawServoDeclarationBlockStrong {
     let name = unsafe { property.as_ref().unwrap().as_str_unchecked() };
     let id = if let Ok(id) = PropertyId::parse(name.into()) {
         id
     } else {
         return RawServoDeclarationBlockStrong::null()
     };
     let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
-    let base_str = unsafe { base_url.as_ref().unwrap().as_str_unchecked() };
-    let base_url = ServoUrl::parse(base_str).unwrap();
-    let extra_data = unsafe { ParserContextExtraData {
-        base: Some(GeckoArcURI::new(base)),
-        referrer: Some(GeckoArcURI::new(referrer)),
-        principal: Some(GeckoArcPrincipal::new(principal)),
-    }};
+
+    make_context!((base, data) => (base_url, extra_data));
 
-    let context = ParserContext::new_with_extra_data(Origin::Author, &base_url,
+    let context = ParserContext::new_with_extra_data(Origin::Author,
+                                                     &base_url,
                                                      Box::new(StdoutErrorReporter),
                                                      extra_data);
 
     match ParsedDeclaration::parse(id, &context, &mut Parser::new(value), false) {
         Ok(parsed) => {
             let mut block = PropertyDeclarationBlock::new();
             parsed.expand(|d| block.push(d, Importance::Normal));
             Arc::new(RwLock::new(block)).into_strong()
@@ -814,47 +820,53 @@ pub extern "C" fn Servo_DeclarationBlock
 pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed,
                                                                 property: *const nsACString) -> bool {
     let property_id = get_property_id_from_property!(property, false);
     let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
     declarations.read().property_priority(&property_id).important()
 }
 
 fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId,
-                value: *mut nsACString, is_important: bool) -> bool {
+                value: *const nsACString, is_important: bool,
+                base: *const nsACString, data: *const structs::GeckoParserExtraData) -> bool {
     let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
-    // FIXME Needs real URL and ParserContextExtraData.
-    let base_url = &*DUMMY_BASE_URL;
-    let extra_data = ParserContextExtraData::default();
+
+    make_context!((base, data) => (base_url, extra_data));
     if let Ok(parsed) = parse_one_declaration(property_id, value, &base_url,
                                               Box::new(StdoutErrorReporter), extra_data) {
         let mut declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations).write();
         let importance = if is_important { Importance::Important } else { Importance::Normal };
         let mut changed = false;
         parsed.expand(|decl| {
             changed |= declarations.set_parsed_declaration(decl, importance);
         });
         changed
     } else {
         false
     }
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDeclarationBlockBorrowed,
-                                                     property: *const nsACString, value: *mut nsACString,
-                                                     is_important: bool) -> bool {
-    set_property(declarations, get_property_id_from_property!(property, false), value, is_important)
+                                                     property: *const nsACString, value: *const nsACString,
+                                                     is_important: bool,
+                                                     base: *const nsACString,
+                                                     data: *const structs::GeckoParserExtraData) -> bool {
+    set_property(declarations, get_property_id_from_property!(property, false),
+                 value, is_important, base, data)
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_SetPropertyById(declarations: RawServoDeclarationBlockBorrowed,
-                                                         property: nsCSSPropertyID, value: *mut nsACString,
-                                                         is_important: bool) -> bool {
-    set_property(declarations, get_property_id_from_nscsspropertyid!(property, false), value, is_important)
+                                                         property: nsCSSPropertyID, value: *const nsACString,
+                                                         is_important: bool,
+                                                         base: *const nsACString,
+                                                         data: *const structs::GeckoParserExtraData) -> bool {
+    set_property(declarations, get_property_id_from_nscsspropertyid!(property, false),
+                 value, is_important, base, data)
 }
 
 fn remove_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId) {
     let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
     declarations.write().remove_property(&property_id);
 }
 
 #[no_mangle]