Bug 823394 Part 2: Add WebIDL API to SVGElement and enable binding r=bz
authorDavid Zbarsky <dzbarsky@gmail.com>
Sun, 23 Dec 2012 03:22:58 -0500
changeset 116995 dc2abccc2adb0fd61b6f579436e7706cccf41e03
parent 116994 3b56b12b4a70d649fe035b975c4a05f96bae1acc
child 116996 5a1f68dbd88556ade7f1f2eb0b059bf3ec1de59b
child 116997 e097dd1a2c38bc7a63430bb7163ab1a51d5d0f8a
child 117938 30830a4b9bfdf568fa5484f173135400a27b7603
push id24077
push userryanvm@gmail.com
push dateMon, 24 Dec 2012 13:05:31 +0000
treeherdermozilla-central@dc2abccc2adb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs823394
milestone20.0a1
first release with
nightly linux32
dc2abccc2adb / 20.0a1 / 20121225030757 / files
nightly linux64
dc2abccc2adb / 20.0a1 / 20121225030757 / files
nightly mac
dc2abccc2adb / 20.0a1 / 20121225030757 / files
nightly win32
dc2abccc2adb / 20.0a1 / 20121225030757 / files
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 823394 Part 2: Add WebIDL API to SVGElement and enable binding r=bz
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGElement.h
dom/bindings/Bindings.conf
dom/webidl/SVGElement.webidl
dom/webidl/WebIDL.mk
js/xpconnect/src/dom_quickstubs.qsconf
js/xpconnect/src/nsDOMQS.h
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -54,16 +54,17 @@
 #include "nsIFrame.h"
 #include "prdtoa.h"
 #include <stdarg.h>
 #include "nsSMILMappedAttribute.h"
 #include "SVGMotionSMILAttr.h"
 #include "nsAttrValueOrString.h"
 #include "nsSMILAnimationController.h"
 #include "nsDOMCSSDeclaration.h"
+#include "mozilla/dom/SVGElementBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // This is needed to ensure correct handling of calls to the
 // vararg-list methods in this file:
 //   nsSVGElement::GetAnimated{Length,Number,Integer}Values
 // See bug 547964 for details:
@@ -76,50 +77,73 @@ nsSVGEnumMapping nsSVGElement::sSVGUnitT
   {nullptr, 0}
 };
 
 nsSVGElement::nsSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsSVGElementBase(aNodeInfo)
 {
 }
 
+JSObject*
+nsSVGElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+  return SVGElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
 //----------------------------------------------------------------------
 
 /* readonly attribute nsIDOMSVGAnimatedString className; */
 NS_IMETHODIMP
 nsSVGElement::GetClassName(nsIDOMSVGAnimatedString** aClassName)
 {
-  return mClassAttribute.ToDOMAnimatedString(aClassName, this);
+  *aClassName = ClassName().get();
+  return NS_OK;
 }
 
 /* readonly attribute nsIDOMCSSStyleDeclaration style; */
 NS_IMETHODIMP
 nsSVGElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
 {
-  nsresult rv;
-  *aStyle = nsSVGElementBase::GetStyle(&rv);
-  if (NS_FAILED(rv)) {
-    return rv;
+  ErrorResult rv;
+  NS_ADDREF(*aStyle = GetStyle(rv));
+  return rv.ErrorCode();
+}
+
+nsICSSDeclaration*
+nsSVGElement::GetStyle(ErrorResult& rv)
+{
+  nsresult res;
+  nsICSSDeclaration* style = nsSVGElementBase::GetStyle(&res);
+  if (NS_FAILED(res)) {
+    rv.Throw(res);
+    return nullptr;
   }
-  NS_ADDREF(*aStyle);
-  return NS_OK;
+
+  return style;
 }
 
 /* nsIDOMCSSValue getPresentationAttribute (in DOMString name); */
 NS_IMETHODIMP
 nsSVGElement::GetPresentationAttribute(const nsAString& aName,
                                        nsIDOMCSSValue** aReturn)
 {
   // Let's not implement this just yet. The CSSValue interface has been
   // deprecated by the CSS WG.
   // http://lists.w3.org/Archives/Public/www-style/2003Oct/0347.html
 
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+already_AddRefed<CSSValue>
+nsSVGElement::GetPresentationAttribute(const nsAString& aName, ErrorResult& rv)
+{
+  rv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+  return nullptr;
+}
+
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 void
 nsSVGElement::DidAnimateClass()
 {
   nsAutoString src;
   mClassAttribute.GetAnimValue(src, this);
@@ -1122,34 +1146,62 @@ NS_IMETHODIMP nsSVGElement::SetId(const 
 {
   return SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true);
 }
 
 /* readonly attribute nsIDOMSVGSVGElement ownerSVGElement; */
 NS_IMETHODIMP
 nsSVGElement::GetOwnerSVGElement(nsIDOMSVGSVGElement * *aOwnerSVGElement)
 {
-  NS_IF_ADDREF(*aOwnerSVGElement = GetCtx());
-
-  if (*aOwnerSVGElement || Tag() == nsGkAtoms::svg) {
-    // If we found something or we're the outermost SVG element, that's OK.
-    return NS_OK;
+  ErrorResult rv;
+  NS_IF_ADDREF(*aOwnerSVGElement = GetOwnerSVGElement(rv));
+  return rv.ErrorCode();
+}
+
+nsSVGSVGElement*
+nsSVGElement::GetOwnerSVGElement(ErrorResult& rv)
+{
+  nsSVGSVGElement* ownerSVGElement = GetCtx();
+
+  // If we didn't find anything and we're not the outermost SVG element,
+  // we've got an invalid structure
+  if (!ownerSVGElement && Tag() != nsGkAtoms::svg) {
+    rv.Throw(NS_ERROR_FAILURE);
   }
-  // Otherwise, we've got an invalid structure
-  return NS_ERROR_FAILURE;
+
+  return ownerSVGElement;
 }
 
 /* readonly attribute nsIDOMSVGElement viewportElement; */
 NS_IMETHODIMP
 nsSVGElement::GetViewportElement(nsIDOMSVGElement * *aViewportElement)
 {
-  *aViewportElement = SVGContentUtils::GetNearestViewportElement(this).get();
+  nsCOMPtr<nsSVGElement> elem = GetViewportElement();
+  nsCOMPtr<nsIDOMSVGElement> svgElem = do_QueryInterface(elem);
+  svgElem.forget(aViewportElement);
   return NS_OK;
 }
 
+already_AddRefed<nsSVGElement>
+nsSVGElement::GetViewportElement()
+{
+  nsCOMPtr<nsIDOMSVGElement> elem =
+    SVGContentUtils::GetNearestViewportElement(this);
+  nsCOMPtr<nsSVGElement> svgElem = do_QueryInterface(elem);
+  return svgElem.forget();
+}
+
+already_AddRefed<nsIDOMSVGAnimatedString>
+nsSVGElement::ClassName()
+{
+  nsCOMPtr<nsIDOMSVGAnimatedString> className;
+  mClassAttribute.ToDOMAnimatedString(getter_AddRefs(className), this);
+  return className.forget();
+}
+
 //------------------------------------------------------------------------
 // Helper class: MappedAttrParser, for parsing values of mapped attributes
 
 namespace {
 
 class MappedAttrParser {
 public:
   MappedAttrParser(css::Loader* aLoader,
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -32,16 +32,20 @@ class nsSVGIntegerPair;
 class nsSVGLength2;
 class nsSVGNumber2;
 class nsSVGNumberPair;
 class nsSVGString;
 class nsSVGSVGElement;
 class nsSVGViewBox;
 
 namespace mozilla {
+namespace dom {
+class CSSValue;
+}
+
 class SVGAnimatedNumberList;
 class SVGNumberList;
 class SVGAnimatedLengthList;
 class SVGUserUnitList;
 class SVGAnimatedPointList;
 class SVGAnimatedPathSegList;
 class SVGAnimatedPreserveAspectRatio;
 class SVGAnimatedTransformList;
@@ -289,17 +293,25 @@ public:
   }
   virtual nsIAtom* GetPathDataAttrName() const {
     return nullptr;
   }
   virtual nsIAtom* GetTransformListAttrName() const {
     return nullptr;
   }
 
+  // WebIDL
+  nsSVGSVGElement* GetOwnerSVGElement(mozilla::ErrorResult& rv);
+  already_AddRefed<nsSVGElement> GetViewportElement();
+  already_AddRefed<nsIDOMSVGAnimatedString> ClassName();
+  nsICSSDeclaration* GetStyle(mozilla::ErrorResult& rv);
+  already_AddRefed<mozilla::dom::CSSValue> GetPresentationAttribute(const nsAString& aName, mozilla::ErrorResult& rv);
 protected:
+  virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap);
+
 #ifdef DEBUG
   // We define BeforeSetAttr here and mark it MOZ_FINAL to ensure it is NOT used
   // by SVG elements.
   // This is because we're not currently passing the correct value for aValue to
   // BeforeSetAttr since it would involve allocating extra SVG value types.
   // See the comment in nsSVGElement::WillChangeValue.
   virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                                  const nsAttrValueOrString* aValue,
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -458,16 +458,23 @@ DOMInterfaces = {
     'headerFile': 'SVGAnimatedPreserveAspectRatio.h'
 },
 
 'SVGAnimatedTransformList': {
     'nativeType': 'mozilla::DOMSVGAnimatedTransformList',
     'headerFile': 'DOMSVGAnimatedTransformList.h'
 },
 
+'SVGElement': {
+    'nativeType': 'nsSVGElement',
+    'hasXPConnectImpls': True,
+    'hasInstanceInterface': 'nsIDOMSVGElement',
+    'resultNotAddRefed': ['ownerSVGElement', 'style']
+},
+
 'SVGLengthList': {
     'nativeType': 'mozilla::DOMSVGLengthList',
     'headerFile': 'DOMSVGLengthList.h',
     'resultNotAddRefed': [ 'getItem' ]
 },
 
 'SVGMatrix': {
     'nativeType': 'mozilla::DOMSVGMatrix',
@@ -995,18 +1002,20 @@ addExternalIface('nsISupports', nativeTy
 addExternalIface('OutputStream', nativeType='nsIOutputStream',
                  notflattened=True)
 addExternalIface('Principal', nativeType='nsIPrincipal',
                  headerFile='nsIPrincipal.h', notflattened=True)
 addExternalIface('ProcessingInstruction', nativeType='nsXMLProcessingInstruction')
 addExternalIface('Range', nativeType='nsRange')
 addExternalIface("Rect")
 addExternalIface('StyleSheetList')
+addExternalIface('SVGAnimatedString')
 addExternalIface('SVGLength')
 addExternalIface('SVGNumber')
+addExternalIface('SVGSVGElement', nativeType='nsSVGSVGElement')
 addExternalIface('Text', nativeType='nsTextNode')
 addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('TreeWalker')
 addExternalIface('Touch', headerFile='nsIDOMTouchEvent.h')
 addExternalIface('TouchList', headerFile='nsIDOMTouchEvent.h')
 addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
                  notflattened=True)
 addExternalIface('UserDataHandler')
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGElement.webidl
@@ -0,0 +1,36 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * http://www.w3.org/TR/SVG2/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGSVGElement;
+interface SVGAnimatedString;
+
+interface SVGElement : Element {
+           attribute DOMString id;
+/*           [SetterThrows]
+           attribute DOMString xmlbase; */
+
+  readonly attribute SVGAnimatedString className;
+  [Throws]
+  readonly attribute CSSStyleDeclaration style;
+
+  [Throws] // because not implemented
+  CSSValue? getPresentationAttribute(DOMString name);
+
+  /*[SetterThrows]
+  attribute DOMString xmllang;
+  [SetterThrows]
+  attribute DOMString xmlspace;*/
+
+  [Throws]
+  readonly attribute SVGSVGElement? ownerSVGElement;
+  readonly attribute SVGElement? viewportElement;
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -71,16 +71,17 @@ webidl_files = \
   Screen.webidl \
   SVGAngle.webidl \
   SVGAnimatedAngle.webidl \
   SVGAnimatedBoolean.webidl \
   SVGAnimatedLengthList.webidl \
   SVGAnimatedNumberList.webidl \
   SVGAnimatedPreserveAspectRatio.webidl \
   SVGAnimatedTransformList.webidl \
+  SVGElement.webidl \
   SVGLengthList.webidl \
   SVGMatrix.webidl \
   SVGNumberList.webidl \
   SVGPathSeg.webidl \
   SVGPathSegList.webidl \
   SVGPoint.webidl \
   SVGPointList.webidl \
   SVGPreserveAspectRatio.webidl \
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -383,17 +383,18 @@ customIncludes = [
     'nsDOMQS.h',
     'nsDOMStringMap.h',
     'HTMLPropertiesCollection.h',
     'nsHTMLMenuElement.h',
     'nsICSSDeclaration.h',
     'mozilla/dom/NodeBinding.h',
     'mozilla/dom/ElementBinding.h',
     'mozilla/dom/HTMLElementBinding.h',
-    'mozilla/dom/DocumentBinding.h'
+    'mozilla/dom/DocumentBinding.h',
+    'mozilla/dom/SVGElementBinding.h'
     ]
 
 customReturnInterfaces = [
     'nsIDOMCanvasPattern',
     'nsIDOMCanvasGradient',
     ]
 
 nsIDOMHTMLDocument_Write_customMethodCallCode = """
@@ -492,10 +493,11 @@ customMethodCalls = {
         'unwrapThisFailureFatal' : False
         }
     }
 
 newBindingProperties = {
     'nsIDOMNode': 'mozilla::dom::NodeBinding::sNativePropertyHooks.mNativeProperties.regular',
     'nsIDOMElement': 'mozilla::dom::ElementBinding::sNativePropertyHooks.mNativeProperties.regular',
     'nsIDOMHTMLElement': 'mozilla::dom::HTMLElementBinding::sNativePropertyHooks.mNativeProperties.regular',
-    'nsIDOMDocument': 'mozilla::dom::DocumentBinding::sNativePropertyHooks.mNativeProperties.regular'
+    'nsIDOMDocument': 'mozilla::dom::DocumentBinding::sNativePropertyHooks.mNativeProperties.regular',
+    'nsIDOMSVGElement': 'mozilla::dom::SVGElementBinding::sNativePropertyHooks.mNativeProperties.regular'
     }
--- a/js/xpconnect/src/nsDOMQS.h
+++ b/js/xpconnect/src/nsDOMQS.h
@@ -16,16 +16,17 @@
 #include "nsHTMLDocument.h"
 #include "nsICSSDeclaration.h"
 #include "nsSVGElement.h"
 #include "mozilla/dom/EventTargetBinding.h"
 #include "mozilla/dom/NodeBinding.h"
 #include "mozilla/dom/ElementBinding.h"
 #include "mozilla/dom/HTMLElementBinding.h"
 #include "mozilla/dom/DocumentBinding.h"
+#include "mozilla/dom/SVGElementBinding.h"
 
 template<class T>
 struct ProtoIDAndDepth
 {
     enum {
         PrototypeID = mozilla::dom::prototypes::id::_ID_Count,
         Depth = -1
     };
@@ -43,16 +44,17 @@ struct ProtoIDAndDepth<_native>         
 }
 
 NEW_BINDING(mozilla::dom::EventTarget, EventTarget);
 NEW_BINDING(nsINode, Node);
 NEW_BINDING(mozilla::dom::Element, Element);
 NEW_BINDING(nsGenericHTMLElement, HTMLElement);
 NEW_BINDING(nsIDocument, Document);
 NEW_BINDING(nsDocument, Document);
+NEW_BINDING(nsSVGElement, SVGElement);
 
 #define DEFINE_UNWRAP_CAST(_interface, _base, _bit)                           \
 template <>                                                                   \
 MOZ_ALWAYS_INLINE JSBool                                                      \
 xpc_qsUnwrapThis<_interface>(JSContext *cx,                                   \
                              JSObject *obj,                                   \
                              _interface **ppThis,                             \
                              nsISupports **pThisRef,                          \