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/SVGStyleElement.h"
9 #include "mozilla/RefPtr.h"
10 #include "mozilla/dom/Document.h"
11 #include "mozilla/dom/Element.h"
12 #include "mozilla/dom/FetchPriority.h"
13 #include "mozilla/dom/ReferrerInfo.h"
14 #include "mozilla/dom/SVGStyleElementBinding.h"
16 #include "nsContentUtils.h"
18 NS_IMPL_NS_NEW_SVG_ELEMENT(Style
)
20 namespace mozilla::dom
{
22 JSObject
* SVGStyleElement::WrapNode(JSContext
* aCx
,
23 JS::Handle
<JSObject
*> aGivenProto
) {
24 return SVGStyleElement_Binding::Wrap(aCx
, this, aGivenProto
);
27 //----------------------------------------------------------------------
28 // nsISupports methods
30 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(SVGStyleElement
,
34 NS_IMPL_CYCLE_COLLECTION_CLASS(SVGStyleElement
)
36 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGStyleElement
,
38 tmp
->LinkStyle::Traverse(cb
);
39 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
41 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGStyleElement
,
43 tmp
->LinkStyle::Unlink();
44 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
46 //----------------------------------------------------------------------
49 SVGStyleElement::SVGStyleElement(
50 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
)
51 : SVGStyleElementBase(std::move(aNodeInfo
)) {
52 AddMutationObserver(this);
53 SetEnabledCallbacks(kCharacterDataChanged
| kContentAppended
|
54 kContentInserted
| kContentWillBeRemoved
);
57 //----------------------------------------------------------------------
60 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGStyleElement
)
62 //----------------------------------------------------------------------
65 nsresult
SVGStyleElement::BindToTree(BindContext
& aContext
, nsINode
& aParent
) {
66 nsresult rv
= SVGStyleElementBase::BindToTree(aContext
, aParent
);
67 NS_ENSURE_SUCCESS(rv
, rv
);
68 LinkStyle::BindToTree();
72 void SVGStyleElement::UnbindFromTree(UnbindContext
& aContext
) {
73 nsCOMPtr
<Document
> oldDoc
= GetUncomposedDoc();
74 ShadowRoot
* oldShadow
= GetContainingShadow();
75 SVGStyleElementBase::UnbindFromTree(aContext
);
76 Unused
<< UpdateStyleSheetInternal(oldDoc
, oldShadow
);
79 void SVGStyleElement::AfterSetAttr(int32_t aNameSpaceID
, nsAtom
* aName
,
80 const nsAttrValue
* aValue
,
81 const nsAttrValue
* aOldValue
,
82 nsIPrincipal
* aMaybeScriptedPrincipal
,
84 if (aNameSpaceID
== kNameSpaceID_None
) {
85 if (aName
== nsGkAtoms::title
|| aName
== nsGkAtoms::media
||
86 aName
== nsGkAtoms::type
) {
87 Unused
<< UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes
);
91 return SVGStyleElementBase::AfterSetAttr(
92 aNameSpaceID
, aName
, aValue
, aOldValue
, aMaybeScriptedPrincipal
, aNotify
);
95 bool SVGStyleElement::ParseAttribute(int32_t aNamespaceID
, nsAtom
* aAttribute
,
96 const nsAString
& aValue
,
97 nsIPrincipal
* aMaybeScriptedPrincipal
,
98 nsAttrValue
& aResult
) {
99 if (aNamespaceID
== kNameSpaceID_None
&&
100 aAttribute
== nsGkAtoms::crossorigin
) {
101 ParseCORSValue(aValue
, aResult
);
105 return SVGStyleElementBase::ParseAttribute(aNamespaceID
, aAttribute
, aValue
,
106 aMaybeScriptedPrincipal
, aResult
);
109 //----------------------------------------------------------------------
110 // nsIMutationObserver methods
112 void SVGStyleElement::CharacterDataChanged(nsIContent
* aContent
,
113 const CharacterDataChangeInfo
&) {
114 ContentChanged(aContent
);
117 void SVGStyleElement::ContentAppended(nsIContent
* aFirstNewContent
) {
118 ContentChanged(aFirstNewContent
->GetParent());
121 void SVGStyleElement::ContentInserted(nsIContent
* aChild
) {
122 ContentChanged(aChild
);
125 void SVGStyleElement::ContentWillBeRemoved(nsIContent
* aChild
) {
126 if (nsContentUtils::IsInSameAnonymousTree(this, aChild
)) {
127 // Make sure to run this once the removal has taken place.
128 nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
129 "SVGStyleElement::ContentWillBeRemoved",
130 [self
= RefPtr
{this}] { self
->UpdateStyleSheetInternal(); }));
134 void SVGStyleElement::ContentChanged(nsIContent
* aContent
) {
135 if (nsContentUtils::IsInSameAnonymousTree(this, aContent
)) {
136 Unused
<< UpdateStyleSheetInternal(nullptr, nullptr);
140 //----------------------------------------------------------------------
142 void SVGStyleElement::GetMedia(nsAString
& aMedia
) {
143 GetAttr(nsGkAtoms::media
, aMedia
);
146 void SVGStyleElement::SetMedia(const nsAString
& aMedia
, ErrorResult
& rv
) {
147 SetAttr(nsGkAtoms::media
, aMedia
, rv
);
150 void SVGStyleElement::GetType(nsAString
& aType
) {
151 GetAttr(nsGkAtoms::type
, aType
);
154 void SVGStyleElement::SetType(const nsAString
& aType
, ErrorResult
& rv
) {
155 SetAttr(nsGkAtoms::type
, aType
, rv
);
158 void SVGStyleElement::GetTitle(nsAString
& aTitle
) {
159 GetAttr(nsGkAtoms::title
, aTitle
);
162 void SVGStyleElement::SetTitle(const nsAString
& aTitle
, ErrorResult
& rv
) {
163 SetAttr(nsGkAtoms::title
, aTitle
, rv
);
166 bool SVGStyleElement::Disabled() const {
167 StyleSheet
* ss
= GetSheet();
168 return ss
&& ss
->Disabled();
171 void SVGStyleElement::SetDisabled(bool aDisabled
) {
172 if (StyleSheet
* ss
= GetSheet()) {
173 ss
->SetDisabled(aDisabled
);
177 //----------------------------------------------------------------------
178 // nsStyleLinkElement methods
180 Maybe
<LinkStyle::SheetInfo
> SVGStyleElement::GetStyleSheetInfo() {
181 if (!IsCSSMimeTypeAttributeForStyleElement(*this)) {
187 GetTitleAndMediaForElement(*this, title
, media
);
189 return Some(SheetInfo
{
193 // FIXME(bug 1459822): Why doesn't this need a principal, but
194 // HTMLStyleElement does?
196 // FIXME(bug 1459822): Why does this need a crossorigin attribute, but
197 // HTMLStyleElement doesn't?
198 MakeAndAddRef
<ReferrerInfo
>(*this),
199 AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin
)),
202 /* integrity = */ u
""_ns
,
203 /* nsStyleUtil::CSPAllowsInlineStyle takes care of nonce checking for
204 inline styles. Bug 1607011 */
205 /* nonce = */ u
""_ns
,
208 IsExplicitlyEnabled::No
,
213 } // namespace mozilla::dom