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"
9 #include "mozilla/dom/Document.h"
10 #include "mozilla/dom/FetchPriority.h"
11 #include "nsGkAtoms.h"
12 #include "nsNetUtil.h"
13 #include "nsContentUtils.h"
14 #include "mozilla/dom/SVGScriptElementBinding.h"
15 #include "nsIScriptError.h"
17 NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(Script
)
19 using JS::loader::ScriptKind
;
21 namespace mozilla::dom
{
23 JSObject
* SVGScriptElement::WrapNode(JSContext
* aCx
,
24 JS::Handle
<JSObject
*> aGivenProto
) {
25 return SVGScriptElement_Binding::Wrap(aCx
, this, aGivenProto
);
28 SVGElement::StringInfo
SVGScriptElement::sStringInfo
[2] = {
29 {nsGkAtoms::href
, kNameSpaceID_None
, false},
30 {nsGkAtoms::href
, kNameSpaceID_XLink
, false}};
32 //----------------------------------------------------------------------
33 // nsISupports methods
35 NS_IMPL_ISUPPORTS_INHERITED(SVGScriptElement
, SVGScriptElementBase
,
36 nsIScriptLoaderObserver
, nsIScriptElement
,
39 //----------------------------------------------------------------------
42 SVGScriptElement::SVGScriptElement(
43 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
,
44 FromParser aFromParser
)
45 : SVGScriptElementBase(std::move(aNodeInfo
)), ScriptElement(aFromParser
) {
46 AddMutationObserver(this);
49 //----------------------------------------------------------------------
52 nsresult
SVGScriptElement::Clone(dom::NodeInfo
* aNodeInfo
,
53 nsINode
** aResult
) const {
56 SVGScriptElement
* it
= new (aNodeInfo
->NodeInfoManager())
57 SVGScriptElement(do_AddRef(aNodeInfo
), NOT_FROM_PARSER
);
59 nsCOMPtr
<nsINode
> kungFuDeathGrip
= it
;
60 nsresult rv1
= it
->Init();
61 nsresult rv2
= const_cast<SVGScriptElement
*>(this)->CopyInnerTo(it
);
62 NS_ENSURE_SUCCESS(rv1
, rv1
);
63 NS_ENSURE_SUCCESS(rv2
, rv2
);
65 // The clone should be marked evaluated if we are.
66 it
->mAlreadyStarted
= mAlreadyStarted
;
67 it
->mLineNumber
= mLineNumber
;
68 it
->mMalformed
= mMalformed
;
70 kungFuDeathGrip
.swap(*aResult
);
75 //----------------------------------------------------------------------
76 void SVGScriptElement::GetType(nsAString
& aType
) {
77 GetAttr(nsGkAtoms::type
, aType
);
80 void SVGScriptElement::SetType(const nsAString
& aType
, ErrorResult
& rv
) {
81 rv
= SetAttr(kNameSpaceID_None
, nsGkAtoms::type
, aType
, true);
84 void SVGScriptElement::GetCrossOrigin(nsAString
& aCrossOrigin
) {
85 // Null for both missing and invalid defaults is ok, since we
86 // always parse to an enum value, so we don't need an invalid
87 // default, and we _want_ the missing default to be null.
88 GetEnumAttr(nsGkAtoms::crossorigin
, nullptr, aCrossOrigin
);
91 void SVGScriptElement::SetCrossOrigin(const nsAString
& aCrossOrigin
,
92 ErrorResult
& aError
) {
93 SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin
, aCrossOrigin
, aError
);
96 already_AddRefed
<DOMSVGAnimatedString
> SVGScriptElement::Href() {
97 return mStringAttributes
[HREF
].IsExplicitlySet()
98 ? mStringAttributes
[HREF
].ToDOMAnimatedString(this)
99 : mStringAttributes
[XLINK_HREF
].ToDOMAnimatedString(this);
102 //----------------------------------------------------------------------
103 // nsIScriptElement methods
105 void SVGScriptElement::GetScriptText(nsAString
& text
) const {
106 nsContentUtils::GetNodeTextContent(this, false, text
);
109 void SVGScriptElement::GetScriptCharset(nsAString
& charset
) {
113 void SVGScriptElement::FreezeExecutionAttrs(const Document
* aOwnerDoc
) {
118 // Determine whether this is a(n) classic/module/importmap script.
119 DetermineKindFromType(aOwnerDoc
);
121 if (mStringAttributes
[HREF
].IsExplicitlySet() ||
122 mStringAttributes
[XLINK_HREF
].IsExplicitlySet()) {
123 // variation of this code in nsHTMLScriptElement - check if changes
124 // need to be transferred when modifying
127 if (mStringAttributes
[HREF
].IsExplicitlySet()) {
128 mStringAttributes
[HREF
].GetAnimValue(src
, this);
131 mStringAttributes
[XLINK_HREF
].GetAnimValue(src
, this);
134 SourceLocation loc
{OwnerDoc()->GetDocumentURI(), GetScriptLineNumber(),
135 GetScriptColumnNumber().oneOriginValue()};
136 // Empty src should be treated as invalid URL.
137 if (!src
.IsEmpty()) {
138 NS_NewURI(getter_AddRefs(mUri
), src
, nullptr, GetBaseURI());
141 AutoTArray
<nsString
, 2> params
= {
142 isHref
? u
"href"_ns
: u
"xlink:href"_ns
, src
};
144 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag
, "SVG"_ns
,
146 nsContentUtils::eDOM_PROPERTIES
,
147 "ScriptSourceInvalidUri", params
, loc
);
150 AutoTArray
<nsString
, 1> params
= {isHref
? u
"href"_ns
: u
"xlink:href"_ns
};
152 nsContentUtils::ReportToConsole(
153 nsIScriptError::warningFlag
, "SVG"_ns
, OwnerDoc(),
154 nsContentUtils::eDOM_PROPERTIES
, "ScriptSourceEmpty", params
, loc
);
157 // At this point mUri will be null for invalid URLs.
161 bool async
= (mExternal
|| mKind
== ScriptKind::eModule
) && Async();
162 bool defer
= mExternal
&& Defer();
164 mDefer
= !async
&& defer
;
170 //----------------------------------------------------------------------
171 // ScriptElement methods
173 bool SVGScriptElement::HasScriptContent() {
174 return (mFrozen
? mExternal
175 : mStringAttributes
[HREF
].IsExplicitlySet() ||
176 mStringAttributes
[XLINK_HREF
].IsExplicitlySet()) ||
177 nsContentUtils::HasNonEmptyTextContent(this);
180 //----------------------------------------------------------------------
181 // SVGElement methods
183 SVGElement::StringAttributesInfo
SVGScriptElement::GetStringInfo() {
184 return StringAttributesInfo(mStringAttributes
, sStringInfo
,
185 std::size(sStringInfo
));
188 //----------------------------------------------------------------------
189 // nsIContent methods
191 nsresult
SVGScriptElement::BindToTree(BindContext
& aContext
, nsINode
& aParent
) {
192 nsresult rv
= SVGScriptElementBase::BindToTree(aContext
, aParent
);
193 NS_ENSURE_SUCCESS(rv
, rv
);
195 if (IsInComposedDoc()) {
196 MaybeProcessScript();
202 bool SVGScriptElement::ParseAttribute(int32_t aNamespaceID
, nsAtom
* aAttribute
,
203 const nsAString
& aValue
,
204 nsIPrincipal
* aMaybeScriptedPrincipal
,
205 nsAttrValue
& aResult
) {
206 if (aNamespaceID
== kNameSpaceID_None
&&
207 aAttribute
== nsGkAtoms::crossorigin
) {
208 ParseCORSValue(aValue
, aResult
);
212 return SVGScriptElementBase::ParseAttribute(aNamespaceID
, aAttribute
, aValue
,
213 aMaybeScriptedPrincipal
, aResult
);
216 CORSMode
SVGScriptElement::GetCORSMode() const {
217 return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin
));
220 FetchPriority
SVGScriptElement::GetFetchPriority() const {
221 // <https://github.com/w3c/svgwg/issues/916>.
222 return FetchPriority::Auto
;
225 } // namespace mozilla::dom