Merge mozilla-central to autoland on a CLOSED TREE
[gecko.git] / dom / svg / SVGScriptElement.cpp
blobfa19460e01c915fea9a4d785bf4817051922f6b7
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 "nsGkAtoms.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)
17 using JS::loader::ScriptKind;
19 namespace mozilla::dom {
21 JSObject* SVGScriptElement::WrapNode(JSContext* aCx,
22 JS::Handle<JSObject*> aGivenProto) {
23 return SVGScriptElement_Binding::Wrap(aCx, this, aGivenProto);
26 SVGElement::StringInfo SVGScriptElement::sStringInfo[2] = {
27 {nsGkAtoms::href, kNameSpaceID_None, false},
28 {nsGkAtoms::href, kNameSpaceID_XLink, false}};
30 //----------------------------------------------------------------------
31 // nsISupports methods
33 NS_IMPL_ISUPPORTS_INHERITED(SVGScriptElement, SVGScriptElementBase,
34 nsIScriptLoaderObserver, nsIScriptElement,
35 nsIMutationObserver)
37 //----------------------------------------------------------------------
38 // Implementation
40 SVGScriptElement::SVGScriptElement(
41 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
42 FromParser aFromParser)
43 : SVGScriptElementBase(std::move(aNodeInfo)), ScriptElement(aFromParser) {
44 AddMutationObserver(this);
47 //----------------------------------------------------------------------
48 // nsINode methods
50 nsresult SVGScriptElement::Clone(dom::NodeInfo* aNodeInfo,
51 nsINode** aResult) const {
52 *aResult = nullptr;
54 SVGScriptElement* it = new (aNodeInfo->NodeInfoManager())
55 SVGScriptElement(do_AddRef(aNodeInfo), NOT_FROM_PARSER);
57 nsCOMPtr<nsINode> kungFuDeathGrip = it;
58 nsresult rv1 = it->Init();
59 nsresult rv2 = const_cast<SVGScriptElement*>(this)->CopyInnerTo(it);
60 NS_ENSURE_SUCCESS(rv1, rv1);
61 NS_ENSURE_SUCCESS(rv2, rv2);
63 // The clone should be marked evaluated if we are.
64 it->mAlreadyStarted = mAlreadyStarted;
65 it->mLineNumber = mLineNumber;
66 it->mMalformed = mMalformed;
68 kungFuDeathGrip.swap(*aResult);
70 return NS_OK;
73 //----------------------------------------------------------------------
74 void SVGScriptElement::GetType(nsAString& aType) {
75 GetAttr(nsGkAtoms::type, aType);
78 void SVGScriptElement::SetType(const nsAString& aType, ErrorResult& rv) {
79 rv = SetAttr(kNameSpaceID_None, nsGkAtoms::type, aType, true);
82 void SVGScriptElement::GetCrossOrigin(nsAString& aCrossOrigin) {
83 // Null for both missing and invalid defaults is ok, since we
84 // always parse to an enum value, so we don't need an invalid
85 // default, and we _want_ the missing default to be null.
86 GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aCrossOrigin);
89 void SVGScriptElement::SetCrossOrigin(const nsAString& aCrossOrigin,
90 ErrorResult& aError) {
91 SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
94 already_AddRefed<DOMSVGAnimatedString> SVGScriptElement::Href() {
95 return mStringAttributes[HREF].IsExplicitlySet()
96 ? mStringAttributes[HREF].ToDOMAnimatedString(this)
97 : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
100 //----------------------------------------------------------------------
101 // nsIScriptElement methods
103 void SVGScriptElement::GetScriptText(nsAString& text) const {
104 nsContentUtils::GetNodeTextContent(this, false, text);
107 void SVGScriptElement::GetScriptCharset(nsAString& charset) {
108 charset.Truncate();
111 void SVGScriptElement::FreezeExecutionAttrs(const Document* aOwnerDoc) {
112 if (mFrozen) {
113 return;
116 // Determine whether this is a(n) classic/module/importmap script.
117 DetermineKindFromType(aOwnerDoc);
119 if (mStringAttributes[HREF].IsExplicitlySet() ||
120 mStringAttributes[XLINK_HREF].IsExplicitlySet()) {
121 // variation of this code in nsHTMLScriptElement - check if changes
122 // need to be transferred when modifying
123 bool isHref = false;
124 nsAutoString src;
125 if (mStringAttributes[HREF].IsExplicitlySet()) {
126 mStringAttributes[HREF].GetAnimValue(src, this);
127 isHref = true;
128 } else {
129 mStringAttributes[XLINK_HREF].GetAnimValue(src, this);
132 // Empty src should be treated as invalid URL.
133 if (!src.IsEmpty()) {
134 NS_NewURI(getter_AddRefs(mUri), src, nullptr, GetBaseURI());
136 if (!mUri) {
137 AutoTArray<nsString, 2> params = {
138 isHref ? u"href"_ns : u"xlink:href"_ns, src};
140 nsContentUtils::ReportToConsole(
141 nsIScriptError::warningFlag, "SVG"_ns, OwnerDoc(),
142 nsContentUtils::eDOM_PROPERTIES, "ScriptSourceInvalidUri", params,
143 nullptr, u""_ns, GetScriptLineNumber(), GetScriptColumnNumber());
145 } else {
146 AutoTArray<nsString, 1> params = {isHref ? u"href"_ns : u"xlink:href"_ns};
148 nsContentUtils::ReportToConsole(
149 nsIScriptError::warningFlag, "SVG"_ns, OwnerDoc(),
150 nsContentUtils::eDOM_PROPERTIES, "ScriptSourceEmpty", params, nullptr,
151 u""_ns, GetScriptLineNumber(), GetScriptColumnNumber());
154 // At this point mUri will be null for invalid URLs.
155 mExternal = true;
158 bool async = (mExternal || mKind == ScriptKind::eModule) && Async();
159 bool defer = mExternal && Defer();
161 mDefer = !async && defer;
162 mAsync = async;
164 mFrozen = true;
167 //----------------------------------------------------------------------
168 // ScriptElement methods
170 bool SVGScriptElement::HasScriptContent() {
171 return (mFrozen ? mExternal
172 : mStringAttributes[HREF].IsExplicitlySet() ||
173 mStringAttributes[XLINK_HREF].IsExplicitlySet()) ||
174 nsContentUtils::HasNonEmptyTextContent(this);
177 //----------------------------------------------------------------------
178 // SVGElement methods
180 SVGElement::StringAttributesInfo SVGScriptElement::GetStringInfo() {
181 return StringAttributesInfo(mStringAttributes, sStringInfo,
182 ArrayLength(sStringInfo));
185 //----------------------------------------------------------------------
186 // nsIContent methods
188 nsresult SVGScriptElement::BindToTree(BindContext& aContext, nsINode& aParent) {
189 nsresult rv = SVGScriptElementBase::BindToTree(aContext, aParent);
190 NS_ENSURE_SUCCESS(rv, rv);
192 if (IsInComposedDoc()) {
193 MaybeProcessScript();
196 return NS_OK;
199 bool SVGScriptElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
200 const nsAString& aValue,
201 nsIPrincipal* aMaybeScriptedPrincipal,
202 nsAttrValue& aResult) {
203 if (aNamespaceID == kNameSpaceID_None &&
204 aAttribute == nsGkAtoms::crossorigin) {
205 ParseCORSValue(aValue, aResult);
206 return true;
209 return SVGScriptElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
210 aMaybeScriptedPrincipal, aResult);
213 CORSMode SVGScriptElement::GetCORSMode() const {
214 return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
217 } // namespace mozilla::dom