1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/SVGGradientElement.h"
9 #include "mozilla/AlreadyAddRefed.h"
10 #include "mozilla/ArrayUtils.h"
11 #include "mozilla/dom/SVGElement.h"
12 #include "mozilla/dom/SVGGradientElementBinding.h"
13 #include "mozilla/dom/SVGLengthBinding.h"
14 #include "mozilla/dom/SVGLinearGradientElementBinding.h"
15 #include "mozilla/dom/SVGRadialGradientElementBinding.h"
16 #include "mozilla/dom/SVGUnitTypesBinding.h"
17 #include "DOMSVGAnimatedTransformList.h"
18 #include "nsGkAtoms.h"
20 NS_IMPL_NS_NEW_SVG_ELEMENT(LinearGradient
)
21 NS_IMPL_NS_NEW_SVG_ELEMENT(RadialGradient
)
23 namespace mozilla::dom
{
25 using namespace SVGGradientElement_Binding
;
26 using namespace SVGUnitTypes_Binding
;
28 //--------------------- Gradients------------------------
30 SVGEnumMapping
SVGGradientElement::sSpreadMethodMap
[] = {
31 {nsGkAtoms::pad
, SVG_SPREADMETHOD_PAD
},
32 {nsGkAtoms::reflect
, SVG_SPREADMETHOD_REFLECT
},
33 {nsGkAtoms::repeat
, SVG_SPREADMETHOD_REPEAT
},
36 SVGElement::EnumInfo
SVGGradientElement::sEnumInfo
[2] = {
37 {nsGkAtoms::gradientUnits
, sSVGUnitTypesMap
,
38 SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
},
39 {nsGkAtoms::spreadMethod
, sSpreadMethodMap
, SVG_SPREADMETHOD_PAD
}};
41 SVGElement::StringInfo
SVGGradientElement::sStringInfo
[2] = {
42 {nsGkAtoms::href
, kNameSpaceID_None
, true},
43 {nsGkAtoms::href
, kNameSpaceID_XLink
, true}};
45 //----------------------------------------------------------------------
48 SVGGradientElement::SVGGradientElement(
49 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
)
50 : SVGGradientElementBase(std::move(aNodeInfo
)) {}
52 //----------------------------------------------------------------------
55 SVGElement::EnumAttributesInfo
SVGGradientElement::GetEnumInfo() {
56 return EnumAttributesInfo(mEnumAttributes
, sEnumInfo
, std::size(sEnumInfo
));
59 SVGElement::StringAttributesInfo
SVGGradientElement::GetStringInfo() {
60 return StringAttributesInfo(mStringAttributes
, sStringInfo
,
61 std::size(sStringInfo
));
64 already_AddRefed
<DOMSVGAnimatedEnumeration
>
65 SVGGradientElement::GradientUnits() {
66 return mEnumAttributes
[GRADIENTUNITS
].ToDOMAnimatedEnum(this);
69 already_AddRefed
<DOMSVGAnimatedTransformList
>
70 SVGGradientElement::GradientTransform() {
71 // We're creating a DOM wrapper, so we must tell GetAnimatedTransformList
72 // to allocate the DOMSVGAnimatedTransformList if it hasn't already done so:
73 return DOMSVGAnimatedTransformList::GetDOMWrapper(
74 GetAnimatedTransformList(DO_ALLOCATE
), this);
77 already_AddRefed
<DOMSVGAnimatedEnumeration
> SVGGradientElement::SpreadMethod() {
78 return mEnumAttributes
[SPREADMETHOD
].ToDOMAnimatedEnum(this);
81 already_AddRefed
<DOMSVGAnimatedString
> SVGGradientElement::Href() {
82 return mStringAttributes
[HREF
].IsExplicitlySet()
83 ? mStringAttributes
[HREF
].ToDOMAnimatedString(this)
84 : mStringAttributes
[XLINK_HREF
].ToDOMAnimatedString(this);
87 //---------------------Linear Gradients------------------------
89 JSObject
* SVGLinearGradientElement::WrapNode(
90 JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) {
91 return SVGLinearGradientElement_Binding::Wrap(aCx
, this, aGivenProto
);
94 SVGElement::LengthInfo
SVGLinearGradientElement::sLengthInfo
[4] = {
95 {nsGkAtoms::x1
, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
97 {nsGkAtoms::y1
, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
99 {nsGkAtoms::x2
, 100, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
101 {nsGkAtoms::y2
, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
105 //----------------------------------------------------------------------
108 SVGLinearGradientElement::SVGLinearGradientElement(
109 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
)
110 : SVGLinearGradientElementBase(std::move(aNodeInfo
)) {}
112 //----------------------------------------------------------------------
115 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGLinearGradientElement
)
117 //----------------------------------------------------------------------
119 already_AddRefed
<DOMSVGAnimatedLength
> SVGLinearGradientElement::X1() {
120 return mLengthAttributes
[ATTR_X1
].ToDOMAnimatedLength(this);
123 already_AddRefed
<DOMSVGAnimatedLength
> SVGLinearGradientElement::Y1() {
124 return mLengthAttributes
[ATTR_Y1
].ToDOMAnimatedLength(this);
127 already_AddRefed
<DOMSVGAnimatedLength
> SVGLinearGradientElement::X2() {
128 return mLengthAttributes
[ATTR_X2
].ToDOMAnimatedLength(this);
131 already_AddRefed
<DOMSVGAnimatedLength
> SVGLinearGradientElement::Y2() {
132 return mLengthAttributes
[ATTR_Y2
].ToDOMAnimatedLength(this);
135 //----------------------------------------------------------------------
136 // SVGElement methods
138 SVGAnimatedTransformList
* SVGGradientElement::GetAnimatedTransformList(
140 if (!mGradientTransform
&& (aFlags
& DO_ALLOCATE
)) {
141 mGradientTransform
= MakeUnique
<SVGAnimatedTransformList
>();
143 return mGradientTransform
.get();
146 SVGElement::LengthAttributesInfo
SVGLinearGradientElement::GetLengthInfo() {
147 return LengthAttributesInfo(mLengthAttributes
, sLengthInfo
,
148 std::size(sLengthInfo
));
151 //-------------------------- Radial Gradients ----------------------------
153 JSObject
* SVGRadialGradientElement::WrapNode(
154 JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) {
155 return SVGRadialGradientElement_Binding::Wrap(aCx
, this, aGivenProto
);
158 SVGElement::LengthInfo
SVGRadialGradientElement::sLengthInfo
[6] = {
159 {nsGkAtoms::cx
, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
161 {nsGkAtoms::cy
, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
163 {nsGkAtoms::r
, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
164 SVGContentUtils::XY
},
165 {nsGkAtoms::fx
, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
167 {nsGkAtoms::fy
, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
169 {nsGkAtoms::fr
, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE
,
170 SVGContentUtils::XY
},
173 //----------------------------------------------------------------------
176 SVGRadialGradientElement::SVGRadialGradientElement(
177 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
)
178 : SVGRadialGradientElementBase(std::move(aNodeInfo
)) {}
180 //----------------------------------------------------------------------
183 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGRadialGradientElement
)
185 //----------------------------------------------------------------------
187 already_AddRefed
<DOMSVGAnimatedLength
> SVGRadialGradientElement::Cx() {
188 return mLengthAttributes
[ATTR_CX
].ToDOMAnimatedLength(this);
191 already_AddRefed
<DOMSVGAnimatedLength
> SVGRadialGradientElement::Cy() {
192 return mLengthAttributes
[ATTR_CY
].ToDOMAnimatedLength(this);
195 already_AddRefed
<DOMSVGAnimatedLength
> SVGRadialGradientElement::R() {
196 return mLengthAttributes
[ATTR_R
].ToDOMAnimatedLength(this);
199 already_AddRefed
<DOMSVGAnimatedLength
> SVGRadialGradientElement::Fx() {
200 return mLengthAttributes
[ATTR_FX
].ToDOMAnimatedLength(this);
203 already_AddRefed
<DOMSVGAnimatedLength
> SVGRadialGradientElement::Fy() {
204 return mLengthAttributes
[ATTR_FY
].ToDOMAnimatedLength(this);
207 already_AddRefed
<DOMSVGAnimatedLength
> SVGRadialGradientElement::Fr() {
208 return mLengthAttributes
[ATTR_FR
].ToDOMAnimatedLength(this);
211 bool SVGGradientElement::IsAttributeMapped(const nsAtom
* aAttribute
) const {
212 return aAttribute
== nsGkAtoms::gradientTransform
||
213 SVGElement::IsAttributeMapped(aAttribute
);
216 //----------------------------------------------------------------------
217 // SVGElement methods
219 SVGElement::LengthAttributesInfo
SVGRadialGradientElement::GetLengthInfo() {
220 return LengthAttributesInfo(mLengthAttributes
, sLengthInfo
,
221 std::size(sLengthInfo
));
224 } // namespace mozilla::dom