Line data Source code
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 "nsGkAtoms.h"
8 : #include "nsNetUtil.h"
9 : #include "nsContentUtils.h"
10 : #include "mozilla/dom/SVGScriptElement.h"
11 : #include "mozilla/dom/SVGScriptElementBinding.h"
12 : #include "nsIScriptError.h"
13 :
14 0 : NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT_CHECK_PARSER(Script)
15 :
16 : namespace mozilla {
17 : namespace dom {
18 :
19 : JSObject*
20 0 : SVGScriptElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
21 : {
22 0 : return SVGScriptElementBinding::Wrap(aCx, this, aGivenProto);
23 : }
24 :
25 : nsSVGElement::StringInfo SVGScriptElement::sStringInfo[2] =
26 : {
27 : { &nsGkAtoms::href, kNameSpaceID_None, false },
28 : { &nsGkAtoms::href, kNameSpaceID_XLink, false }
29 : };
30 :
31 : //----------------------------------------------------------------------
32 : // nsISupports methods
33 :
34 0 : NS_IMPL_ISUPPORTS_INHERITED(SVGScriptElement, SVGScriptElementBase,
35 : nsIDOMNode, nsIDOMElement,
36 : nsIDOMSVGElement,
37 : nsIScriptLoaderObserver,
38 : nsIScriptElement, nsIMutationObserver)
39 :
40 : //----------------------------------------------------------------------
41 : // Implementation
42 :
43 0 : SVGScriptElement::SVGScriptElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
44 0 : FromParser aFromParser)
45 : : SVGScriptElementBase(aNodeInfo)
46 0 : , ScriptElement(aFromParser)
47 : {
48 0 : AddMutationObserver(this);
49 0 : }
50 :
51 0 : SVGScriptElement::~SVGScriptElement()
52 : {
53 0 : }
54 :
55 : //----------------------------------------------------------------------
56 : // nsIDOMNode methods
57 :
58 : nsresult
59 0 : SVGScriptElement::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
60 : bool aPreallocateChildren) const
61 : {
62 0 : *aResult = nullptr;
63 :
64 0 : already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
65 0 : SVGScriptElement* it = new SVGScriptElement(ni, NOT_FROM_PARSER);
66 :
67 0 : nsCOMPtr<nsINode> kungFuDeathGrip = it;
68 0 : nsresult rv1 = it->Init();
69 0 : nsresult rv2 = const_cast<SVGScriptElement*>(this)->CopyInnerTo(it, aPreallocateChildren);
70 0 : NS_ENSURE_SUCCESS(rv1, rv1);
71 0 : NS_ENSURE_SUCCESS(rv2, rv2);
72 :
73 : // The clone should be marked evaluated if we are.
74 0 : it->mAlreadyStarted = mAlreadyStarted;
75 0 : it->mLineNumber = mLineNumber;
76 0 : it->mMalformed = mMalformed;
77 :
78 0 : kungFuDeathGrip.swap(*aResult);
79 :
80 0 : return NS_OK;
81 : }
82 :
83 : //----------------------------------------------------------------------
84 : void
85 0 : SVGScriptElement::GetType(nsAString & aType)
86 : {
87 0 : GetScriptType(aType);
88 0 : }
89 :
90 : void
91 0 : SVGScriptElement::SetType(const nsAString & aType, ErrorResult& rv)
92 : {
93 0 : rv = SetAttr(kNameSpaceID_None, nsGkAtoms::type, aType, true);
94 0 : }
95 :
96 : void
97 0 : SVGScriptElement::GetCrossOrigin(nsAString & aCrossOrigin)
98 : {
99 : // Null for both missing and invalid defaults is ok, since we
100 : // always parse to an enum value, so we don't need an invalid
101 : // default, and we _want_ the missing default to be null.
102 0 : GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aCrossOrigin);
103 0 : }
104 :
105 : void
106 0 : SVGScriptElement::SetCrossOrigin(const nsAString & aCrossOrigin,
107 : ErrorResult& aError)
108 : {
109 0 : SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
110 0 : }
111 :
112 : already_AddRefed<SVGAnimatedString>
113 0 : SVGScriptElement::Href()
114 : {
115 0 : return mStringAttributes[HREF].IsExplicitlySet()
116 : ? mStringAttributes[HREF].ToDOMAnimatedString(this)
117 0 : : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
118 : }
119 :
120 : //----------------------------------------------------------------------
121 : // nsIScriptElement methods
122 :
123 : bool
124 0 : SVGScriptElement::GetScriptType(nsAString& type)
125 : {
126 0 : return GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
127 : }
128 :
129 : void
130 0 : SVGScriptElement::GetScriptText(nsAString& text)
131 : {
132 0 : nsContentUtils::GetNodeTextContent(this, false, text);
133 0 : }
134 :
135 : void
136 0 : SVGScriptElement::GetScriptCharset(nsAString& charset)
137 : {
138 0 : charset.Truncate();
139 0 : }
140 :
141 : void
142 0 : SVGScriptElement::FreezeUriAsyncDefer()
143 : {
144 0 : if (mFrozen) {
145 0 : return;
146 : }
147 :
148 0 : if (mStringAttributes[HREF].IsExplicitlySet() ||
149 0 : mStringAttributes[XLINK_HREF].IsExplicitlySet()) {
150 : // variation of this code in nsHTMLScriptElement - check if changes
151 : // need to be transfered when modifying
152 0 : bool isHref = false;
153 0 : nsAutoString src;
154 0 : if (mStringAttributes[HREF].IsExplicitlySet()) {
155 0 : mStringAttributes[HREF].GetAnimValue(src, this);
156 0 : isHref = true;
157 : } else {
158 0 : mStringAttributes[XLINK_HREF].GetAnimValue(src, this);
159 : }
160 :
161 : // Empty src should be treated as invalid URL.
162 0 : if (!src.IsEmpty()) {
163 0 : nsCOMPtr<nsIURI> baseURI = GetBaseURI();
164 0 : NS_NewURI(getter_AddRefs(mUri), src, nullptr, baseURI);
165 :
166 0 : if (!mUri) {
167 0 : const char16_t* params[] = { isHref ? u"href" : u"xlink:href", src.get() };
168 :
169 0 : nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
170 0 : NS_LITERAL_CSTRING("SVG"), OwnerDoc(),
171 : nsContentUtils::eDOM_PROPERTIES, "ScriptSourceInvalidUri",
172 0 : params, ArrayLength(params), nullptr,
173 0 : EmptyString(), GetScriptLineNumber());
174 : }
175 : } else {
176 0 : const char16_t* params[] = { isHref ? u"href" : u"xlink:href" };
177 :
178 0 : nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
179 0 : NS_LITERAL_CSTRING("SVG"), OwnerDoc(),
180 : nsContentUtils::eDOM_PROPERTIES, "ScriptSourceEmpty",
181 0 : params, ArrayLength(params), nullptr,
182 0 : EmptyString(), GetScriptLineNumber());
183 : }
184 :
185 : // At this point mUri will be null for invalid URLs.
186 0 : mExternal = true;
187 : }
188 :
189 0 : mFrozen = true;
190 : }
191 :
192 : //----------------------------------------------------------------------
193 : // ScriptElement methods
194 :
195 : bool
196 0 : SVGScriptElement::HasScriptContent()
197 : {
198 0 : return (mFrozen ? mExternal
199 0 : : mStringAttributes[HREF].IsExplicitlySet() ||
200 0 : mStringAttributes[XLINK_HREF].IsExplicitlySet()) ||
201 0 : nsContentUtils::HasNonEmptyTextContent(this);
202 : }
203 :
204 : //----------------------------------------------------------------------
205 : // nsSVGElement methods
206 :
207 : nsSVGElement::StringAttributesInfo
208 0 : SVGScriptElement::GetStringInfo()
209 : {
210 : return StringAttributesInfo(mStringAttributes, sStringInfo,
211 0 : ArrayLength(sStringInfo));
212 : }
213 :
214 : //----------------------------------------------------------------------
215 : // nsIContent methods
216 :
217 : nsresult
218 0 : SVGScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
219 : nsIContent* aBindingParent,
220 : bool aCompileEventHandlers)
221 : {
222 0 : nsresult rv = SVGScriptElementBase::BindToTree(aDocument, aParent,
223 : aBindingParent,
224 0 : aCompileEventHandlers);
225 0 : NS_ENSURE_SUCCESS(rv, rv);
226 :
227 0 : if (aDocument) {
228 0 : MaybeProcessScript();
229 : }
230 :
231 0 : return NS_OK;
232 : }
233 :
234 : nsresult
235 0 : SVGScriptElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
236 : const nsAttrValue* aValue,
237 : const nsAttrValue* aOldValue, bool aNotify)
238 : {
239 0 : if ((aNamespaceID == kNameSpaceID_XLink ||
240 0 : aNamespaceID == kNameSpaceID_None) &&
241 0 : aName == nsGkAtoms::href) {
242 0 : MaybeProcessScript();
243 : }
244 0 : return SVGScriptElementBase::AfterSetAttr(aNamespaceID, aName,
245 0 : aValue, aOldValue, aNotify);
246 : }
247 :
248 : bool
249 0 : SVGScriptElement::ParseAttribute(int32_t aNamespaceID,
250 : nsIAtom* aAttribute,
251 : const nsAString& aValue,
252 : nsAttrValue& aResult)
253 : {
254 0 : if (aNamespaceID == kNameSpaceID_None &&
255 0 : aAttribute == nsGkAtoms::crossorigin) {
256 0 : ParseCORSValue(aValue, aResult);
257 0 : return true;
258 : }
259 :
260 0 : return SVGScriptElementBase::ParseAttribute(aNamespaceID, aAttribute,
261 0 : aValue, aResult);
262 : }
263 :
264 : CORSMode
265 0 : SVGScriptElement::GetCORSMode() const
266 : {
267 0 : return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
268 : }
269 :
270 : } // namespace dom
271 : } // namespace mozilla
|