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/HTMLOutputElement.h"
9 #include "mozAutoDocUpdate.h"
10 #include "mozilla/dom/HTMLFormElement.h"
11 #include "mozilla/dom/HTMLOutputElementBinding.h"
12 #include "nsContentUtils.h"
13 #include "nsDOMTokenList.h"
15 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Output
)
17 namespace mozilla::dom
{
19 HTMLOutputElement::HTMLOutputElement(
20 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
,
21 FromParser aFromParser
)
22 : nsGenericHTMLFormControlElement(std::move(aNodeInfo
),
23 FormControlType::Output
),
24 mValueModeFlag(eModeDefault
),
25 mIsDoneAddingChildren(!aFromParser
) {
26 AddMutationObserver(this);
28 // <output> is always barred from constraint validation since it is not a
29 // submittable element.
30 SetBarredFromConstraintValidation(true);
33 HTMLOutputElement::~HTMLOutputElement() = default;
35 NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLOutputElement
,
36 nsGenericHTMLFormControlElement
, mValidity
,
39 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLOutputElement
,
40 nsGenericHTMLFormControlElement
,
42 nsIConstraintValidation
)
44 NS_IMPL_ELEMENT_CLONE(HTMLOutputElement
)
46 void HTMLOutputElement::SetCustomValidity(const nsAString
& aError
) {
47 ConstraintValidation::SetCustomValidity(aError
);
51 HTMLOutputElement::Reset() {
52 mValueModeFlag
= eModeDefault
;
53 // We can't pass mDefaultValue, because it'll be truncated when
54 // the element's descendants are changed, so pass a copy instead.
55 const nsAutoString
currentDefaultValue(mDefaultValue
);
56 return nsContentUtils::SetNodeTextContent(this, currentDefaultValue
, true);
59 bool HTMLOutputElement::ParseAttribute(int32_t aNamespaceID
, nsAtom
* aAttribute
,
60 const nsAString
& aValue
,
61 nsIPrincipal
* aMaybeScriptedPrincipal
,
62 nsAttrValue
& aResult
) {
63 if (aNamespaceID
== kNameSpaceID_None
) {
64 if (aAttribute
== nsGkAtoms::_for
) {
65 aResult
.ParseAtomArray(aValue
);
70 return nsGenericHTMLFormControlElement::ParseAttribute(
71 aNamespaceID
, aAttribute
, aValue
, aMaybeScriptedPrincipal
, aResult
);
74 void HTMLOutputElement::DoneAddingChildren(bool aHaveNotified
) {
75 mIsDoneAddingChildren
= true;
76 // We should update DefaultValue, after parsing is done.
80 void HTMLOutputElement::GetValue(nsAString
& aValue
) const {
81 nsContentUtils::GetNodeTextContent(this, true, aValue
);
84 void HTMLOutputElement::SetValue(const nsAString
& aValue
, ErrorResult
& aRv
) {
85 mValueModeFlag
= eModeValue
;
86 aRv
= nsContentUtils::SetNodeTextContent(this, aValue
, true);
89 void HTMLOutputElement::SetDefaultValue(const nsAString
& aDefaultValue
,
91 mDefaultValue
= aDefaultValue
;
92 if (mValueModeFlag
== eModeDefault
) {
93 // We can't pass mDefaultValue, because it'll be truncated when
94 // the element's descendants are changed.
95 aRv
= nsContentUtils::SetNodeTextContent(this, aDefaultValue
, true);
99 nsDOMTokenList
* HTMLOutputElement::HtmlFor() {
101 mTokenList
= new nsDOMTokenList(this, nsGkAtoms::_for
);
106 void HTMLOutputElement::DescendantsChanged() {
107 if (mIsDoneAddingChildren
&& mValueModeFlag
== eModeDefault
) {
108 nsContentUtils::GetNodeTextContent(this, true, mDefaultValue
);
112 // nsIMutationObserver
114 void HTMLOutputElement::CharacterDataChanged(nsIContent
* aContent
,
115 const CharacterDataChangeInfo
&) {
116 DescendantsChanged();
119 void HTMLOutputElement::ContentAppended(nsIContent
* aFirstNewContent
) {
120 DescendantsChanged();
123 void HTMLOutputElement::ContentInserted(nsIContent
* aChild
) {
124 DescendantsChanged();
127 void HTMLOutputElement::ContentRemoved(nsIContent
* aChild
,
128 nsIContent
* aPreviousSibling
) {
129 DescendantsChanged();
132 JSObject
* HTMLOutputElement::WrapNode(JSContext
* aCx
,
133 JS::Handle
<JSObject
*> aGivenProto
) {
134 return HTMLOutputElement_Binding::Wrap(aCx
, this, aGivenProto
);
137 } // namespace mozilla::dom