Line data Source code
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 :
7 : #ifndef mozilla_dom_HTMLTextAreaElement_h
8 : #define mozilla_dom_HTMLTextAreaElement_h
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "nsIDOMHTMLTextAreaElement.h"
12 : #include "nsITextControlElement.h"
13 : #include "nsIControllers.h"
14 : #include "nsIDOMNSEditableElement.h"
15 : #include "nsCOMPtr.h"
16 : #include "nsGenericHTMLElement.h"
17 : #include "nsStubMutationObserver.h"
18 : #include "nsIConstraintValidation.h"
19 : #include "mozilla/dom/HTMLFormElement.h"
20 : #include "mozilla/dom/HTMLInputElementBinding.h"
21 : #include "nsGkAtoms.h"
22 :
23 : #include "mozilla/TextEditor.h"
24 : #include "nsTextEditorState.h"
25 :
26 : class nsIControllers;
27 : class nsIDocument;
28 : class nsPresContext;
29 : class nsPresState;
30 :
31 : namespace mozilla {
32 :
33 : class EventChainPostVisitor;
34 : class EventChainPreVisitor;
35 : class EventStates;
36 :
37 : namespace dom {
38 :
39 : class HTMLFormSubmission;
40 :
41 : class HTMLTextAreaElement final : public nsGenericHTMLFormElementWithState,
42 : public nsIDOMHTMLTextAreaElement,
43 : public nsITextControlElement,
44 : public nsIDOMNSEditableElement,
45 : public nsStubMutationObserver,
46 : public nsIConstraintValidation
47 : {
48 : public:
49 : using nsIConstraintValidation::GetValidationMessage;
50 :
51 : explicit HTMLTextAreaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
52 : FromParser aFromParser = NOT_FROM_PARSER);
53 :
54 : // nsISupports
55 : NS_DECL_ISUPPORTS_INHERITED
56 :
57 : virtual int32_t TabIndexDefault() override;
58 :
59 : // Element
60 0 : virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override
61 : {
62 0 : return true;
63 : }
64 :
65 : // nsIDOMHTMLTextAreaElement
66 : NS_DECL_NSIDOMHTMLTEXTAREAELEMENT
67 :
68 : // nsIDOMNSEditableElement
69 0 : NS_IMETHOD GetEditor(nsIEditor** aEditor) override
70 : {
71 0 : nsCOMPtr<nsIEditor> editor = GetEditor();
72 0 : editor.forget(aEditor);
73 0 : return NS_OK;
74 : }
75 : NS_IMETHOD SetUserInput(const nsAString& aInput) override;
76 :
77 : // nsIFormControl
78 : NS_IMETHOD Reset() override;
79 : NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
80 : NS_IMETHOD SaveState() override;
81 : virtual bool RestoreState(nsPresState* aState) override;
82 : virtual bool IsDisabledForEvents(EventMessage aMessage) override;
83 :
84 : virtual void FieldSetDisabledChanged(bool aNotify) override;
85 :
86 : virtual EventStates IntrinsicState() const override;
87 :
88 : // nsITextControlElemet
89 : NS_IMETHOD SetValueChanged(bool aValueChanged) override;
90 : NS_IMETHOD_(bool) IsSingleLineTextControl() const override;
91 : NS_IMETHOD_(bool) IsTextArea() const override;
92 : NS_IMETHOD_(bool) IsPlainTextControl() const override;
93 : NS_IMETHOD_(bool) IsPasswordTextControl() const override;
94 : NS_IMETHOD_(int32_t) GetCols() override;
95 : NS_IMETHOD_(int32_t) GetWrapCols() override;
96 : NS_IMETHOD_(int32_t) GetRows() override;
97 : NS_IMETHOD_(void) GetDefaultValueFromContent(nsAString& aValue) override;
98 : NS_IMETHOD_(bool) ValueChanged() const override;
99 : NS_IMETHOD_(void) GetTextEditorValue(nsAString& aValue, bool aIgnoreWrap) const override;
100 : NS_IMETHOD_(mozilla::TextEditor*) GetTextEditor() override;
101 : NS_IMETHOD_(nsISelectionController*) GetSelectionController() override;
102 : NS_IMETHOD_(nsFrameSelection*) GetConstFrameSelection() override;
103 : NS_IMETHOD BindToFrame(nsTextControlFrame* aFrame) override;
104 : NS_IMETHOD_(void) UnbindFromFrame(nsTextControlFrame* aFrame) override;
105 : NS_IMETHOD CreateEditor() override;
106 : NS_IMETHOD_(Element*) GetRootEditorNode() override;
107 : NS_IMETHOD_(Element*) CreatePlaceholderNode() override;
108 : NS_IMETHOD_(Element*) GetPlaceholderNode() override;
109 : NS_IMETHOD_(Element*) CreatePreviewNode() override;
110 : NS_IMETHOD_(Element*) GetPreviewNode() override;
111 : NS_IMETHOD_(void) UpdateOverlayTextVisibility(bool aNotify) override;
112 : NS_IMETHOD_(bool) GetPlaceholderVisibility() override;
113 : NS_IMETHOD_(bool) GetPreviewVisibility() override;
114 : NS_IMETHOD_(void) SetPreviewValue(const nsAString& aValue) override;
115 : NS_IMETHOD_(void) GetPreviewValue(nsAString& aValue) override;
116 : NS_IMETHOD_(void) EnablePreview() override;
117 : NS_IMETHOD_(bool) IsPreviewEnabled() override;
118 : NS_IMETHOD_(void) InitializeKeyboardEventListeners() override;
119 : NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) override;
120 : virtual void GetValueFromSetRangeText(nsAString& aValue) override;
121 : virtual nsresult SetValueFromSetRangeText(const nsAString& aValue) override;
122 : NS_IMETHOD_(bool) HasCachedSelection() override;
123 :
124 :
125 : // nsIContent
126 : virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
127 : nsIContent* aBindingParent,
128 : bool aCompileEventHandlers) override;
129 : virtual void UnbindFromTree(bool aDeep = true,
130 : bool aNullParent = true) override;
131 : virtual bool ParseAttribute(int32_t aNamespaceID,
132 : nsIAtom* aAttribute,
133 : const nsAString& aValue,
134 : nsAttrValue& aResult) override;
135 : virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
136 : virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
137 : int32_t aModType) const override;
138 : NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
139 :
140 : virtual nsresult GetEventTargetParent(
141 : EventChainPreVisitor& aVisitor) override;
142 : virtual nsresult PreHandleEvent(EventChainVisitor& aVisitor) override;
143 : virtual nsresult PostHandleEvent(
144 : EventChainPostVisitor& aVisitor) override;
145 :
146 : virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
147 :
148 : virtual void DoneAddingChildren(bool aHaveNotified) override;
149 : virtual bool IsDoneAddingChildren() override;
150 :
151 : virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
152 : bool aPreallocateChildren) const override;
153 :
154 : nsresult CopyInnerTo(Element* aDest, bool aPreallocateChildren);
155 :
156 : /**
157 : * Called when an attribute is about to be changed
158 : */
159 : virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
160 : const nsAttrValueOrString* aValue,
161 : bool aNotify) override;
162 :
163 : // nsIMutationObserver
164 : NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
165 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
166 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
167 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
168 :
169 1 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTextAreaElement,
170 : nsGenericHTMLFormElementWithState)
171 :
172 : // nsIConstraintValidation
173 : bool IsTooLong();
174 : bool IsTooShort();
175 : bool IsValueMissing() const;
176 : void UpdateTooLongValidityState();
177 : void UpdateTooShortValidityState();
178 : void UpdateValueMissingValidityState();
179 : void UpdateBarredFromConstraintValidation();
180 : nsresult GetValidationMessage(nsAString& aValidationMessage,
181 : ValidityStateType aType) override;
182 :
183 : // Web IDL binding methods
184 0 : bool Autofocus()
185 : {
186 0 : return GetBoolAttr(nsGkAtoms::autofocus);
187 : }
188 0 : void SetAutofocus(bool aAutoFocus, ErrorResult& aError)
189 : {
190 0 : SetHTMLBoolAttr(nsGkAtoms::autofocus, aAutoFocus, aError);
191 0 : }
192 0 : uint32_t Cols()
193 : {
194 0 : return GetIntAttr(nsGkAtoms::cols, DEFAULT_COLS);
195 : }
196 0 : void SetCols(uint32_t aCols, ErrorResult& aError)
197 : {
198 0 : uint32_t cols = aCols ? aCols : DEFAULT_COLS;
199 0 : SetUnsignedIntAttr(nsGkAtoms::cols, cols, DEFAULT_COLS, aError);
200 0 : }
201 0 : bool Disabled()
202 : {
203 0 : return GetBoolAttr(nsGkAtoms::disabled);
204 : }
205 0 : void SetDisabled(bool aDisabled, ErrorResult& aError)
206 : {
207 0 : SetHTMLBoolAttr(nsGkAtoms::disabled, aDisabled, aError);
208 0 : }
209 : // nsGenericHTMLFormElementWithState::GetForm is fine
210 : using nsGenericHTMLFormElementWithState::GetForm;
211 0 : int32_t MaxLength()
212 : {
213 0 : return GetIntAttr(nsGkAtoms::maxlength, -1);
214 : }
215 0 : void SetMaxLength(int32_t aMaxLength, ErrorResult& aError)
216 : {
217 0 : int32_t minLength = MinLength();
218 0 : if (aMaxLength < 0 || (minLength >= 0 && aMaxLength < minLength)) {
219 0 : aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
220 : } else {
221 0 : SetHTMLIntAttr(nsGkAtoms::maxlength, aMaxLength, aError);
222 : }
223 0 : }
224 0 : int32_t MinLength()
225 : {
226 0 : return GetIntAttr(nsGkAtoms::minlength, -1);
227 : }
228 0 : void SetMinLength(int32_t aMinLength, ErrorResult& aError)
229 : {
230 0 : int32_t maxLength = MaxLength();
231 0 : if (aMinLength < 0 || (maxLength >= 0 && aMinLength > maxLength)) {
232 0 : aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
233 : } else {
234 0 : SetHTMLIntAttr(nsGkAtoms::minlength, aMinLength, aError);
235 : }
236 0 : }
237 : // XPCOM GetName is fine
238 0 : void SetName(const nsAString& aName, ErrorResult& aError)
239 : {
240 0 : SetHTMLAttr(nsGkAtoms::name, aName, aError);
241 0 : }
242 : // XPCOM GetPlaceholder is fine
243 0 : void SetPlaceholder(const nsAString& aPlaceholder, ErrorResult& aError)
244 : {
245 0 : SetHTMLAttr(nsGkAtoms::placeholder, aPlaceholder, aError);
246 0 : }
247 0 : bool ReadOnly()
248 : {
249 0 : return GetBoolAttr(nsGkAtoms::readonly);
250 : }
251 0 : void SetReadOnly(bool aReadOnly, ErrorResult& aError)
252 : {
253 0 : SetHTMLBoolAttr(nsGkAtoms::readonly, aReadOnly, aError);
254 0 : }
255 0 : bool Required()
256 : {
257 0 : return GetBoolAttr(nsGkAtoms::required);
258 : }
259 :
260 : void SetRangeText(const nsAString& aReplacement, ErrorResult& aRv);
261 :
262 : void SetRangeText(const nsAString& aReplacement, uint32_t aStart,
263 : uint32_t aEnd, SelectionMode aSelectMode,
264 : ErrorResult& aRv);
265 :
266 0 : void SetRequired(bool aRequired, ErrorResult& aError)
267 : {
268 0 : SetHTMLBoolAttr(nsGkAtoms::required, aRequired, aError);
269 0 : }
270 0 : uint32_t Rows()
271 : {
272 0 : return GetIntAttr(nsGkAtoms::rows, DEFAULT_ROWS_TEXTAREA);
273 : }
274 0 : void SetRows(uint32_t aRows, ErrorResult& aError)
275 : {
276 0 : uint32_t rows = aRows ? aRows : DEFAULT_ROWS_TEXTAREA;
277 0 : SetUnsignedIntAttr(nsGkAtoms::rows, rows, DEFAULT_ROWS_TEXTAREA, aError);
278 0 : }
279 : // XPCOM GetWrap is fine
280 0 : void SetWrap(const nsAString& aWrap, ErrorResult& aError)
281 : {
282 0 : SetHTMLAttr(nsGkAtoms::wrap, aWrap, aError);
283 0 : }
284 : // XPCOM GetType is fine
285 : // XPCOM GetDefaultValue is fine
286 : void SetDefaultValue(const nsAString& aDefaultValue, ErrorResult& aError);
287 : // XPCOM GetValue/SetValue are fine
288 : uint32_t GetTextLength();
289 : // nsIConstraintValidation::WillValidate is fine.
290 : // nsIConstraintValidation::Validity() is fine.
291 : // nsIConstraintValidation::GetValidationMessage() is fine.
292 : // nsIConstraintValidation::CheckValidity() is fine.
293 : using nsIConstraintValidation::CheckValidity;
294 : using nsIConstraintValidation::ReportValidity;
295 : // nsIConstraintValidation::SetCustomValidity() is fine.
296 : // XPCOM Select is fine
297 : Nullable<uint32_t> GetSelectionStart(ErrorResult& aError);
298 : void SetSelectionStart(const Nullable<uint32_t>& aSelectionStart, ErrorResult& aError);
299 : Nullable<uint32_t> GetSelectionEnd(ErrorResult& aError);
300 : void SetSelectionEnd(const Nullable<uint32_t>& aSelectionEnd, ErrorResult& aError);
301 : void GetSelectionDirection(nsAString& aDirection, ErrorResult& aError);
302 : void SetSelectionDirection(const nsAString& aDirection, ErrorResult& aError);
303 : void SetSelectionRange(uint32_t aSelectionStart, uint32_t aSelectionEnd, const Optional<nsAString>& aDirecton, ErrorResult& aError);
304 : nsIControllers* GetControllers(ErrorResult& aError);
305 0 : nsIEditor* GetEditor()
306 : {
307 0 : return mState.GetTextEditor();
308 : }
309 :
310 : protected:
311 0 : virtual ~HTMLTextAreaElement() {}
312 :
313 : // get rid of the compiler warning
314 : using nsGenericHTMLFormElementWithState::IsSingleLineTextControl;
315 :
316 : virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
317 :
318 : nsCOMPtr<nsIControllers> mControllers;
319 : /** Whether or not the value has changed since its default value was given. */
320 : bool mValueChanged;
321 : /** Whether or not the last change to the value was made interactively by the user. */
322 : bool mLastValueChangeWasInteractive;
323 : /** Whether or not we are already handling select event. */
324 : bool mHandlingSelect;
325 : /** Whether or not we are done adding children (always true if not
326 : created by a parser */
327 : bool mDoneAddingChildren;
328 : /** Whether state restoration should be inhibited in DoneAddingChildren. */
329 : bool mInhibitStateRestoration;
330 : /** Whether our disabled state has changed from the default **/
331 : bool mDisabledChanged;
332 : /** Whether we should make :-moz-ui-invalid apply on the element. **/
333 : bool mCanShowInvalidUI;
334 : /** Whether we should make :-moz-ui-valid apply on the element. **/
335 : bool mCanShowValidUI;
336 : bool mIsPreviewEnabled;
337 :
338 : void FireChangeEventIfNeeded();
339 :
340 : nsString mFocusedValue;
341 :
342 : /** The state of the text editor (selection controller and the editor) **/
343 : nsTextEditorState mState;
344 :
345 : NS_IMETHOD SelectAll(nsPresContext* aPresContext);
346 : /**
347 : * Get the value, whether it is from the content or the frame.
348 : * @param aValue the value [out]
349 : * @param aIgnoreWrap whether to ignore the wrap attribute when getting the
350 : * value. If this is true, linebreaks will not be inserted even if
351 : * wrap=hard.
352 : */
353 : void GetValueInternal(nsAString& aValue, bool aIgnoreWrap) const;
354 :
355 : /**
356 : * Setting the value.
357 : *
358 : * @param aValue String to set.
359 : * @param aFlags See nsTextEditorState::SetValueFlags.
360 : */
361 : nsresult SetValueInternal(const nsAString& aValue, uint32_t aFlags);
362 :
363 : /**
364 : * Common method to call from the various mutation observer methods.
365 : * aContent is a content node that's either the one that changed or its
366 : * parent; we should only respond to the change if aContent is non-anonymous.
367 : */
368 : void ContentChanged(nsIContent* aContent);
369 :
370 : virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom *aName,
371 : const nsAttrValue* aValue,
372 : const nsAttrValue* aOldValue,
373 : bool aNotify) override;
374 :
375 : /**
376 : * Return if an element should have a specific validity UI
377 : * (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
378 : *
379 : * @return Whether the element should have a validity UI.
380 : */
381 6 : bool ShouldShowValidityUI() const {
382 : /**
383 : * Always show the validity UI if the form has already tried to be submitted
384 : * but was invalid.
385 : *
386 : * Otherwise, show the validity UI if the element's value has been changed.
387 : */
388 :
389 6 : if (mForm && mForm->HasEverTriedInvalidSubmit()) {
390 0 : return true;
391 : }
392 :
393 6 : return mValueChanged;
394 : }
395 :
396 : /**
397 : * Get the mutable state of the element.
398 : */
399 : bool IsMutable() const;
400 :
401 : /**
402 : * Returns whether the current value is the empty string.
403 : *
404 : * @return whether the current value is the empty string.
405 : */
406 : bool IsValueEmpty() const;
407 :
408 : /**
409 : * A helper to get the current selection range. Will throw on the ErrorResult
410 : * if we have no editor state.
411 : */
412 : void GetSelectionRange(uint32_t* aSelectionStart,
413 : uint32_t* aSelectionEnd,
414 : ErrorResult& aRv);
415 : private:
416 : static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
417 : GenericSpecifiedValues* aGenericData);
418 : };
419 :
420 : } // namespace dom
421 : } // namespace mozilla
422 :
423 : #endif
424 :
|