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/. */
6
7 #include "mozilla/dom/SVGGradientElement.h"
8
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"
19
20 NS_IMPL_NS_NEW_SVG_ELEMENT(LinearGradient)
21 NS_IMPL_NS_NEW_SVG_ELEMENT(RadialGradient)
22
23 namespace mozilla {
24 namespace dom {
25
26 using namespace SVGGradientElement_Binding;
27 using namespace SVGUnitTypes_Binding;
28
29 //--------------------- Gradients------------------------
30
31 SVGEnumMapping SVGGradientElement::sSpreadMethodMap[] = {
32 {nsGkAtoms::pad, SVG_SPREADMETHOD_PAD},
33 {nsGkAtoms::reflect, SVG_SPREADMETHOD_REFLECT},
34 {nsGkAtoms::repeat, SVG_SPREADMETHOD_REPEAT},
35 {nullptr, 0}};
36
37 SVGElement::EnumInfo SVGGradientElement::sEnumInfo[2] = {
38 {nsGkAtoms::gradientUnits, sSVGUnitTypesMap,
39 SVG_UNIT_TYPE_OBJECTBOUNDINGBOX},
40 {nsGkAtoms::spreadMethod, sSpreadMethodMap, SVG_SPREADMETHOD_PAD}};
41
42 SVGElement::StringInfo SVGGradientElement::sStringInfo[2] = {
43 {nsGkAtoms::href, kNameSpaceID_None, true},
44 {nsGkAtoms::href, kNameSpaceID_XLink, true}};
45
46 //----------------------------------------------------------------------
47 // Implementation
48
SVGGradientElement(already_AddRefed<mozilla::dom::NodeInfo> && aNodeInfo)49 SVGGradientElement::SVGGradientElement(
50 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
51 : SVGGradientElementBase(std::move(aNodeInfo)) {}
52
53 //----------------------------------------------------------------------
54 // SVGElement methods
55
GetEnumInfo()56 SVGElement::EnumAttributesInfo SVGGradientElement::GetEnumInfo() {
57 return EnumAttributesInfo(mEnumAttributes, sEnumInfo, ArrayLength(sEnumInfo));
58 }
59
GetStringInfo()60 SVGElement::StringAttributesInfo SVGGradientElement::GetStringInfo() {
61 return StringAttributesInfo(mStringAttributes, sStringInfo,
62 ArrayLength(sStringInfo));
63 }
64
65 already_AddRefed<DOMSVGAnimatedEnumeration>
GradientUnits()66 SVGGradientElement::GradientUnits() {
67 return mEnumAttributes[GRADIENTUNITS].ToDOMAnimatedEnum(this);
68 }
69
70 already_AddRefed<DOMSVGAnimatedTransformList>
GradientTransform()71 SVGGradientElement::GradientTransform() {
72 // We're creating a DOM wrapper, so we must tell GetAnimatedTransformList
73 // to allocate the DOMSVGAnimatedTransformList if it hasn't already done so:
74 return DOMSVGAnimatedTransformList::GetDOMWrapper(
75 GetAnimatedTransformList(DO_ALLOCATE), this);
76 }
77
SpreadMethod()78 already_AddRefed<DOMSVGAnimatedEnumeration> SVGGradientElement::SpreadMethod() {
79 return mEnumAttributes[SPREADMETHOD].ToDOMAnimatedEnum(this);
80 }
81
Href()82 already_AddRefed<DOMSVGAnimatedString> SVGGradientElement::Href() {
83 return mStringAttributes[HREF].IsExplicitlySet()
84 ? mStringAttributes[HREF].ToDOMAnimatedString(this)
85 : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
86 }
87
88 //----------------------------------------------------------------------
89 // nsIContent methods
90
NS_IMETHODIMP_(bool)91 NS_IMETHODIMP_(bool)
92 SVGGradientElement::IsAttributeMapped(const nsAtom* name) const {
93 static const MappedAttributeEntry* const map[] = {sColorMap,
94 sGradientStopMap};
95
96 return FindAttributeDependence(name, map) ||
97 SVGGradientElementBase::IsAttributeMapped(name);
98 }
99
100 //---------------------Linear Gradients------------------------
101
WrapNode(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)102 JSObject* SVGLinearGradientElement::WrapNode(
103 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
104 return SVGLinearGradientElement_Binding::Wrap(aCx, this, aGivenProto);
105 }
106
107 SVGElement::LengthInfo SVGLinearGradientElement::sLengthInfo[4] = {
108 {nsGkAtoms::x1, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
109 SVGContentUtils::X},
110 {nsGkAtoms::y1, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
111 SVGContentUtils::Y},
112 {nsGkAtoms::x2, 100, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
113 SVGContentUtils::X},
114 {nsGkAtoms::y2, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
115 SVGContentUtils::Y},
116 };
117
118 //----------------------------------------------------------------------
119 // Implementation
120
SVGLinearGradientElement(already_AddRefed<mozilla::dom::NodeInfo> && aNodeInfo)121 SVGLinearGradientElement::SVGLinearGradientElement(
122 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
123 : SVGLinearGradientElementBase(std::move(aNodeInfo)) {}
124
125 //----------------------------------------------------------------------
126 // nsINode methods
127
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGLinearGradientElement)128 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGLinearGradientElement)
129
130 //----------------------------------------------------------------------
131
132 already_AddRefed<DOMSVGAnimatedLength> SVGLinearGradientElement::X1() {
133 return mLengthAttributes[ATTR_X1].ToDOMAnimatedLength(this);
134 }
135
Y1()136 already_AddRefed<DOMSVGAnimatedLength> SVGLinearGradientElement::Y1() {
137 return mLengthAttributes[ATTR_Y1].ToDOMAnimatedLength(this);
138 }
139
X2()140 already_AddRefed<DOMSVGAnimatedLength> SVGLinearGradientElement::X2() {
141 return mLengthAttributes[ATTR_X2].ToDOMAnimatedLength(this);
142 }
143
Y2()144 already_AddRefed<DOMSVGAnimatedLength> SVGLinearGradientElement::Y2() {
145 return mLengthAttributes[ATTR_Y2].ToDOMAnimatedLength(this);
146 }
147
148 //----------------------------------------------------------------------
149 // SVGElement methods
150
GetAnimatedTransformList(uint32_t aFlags)151 SVGAnimatedTransformList* SVGGradientElement::GetAnimatedTransformList(
152 uint32_t aFlags) {
153 if (!mGradientTransform && (aFlags & DO_ALLOCATE)) {
154 mGradientTransform = MakeUnique<SVGAnimatedTransformList>();
155 }
156 return mGradientTransform.get();
157 }
158
GetLengthInfo()159 SVGElement::LengthAttributesInfo SVGLinearGradientElement::GetLengthInfo() {
160 return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
161 ArrayLength(sLengthInfo));
162 }
163
164 //-------------------------- Radial Gradients ----------------------------
165
WrapNode(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)166 JSObject* SVGRadialGradientElement::WrapNode(
167 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
168 return SVGRadialGradientElement_Binding::Wrap(aCx, this, aGivenProto);
169 }
170
171 SVGElement::LengthInfo SVGRadialGradientElement::sLengthInfo[6] = {
172 {nsGkAtoms::cx, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
173 SVGContentUtils::X},
174 {nsGkAtoms::cy, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
175 SVGContentUtils::Y},
176 {nsGkAtoms::r, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
177 SVGContentUtils::XY},
178 {nsGkAtoms::fx, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
179 SVGContentUtils::X},
180 {nsGkAtoms::fy, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
181 SVGContentUtils::Y},
182 {nsGkAtoms::fr, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE,
183 SVGContentUtils::XY},
184 };
185
186 //----------------------------------------------------------------------
187 // Implementation
188
SVGRadialGradientElement(already_AddRefed<mozilla::dom::NodeInfo> && aNodeInfo)189 SVGRadialGradientElement::SVGRadialGradientElement(
190 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
191 : SVGRadialGradientElementBase(std::move(aNodeInfo)) {}
192
193 //----------------------------------------------------------------------
194 // nsINode methods
195
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGRadialGradientElement)196 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGRadialGradientElement)
197
198 //----------------------------------------------------------------------
199
200 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Cx() {
201 return mLengthAttributes[ATTR_CX].ToDOMAnimatedLength(this);
202 }
203
Cy()204 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Cy() {
205 return mLengthAttributes[ATTR_CY].ToDOMAnimatedLength(this);
206 }
207
R()208 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::R() {
209 return mLengthAttributes[ATTR_R].ToDOMAnimatedLength(this);
210 }
211
Fx()212 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Fx() {
213 return mLengthAttributes[ATTR_FX].ToDOMAnimatedLength(this);
214 }
215
Fy()216 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Fy() {
217 return mLengthAttributes[ATTR_FY].ToDOMAnimatedLength(this);
218 }
219
Fr()220 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Fr() {
221 return mLengthAttributes[ATTR_FR].ToDOMAnimatedLength(this);
222 }
223
224 //----------------------------------------------------------------------
225 // SVGElement methods
226
GetLengthInfo()227 SVGElement::LengthAttributesInfo SVGRadialGradientElement::GetLengthInfo() {
228 return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
229 ArrayLength(sLengthInfo));
230 }
231
232 } // namespace dom
233 } // namespace mozilla
234