From a4730bced7b70530498e7065deb486485948ecdb Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Sun, 23 Dec 2012 03:22:58 -0500 Subject: [PATCH] Bug 823394 Part 2: Add WebIDL API to SVGElement and enable binding r=bz --- content/svg/content/src/nsSVGElement.cpp | 80 +++++++++++++++++++----- content/svg/content/src/nsSVGElement.h | 12 ++++ dom/bindings/Bindings.conf | 9 +++ dom/webidl/SVGElement.webidl | 36 +++++++++++ dom/webidl/WebIDL.mk | 1 + js/xpconnect/src/dom_quickstubs.qsconf | 6 +- js/xpconnect/src/nsDOMQS.h | 2 + 7 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 dom/webidl/SVGElement.webidl diff --git a/content/svg/content/src/nsSVGElement.cpp b/content/svg/content/src/nsSVGElement.cpp index 8f7022b3ab1b..ef59a97e3850 100644 --- a/content/svg/content/src/nsSVGElement.cpp +++ b/content/svg/content/src/nsSVGElement.cpp @@ -59,6 +59,7 @@ #include "nsAttrValueOrString.h" #include "nsSMILAnimationController.h" #include "nsDOMCSSDeclaration.h" +#include "mozilla/dom/SVGElementBinding.h" using namespace mozilla; using namespace mozilla::dom; @@ -81,26 +82,42 @@ nsSVGElement::nsSVGElement(already_AddRefed 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); */ @@ -115,6 +132,13 @@ nsSVGElement::GetPresentationAttribute(const nsAString& aName, return NS_ERROR_NOT_IMPLEMENTED; } +already_AddRefed +nsSVGElement::GetPresentationAttribute(const nsAString& aName, ErrorResult& rv) +{ + rv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return nullptr; +} + //---------------------------------------------------------------------- // nsSVGElement methods @@ -1127,24 +1151,52 @@ NS_IMETHODIMP nsSVGElement::SetId(const nsAString & aId) NS_IMETHODIMP nsSVGElement::GetOwnerSVGElement(nsIDOMSVGSVGElement * *aOwnerSVGElement) { - NS_IF_ADDREF(*aOwnerSVGElement = GetCtx()); + ErrorResult rv; + NS_IF_ADDREF(*aOwnerSVGElement = GetOwnerSVGElement(rv)); + return rv.ErrorCode(); +} - if (*aOwnerSVGElement || Tag() == nsGkAtoms::svg) { - // If we found something or we're the outermost SVG element, that's OK. - return NS_OK; +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 elem = GetViewportElement(); + nsCOMPtr svgElem = do_QueryInterface(elem); + svgElem.forget(aViewportElement); return NS_OK; } +already_AddRefed +nsSVGElement::GetViewportElement() +{ + nsCOMPtr elem = + SVGContentUtils::GetNearestViewportElement(this); + nsCOMPtr svgElem = do_QueryInterface(elem); + return svgElem.forget(); +} + +already_AddRefed +nsSVGElement::ClassName() +{ + nsCOMPtr className; + mClassAttribute.ToDOMAnimatedString(getter_AddRefs(className), this); + return className.forget(); +} + //------------------------------------------------------------------------ // Helper class: MappedAttrParser, for parsing values of mapped attributes diff --git a/content/svg/content/src/nsSVGElement.h b/content/svg/content/src/nsSVGElement.h index f803b45c6ec4..b5d0cb49bcd0 100644 --- a/content/svg/content/src/nsSVGElement.h +++ b/content/svg/content/src/nsSVGElement.h @@ -37,6 +37,10 @@ class nsSVGSVGElement; class nsSVGViewBox; namespace mozilla { +namespace dom { +class CSSValue; +} + class SVGAnimatedNumberList; class SVGNumberList; class SVGAnimatedLengthList; @@ -294,7 +298,15 @@ public: return nullptr; } + // WebIDL + nsSVGSVGElement* GetOwnerSVGElement(mozilla::ErrorResult& rv); + already_AddRefed GetViewportElement(); + already_AddRefed ClassName(); + nsICSSDeclaration* GetStyle(mozilla::ErrorResult& rv); + already_AddRefed 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. diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index ede703328018..70a2078b665b 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -463,6 +463,13 @@ DOMInterfaces = { 'headerFile': 'DOMSVGAnimatedTransformList.h' }, +'SVGElement': { + 'nativeType': 'nsSVGElement', + 'hasXPConnectImpls': True, + 'hasInstanceInterface': 'nsIDOMSVGElement', + 'resultNotAddRefed': ['ownerSVGElement', 'style'] +}, + 'SVGLengthList': { 'nativeType': 'mozilla::DOMSVGLengthList', 'headerFile': 'DOMSVGLengthList.h', @@ -1000,8 +1007,10 @@ 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') diff --git a/dom/webidl/SVGElement.webidl b/dom/webidl/SVGElement.webidl new file mode 100644 index 000000000000..1a82719c4933 --- /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; +}; diff --git a/dom/webidl/WebIDL.mk b/dom/webidl/WebIDL.mk index 3da6c9bcded5..7102d3158bfd 100644 --- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -76,6 +76,7 @@ webidl_files = \ SVGAnimatedNumberList.webidl \ SVGAnimatedPreserveAspectRatio.webidl \ SVGAnimatedTransformList.webidl \ + SVGElement.webidl \ SVGLengthList.webidl \ SVGMatrix.webidl \ SVGNumberList.webidl \ diff --git a/js/xpconnect/src/dom_quickstubs.qsconf b/js/xpconnect/src/dom_quickstubs.qsconf index 824b54ab9c0a..c9cceb0acaea 100644 --- a/js/xpconnect/src/dom_quickstubs.qsconf +++ b/js/xpconnect/src/dom_quickstubs.qsconf @@ -388,7 +388,8 @@ customIncludes = [ '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 = [ @@ -497,5 +498,6 @@ 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' } diff --git a/js/xpconnect/src/nsDOMQS.h b/js/xpconnect/src/nsDOMQS.h index b9dfed41096b..fa0bab592fbe 100644 --- a/js/xpconnect/src/nsDOMQS.h +++ b/js/xpconnect/src/nsDOMQS.h @@ -21,6 +21,7 @@ #include "mozilla/dom/ElementBinding.h" #include "mozilla/dom/HTMLElementBinding.h" #include "mozilla/dom/DocumentBinding.h" +#include "mozilla/dom/SVGElementBinding.h" template struct ProtoIDAndDepth @@ -48,6 +49,7 @@ 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 <> \