Bug 1343964 part 5 - Factor out common part of nsDOMCSSDeclaration::Parse{,Custom}PropertyValue. r=heycam draft
authorXidorn Quan <me@upsuper.org>
Tue, 04 Apr 2017 15:28:07 +1000
changeset 557552 f2201e70f58e0a89fcb90e222bcf129048056a8b
parent 557551 b5acc48044c57ca109626509ce5763626572bd24
child 557553 5f801d8c43d300c16ea325bfca7c3d3cee6e3cb6
push id52752
push userxquan@mozilla.com
push dateFri, 07 Apr 2017 00:04:02 +0000
reviewersheycam
bugs1343964
milestone55.0a1
Bug 1343964 part 5 - Factor out common part of nsDOMCSSDeclaration::Parse{,Custom}PropertyValue. r=heycam MozReview-Commit-ID: 6IX8sWF4Vhn
layout/style/nsDOMCSSDeclaration.cpp
layout/style/nsDOMCSSDeclaration.h
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -271,20 +271,20 @@ nsDOMCSSDeclaration::GetCSSParsingEnviro
 
   nsIDocument* document = sheet->GetAssociatedDocument();
   aCSSParseEnv.mSheetURI = sheet->GetSheetURI();
   aCSSParseEnv.mBaseURI = sheet->GetBaseURI();
   aCSSParseEnv.mPrincipal = sheet->Principal();
   aCSSParseEnv.mCSSLoader = document ? document->CSSLoader() : nullptr;
 }
 
+template<typename GeckoFunc, typename ServoFunc>
 nsresult
-nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSPropertyID aPropID,
-                                        const nsAString& aPropValue,
-                                        bool aIsImportant)
+nsDOMCSSDeclaration::ModifyDeclaration(GeckoFunc aGeckoFunc,
+                                       ServoFunc aServoFunc)
 {
   DeclarationBlock* olddecl = GetCSSDeclaration(eOperation_Modify);
   if (!olddecl) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   CSSParsingEnvironment env;
   GetCSSParsingEnvironment(env);
@@ -297,83 +297,70 @@ nsDOMCSSDeclaration::ParsePropertyValue(
   // 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();
 
   bool changed;
   if (decl->IsGecko()) {
-    nsCSSParser cssParser(env.mCSSLoader);
-    cssParser.ParseProperty(aPropID, aPropValue,
-                            env.mSheetURI, env.mBaseURI, env.mPrincipal,
-                            decl->AsGecko(), &changed, aIsImportant);
+    aGeckoFunc(decl->AsGecko(), env, &changed);
   } else {
-    NS_ConvertUTF16toUTF8 value(aPropValue);
     // FIXME (bug 1343964): Figure out a better solution for sending the base uri to servo
     RefPtr<URLExtraData> data =
       new URLExtraData(env.mBaseURI, env.mSheetURI, env.mPrincipal);
-    changed = Servo_DeclarationBlock_SetPropertyById(
-      decl->AsServo()->Raw(), aPropID, &value, aIsImportant, data);
+    changed = aServoFunc(decl->AsServo(), data);
   }
   if (!changed) {
     // Parsing failed -- but we don't throw an exception for that.
     return NS_OK;
   }
 
   return SetCSSDeclaration(decl);
 }
 
 nsresult
+nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSPropertyID aPropID,
+                                        const nsAString& aPropValue,
+                                        bool aIsImportant)
+{
+  return ModifyDeclaration(
+    [&](Declaration* decl, CSSParsingEnvironment& env, bool* changed) {
+      nsCSSParser cssParser(env.mCSSLoader);
+      cssParser.ParseProperty(aPropID, aPropValue,
+                              env.mSheetURI, env.mBaseURI, env.mPrincipal,
+                              decl, changed, aIsImportant);
+    },
+    [&](ServoDeclarationBlock* decl, URLExtraData* data) {
+      NS_ConvertUTF16toUTF8 value(aPropValue);
+      return Servo_DeclarationBlock_SetPropertyById(
+        decl->Raw(), aPropID, &value, aIsImportant, data);
+    });
+}
+
+nsresult
 nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName,
                                               const nsAString& aPropValue,
                                               bool aIsImportant)
 {
   MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName));
-
-  DeclarationBlock* olddecl = GetCSSDeclaration(eOperation_Modify);
-  if (!olddecl) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  CSSParsingEnvironment env;
-  GetCSSParsingEnvironment(env);
-  if (!env.mPrincipal) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  // 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();
-
-  bool changed;
-  if (decl->IsGecko()) {
-    nsCSSParser cssParser(env.mCSSLoader);
-    auto propName = Substring(aPropertyName, CSS_CUSTOM_NAME_PREFIX_LENGTH);
-    cssParser.ParseVariable(propName, aPropValue, env.mSheetURI,
-                            env.mBaseURI, env.mPrincipal, decl->AsGecko(),
-                            &changed, aIsImportant);
-  } else {
-    NS_ConvertUTF16toUTF8 property(aPropertyName);
-    NS_ConvertUTF16toUTF8 value(aPropValue);
-    RefPtr<URLExtraData> data =
-      new URLExtraData(env.mBaseURI, env.mSheetURI, env.mPrincipal);
-    changed = Servo_DeclarationBlock_SetProperty(
-      decl->AsServo()->Raw(), &property, &value, aIsImportant, data);
-  }
-  if (!changed) {
-    // Parsing failed -- but we don't throw an exception for that.
-    return NS_OK;
-  }
-
-  return SetCSSDeclaration(decl);
+  return ModifyDeclaration(
+    [&](Declaration* decl, CSSParsingEnvironment& env, bool* changed) {
+      nsCSSParser cssParser(env.mCSSLoader);
+      auto propName = Substring(aPropertyName, CSS_CUSTOM_NAME_PREFIX_LENGTH);
+      cssParser.ParseVariable(propName, aPropValue, env.mSheetURI,
+                              env.mBaseURI, env.mPrincipal, decl,
+                              changed, aIsImportant);
+    },
+    [&](ServoDeclarationBlock* decl, URLExtraData* data) {
+      NS_ConvertUTF16toUTF8 property(aPropertyName);
+      NS_ConvertUTF16toUTF8 value(aPropValue);
+      return Servo_DeclarationBlock_SetProperty(
+        decl->Raw(), &property, &value, aIsImportant, data);
+    });
 }
 
 nsresult
 nsDOMCSSDeclaration::RemovePropertyInternal(nsCSSPropertyID aPropID)
 {
   DeclarationBlock* olddecl = GetCSSDeclaration(eOperation_RemoveProperty);
   if (!olddecl) {
     return NS_OK; // no decl, so nothing to remove
--- a/layout/style/nsDOMCSSDeclaration.h
+++ b/layout/style/nsDOMCSSDeclaration.h
@@ -164,11 +164,15 @@ protected:
                                     const nsAString& aPropValue,
                                     bool aIsImportant);
 
   nsresult RemovePropertyInternal(nsCSSPropertyID aPropID);
   nsresult RemovePropertyInternal(const nsAString& aProperty);
 
 protected:
   virtual ~nsDOMCSSDeclaration();
+
+private:
+  template<typename GeckoFunc, typename ServoFunc>
+  inline nsresult ModifyDeclaration(GeckoFunc aGeckoFunc, ServoFunc aServoFunc);
 };
 
 #endif // nsDOMCSSDeclaration_h___