Bug 1880216 - Migrate Fenix docs into Sphinx. r=owlish,geckoview-reviewers,android...
[gecko.git] / dom / html / HTMLStyleElement.cpp
blobe0bc22801142564a6f47e227697e1a15c244d28a
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 "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,
34 nsGenericHTMLElement)
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,
40 nsGenericHTMLElement)
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,
46 nsGenericHTMLElement,
47 nsIMutationObserver)
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();
91 return rv;
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 bool HTMLStyleElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
104 const nsAString& aValue,
105 nsIPrincipal* aMaybeScriptedPrincipal,
106 nsAttrValue& aResult) {
107 if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::blocking &&
108 StaticPrefs::dom_element_blocking_enabled()) {
109 aResult.ParseAtomArray(aValue);
110 return true;
113 return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
114 aMaybeScriptedPrincipal, aResult);
117 void HTMLStyleElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
118 const nsAttrValue* aValue,
119 const nsAttrValue* aOldValue,
120 nsIPrincipal* aSubjectPrincipal,
121 bool aNotify) {
122 if (aNameSpaceID == kNameSpaceID_None) {
123 if (aName == nsGkAtoms::title || aName == nsGkAtoms::media ||
124 aName == nsGkAtoms::type) {
125 Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
129 return nsGenericHTMLElement::AfterSetAttr(
130 aNameSpaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
133 void HTMLStyleElement::GetInnerHTML(nsAString& aInnerHTML,
134 OOMReporter& aError) {
135 if (!nsContentUtils::GetNodeTextContent(this, false, aInnerHTML, fallible)) {
136 aError.ReportOOM();
140 void HTMLStyleElement::SetInnerHTML(const nsAString& aInnerHTML,
141 nsIPrincipal* aScriptedPrincipal,
142 ErrorResult& aError) {
143 SetTextContentInternal(aInnerHTML, aScriptedPrincipal, aError);
146 void HTMLStyleElement::SetTextContentInternal(const nsAString& aTextContent,
147 nsIPrincipal* aScriptedPrincipal,
148 ErrorResult& aError) {
149 // Per spec, if we're setting text content to an empty string and don't
150 // already have any children, we should not trigger any mutation observers, or
151 // re-parse the stylesheet.
152 if (aTextContent.IsEmpty() && !GetFirstChild()) {
153 nsIPrincipal* principal =
154 mTriggeringPrincipal ? mTriggeringPrincipal.get() : NodePrincipal();
155 if (principal == aScriptedPrincipal) {
156 return;
160 const bool updatesWereEnabled = mUpdatesEnabled;
161 DisableUpdates();
163 aError = nsContentUtils::SetNodeTextContent(this, aTextContent, true);
164 if (updatesWereEnabled) {
165 mTriggeringPrincipal = aScriptedPrincipal;
166 Unused << EnableUpdatesAndUpdateStyleSheet(nullptr);
170 void HTMLStyleElement::SetDevtoolsAsTriggeringPrincipal() {
171 mTriggeringPrincipal = CreateDevtoolsPrincipal();
174 Maybe<LinkStyle::SheetInfo> HTMLStyleElement::GetStyleSheetInfo() {
175 if (!IsCSSMimeTypeAttributeForStyleElement(*this)) {
176 return Nothing();
179 nsAutoString title;
180 nsAutoString media;
181 GetTitleAndMediaForElement(*this, title, media);
183 return Some(SheetInfo{
184 *OwnerDoc(),
185 this,
186 nullptr,
187 do_AddRef(mTriggeringPrincipal),
188 MakeAndAddRef<ReferrerInfo>(*this),
189 CORS_NONE,
190 title,
191 media,
192 /* integrity = */ u""_ns,
193 /* nsStyleUtil::CSPAllowsInlineStyle takes care of nonce checking for
194 inline styles. Bug 1607011 */
195 /* nonce = */ u""_ns,
196 HasAlternateRel::No,
197 IsInline::Yes,
198 IsExplicitlyEnabled::No,
199 FetchPriority::Auto,
203 JSObject* HTMLStyleElement::WrapNode(JSContext* aCx,
204 JS::Handle<JSObject*> aGivenProto) {
205 return HTMLStyleElement_Binding::Wrap(aCx, this, aGivenProto);
208 nsDOMTokenList* HTMLStyleElement::Blocking() {
209 if (!mBlocking) {
210 mBlocking =
211 new nsDOMTokenList(this, nsGkAtoms::blocking, sSupportedBlockingValues);
213 return mBlocking;
216 bool HTMLStyleElement::IsPotentiallyRenderBlocking() {
217 return BlockingContainsRender();
219 // TODO: handle implicitly potentially render blocking
220 // https://html.spec.whatwg.org/#implicitly-potentially-render-blocking
221 // A style element is implicitly potentially render-blocking if the element
222 // was created by its node document's parser.
225 } // namespace mozilla::dom