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 #ifndef mozilla_dom_HTMLTextAreaElement_h
8 #define mozilla_dom_HTMLTextAreaElement_h
10 #include "mozilla/Attributes.h"
11 #include "mozilla/TextControlElement.h"
12 #include "mozilla/TextControlState.h"
13 #include "mozilla/TextEditor.h"
14 #include "mozilla/dom/ConstraintValidation.h"
15 #include "mozilla/dom/HTMLFormElement.h"
16 #include "mozilla/dom/HTMLInputElementBinding.h"
17 #include "nsIControllers.h"
19 #include "nsGenericHTMLElement.h"
20 #include "nsStubMutationObserver.h"
21 #include "nsGkAtoms.h"
28 class EventChainPostVisitor
;
29 class EventChainPreVisitor
;
36 class HTMLTextAreaElement final
: public TextControlElement
,
37 public nsStubMutationObserver
,
38 public ConstraintValidation
{
40 using ConstraintValidation::GetValidationMessage
;
41 using ValueSetterOption
= TextControlState::ValueSetterOption
;
42 using ValueSetterOptions
= TextControlState::ValueSetterOptions
;
44 explicit HTMLTextAreaElement(
45 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
,
46 FromParser aFromParser
= NOT_FROM_PARSER
);
49 NS_DECL_ISUPPORTS_INHERITED
51 NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLTextAreaElement
, textarea
)
53 int32_t TabIndexDefault() override
;
56 bool IsInteractiveHTMLContent() const override
{ return true; }
58 // nsGenericHTMLElement
59 bool IsDisabledForEvents(WidgetEvent
* aEvent
) override
;
61 // nsGenericHTMLFormElement
62 void SaveState() override
;
64 // FIXME: Shouldn't be a CAN_RUN_SCRIPT_BOUNDARY probably?
65 MOZ_CAN_RUN_SCRIPT_BOUNDARY
bool RestoreState(PresState
*) override
;
68 MOZ_CAN_RUN_SCRIPT_BOUNDARY
69 NS_IMETHOD
Reset() override
;
70 NS_IMETHOD
SubmitNamesValues(FormData
* aFormData
) override
;
72 void FieldSetDisabledChanged(bool aNotify
) override
;
74 void SetLastValueChangeWasInteractive(bool);
77 bool IsSingleLineTextControlOrTextArea() const override
{ return true; }
78 void SetValueChanged(bool aValueChanged
) override
;
79 bool IsSingleLineTextControl() const override
;
80 bool IsTextArea() const override
;
81 bool IsPasswordTextControl() const override
;
82 int32_t GetCols() override
;
83 int32_t GetWrapCols() override
;
84 int32_t GetRows() override
;
85 void GetDefaultValueFromContent(nsAString
& aValue
, bool aForDisplay
) override
;
86 bool ValueChanged() const override
;
87 void GetTextEditorValue(nsAString
& aValue
) const override
;
88 MOZ_CAN_RUN_SCRIPT TextEditor
* GetTextEditor() override
;
89 TextEditor
* GetTextEditorWithoutCreation() const override
;
90 nsISelectionController
* GetSelectionController() override
;
91 nsFrameSelection
* GetConstFrameSelection() override
;
92 TextControlState
* GetTextControlState() const override
{ return mState
; }
93 nsresult
BindToFrame(nsTextControlFrame
* aFrame
) override
;
94 MOZ_CAN_RUN_SCRIPT
void UnbindFromFrame(nsTextControlFrame
* aFrame
) override
;
95 MOZ_CAN_RUN_SCRIPT nsresult
CreateEditor() override
;
96 void SetPreviewValue(const nsAString
& aValue
) override
;
97 void GetPreviewValue(nsAString
& aValue
) override
;
98 void EnablePreview() override
;
99 bool IsPreviewEnabled() override
;
100 void InitializeKeyboardEventListeners() override
;
101 void UpdatePlaceholderShownState();
102 void OnValueChanged(ValueChangeKind
, bool aNewValueEmpty
,
103 const nsAString
* aKnownNewValue
) override
;
104 void GetValueFromSetRangeText(nsAString
& aValue
) override
;
105 MOZ_CAN_RUN_SCRIPT nsresult
106 SetValueFromSetRangeText(const nsAString
& aValue
) override
;
107 bool HasCachedSelection() override
;
110 nsresult
BindToTree(BindContext
&, nsINode
& aParent
) override
;
111 void UnbindFromTree(UnbindContext
&) override
;
112 bool ParseAttribute(int32_t aNamespaceID
, nsAtom
* aAttribute
,
113 const nsAString
& aValue
,
114 nsIPrincipal
* aMaybeScriptedPrincipal
,
115 nsAttrValue
& aResult
) override
;
116 nsMapRuleToAttributesFunc
GetAttributeMappingFunction() const override
;
117 nsChangeHint
GetAttributeChangeHint(const nsAtom
* aAttribute
,
118 int32_t aModType
) const override
;
119 NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom
* aAttribute
) const override
;
121 void GetEventTargetParent(EventChainPreVisitor
& aVisitor
) override
;
122 nsresult
PreHandleEvent(EventChainVisitor
& aVisitor
) override
;
123 nsresult
PostHandleEvent(EventChainPostVisitor
& aVisitor
) override
;
125 bool IsHTMLFocusable(bool aWithMouse
, bool* aIsFocusable
,
126 int32_t* aTabIndex
) override
;
128 void DoneAddingChildren(bool aHaveNotified
) override
;
130 nsresult
Clone(dom::NodeInfo
*, nsINode
** aResult
) const override
;
132 MOZ_CAN_RUN_SCRIPT_BOUNDARY
133 nsresult
CopyInnerTo(Element
* aDest
);
136 * Called when an attribute is about to be changed
138 void BeforeSetAttr(int32_t aNameSpaceID
, nsAtom
* aName
,
139 const nsAttrValue
* aValue
, bool aNotify
) override
;
141 // nsIMutationObserver
142 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
143 NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
144 NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
145 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
147 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTextAreaElement
,
150 // nsIConstraintValidation
153 bool IsValueMissing() const;
154 void UpdateTooLongValidityState();
155 void UpdateTooShortValidityState();
156 void UpdateValueMissingValidityState();
157 void UpdateBarredFromConstraintValidation();
159 // ConstraintValidation
160 nsresult
GetValidationMessage(nsAString
& aValidationMessage
,
161 ValidityStateType aType
) override
;
163 // Web IDL binding methods
164 void GetAutocomplete(DOMString
& aValue
);
165 void SetAutocomplete(const nsAString
& aValue
, ErrorResult
& aRv
) {
166 SetHTMLAttr(nsGkAtoms::autocomplete
, aValue
, aRv
);
168 uint32_t Cols() { return GetUnsignedIntAttr(nsGkAtoms::cols
, DEFAULT_COLS
); }
169 void SetCols(uint32_t aCols
, ErrorResult
& aError
) {
170 uint32_t cols
= aCols
? aCols
: DEFAULT_COLS
;
171 SetUnsignedIntAttr(nsGkAtoms::cols
, cols
, DEFAULT_COLS
, aError
);
173 void GetDirName(nsAString
& aValue
) {
174 GetHTMLAttr(nsGkAtoms::dirname
, aValue
);
176 void SetDirName(const nsAString
& aValue
, ErrorResult
& aError
) {
177 SetHTMLAttr(nsGkAtoms::dirname
, aValue
, aError
);
179 bool Disabled() { return GetBoolAttr(nsGkAtoms::disabled
); }
180 void SetDisabled(bool aDisabled
, ErrorResult
& aError
) {
181 SetHTMLBoolAttr(nsGkAtoms::disabled
, aDisabled
, aError
);
183 // nsGenericHTMLFormControlElementWithState::GetForm is fine
184 using nsGenericHTMLFormControlElementWithState::GetForm
;
185 int32_t MaxLength() const { return GetIntAttr(nsGkAtoms::maxlength
, -1); }
186 int32_t UsedMaxLength() const final
{ return MaxLength(); }
187 void SetMaxLength(int32_t aMaxLength
, ErrorResult
& aError
) {
188 int32_t minLength
= MinLength();
189 if (aMaxLength
< 0 || (minLength
>= 0 && aMaxLength
< minLength
)) {
190 aError
.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR
);
192 SetHTMLIntAttr(nsGkAtoms::maxlength
, aMaxLength
, aError
);
195 int32_t MinLength() const { return GetIntAttr(nsGkAtoms::minlength
, -1); }
196 void SetMinLength(int32_t aMinLength
, ErrorResult
& aError
) {
197 int32_t maxLength
= MaxLength();
198 if (aMinLength
< 0 || (maxLength
>= 0 && aMinLength
> maxLength
)) {
199 aError
.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR
);
201 SetHTMLIntAttr(nsGkAtoms::minlength
, aMinLength
, aError
);
204 void GetName(nsAString
& aName
) { GetHTMLAttr(nsGkAtoms::name
, aName
); }
205 void SetName(const nsAString
& aName
, ErrorResult
& aError
) {
206 SetHTMLAttr(nsGkAtoms::name
, aName
, aError
);
208 void GetPlaceholder(nsAString
& aPlaceholder
) {
209 GetHTMLAttr(nsGkAtoms::placeholder
, aPlaceholder
);
211 void SetPlaceholder(const nsAString
& aPlaceholder
, ErrorResult
& aError
) {
212 SetHTMLAttr(nsGkAtoms::placeholder
, aPlaceholder
, aError
);
214 bool ReadOnly() { return GetBoolAttr(nsGkAtoms::readonly
); }
215 void SetReadOnly(bool aReadOnly
, ErrorResult
& aError
) {
216 SetHTMLBoolAttr(nsGkAtoms::readonly
, aReadOnly
, aError
);
218 bool Required() const { return State().HasState(ElementState::REQUIRED
); }
220 MOZ_CAN_RUN_SCRIPT
void SetRangeText(const nsAString
& aReplacement
,
223 MOZ_CAN_RUN_SCRIPT
void SetRangeText(const nsAString
& aReplacement
,
224 uint32_t aStart
, uint32_t aEnd
,
225 SelectionMode aSelectMode
,
228 void SetRequired(bool aRequired
, ErrorResult
& aError
) {
229 SetHTMLBoolAttr(nsGkAtoms::required
, aRequired
, aError
);
232 return GetUnsignedIntAttr(nsGkAtoms::rows
, DEFAULT_ROWS_TEXTAREA
);
234 void SetRows(uint32_t aRows
, ErrorResult
& aError
) {
235 uint32_t rows
= aRows
? aRows
: DEFAULT_ROWS_TEXTAREA
;
236 SetUnsignedIntAttr(nsGkAtoms::rows
, rows
, DEFAULT_ROWS_TEXTAREA
, aError
);
238 void GetWrap(nsAString
& aWrap
) { GetHTMLAttr(nsGkAtoms::wrap
, aWrap
); }
239 void SetWrap(const nsAString
& aWrap
, ErrorResult
& aError
) {
240 SetHTMLAttr(nsGkAtoms::wrap
, aWrap
, aError
);
242 void GetType(nsAString
& aType
);
243 void GetDefaultValue(nsAString
& aDefaultValue
, ErrorResult
& aError
) const;
244 void SetDefaultValue(const nsAString
& aDefaultValue
, ErrorResult
& aError
);
245 void GetValue(nsAString
& aValue
);
246 MOZ_CAN_RUN_SCRIPT
void SetValue(const nsAString
&, ErrorResult
&);
248 uint32_t GetTextLength();
250 // Override SetCustomValidity so we update our state properly when it's called
252 void SetCustomValidity(const nsAString
& aError
);
254 MOZ_CAN_RUN_SCRIPT
void Select();
255 Nullable
<uint32_t> GetSelectionStart(ErrorResult
& aError
);
256 MOZ_CAN_RUN_SCRIPT
void SetSelectionStart(
257 const Nullable
<uint32_t>& aSelectionStart
, ErrorResult
& aError
);
258 Nullable
<uint32_t> GetSelectionEnd(ErrorResult
& aError
);
259 MOZ_CAN_RUN_SCRIPT
void SetSelectionEnd(
260 const Nullable
<uint32_t>& aSelectionEnd
, ErrorResult
& aError
);
261 void GetSelectionDirection(nsAString
& aDirection
, ErrorResult
& aError
);
262 MOZ_CAN_RUN_SCRIPT
void SetSelectionDirection(const nsAString
& aDirection
,
263 ErrorResult
& aError
);
264 MOZ_CAN_RUN_SCRIPT
void SetSelectionRange(
265 uint32_t aSelectionStart
, uint32_t aSelectionEnd
,
266 const Optional
<nsAString
>& aDirecton
, ErrorResult
& aError
);
267 nsIControllers
* GetControllers(ErrorResult
& aError
);
268 // XPCOM adapter function widely used throughout code, leaving it as is.
269 nsresult
GetControllers(nsIControllers
** aResult
);
271 MOZ_CAN_RUN_SCRIPT nsIEditor
* GetEditorForBindings();
272 bool HasEditor() const {
274 return !!mState
->GetTextEditorWithoutCreation();
277 bool IsInputEventTarget() const { return true; }
279 MOZ_CAN_RUN_SCRIPT_BOUNDARY
void SetUserInput(
280 const nsAString
& aValue
, nsIPrincipal
& aSubjectPrincipal
);
283 MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual ~HTMLTextAreaElement();
285 // get rid of the compiler warning
286 using nsGenericHTMLFormControlElementWithState::IsSingleLineTextControl
;
288 JSObject
* WrapNode(JSContext
*, JS::Handle
<JSObject
*> aGivenProto
) override
;
290 nsCOMPtr
<nsIControllers
> mControllers
;
291 /** https://html.spec.whatwg.org/#user-interacted */
292 bool mUserInteracted
= false;
293 /** Whether or not the value has changed since its default value was given. */
294 bool mValueChanged
= false;
295 /** Whether or not the last change to the value was made interactively by the
297 bool mLastValueChangeWasInteractive
= false;
298 /** Whether or not we are already handling select event. */
299 bool mHandlingSelect
= false;
300 /** Whether or not we are done adding children (always true if not
301 created by a parser */
302 bool mDoneAddingChildren
;
303 /** Whether state restoration should be inhibited in DoneAddingChildren. */
304 bool mInhibitStateRestoration
;
305 /** Whether our disabled state has changed from the default **/
306 bool mDisabledChanged
= false;
307 bool mIsPreviewEnabled
= false;
309 nsContentUtils::AutocompleteAttrState mAutocompleteAttrState
;
311 void FireChangeEventIfNeeded();
313 nsString mFocusedValue
;
315 /** The state of the text editor (selection controller and the editor) **/
316 TextControlState
* mState
;
318 NS_IMETHOD
SelectAll(nsPresContext
* aPresContext
);
320 * Get the value, whether it is from the content or the frame.
321 * @param aValue the value [out]
322 * @param aIgnoreWrap whether to ignore the wrap attribute when getting the
323 * value. If this is true, linebreaks will not be inserted even if
326 void GetValueInternal(nsAString
& aValue
, bool aIgnoreWrap
) const;
331 * @param aValue String to set.
332 * @param aOptions See TextControlState::ValueSetterOption.
334 MOZ_CAN_RUN_SCRIPT nsresult
335 SetValueInternal(const nsAString
& aValue
, const ValueSetterOptions
& aOptions
);
338 * Common method to call from the various mutation observer methods.
339 * aContent is a content node that's either the one that changed or its
340 * parent; we should only respond to the change if aContent is non-anonymous.
342 void ContentChanged(nsIContent
* aContent
);
344 void AfterSetAttr(int32_t aNamespaceID
, nsAtom
* aName
,
345 const nsAttrValue
* aValue
, const nsAttrValue
* aOldValue
,
346 nsIPrincipal
* aSubjectPrincipal
, bool aNotify
) override
;
348 void SetDirectionFromValue(bool aNotify
,
349 const nsAString
* aKnownValue
= nullptr);
352 * Get the mutable state of the element.
354 bool IsMutable() const;
357 * Returns whether the current value is the empty string.
359 * @return whether the current value is the empty string.
361 bool IsValueEmpty() const {
362 return State().HasState(ElementState::VALUE_EMPTY
);
366 * A helper to get the current selection range. Will throw on the ErrorResult
367 * if we have no editor state.
369 void GetSelectionRange(uint32_t* aSelectionStart
, uint32_t* aSelectionEnd
,
372 void SetUserInteracted(bool) final
;
373 void UpdateValidityElementStates(bool aNotify
);
376 static void MapAttributesIntoRule(MappedDeclarationsBuilder
&);
380 } // namespace mozilla