mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 10:33:33 +00:00
51758cfc9b
Same rg + sed shenanigans as the first patch. There were two that could fail, both due to OOM: * HTMLInputElement::AfterSetAttr: If we fail (only in the type=range case) we end up with an old value without it being clamped by min/max/step. * HTMLBodyElement::AfterSetAttr: If we fail we won't peek up the DocShell's frame margins and styling could be incorrect. That seems better than having to deal with broken states after we've already set the attribute. Depends on D176069 Differential Revision: https://phabricator.services.mozilla.com/D176070
196 lines
6.3 KiB
C++
196 lines
6.3 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#include "mozilla/dom/HTMLStyleElement.h"
|
|
#include "mozilla/dom/HTMLStyleElementBinding.h"
|
|
#include "nsGkAtoms.h"
|
|
#include "nsStyleConsts.h"
|
|
#include "mozilla/dom/Document.h"
|
|
#include "mozilla/dom/ReferrerInfo.h"
|
|
#include "nsUnicharUtils.h"
|
|
#include "nsThreadUtils.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsStubMutationObserver.h"
|
|
|
|
NS_IMPL_NS_NEW_HTML_ELEMENT(Style)
|
|
|
|
namespace mozilla::dom {
|
|
|
|
HTMLStyleElement::HTMLStyleElement(
|
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
|
: nsGenericHTMLElement(std::move(aNodeInfo)) {
|
|
AddMutationObserver(this);
|
|
}
|
|
|
|
HTMLStyleElement::~HTMLStyleElement() = default;
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLStyleElement)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLStyleElement,
|
|
nsGenericHTMLElement)
|
|
tmp->LinkStyle::Traverse(cb);
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLStyleElement,
|
|
nsGenericHTMLElement)
|
|
tmp->LinkStyle::Unlink();
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLStyleElement,
|
|
nsGenericHTMLElement,
|
|
nsIMutationObserver)
|
|
|
|
NS_IMPL_ELEMENT_CLONE(HTMLStyleElement)
|
|
|
|
bool HTMLStyleElement::Disabled() const {
|
|
StyleSheet* ss = GetSheet();
|
|
return ss && ss->Disabled();
|
|
}
|
|
|
|
void HTMLStyleElement::SetDisabled(bool aDisabled) {
|
|
if (StyleSheet* ss = GetSheet()) {
|
|
ss->SetDisabled(aDisabled);
|
|
}
|
|
}
|
|
|
|
void HTMLStyleElement::CharacterDataChanged(nsIContent* aContent,
|
|
const CharacterDataChangeInfo&) {
|
|
ContentChanged(aContent);
|
|
}
|
|
|
|
void HTMLStyleElement::ContentAppended(nsIContent* aFirstNewContent) {
|
|
ContentChanged(aFirstNewContent->GetParent());
|
|
}
|
|
|
|
void HTMLStyleElement::ContentInserted(nsIContent* aChild) {
|
|
ContentChanged(aChild);
|
|
}
|
|
|
|
void HTMLStyleElement::ContentRemoved(nsIContent* aChild,
|
|
nsIContent* aPreviousSibling) {
|
|
ContentChanged(aChild);
|
|
}
|
|
|
|
void HTMLStyleElement::ContentChanged(nsIContent* aContent) {
|
|
mTriggeringPrincipal = nullptr;
|
|
if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
|
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr);
|
|
}
|
|
}
|
|
|
|
nsresult HTMLStyleElement::BindToTree(BindContext& aContext, nsINode& aParent) {
|
|
nsresult rv = nsGenericHTMLElement::BindToTree(aContext, aParent);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
void (HTMLStyleElement::*update)() =
|
|
&HTMLStyleElement::UpdateStyleSheetInternal;
|
|
nsContentUtils::AddScriptRunner(
|
|
NewRunnableMethod("dom::HTMLStyleElement::BindToTree", this, update));
|
|
|
|
return rv;
|
|
}
|
|
|
|
void HTMLStyleElement::UnbindFromTree(bool aNullParent) {
|
|
RefPtr<Document> oldDoc = GetUncomposedDoc();
|
|
ShadowRoot* oldShadow = GetContainingShadow();
|
|
|
|
nsGenericHTMLElement::UnbindFromTree(aNullParent);
|
|
|
|
Unused << UpdateStyleSheetInternal(oldDoc, oldShadow);
|
|
}
|
|
|
|
void HTMLStyleElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|
const nsAttrValue* aValue,
|
|
const nsAttrValue* aOldValue,
|
|
nsIPrincipal* aSubjectPrincipal,
|
|
bool aNotify) {
|
|
if (aNameSpaceID == kNameSpaceID_None) {
|
|
if (aName == nsGkAtoms::title || aName == nsGkAtoms::media ||
|
|
aName == nsGkAtoms::type) {
|
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
|
|
}
|
|
}
|
|
|
|
return nsGenericHTMLElement::AfterSetAttr(
|
|
aNameSpaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
|
|
}
|
|
|
|
void HTMLStyleElement::GetInnerHTML(nsAString& aInnerHTML,
|
|
OOMReporter& aError) {
|
|
if (!nsContentUtils::GetNodeTextContent(this, false, aInnerHTML, fallible)) {
|
|
aError.ReportOOM();
|
|
}
|
|
}
|
|
|
|
void HTMLStyleElement::SetInnerHTML(const nsAString& aInnerHTML,
|
|
nsIPrincipal* aScriptedPrincipal,
|
|
ErrorResult& aError) {
|
|
SetTextContentInternal(aInnerHTML, aScriptedPrincipal, aError);
|
|
}
|
|
|
|
void HTMLStyleElement::SetTextContentInternal(const nsAString& aTextContent,
|
|
nsIPrincipal* aScriptedPrincipal,
|
|
ErrorResult& aError) {
|
|
// Per spec, if we're setting text content to an empty string and don't
|
|
// already have any children, we should not trigger any mutation observers, or
|
|
// re-parse the stylesheet.
|
|
if (aTextContent.IsEmpty() && !GetFirstChild()) {
|
|
nsIPrincipal* principal =
|
|
mTriggeringPrincipal ? mTriggeringPrincipal.get() : NodePrincipal();
|
|
if (principal == aScriptedPrincipal) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
SetEnableUpdates(false);
|
|
|
|
aError = nsContentUtils::SetNodeTextContent(this, aTextContent, true);
|
|
|
|
SetEnableUpdates(true);
|
|
|
|
mTriggeringPrincipal = aScriptedPrincipal;
|
|
|
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr);
|
|
}
|
|
|
|
void HTMLStyleElement::SetDevtoolsAsTriggeringPrincipal() {
|
|
mTriggeringPrincipal = CreateDevtoolsPrincipal();
|
|
}
|
|
|
|
Maybe<LinkStyle::SheetInfo> HTMLStyleElement::GetStyleSheetInfo() {
|
|
if (!IsCSSMimeTypeAttributeForStyleElement(*this)) {
|
|
return Nothing();
|
|
}
|
|
|
|
nsAutoString title;
|
|
nsAutoString media;
|
|
GetTitleAndMediaForElement(*this, title, media);
|
|
|
|
return Some(SheetInfo{
|
|
*OwnerDoc(),
|
|
this,
|
|
nullptr,
|
|
do_AddRef(mTriggeringPrincipal),
|
|
MakeAndAddRef<ReferrerInfo>(*this),
|
|
CORS_NONE,
|
|
title,
|
|
media,
|
|
/* integrity = */ u""_ns,
|
|
/* nsStyleUtil::CSPAllowsInlineStyle takes care of nonce checking for
|
|
inline styles. Bug 1607011 */
|
|
/* nonce = */ u""_ns,
|
|
HasAlternateRel::No,
|
|
IsInline::Yes,
|
|
IsExplicitlyEnabled::No,
|
|
});
|
|
}
|
|
|
|
JSObject* HTMLStyleElement::WrapNode(JSContext* aCx,
|
|
JS::Handle<JSObject*> aGivenProto) {
|
|
return HTMLStyleElement_Binding::Wrap(aCx, this, aGivenProto);
|
|
}
|
|
|
|
} // namespace mozilla::dom
|