Bug 1936278 - Prevent search mode chiclet from being dismissed when clicking in page...
[gecko.git] / dom / svg / SVGScriptElement.cpp
blob04a4723d579c4bba679f0913499fa2e110d209ec
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,
37 nsIMutationObserver)
39 //----------------------------------------------------------------------
40 // Implementation
42 SVGScriptElement::SVGScriptElement(
43 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
44 FromParser aFromParser)
45 : SVGScriptElementBase(std::move(aNodeInfo)), ScriptElement(aFromParser) {
46 AddMutationObserver(this);
49 //----------------------------------------------------------------------
50 // nsINode methods
52 nsresult SVGScriptElement::Clone(dom::NodeInfo* aNodeInfo,
53 nsINode** aResult) const {
54 *aResult = nullptr;
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);
72 return NS_OK;
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) {
110 charset.Truncate();
113 void SVGScriptElement::FreezeExecutionAttrs(const Document* aOwnerDoc) {
114 if (mFrozen) {
115 return;
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
125 bool isHref = false;
126 nsAutoString src;
127 if (mStringAttributes[HREF].IsExplicitlySet()) {
128 mStringAttributes[HREF].GetAnimValue(src, this);
129 isHref = true;
130 } else {
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());
140 if (!mUri) {
141 AutoTArray<nsString, 2> params = {
142 isHref ? u"href"_ns : u"xlink:href"_ns, src};
144 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "SVG"_ns,
145 OwnerDoc(),
146 nsContentUtils::eDOM_PROPERTIES,
147 "ScriptSourceInvalidUri", params, loc);
149 } else {
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.
158 mExternal = true;
161 bool async = (mExternal || mKind == ScriptKind::eModule) && Async();
162 bool defer = mExternal && Defer();
164 mDefer = !async && defer;
165 mAsync = async;
167 mFrozen = true;
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();
199 return NS_OK;
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);
209 return true;
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