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/SVGTextPathElement.h"
8 #include "mozilla/dom/SVGLengthBinding.h"
9 #include "mozilla/dom/SVGTextContentElementBinding.h"
10 #include "mozilla/dom/SVGTextPathElementBinding.h"
11 #include "SVGElement.h"
12 #include "nsGkAtoms.h"
13 #include "nsError.h"
14 
15 NS_IMPL_NS_NEW_SVG_ELEMENT(TextPath)
16 
17 namespace mozilla {
18 namespace dom {
19 
20 using namespace SVGTextContentElement_Binding;
21 using namespace SVGTextPathElement_Binding;
22 
23 class DOMSVGAnimatedLength;
24 
WrapNode(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)25 JSObject* SVGTextPathElement::WrapNode(JSContext* aCx,
26                                        JS::Handle<JSObject*> aGivenProto) {
27   return SVGTextPathElement_Binding::Wrap(aCx, this, aGivenProto);
28 }
29 
30 SVGElement::LengthInfo SVGTextPathElement::sLengthInfo[2] = {
31     // from SVGTextContentElement:
32     {nsGkAtoms::textLength, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
33      SVGContentUtils::XY},
34     // from SVGTextPathElement:
35     {nsGkAtoms::startOffset, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
36      SVGContentUtils::X}};
37 
38 SVGEnumMapping SVGTextPathElement::sMethodMap[] = {
39     {nsGkAtoms::align, TEXTPATH_METHODTYPE_ALIGN},
40     {nsGkAtoms::stretch, TEXTPATH_METHODTYPE_STRETCH},
41     {nullptr, 0}};
42 
43 SVGEnumMapping SVGTextPathElement::sSpacingMap[] = {
44     {nsGkAtoms::_auto, TEXTPATH_SPACINGTYPE_AUTO},
45     {nsGkAtoms::exact, TEXTPATH_SPACINGTYPE_EXACT},
46     {nullptr, 0}};
47 
48 SVGEnumMapping SVGTextPathElement::sSideMap[] = {
49     {nsGkAtoms::left, TEXTPATH_SIDETYPE_LEFT},
50     {nsGkAtoms::right, TEXTPATH_SIDETYPE_RIGHT},
51     {nullptr, 0}};
52 
53 SVGElement::EnumInfo SVGTextPathElement::sEnumInfo[4] = {
54     // from SVGTextContentElement:
55     {nsGkAtoms::lengthAdjust, sLengthAdjustMap, LENGTHADJUST_SPACING},
56     // from SVGTextPathElement:
57     {nsGkAtoms::method, sMethodMap, TEXTPATH_METHODTYPE_ALIGN},
58     {nsGkAtoms::spacing, sSpacingMap, TEXTPATH_SPACINGTYPE_EXACT},
59     {nsGkAtoms::side_, sSideMap, TEXTPATH_SIDETYPE_LEFT}};
60 
61 SVGElement::StringInfo SVGTextPathElement::sStringInfo[2] = {
62     {nsGkAtoms::href, kNameSpaceID_None, true},
63     {nsGkAtoms::href, kNameSpaceID_XLink, true}};
64 
65 //----------------------------------------------------------------------
66 // Implementation
67 
SVGTextPathElement(already_AddRefed<mozilla::dom::NodeInfo> && aNodeInfo)68 SVGTextPathElement::SVGTextPathElement(
69     already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
70     : SVGTextPathElementBase(std::move(aNodeInfo)) {}
71 
HrefAsString(nsAString & aHref)72 void SVGTextPathElement::HrefAsString(nsAString& aHref) {
73   if (mStringAttributes[SVGTextPathElement::HREF].IsExplicitlySet()) {
74     mStringAttributes[SVGTextPathElement::HREF].GetAnimValue(aHref, this);
75   } else {
76     mStringAttributes[SVGTextPathElement::XLINK_HREF].GetAnimValue(aHref, this);
77   }
78 }
79 
80 //----------------------------------------------------------------------
81 // nsINode methods
82 
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGTextPathElement)83 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGTextPathElement)
84 
85 already_AddRefed<DOMSVGAnimatedString> SVGTextPathElement::Href() {
86   return mStringAttributes[HREF].IsExplicitlySet()
87              ? mStringAttributes[HREF].ToDOMAnimatedString(this)
88              : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
89 }
90 
91 //----------------------------------------------------------------------
92 
StartOffset()93 already_AddRefed<DOMSVGAnimatedLength> SVGTextPathElement::StartOffset() {
94   return mLengthAttributes[STARTOFFSET].ToDOMAnimatedLength(this);
95 }
96 
Method()97 already_AddRefed<DOMSVGAnimatedEnumeration> SVGTextPathElement::Method() {
98   return mEnumAttributes[METHOD].ToDOMAnimatedEnum(this);
99 }
100 
Spacing()101 already_AddRefed<DOMSVGAnimatedEnumeration> SVGTextPathElement::Spacing() {
102   return mEnumAttributes[SPACING].ToDOMAnimatedEnum(this);
103 }
104 
Side()105 already_AddRefed<DOMSVGAnimatedEnumeration> SVGTextPathElement::Side() {
106   return mEnumAttributes[SIDE].ToDOMAnimatedEnum(this);
107 }
108 
109 //----------------------------------------------------------------------
110 // nsIContent methods
111 
NS_IMETHODIMP_(bool)112 NS_IMETHODIMP_(bool)
113 SVGTextPathElement::IsAttributeMapped(const nsAtom* name) const {
114   static const MappedAttributeEntry* const map[] = {
115       sColorMap, sFillStrokeMap, sFontSpecificationMap, sGraphicsMap,
116       sTextContentElementsMap};
117 
118   return FindAttributeDependence(name, map) ||
119          SVGTextPathElementBase::IsAttributeMapped(name);
120 }
121 
122 //----------------------------------------------------------------------
123 // SVGElement overrides
124 
GetLengthInfo()125 SVGElement::LengthAttributesInfo SVGTextPathElement::GetLengthInfo() {
126   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
127                               ArrayLength(sLengthInfo));
128 }
129 
GetEnumInfo()130 SVGElement::EnumAttributesInfo SVGTextPathElement::GetEnumInfo() {
131   return EnumAttributesInfo(mEnumAttributes, sEnumInfo, ArrayLength(sEnumInfo));
132 }
133 
GetStringInfo()134 SVGElement::StringAttributesInfo SVGTextPathElement::GetStringInfo() {
135   return StringAttributesInfo(mStringAttributes, sStringInfo,
136                               ArrayLength(sStringInfo));
137 }
138 
139 }  // namespace dom
140 }  // namespace mozilla
141