Bug 1685822 [wpt PR 27117] - [Import Maps] Add tests for rejecting multiple import...
[gecko.git] / dom / html / HTMLStyleElement.cpp
blob490b5d8d757f8da316b6e6915323401f9f1f3f2e
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"
8 #include "nsGkAtoms.h"
9 #include "nsStyleConsts.h"
10 #include "mozilla/dom/Document.h"
11 #include "nsUnicharUtils.h"
12 #include "nsThreadUtils.h"
13 #include "nsContentUtils.h"
14 #include "nsStubMutationObserver.h"
16 NS_IMPL_NS_NEW_HTML_ELEMENT(Style)
18 namespace mozilla::dom {
20 HTMLStyleElement::HTMLStyleElement(
21 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
22 : nsGenericHTMLElement(std::move(aNodeInfo)) {
23 AddMutationObserver(this);
26 HTMLStyleElement::~HTMLStyleElement() = default;
28 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLStyleElement)
30 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLStyleElement,
31 nsGenericHTMLElement)
32 tmp->LinkStyle::Traverse(cb);
33 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
35 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLStyleElement,
36 nsGenericHTMLElement)
37 tmp->LinkStyle::Unlink();
38 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
40 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLStyleElement,
41 nsGenericHTMLElement,
42 nsIMutationObserver)
44 NS_IMPL_ELEMENT_CLONE(HTMLStyleElement)
46 bool HTMLStyleElement::Disabled() const {
47 StyleSheet* ss = GetSheet();
48 return ss && ss->Disabled();
51 void HTMLStyleElement::SetDisabled(bool aDisabled) {
52 if (StyleSheet* ss = GetSheet()) {
53 ss->SetDisabled(aDisabled);
57 void HTMLStyleElement::CharacterDataChanged(nsIContent* aContent,
58 const CharacterDataChangeInfo&) {
59 ContentChanged(aContent);
62 void HTMLStyleElement::ContentAppended(nsIContent* aFirstNewContent) {
63 ContentChanged(aFirstNewContent->GetParent());
66 void HTMLStyleElement::ContentInserted(nsIContent* aChild) {
67 ContentChanged(aChild);
70 void HTMLStyleElement::ContentRemoved(nsIContent* aChild,
71 nsIContent* aPreviousSibling) {
72 ContentChanged(aChild);
75 void HTMLStyleElement::ContentChanged(nsIContent* aContent) {
76 mTriggeringPrincipal = nullptr;
77 if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
78 Unused << UpdateStyleSheetInternal(nullptr, nullptr);
82 nsresult HTMLStyleElement::BindToTree(BindContext& aContext, nsINode& aParent) {
83 nsresult rv = nsGenericHTMLElement::BindToTree(aContext, aParent);
84 NS_ENSURE_SUCCESS(rv, rv);
86 void (HTMLStyleElement::*update)() =
87 &HTMLStyleElement::UpdateStyleSheetInternal;
88 nsContentUtils::AddScriptRunner(
89 NewRunnableMethod("dom::HTMLStyleElement::BindToTree", this, update));
91 return rv;
94 void HTMLStyleElement::UnbindFromTree(bool aNullParent) {
95 nsCOMPtr<Document> oldDoc = GetUncomposedDoc();
96 ShadowRoot* oldShadow = GetContainingShadow();
98 nsGenericHTMLElement::UnbindFromTree(aNullParent);
100 if (oldShadow && GetContainingShadow()) {
101 // The style is in a shadow tree and is still in the
102 // shadow tree. Thus the sheets in the shadow DOM
103 // do not need to be updated.
104 return;
107 Unused << UpdateStyleSheetInternal(oldDoc, oldShadow);
110 nsresult HTMLStyleElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
111 const nsAttrValue* aValue,
112 const nsAttrValue* aOldValue,
113 nsIPrincipal* aSubjectPrincipal,
114 bool aNotify) {
115 if (aNameSpaceID == kNameSpaceID_None) {
116 if (aName == nsGkAtoms::title || aName == nsGkAtoms::media ||
117 aName == nsGkAtoms::type) {
118 Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
122 return nsGenericHTMLElement::AfterSetAttr(
123 aNameSpaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
126 void HTMLStyleElement::GetInnerHTML(nsAString& aInnerHTML,
127 OOMReporter& aError) {
128 if (!nsContentUtils::GetNodeTextContent(this, false, aInnerHTML, fallible)) {
129 aError.ReportOOM();
133 void HTMLStyleElement::SetInnerHTML(const nsAString& aInnerHTML,
134 nsIPrincipal* aScriptedPrincipal,
135 ErrorResult& aError) {
136 SetTextContentInternal(aInnerHTML, aScriptedPrincipal, aError);
139 void HTMLStyleElement::SetTextContentInternal(const nsAString& aTextContent,
140 nsIPrincipal* aScriptedPrincipal,
141 ErrorResult& aError) {
142 // Per spec, if we're setting text content to an empty string and don't
143 // already have any children, we should not trigger any mutation observers, or
144 // re-parse the stylesheet.
145 if (aTextContent.IsEmpty() && !GetFirstChild()) {
146 nsIPrincipal* principal =
147 mTriggeringPrincipal ? mTriggeringPrincipal.get() : NodePrincipal();
148 if (principal == aScriptedPrincipal) {
149 return;
153 SetEnableUpdates(false);
155 aError = nsContentUtils::SetNodeTextContent(this, aTextContent, true);
157 SetEnableUpdates(true);
159 mTriggeringPrincipal = aScriptedPrincipal;
161 Unused << UpdateStyleSheetInternal(nullptr, nullptr);
164 void HTMLStyleElement::SetDevtoolsAsTriggeringPrincipal() {
165 mTriggeringPrincipal = CreateDevtoolsPrincipal();
168 Maybe<LinkStyle::SheetInfo> HTMLStyleElement::GetStyleSheetInfo() {
169 if (!IsCSSMimeTypeAttributeForStyleElement(*this)) {
170 return Nothing();
173 nsAutoString title;
174 nsAutoString media;
175 GetTitleAndMediaForElement(*this, title, media);
177 return Some(SheetInfo{
178 *OwnerDoc(),
179 this,
180 nullptr,
181 do_AddRef(mTriggeringPrincipal),
182 MakeAndAddRef<ReferrerInfo>(*this),
183 CORS_NONE,
184 title,
185 media,
186 /* integrity = */ u""_ns,
187 /* nsStyleUtil::CSPAllowsInlineStyle takes care of nonce checking for
188 inline styles. Bug 1607011 */
189 /* nonce = */ u""_ns,
190 HasAlternateRel::No,
191 IsInline::Yes,
192 IsExplicitlyEnabled::No,
196 JSObject* HTMLStyleElement::WrapNode(JSContext* aCx,
197 JS::Handle<JSObject*> aGivenProto) {
198 return HTMLStyleElement_Binding::Wrap(aCx, this, aGivenProto);
201 } // namespace mozilla::dom