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/SVGScriptElement.h"
10 #include "nsNetUtil.h"
11 #include "nsContentUtils.h"
12 #include "mozilla/dom/SVGScriptElementBinding.h"
13 #include "nsIScriptError.h"
15 NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(Script
)
20 JSObject
* SVGScriptElement::WrapNode(JSContext
* aCx
,
21 JS::Handle
<JSObject
*> aGivenProto
) {
22 return SVGScriptElement_Binding::Wrap(aCx
, this, aGivenProto
);
25 SVGElement::StringInfo
SVGScriptElement::sStringInfo
[2] = {
26 {nsGkAtoms::href
, kNameSpaceID_None
, false},
27 {nsGkAtoms::href
, kNameSpaceID_XLink
, false}};
29 //----------------------------------------------------------------------
30 // nsISupports methods
32 NS_IMPL_ISUPPORTS_INHERITED(SVGScriptElement
, SVGScriptElementBase
,
33 nsIScriptLoaderObserver
, nsIScriptElement
,
36 //----------------------------------------------------------------------
39 SVGScriptElement::SVGScriptElement(
40 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
,
41 FromParser aFromParser
)
42 : SVGScriptElementBase(std::move(aNodeInfo
)), ScriptElement(aFromParser
) {
43 AddMutationObserver(this);
46 //----------------------------------------------------------------------
49 nsresult
SVGScriptElement::Clone(dom::NodeInfo
* aNodeInfo
,
50 nsINode
** aResult
) const {
53 SVGScriptElement
* it
= new (aNodeInfo
->NodeInfoManager())
54 SVGScriptElement(do_AddRef(aNodeInfo
), NOT_FROM_PARSER
);
56 nsCOMPtr
<nsINode
> kungFuDeathGrip
= it
;
57 nsresult rv1
= it
->Init();
58 nsresult rv2
= const_cast<SVGScriptElement
*>(this)->CopyInnerTo(it
);
59 NS_ENSURE_SUCCESS(rv1
, rv1
);
60 NS_ENSURE_SUCCESS(rv2
, rv2
);
62 // The clone should be marked evaluated if we are.
63 it
->mAlreadyStarted
= mAlreadyStarted
;
64 it
->mLineNumber
= mLineNumber
;
65 it
->mMalformed
= mMalformed
;
67 kungFuDeathGrip
.swap(*aResult
);
72 //----------------------------------------------------------------------
73 void SVGScriptElement::GetType(nsAString
& aType
) { GetScriptType(aType
); }
75 void SVGScriptElement::SetType(const nsAString
& aType
, ErrorResult
& rv
) {
76 rv
= SetAttr(kNameSpaceID_None
, nsGkAtoms::type
, aType
, true);
79 void SVGScriptElement::GetCrossOrigin(nsAString
& aCrossOrigin
) {
80 // Null for both missing and invalid defaults is ok, since we
81 // always parse to an enum value, so we don't need an invalid
82 // default, and we _want_ the missing default to be null.
83 GetEnumAttr(nsGkAtoms::crossorigin
, nullptr, aCrossOrigin
);
86 void SVGScriptElement::SetCrossOrigin(const nsAString
& aCrossOrigin
,
87 ErrorResult
& aError
) {
88 SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin
, aCrossOrigin
, aError
);
91 already_AddRefed
<DOMSVGAnimatedString
> SVGScriptElement::Href() {
92 return mStringAttributes
[HREF
].IsExplicitlySet()
93 ? mStringAttributes
[HREF
].ToDOMAnimatedString(this)
94 : mStringAttributes
[XLINK_HREF
].ToDOMAnimatedString(this);
97 //----------------------------------------------------------------------
98 // nsIScriptElement methods
100 bool SVGScriptElement::GetScriptType(nsAString
& type
) {
101 return GetAttr(kNameSpaceID_None
, nsGkAtoms::type
, type
);
104 void SVGScriptElement::GetScriptText(nsAString
& text
) {
105 nsContentUtils::GetNodeTextContent(this, false, text
);
108 void SVGScriptElement::GetScriptCharset(nsAString
& charset
) {
112 void SVGScriptElement::FreezeExecutionAttrs(Document
* aOwnerDoc
) {
117 if (mStringAttributes
[HREF
].IsExplicitlySet() ||
118 mStringAttributes
[XLINK_HREF
].IsExplicitlySet()) {
119 // variation of this code in nsHTMLScriptElement - check if changes
120 // need to be transferred when modifying
123 if (mStringAttributes
[HREF
].IsExplicitlySet()) {
124 mStringAttributes
[HREF
].GetAnimValue(src
, this);
127 mStringAttributes
[XLINK_HREF
].GetAnimValue(src
, this);
130 // Empty src should be treated as invalid URL.
131 if (!src
.IsEmpty()) {
132 NS_NewURI(getter_AddRefs(mUri
), src
, nullptr, GetBaseURI());
135 AutoTArray
<nsString
, 2> params
= {
136 isHref
? u
"href"_ns
: u
"xlink:href"_ns
, src
};
138 nsContentUtils::ReportToConsole(
139 nsIScriptError::warningFlag
, "SVG"_ns
, OwnerDoc(),
140 nsContentUtils::eDOM_PROPERTIES
, "ScriptSourceInvalidUri", params
,
141 nullptr, u
""_ns
, GetScriptLineNumber(), GetScriptColumnNumber());
144 AutoTArray
<nsString
, 1> params
= {isHref
? u
"href"_ns
: u
"xlink:href"_ns
};
146 nsContentUtils::ReportToConsole(
147 nsIScriptError::warningFlag
, "SVG"_ns
, OwnerDoc(),
148 nsContentUtils::eDOM_PROPERTIES
, "ScriptSourceEmpty", params
, nullptr,
149 u
""_ns
, GetScriptLineNumber(), GetScriptColumnNumber());
152 // At this point mUri will be null for invalid URLs.
159 //----------------------------------------------------------------------
160 // ScriptElement methods
162 bool SVGScriptElement::HasScriptContent() {
163 return (mFrozen
? mExternal
164 : mStringAttributes
[HREF
].IsExplicitlySet() ||
165 mStringAttributes
[XLINK_HREF
].IsExplicitlySet()) ||
166 nsContentUtils::HasNonEmptyTextContent(this);
169 //----------------------------------------------------------------------
170 // SVGElement methods
172 SVGElement::StringAttributesInfo
SVGScriptElement::GetStringInfo() {
173 return StringAttributesInfo(mStringAttributes
, sStringInfo
,
174 ArrayLength(sStringInfo
));
177 //----------------------------------------------------------------------
178 // nsIContent methods
180 nsresult
SVGScriptElement::BindToTree(BindContext
& aContext
, nsINode
& aParent
) {
181 nsresult rv
= SVGScriptElementBase::BindToTree(aContext
, aParent
);
182 NS_ENSURE_SUCCESS(rv
, rv
);
184 if (IsInComposedDoc()) {
185 MaybeProcessScript();
191 nsresult
SVGScriptElement::AfterSetAttr(int32_t aNamespaceID
, nsAtom
* aName
,
192 const nsAttrValue
* aValue
,
193 const nsAttrValue
* aOldValue
,
194 nsIPrincipal
* aSubjectPrincipal
,
196 if ((aNamespaceID
== kNameSpaceID_XLink
||
197 aNamespaceID
== kNameSpaceID_None
) &&
198 aName
== nsGkAtoms::href
) {
199 MaybeProcessScript();
201 return SVGScriptElementBase::AfterSetAttr(
202 aNamespaceID
, aName
, aValue
, aOldValue
, aSubjectPrincipal
, aNotify
);
205 bool SVGScriptElement::ParseAttribute(int32_t aNamespaceID
, nsAtom
* aAttribute
,
206 const nsAString
& aValue
,
207 nsIPrincipal
* aMaybeScriptedPrincipal
,
208 nsAttrValue
& aResult
) {
209 if (aNamespaceID
== kNameSpaceID_None
&&
210 aAttribute
== nsGkAtoms::crossorigin
) {
211 ParseCORSValue(aValue
, aResult
);
215 return SVGScriptElementBase::ParseAttribute(aNamespaceID
, aAttribute
, aValue
,
216 aMaybeScriptedPrincipal
, aResult
);
219 CORSMode
SVGScriptElement::GetCORSMode() const {
220 return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin
));
224 } // namespace mozilla