Bug 265894 - Part 1. Implement NS_IMPL_ELEMENT_CLONE_WITH_INIT_AND_PARSER. draft
authorcku <cku@mozilla.com>
Wed, 14 Jun 2017 19:57:40 +0800
changeset 597161 61c2a3e1294a12fd657b59aef07e5a0c466ccec2
parent 597026 416c3c8c4b3db9ba96a103ce7820c9a140a3051d
child 597162 77c3ad45e00713769a9d87786c8a1e17044ce96c
push id64856
push userbmo:cku@mozilla.com
push dateTue, 20 Jun 2017 07:46:45 +0000
bugs265894
milestone56.0a1
Bug 265894 - Part 1. Implement NS_IMPL_ELEMENT_CLONE_WITH_INIT_AND_PARSER. Implement this new macro to reuse clone code in SVGSymbolElement in the following patch. MozReview-Commit-ID: 4vobWVrcbn2
dom/base/Element.h
dom/svg/SVGSVGElement.cpp
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -1782,25 +1782,26 @@ nsresult                                
   nsresult rv = const_cast<_elementName*>(this)->CopyInnerTo(it, aPreallocateChildren); \
   if (NS_SUCCEEDED(rv)) {                                                   \
     kungFuDeathGrip.swap(*aResult);                                         \
   }                                                                         \
                                                                             \
   return rv;                                                                \
 }
 
-#define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName)                       \
+#define EXPAND(...) __VA_ARGS__
+#define NS_IMPL_ELEMENT_CLONE_WITH_INIT_HELPER(_elementName, extra_args_)   \
 nsresult                                                                    \
 _elementName::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,   \
                     bool aPreallocateChildren) const                        \
 {                                                                           \
   *aResult = nullptr;                                                       \
   already_AddRefed<mozilla::dom::NodeInfo> ni =                             \
-    RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();                   \
-  _elementName *it = new _elementName(ni);                                  \
+    RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();                     \
+  _elementName *it = new _elementName(ni EXPAND extra_args_);               \
   if (!it) {                                                                \
     return NS_ERROR_OUT_OF_MEMORY;                                          \
   }                                                                         \
                                                                             \
   nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
   nsresult rv = it->Init();                                                 \
   nsresult rv2 = const_cast<_elementName*>(this)->CopyInnerTo(it, aPreallocateChildren); \
   if (NS_FAILED(rv2)) {                                                     \
@@ -1808,16 +1809,21 @@ nsresult                                
   }                                                                         \
   if (NS_SUCCEEDED(rv)) {                                                   \
     kungFuDeathGrip.swap(*aResult);                                         \
   }                                                                         \
                                                                             \
   return rv;                                                                \
 }
 
+#define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName) \
+  NS_IMPL_ELEMENT_CLONE_WITH_INIT_HELPER(_elementName, ())
+#define NS_IMPL_ELEMENT_CLONE_WITH_INIT_AND_PARSER(_elementName) \
+  NS_IMPL_ELEMENT_CLONE_WITH_INIT_HELPER(_elementName, (, NOT_FROM_PARSER))
+
 /**
  * A macro to implement the getter and setter for a given string
  * valued content property. The method uses the generic GetAttr and
  * SetAttr methods.  We use the 5-argument form of SetAttr, because
  * some consumers only implement that one, hiding superclass
  * 4-argument forms.
  */
 #define NS_IMPL_STRING_ATTR(_class, _method, _atom)                     \
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -185,35 +185,17 @@ SVGSVGElement::SVGSVGElement(already_Add
     mImageNeedsTransformInvalidation(false),
     mHasChildrenOnlyTransform(false)
 {
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
-// From NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGSVGElement)
-nsresult
-SVGSVGElement::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
-                     bool aPreallocateChildren) const
-{
-  *aResult = nullptr;
-  already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
-  SVGSVGElement *it = new SVGSVGElement(ni, NOT_FROM_PARSER);
-
-  nsCOMPtr<nsINode> kungFuDeathGrip = it;
-  nsresult rv1 = it->Init();
-  nsresult rv2 = const_cast<SVGSVGElement*>(this)->CopyInnerTo(it, aPreallocateChildren);
-  if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2)) {
-    kungFuDeathGrip.swap(*aResult);
-  }
-
-  return NS_FAILED(rv1) ? rv1 : rv2;
-}
-
+NS_IMPL_ELEMENT_CLONE_WITH_INIT_AND_PARSER(SVGSVGElement)
 
 //----------------------------------------------------------------------
 // nsIDOMSVGSVGElement methods:
 
 already_AddRefed<SVGAnimatedLength>
 SVGSVGElement::X()
 {
   return mLengthAttributes[ATTR_X].ToDOMAnimatedLength(this);