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/. */
6 #include "mozilla/dom/HTMLStyleElement.h"
7 #include "mozilla/dom/HTMLStyleElementBinding.h"
9 #include "nsStyleConsts.h"
10 #include "mozilla/dom/Document.h"
11 #include "mozilla/dom/FetchPriority.h"
12 #include "mozilla/dom/ReferrerInfo.h"
13 #include "nsUnicharUtils.h"
14 #include "nsThreadUtils.h"
15 #include "nsContentUtils.h"
16 #include "nsStubMutationObserver.h"
17 #include "nsDOMTokenList.h"
19 NS_IMPL_NS_NEW_HTML_ELEMENT(Style
)
21 namespace mozilla::dom
{
23 HTMLStyleElement::HTMLStyleElement(
24 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
)
25 : nsGenericHTMLElement(std::move(aNodeInfo
)) {
26 AddMutationObserver(this);
29 HTMLStyleElement::~HTMLStyleElement() = default;
31 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLStyleElement
)
33 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLStyleElement
,
35 tmp
->LinkStyle::Traverse(cb
);
36 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBlocking
)
37 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
39 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLStyleElement
,
41 tmp
->LinkStyle::Unlink();
42 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBlocking
)
43 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
45 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLStyleElement
,
49 NS_IMPL_ELEMENT_CLONE(HTMLStyleElement
)
51 bool HTMLStyleElement::Disabled() const {
52 StyleSheet
* ss
= GetSheet();
53 return ss
&& ss
->Disabled();
56 void HTMLStyleElement::SetDisabled(bool aDisabled
) {
57 if (StyleSheet
* ss
= GetSheet()) {
58 ss
->SetDisabled(aDisabled
);
62 void HTMLStyleElement::CharacterDataChanged(nsIContent
* aContent
,
63 const CharacterDataChangeInfo
&) {
64 ContentChanged(aContent
);
67 void HTMLStyleElement::ContentAppended(nsIContent
* aFirstNewContent
) {
68 ContentChanged(aFirstNewContent
->GetParent());
71 void HTMLStyleElement::ContentInserted(nsIContent
* aChild
) {
72 ContentChanged(aChild
);
75 void HTMLStyleElement::ContentRemoved(nsIContent
* aChild
,
76 nsIContent
* aPreviousSibling
) {
77 ContentChanged(aChild
);
80 void HTMLStyleElement::ContentChanged(nsIContent
* aContent
) {
81 mTriggeringPrincipal
= nullptr;
82 if (nsContentUtils::IsInSameAnonymousTree(this, aContent
)) {
83 Unused
<< UpdateStyleSheetInternal(nullptr, nullptr);
87 nsresult
HTMLStyleElement::BindToTree(BindContext
& aContext
, nsINode
& aParent
) {
88 nsresult rv
= nsGenericHTMLElement::BindToTree(aContext
, aParent
);
89 NS_ENSURE_SUCCESS(rv
, rv
);
90 LinkStyle::BindToTree();
94 void HTMLStyleElement::UnbindFromTree(UnbindContext
& aContext
) {
95 RefPtr
<Document
> oldDoc
= GetUncomposedDoc();
96 ShadowRoot
* oldShadow
= GetContainingShadow();
98 nsGenericHTMLElement::UnbindFromTree(aContext
);
100 Unused
<< UpdateStyleSheetInternal(oldDoc
, oldShadow
);
103 void HTMLStyleElement::AfterSetAttr(int32_t aNameSpaceID
, nsAtom
* aName
,
104 const nsAttrValue
* aValue
,
105 const nsAttrValue
* aOldValue
,
106 nsIPrincipal
* aSubjectPrincipal
,
108 if (aNameSpaceID
== kNameSpaceID_None
) {
109 if (aName
== nsGkAtoms::title
|| aName
== nsGkAtoms::media
||
110 aName
== nsGkAtoms::type
) {
111 Unused
<< UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes
);
115 return nsGenericHTMLElement::AfterSetAttr(
116 aNameSpaceID
, aName
, aValue
, aOldValue
, aSubjectPrincipal
, aNotify
);
119 void HTMLStyleElement::GetInnerHTML(nsAString
& aInnerHTML
,
120 OOMReporter
& aError
) {
121 if (!nsContentUtils::GetNodeTextContent(this, false, aInnerHTML
, fallible
)) {
126 void HTMLStyleElement::SetInnerHTML(const nsAString
& aInnerHTML
,
127 nsIPrincipal
* aScriptedPrincipal
,
128 ErrorResult
& aError
) {
129 SetTextContentInternal(aInnerHTML
, aScriptedPrincipal
, aError
);
132 void HTMLStyleElement::SetTextContentInternal(const nsAString
& aTextContent
,
133 nsIPrincipal
* aScriptedPrincipal
,
134 ErrorResult
& aError
) {
135 // Per spec, if we're setting text content to an empty string and don't
136 // already have any children, we should not trigger any mutation observers, or
137 // re-parse the stylesheet.
138 if (aTextContent
.IsEmpty() && !GetFirstChild()) {
139 nsIPrincipal
* principal
=
140 mTriggeringPrincipal
? mTriggeringPrincipal
.get() : NodePrincipal();
141 if (principal
== aScriptedPrincipal
) {
146 const bool updatesWereEnabled
= mUpdatesEnabled
;
149 aError
= nsContentUtils::SetNodeTextContent(this, aTextContent
, true);
150 if (updatesWereEnabled
) {
151 mTriggeringPrincipal
= aScriptedPrincipal
;
152 Unused
<< EnableUpdatesAndUpdateStyleSheet(nullptr);
156 void HTMLStyleElement::SetDevtoolsAsTriggeringPrincipal() {
157 mTriggeringPrincipal
= CreateDevtoolsPrincipal();
160 Maybe
<LinkStyle::SheetInfo
> HTMLStyleElement::GetStyleSheetInfo() {
161 if (!IsCSSMimeTypeAttributeForStyleElement(*this)) {
167 GetTitleAndMediaForElement(*this, title
, media
);
169 return Some(SheetInfo
{
173 do_AddRef(mTriggeringPrincipal
),
174 MakeAndAddRef
<ReferrerInfo
>(*this),
178 /* integrity = */ u
""_ns
,
179 /* nsStyleUtil::CSPAllowsInlineStyle takes care of nonce checking for
180 inline styles. Bug 1607011 */
181 /* nonce = */ u
""_ns
,
184 IsExplicitlyEnabled::No
,
189 JSObject
* HTMLStyleElement::WrapNode(JSContext
* aCx
,
190 JS::Handle
<JSObject
*> aGivenProto
) {
191 return HTMLStyleElement_Binding::Wrap(aCx
, this, aGivenProto
);
194 nsDOMTokenList
* HTMLStyleElement::Blocking() {
197 new nsDOMTokenList(this, nsGkAtoms::blocking
, sSupportedBlockingValues
);
202 } // namespace mozilla::dom