Bug 1294299 part 12 - Implemnet setter of properties. r=SimonSapin,heycam draft
authorXidorn Quan <me@upsuper.org>
Tue, 25 Oct 2016 14:44:49 +1100
changeset 432593 50884fe5284930a42d0d402595dc27b821770295
parent 432592 af4978457607505cc44441d28f4b053a7a18c769
child 432594 d77267bdd3361489d8f0981fdb04e5577dbfebcc
push id34373
push userxquan@mozilla.com
push dateWed, 02 Nov 2016 11:29:39 +0000
reviewersSimonSapin, heycam
bugs1294299
milestone52.0a1
Bug 1294299 part 12 - Implemnet setter of properties. r=SimonSapin,heycam MozReview-Commit-ID: 4tGUowsn6AK
layout/style/ServoBindingList.h
layout/style/ServoDeclarationBlock.h
layout/style/nsDOMCSSDeclaration.cpp
servo/components/style/gecko_bindings/bindings.rs
servo/ports/geckolib/glue.rs
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -85,16 +85,20 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
                    RawServoDeclarationBlockBorrowed declarations,
                    uint32_t index, nsAString* result)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetPropertyValue, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsIAtom* property, bool is_custom, nsAString* value)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetPropertyIsImportant, bool,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsIAtom* property, bool is_custom)
+SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetProperty, bool,
+                   RawServoDeclarationBlockBorrowed declarations,
+                   nsIAtom* property, bool is_custom,
+                   nsACString* value, bool is_important)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemoveProperty, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsIAtom* property, bool is_custom)
 
 // CSS supports()
 SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
                    const nsACString* name, const nsACString* value)
 
--- a/layout/style/ServoDeclarationBlock.h
+++ b/layout/style/ServoDeclarationBlock.h
@@ -21,16 +21,17 @@ public:
     : DeclarationBlock(aCopy)
     , mRaw(Servo_DeclarationBlock_Clone(aCopy.mRaw).Consume()) {}
 
   NS_INLINE_DECL_REFCOUNTING(ServoDeclarationBlock)
 
   static already_AddRefed<ServoDeclarationBlock>
   FromCssText(const nsAString& aCssText);
 
+  RawServoDeclarationBlock* Raw() const { return mRaw; }
   RawServoDeclarationBlock* const* RefRaw() const {
     static_assert(sizeof(RefPtr<RawServoDeclarationBlock>) ==
                   sizeof(RawServoDeclarationBlock*),
                   "RefPtr should just be a pointer");
     return reinterpret_cast<RawServoDeclarationBlock* const*>(&mRaw);
   }
 
   void ToString(nsAString& aResult) const {
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -293,21 +293,28 @@ nsDOMCSSDeclaration::ParsePropertyValue(
   // For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
   // Attribute setting code, which leads in turn to BeginUpdate.  We
   // need to start the update now so that the old rule doesn't get used
   // between when we mutate the declaration and when we set the new
   // rule (see stack in bug 209575).
   mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
   RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
 
-  nsCSSParser cssParser(env.mCSSLoader);
   bool changed;
-  cssParser.ParseProperty(aPropID, aPropValue,
-                          env.mSheetURI, env.mBaseURI, env.mPrincipal,
-                          decl->AsGecko(), &changed, aIsImportant);
+  if (decl->IsGecko()) {
+    nsCSSParser cssParser(env.mCSSLoader);
+    cssParser.ParseProperty(aPropID, aPropValue,
+                            env.mSheetURI, env.mBaseURI, env.mPrincipal,
+                            decl->AsGecko(), &changed, aIsImportant);
+  } else {
+    nsIAtom* atom = nsCSSProps::AtomForProperty(aPropID);
+    NS_ConvertUTF16toUTF8 value(aPropValue);
+    changed = Servo_DeclarationBlock_SetProperty(
+      decl->AsServo()->Raw(), atom, false, &value, aIsImportant);
+  }
   if (!changed) {
     // Parsing failed -- but we don't throw an exception for that.
     return NS_OK;
   }
 
   return SetCSSDeclaration(decl);
 }
 
@@ -332,23 +339,29 @@ nsDOMCSSDeclaration::ParseCustomProperty
   // For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
   // Attribute setting code, which leads in turn to BeginUpdate.  We
   // need to start the update now so that the old rule doesn't get used
   // between when we mutate the declaration and when we set the new
   // rule (see stack in bug 209575).
   mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
   RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
 
-  nsCSSParser cssParser(env.mCSSLoader);
   bool changed;
-  cssParser.ParseVariable(Substring(aPropertyName,
-                                    CSS_CUSTOM_NAME_PREFIX_LENGTH),
-                          aPropValue, env.mSheetURI,
-                          env.mBaseURI, env.mPrincipal, decl->AsGecko(),
-                          &changed, aIsImportant);
+  auto propName = Substring(aPropertyName, CSS_CUSTOM_NAME_PREFIX_LENGTH);
+  if (decl->IsGecko()) {
+    nsCSSParser cssParser(env.mCSSLoader);
+    cssParser.ParseVariable(propName, aPropValue, env.mSheetURI,
+                            env.mBaseURI, env.mPrincipal, decl->AsGecko(),
+                            &changed, aIsImportant);
+  } else {
+    RefPtr<nsIAtom> atom = NS_Atomize(propName);
+    NS_ConvertUTF16toUTF8 value(aPropValue);
+    changed = Servo_DeclarationBlock_SetProperty(
+      decl->AsServo()->Raw(), atom, true, &value, aIsImportant);
+  }
   if (!changed) {
     // Parsing failed -- but we don't throw an exception for that.
     return NS_OK;
   }
 
   return SetCSSDeclaration(decl);
 }
 
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -972,16 +972,24 @@ extern "C" {
     pub fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations:
                                                              RawServoDeclarationBlockBorrowed,
                                                          property:
                                                              *mut nsIAtom,
                                                          is_custom: bool)
      -> bool;
 }
 extern "C" {
+    pub fn Servo_DeclarationBlock_SetProperty(declarations:
+                                                  RawServoDeclarationBlockBorrowed,
+                                              property: *mut nsIAtom,
+                                              is_custom: bool,
+                                              value: *mut nsACString_internal,
+                                              is_important: bool) -> bool;
+}
+extern "C" {
     pub fn Servo_DeclarationBlock_RemoveProperty(declarations:
                                                      RawServoDeclarationBlockBorrowed,
                                                  property: *mut nsIAtom,
                                                  is_custom: bool);
 }
 extern "C" {
     pub fn Servo_CSSSupports(name: *const nsACString_internal,
                              value: *const nsACString_internal) -> bool;
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -534,16 +534,38 @@ pub extern "C" fn Servo_DeclarationBlock
 pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed,
                                                                 property: *mut nsIAtom, is_custom: bool) -> bool {
     let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
     let property = get_property_name_from_atom(property, is_custom);
     declarations.read().property_priority(&property).important()
 }
 
 #[no_mangle]
+pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDeclarationBlockBorrowed,
+                                                     property: *mut nsIAtom, is_custom: bool,
+                                                     value: *mut nsACString, is_important: bool) -> bool {
+    let property = get_property_name_from_atom(property, is_custom);
+    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();
+    if let Ok(decls) = parse_one_declaration(&property, 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 };
+        for decl in decls.into_iter() {
+            declarations.set_parsed_declaration(decl, importance);
+        }
+        true
+    } else {
+        false
+    }
+}
+
+#[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_RemoveProperty(declarations: RawServoDeclarationBlockBorrowed,
                                                         property: *mut nsIAtom, is_custom: bool) {
     let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
     let property = get_property_name_from_atom(property, is_custom);
     declarations.write().remove_property(&property);
 }
 
 #[no_mangle]