Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/html/HTMLInputElement.h
Line
Count
Source (jump to first uncovered line)
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_HTMLInputElement_h
8
#define mozilla_dom_HTMLInputElement_h
9
10
#include "mozilla/Attributes.h"
11
#include "nsGenericHTMLElement.h"
12
#include "nsImageLoadingContent.h"
13
#include "nsITextControlElement.h"
14
#include "nsITimer.h"
15
#include "nsCOMPtr.h"
16
#include "nsIConstraintValidation.h"
17
#include "mozilla/UniquePtr.h"
18
#include "mozilla/dom/BindingDeclarations.h"
19
#include "mozilla/dom/HTMLFormElement.h" // for HasEverTriedInvalidSubmit()
20
#include "mozilla/dom/HTMLInputElementBinding.h"
21
#include "mozilla/dom/Promise.h"
22
#include "mozilla/dom/UnionTypes.h"
23
#include "nsIFilePicker.h"
24
#include "nsIContentPrefService2.h"
25
#include "mozilla/Decimal.h"
26
#include "nsContentUtils.h"
27
#include "nsTextEditorState.h"
28
#include "mozilla/Variant.h"
29
#include "SingleLineTextInputTypes.h"
30
#include "NumericInputTypes.h"
31
#include "CheckableInputTypes.h"
32
#include "ButtonInputTypes.h"
33
#include "DateTimeInputTypes.h"
34
#include "ColorInputType.h"
35
#include "FileInputType.h"
36
#include "HiddenInputType.h"
37
38
static constexpr size_t INPUT_TYPE_SIZE = sizeof(
39
  mozilla::Variant<TextInputType, SearchInputType, TelInputType, URLInputType,
40
                   EmailInputType, PasswordInputType, NumberInputType,
41
                   RangeInputType, RadioInputType, CheckboxInputType,
42
                   ButtonInputType, ImageInputType, ResetInputType,
43
                   SubmitInputType, DateInputType, TimeInputType, WeekInputType,
44
                   MonthInputType, DateTimeLocalInputType, FileInputType,
45
                   ColorInputType, HiddenInputType> );
46
47
class InputType;
48
struct DoNotDelete;
49
class nsIRadioGroupContainer;
50
class nsIRadioVisitor;
51
52
namespace mozilla {
53
54
class EventChainPostVisitor;
55
class EventChainPreVisitor;
56
57
namespace dom {
58
59
class AfterSetFilesOrDirectoriesRunnable;
60
class Date;
61
class DispatchChangeEventCallback;
62
class File;
63
class FileList;
64
class FileSystemEntry;
65
class GetFilesHelper;
66
67
/**
68
 * A class we use to create a singleton object that is used to keep track of
69
 * the last directory from which the user has picked files (via
70
 * <input type=file>) on a per-domain basis. The implementation uses
71
 * nsIContentPrefService2/NS_CONTENT_PREF_SERVICE_CONTRACTID to store the last
72
 * directory per-domain, and to ensure that whether the directories are
73
 * persistently saved (saved across sessions) or not honors whether or not the
74
 * page is being viewed in private browsing.
75
 */
76
class UploadLastDir final : public nsIObserver, public nsSupportsWeakReference
77
{
78
  ~UploadLastDir() {}
79
80
public:
81
  NS_DECL_ISUPPORTS
82
  NS_DECL_NSIOBSERVER
83
84
  /**
85
   * Fetch the last used directory for this location from the content
86
   * pref service, and display the file picker opened in that directory.
87
   *
88
   * @param aDoc          current document
89
   * @param aFilePicker   the file picker to open
90
   * @param aFpCallback   the callback object to be run when the file is shown.
91
   */
92
  nsresult FetchDirectoryAndDisplayPicker(nsIDocument* aDoc,
93
                                          nsIFilePicker* aFilePicker,
94
                                          nsIFilePickerShownCallback* aFpCallback);
95
96
  /**
97
   * Store the last used directory for this location using the
98
   * content pref service, if it is available
99
   * @param aURI URI of the current page
100
   * @param aDir Parent directory of the file(s)/directory chosen by the user
101
   */
102
  nsresult StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aDir);
103
104
  class ContentPrefCallback final : public nsIContentPrefCallback2
105
  {
106
    virtual ~ContentPrefCallback()
107
    { }
108
109
  public:
110
    ContentPrefCallback(nsIFilePicker* aFilePicker, nsIFilePickerShownCallback* aFpCallback)
111
    : mFilePicker(aFilePicker)
112
    , mFpCallback(aFpCallback)
113
    { }
114
115
    NS_DECL_ISUPPORTS
116
    NS_DECL_NSICONTENTPREFCALLBACK2
117
118
    nsCOMPtr<nsIFilePicker> mFilePicker;
119
    nsCOMPtr<nsIFilePickerShownCallback> mFpCallback;
120
    nsCOMPtr<nsIContentPref> mResult;
121
  };
122
};
123
124
class HTMLInputElement final : public nsGenericHTMLFormElementWithState,
125
                               public nsImageLoadingContent,
126
                               public nsITextControlElement,
127
                               public nsIConstraintValidation
128
{
129
  friend class AfterSetFilesOrDirectoriesCallback;
130
  friend class DispatchChangeEventCallback;
131
  friend class ::InputType;
132
133
public:
134
  using nsIConstraintValidation::GetValidationMessage;
135
  using nsGenericHTMLFormElementWithState::GetForm;
136
  using nsGenericHTMLFormElementWithState::GetFormAction;
137
138
  enum class FromClone { no, yes };
139
140
  HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
141
                   mozilla::dom::FromParser aFromParser,
142
                   FromClone aFromClone = FromClone::no);
143
144
  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLInputElement, input)
145
146
  // nsISupports
147
  NS_DECL_ISUPPORTS_INHERITED
148
149
  virtual int32_t TabIndexDefault() override;
150
  using nsGenericHTMLElement::Focus;
151
  virtual void Blur(ErrorResult& aError) override;
152
  virtual void Focus(ErrorResult& aError) override;
153
154
  // nsINode
155
#if !defined(ANDROID) && !defined(XP_MACOSX)
156
  virtual bool IsNodeApzAwareInternal() const override;
157
#endif
158
159
  // Element
160
  virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
161
162
  // EventTarget
163
  virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
164
165
  // Overriden nsIFormControl methods
166
  NS_IMETHOD Reset() override;
167
  NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
168
  NS_IMETHOD SaveState() override;
169
  virtual bool RestoreState(PresState* aState) override;
170
  virtual bool AllowDrop() override;
171
  virtual bool IsDisabledForEvents(EventMessage aMessage) override;
172
173
  virtual void FieldSetDisabledChanged(bool aNotify) override;
174
175
  // nsIContent
176
  virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
177
178
  virtual bool ParseAttribute(int32_t aNamespaceID,
179
                                nsAtom* aAttribute,
180
                                const nsAString& aValue,
181
                                nsIPrincipal* aMaybeScriptedPrincipal,
182
                                nsAttrValue& aResult) override;
183
  virtual nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
184
                                              int32_t aModType) const override;
185
  NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
186
  virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
187
188
  void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
189
  virtual nsresult PreHandleEvent(EventChainVisitor& aVisitor) override;
190
  virtual nsresult PostHandleEvent(
191
                     EventChainPostVisitor& aVisitor) override;
192
  void PostHandleEventForRangeThumb(EventChainPostVisitor& aVisitor);
193
  void StartRangeThumbDrag(WidgetGUIEvent* aEvent);
194
  void FinishRangeThumbDrag(WidgetGUIEvent* aEvent = nullptr);
195
  void CancelRangeThumbDrag(bool aIsForUserEvent = true);
196
  void SetValueOfRangeForUserEvent(Decimal aValue);
197
198
  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
199
                              nsIContent* aBindingParent) override;
200
  virtual void UnbindFromTree(bool aDeep = true,
201
                              bool aNullParent = true) override;
202
203
  virtual void DoneCreatingElement() override;
204
205
  virtual EventStates IntrinsicState() const override;
206
207
  // Element
208
private:
209
  virtual void AddStates(EventStates aStates) override;
210
  virtual void RemoveStates(EventStates aStates) override;
211
212
public:
213
214
  // nsITextControlElement
215
  NS_IMETHOD SetValueChanged(bool aValueChanged) override;
216
  NS_IMETHOD_(bool) IsSingleLineTextControl() const override;
217
  NS_IMETHOD_(bool) IsTextArea() const override;
218
  NS_IMETHOD_(bool) IsPasswordTextControl() const override;
219
  NS_IMETHOD_(int32_t) GetCols() override;
220
  NS_IMETHOD_(int32_t) GetWrapCols() override;
221
  NS_IMETHOD_(int32_t) GetRows() override;
222
  NS_IMETHOD_(void) GetDefaultValueFromContent(nsAString& aValue) override;
223
  NS_IMETHOD_(bool) ValueChanged() const override;
224
  NS_IMETHOD_(void) GetTextEditorValue(nsAString& aValue, bool aIgnoreWrap) const override;
225
  NS_IMETHOD_(mozilla::TextEditor*) GetTextEditor() override;
226
  NS_IMETHOD_(nsISelectionController*) GetSelectionController() override;
227
  NS_IMETHOD_(nsFrameSelection*) GetConstFrameSelection() override;
228
  NS_IMETHOD BindToFrame(nsTextControlFrame* aFrame) override;
229
  NS_IMETHOD_(void) UnbindFromFrame(nsTextControlFrame* aFrame) override;
230
  NS_IMETHOD CreateEditor() override;
231
  NS_IMETHOD_(void) UpdateOverlayTextVisibility(bool aNotify) override;
232
  NS_IMETHOD_(void) SetPreviewValue(const nsAString& aValue) override;
233
  NS_IMETHOD_(void) GetPreviewValue(nsAString& aValue) override;
234
  NS_IMETHOD_(void) EnablePreview() override;
235
  NS_IMETHOD_(bool) IsPreviewEnabled() override;
236
  NS_IMETHOD_(bool) GetPlaceholderVisibility() override;
237
  NS_IMETHOD_(bool) GetPreviewVisibility() override;
238
  NS_IMETHOD_(void) InitializeKeyboardEventListeners() override;
239
  NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) override;
240
  virtual void GetValueFromSetRangeText(nsAString& aValue) override;
241
  virtual nsresult SetValueFromSetRangeText(const nsAString& aValue) override;
242
  NS_IMETHOD_(bool) HasCachedSelection() override;
243
244
  // Methods for nsFormFillController so it can do selection operations on input
245
  // types the HTML spec doesn't support them on, like "email".
246
  uint32_t GetSelectionStartIgnoringType(ErrorResult& aRv);
247
  uint32_t GetSelectionEndIgnoringType(ErrorResult& aRv);
248
249
  void GetDisplayFileName(nsAString& aFileName) const;
250
251
  const nsTArray<OwningFileOrDirectory>& GetFilesOrDirectoriesInternal() const;
252
253
  void SetFilesOrDirectories(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories,
254
                             bool aSetValueChanged);
255
  void SetFiles(FileList* aFiles, bool aSetValueChanged);
256
257
  // This method is used for test only. Onces the data is set, a 'change' event
258
  // is dispatched.
259
  void MozSetDndFilesAndDirectories(const nsTArray<OwningFileOrDirectory>& aSequence);
260
261
  // Called when a nsIFilePicker or a nsIColorPicker terminate.
262
  void PickerClosed();
263
264
  void SetCheckedChangedInternal(bool aCheckedChanged);
265
  bool GetCheckedChanged() const {
266
    return mCheckedChanged;
267
  }
268
  void AddedToRadioGroup();
269
  void WillRemoveFromRadioGroup();
270
271
 /**
272
   * Helper function returning the currently selected button in the radio group.
273
   * Returning null if the element is not a button or if there is no selectied
274
   * button in the group.
275
   *
276
   * @return the selected button (or null).
277
   */
278
  HTMLInputElement* GetSelectedRadioButton() const;
279
280
  virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
281
282
  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLInputElement,
283
                                           nsGenericHTMLFormElementWithState)
284
285
  static UploadLastDir* gUploadLastDir;
286
  // create and destroy the static UploadLastDir object for remembering
287
  // which directory was last used on a site-by-site basis
288
  static void InitUploadLastDir();
289
  static void DestroyUploadLastDir();
290
291
  //If the valueAsDate attribute should be enabled in webIDL
292
  static bool ValueAsDateEnabled(JSContext* cx, JSObject* obj);
293
294
  void MaybeLoadImage();
295
296
  void SetSelectionCached()
297
  {
298
    MOZ_ASSERT(mType == NS_FORM_INPUT_NUMBER);
299
    mSelectionCached = true;
300
  }
301
  bool IsSelectionCached() const
302
  {
303
    MOZ_ASSERT(mType == NS_FORM_INPUT_NUMBER);
304
    return mSelectionCached;
305
  }
306
  void ClearSelectionCached()
307
  {
308
    MOZ_ASSERT(mType == NS_FORM_INPUT_NUMBER);
309
    mSelectionCached = false;
310
  }
311
  nsTextEditorState::SelectionProperties& GetSelectionProperties()
312
  {
313
    MOZ_ASSERT(mType == NS_FORM_INPUT_NUMBER);
314
    return mSelectionProperties;
315
  }
316
317
  bool HasPatternAttribute() const
318
  {
319
    return mHasPatternAttribute;
320
  }
321
322
  // nsIConstraintValidation
323
  bool     IsTooLong();
324
  bool     IsTooShort();
325
  bool     IsValueMissing() const;
326
  bool     HasTypeMismatch() const;
327
  bool     HasPatternMismatch() const;
328
  bool     IsRangeOverflow() const;
329
  bool     IsRangeUnderflow() const;
330
  bool     HasStepMismatch(bool aUseZeroIfValueNaN = false) const;
331
  bool     HasBadInput() const;
332
  void     UpdateTooLongValidityState();
333
  void     UpdateTooShortValidityState();
334
  void     UpdateValueMissingValidityState();
335
  void     UpdateTypeMismatchValidityState();
336
  void     UpdatePatternMismatchValidityState();
337
  void     UpdateRangeOverflowValidityState();
338
  void     UpdateRangeUnderflowValidityState();
339
  void     UpdateStepMismatchValidityState();
340
  void     UpdateBadInputValidityState();
341
  // Update all our validity states and then update our element state
342
  // as needed.  aNotify controls whether the element state update
343
  // needs to notify.
344
  void     UpdateAllValidityStates(bool aNotify);
345
  // Update all our validity states without updating element state.
346
  // This should be called instead of UpdateAllValidityStates any time
347
  // we're guaranteed that element state will be updated anyway.
348
  void     UpdateAllValidityStatesButNotElementState();
349
  void     UpdateBarredFromConstraintValidation();
350
  nsresult GetValidationMessage(nsAString& aValidationMessage,
351
                                ValidityStateType aType) override;
352
353
  // Override SetCustomValidity so we update our state properly when it's called
354
  // via bindings.
355
  void SetCustomValidity(const nsAString& aError);
356
357
  /**
358
   * Update the value missing validity state for radio elements when they have
359
   * a group.
360
   *
361
   * @param aIgnoreSelf Whether the required attribute and the checked state
362
   * of the current radio should be ignored.
363
   * @note This method shouldn't be called if the radio element hasn't a group.
364
   */
365
  void     UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf);
366
367
  /**
368
   * Set filters to the filePicker according to the accept attribute value.
369
   *
370
   * See:
371
   * http://dev.w3.org/html5/spec/forms.html#attr-input-accept
372
   *
373
   * @note You should not call this function if the element has no @accept.
374
   * @note "All Files" filter is always set, no matter if there is a valid
375
   * filter specified or not.
376
   * @note If more than one valid filter is found, the "All Supported Types"
377
   * filter is added, which is the concatenation of all valid filters.
378
   * @note Duplicate filters and similar filters (i.e. filters whose file
379
   * extensions already exist in another filter) are ignored.
380
   * @note "All Files" filter will be selected by default if unknown mime types
381
   * have been specified and no file extension filter has been specified.
382
   * Otherwise, specified filter or "All Supported Types" filter will be
383
   * selected by default.
384
   * The logic behind is that having unknown mime type means we might restrict
385
   * user's input too much, as some filters will be missing.
386
   * However, if author has also specified some file extension filters, it's
387
   * likely those are fallback for the unusual mime type we haven't been able
388
   * to resolve; so it's better to select author specified filters in that case.
389
   */
390
  void SetFilePickerFiltersFromAccept(nsIFilePicker* filePicker);
391
392
  /**
393
   * The form might need to request an update of the UI bits
394
   * (BF_CAN_SHOW_INVALID_UI and BF_CAN_SHOW_VALID_UI) when an invalid form
395
   * submission is tried.
396
   *
397
   * @param aIsFocused Whether the element is currently focused.
398
   *
399
   * @note The caller is responsible to call ContentStatesChanged.
400
   */
401
  void UpdateValidityUIBits(bool aIsFocused);
402
403
  /**
404
   * Fires change event if mFocusedValue and current value held are unequal.
405
   */
406
  void FireChangeEventIfNeeded();
407
408
  /**
409
   * Returns the input element's value as a Decimal.
410
   * Returns NaN if the current element's value is not a floating point number.
411
   *
412
   * @return the input element's value as a Decimal.
413
   */
414
  Decimal GetValueAsDecimal() const;
415
416
  /**
417
   * Returns the input's "minimum" (as defined by the HTML5 spec) as a double.
418
   * Note this takes account of any default minimum that the type may have.
419
   * Returns NaN if the min attribute isn't a valid floating point number and
420
   * the input's type does not have a default minimum.
421
   *
422
   * NOTE: Only call this if you know DoesMinMaxApply() returns true.
423
   */
424
  Decimal GetMinimum() const;
425
426
  /**
427
   * Returns the input's "maximum" (as defined by the HTML5 spec) as a double.
428
   * Note this takes account of any default maximum that the type may have.
429
   * Returns NaN if the max attribute isn't a valid floating point number and
430
   * the input's type does not have a default maximum.
431
   *
432
   * NOTE:Only call this if you know DoesMinMaxApply() returns true.
433
   */
434
  Decimal GetMaximum() const;
435
436
  // WebIDL
437
438
  void GetAccept(nsAString& aValue)
439
  {
440
    GetHTMLAttr(nsGkAtoms::accept, aValue);
441
  }
442
  void SetAccept(const nsAString& aValue, ErrorResult& aRv)
443
  {
444
    SetHTMLAttr(nsGkAtoms::accept, aValue, aRv);
445
  }
446
447
  void GetAlt(nsAString& aValue)
448
  {
449
    GetHTMLAttr(nsGkAtoms::alt, aValue);
450
  }
451
  void SetAlt(const nsAString& aValue, ErrorResult& aRv)
452
  {
453
    SetHTMLAttr(nsGkAtoms::alt, aValue, aRv);
454
  }
455
456
  void GetAutocomplete(nsAString& aValue);
457
  void SetAutocomplete(const nsAString& aValue, ErrorResult& aRv)
458
  {
459
    SetHTMLAttr(nsGkAtoms::autocomplete, aValue, aRv);
460
  }
461
462
  void GetAutocompleteInfo(Nullable<AutocompleteInfo>& aInfo);
463
464
  bool Autofocus() const
465
  {
466
    return GetBoolAttr(nsGkAtoms::autofocus);
467
  }
468
469
  void SetAutofocus(bool aValue, ErrorResult& aRv)
470
  {
471
    SetHTMLBoolAttr(nsGkAtoms::autofocus, aValue, aRv);
472
  }
473
474
  bool DefaultChecked() const
475
  {
476
    return HasAttr(kNameSpaceID_None, nsGkAtoms::checked);
477
  }
478
479
  void SetDefaultChecked(bool aValue, ErrorResult& aRv)
480
  {
481
    SetHTMLBoolAttr(nsGkAtoms::checked, aValue, aRv);
482
  }
483
484
  bool Checked() const
485
  {
486
    return mChecked;
487
  }
488
  void SetChecked(bool aChecked);
489
490
  bool Disabled() const
491
  {
492
    return GetBoolAttr(nsGkAtoms::disabled);
493
  }
494
495
  void SetDisabled(bool aValue, ErrorResult& aRv)
496
  {
497
    SetHTMLBoolAttr(nsGkAtoms::disabled, aValue, aRv);
498
  }
499
500
  FileList* GetFiles();
501
  void SetFiles(FileList* aFiles);
502
503
  void SetFormAction(const nsAString& aValue, ErrorResult& aRv)
504
  {
505
    SetHTMLAttr(nsGkAtoms::formaction, aValue, aRv);
506
  }
507
508
  void GetFormEnctype(nsAString& aValue);
509
  void SetFormEnctype(const nsAString& aValue, ErrorResult& aRv)
510
  {
511
    SetHTMLAttr(nsGkAtoms::formenctype, aValue, aRv);
512
  }
513
514
  void GetFormMethod(nsAString& aValue);
515
  void SetFormMethod(const nsAString& aValue, ErrorResult& aRv)
516
  {
517
    SetHTMLAttr(nsGkAtoms::formmethod, aValue, aRv);
518
  }
519
520
  bool FormNoValidate() const
521
  {
522
    return GetBoolAttr(nsGkAtoms::formnovalidate);
523
  }
524
525
  void SetFormNoValidate(bool aValue, ErrorResult& aRv)
526
  {
527
    SetHTMLBoolAttr(nsGkAtoms::formnovalidate, aValue, aRv);
528
  }
529
530
  void GetFormTarget(nsAString& aValue)
531
  {
532
    GetHTMLAttr(nsGkAtoms::formtarget, aValue);
533
  }
534
  void SetFormTarget(const nsAString& aValue, ErrorResult& aRv)
535
  {
536
    SetHTMLAttr(nsGkAtoms::formtarget, aValue, aRv);
537
  }
538
539
  MOZ_CAN_RUN_SCRIPT uint32_t Height();
540
541
  void SetHeight(uint32_t aValue, ErrorResult& aRv)
542
  {
543
    SetUnsignedIntAttr(nsGkAtoms::height, aValue, 0, aRv);
544
  }
545
546
  bool Indeterminate() const
547
  {
548
    return mIndeterminate;
549
  }
550
551
  bool IsDraggingRange() const
552
  {
553
    return mIsDraggingRange;
554
  }
555
  void SetIndeterminate(bool aValue);
556
557
  void GetInputMode(nsAString& aValue);
558
  void SetInputMode(const nsAString& aValue, ErrorResult& aRv)
559
  {
560
    SetHTMLAttr(nsGkAtoms::inputmode, aValue, aRv);
561
  }
562
563
  nsGenericHTMLElement* GetList() const;
564
565
  void GetMax(nsAString& aValue)
566
  {
567
    GetHTMLAttr(nsGkAtoms::max, aValue);
568
  }
569
  void SetMax(const nsAString& aValue, ErrorResult& aRv)
570
  {
571
    SetHTMLAttr(nsGkAtoms::max, aValue, aRv);
572
  }
573
574
  int32_t MaxLength() const
575
  {
576
    return GetIntAttr(nsGkAtoms::maxlength, -1);
577
  }
578
579
  void SetMaxLength(int32_t aValue, ErrorResult& aRv)
580
  {
581
    int32_t minLength = MinLength();
582
    if (aValue < 0 || (minLength >= 0 && aValue < minLength)) {
583
      aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
584
      return;
585
    }
586
587
    SetHTMLIntAttr(nsGkAtoms::maxlength, aValue, aRv);
588
  }
589
590
  int32_t MinLength() const
591
  {
592
    return GetIntAttr(nsGkAtoms::minlength, -1);
593
  }
594
595
  void SetMinLength(int32_t aValue, ErrorResult& aRv)
596
  {
597
    int32_t maxLength = MaxLength();
598
    if (aValue < 0 || (maxLength >= 0 && aValue > maxLength)) {
599
      aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
600
      return;
601
    }
602
603
    SetHTMLIntAttr(nsGkAtoms::minlength, aValue, aRv);
604
  }
605
606
  void GetMin(nsAString& aValue)
607
  {
608
    GetHTMLAttr(nsGkAtoms::min, aValue);
609
  }
610
  void SetMin(const nsAString& aValue, ErrorResult& aRv)
611
  {
612
    SetHTMLAttr(nsGkAtoms::min, aValue, aRv);
613
  }
614
615
  bool Multiple() const
616
  {
617
    return GetBoolAttr(nsGkAtoms::multiple);
618
  }
619
620
  void SetMultiple(bool aValue, ErrorResult& aRv)
621
  {
622
    SetHTMLBoolAttr(nsGkAtoms::multiple, aValue, aRv);
623
  }
624
625
  void GetName(nsAString& aValue)
626
  {
627
    GetHTMLAttr(nsGkAtoms::name, aValue);
628
  }
629
  void SetName(const nsAString& aValue, ErrorResult& aRv)
630
  {
631
    SetHTMLAttr(nsGkAtoms::name, aValue, aRv);
632
  }
633
634
  void GetPattern(nsAString& aValue)
635
  {
636
    GetHTMLAttr(nsGkAtoms::pattern, aValue);
637
  }
638
  void SetPattern(const nsAString& aValue, ErrorResult& aRv)
639
  {
640
    SetHTMLAttr(nsGkAtoms::pattern, aValue, aRv);
641
  }
642
643
  void GetPlaceholder(nsAString& aValue)
644
  {
645
    GetHTMLAttr(nsGkAtoms::placeholder, aValue);
646
  }
647
  void SetPlaceholder(const nsAString& aValue, ErrorResult& aRv)
648
  {
649
    SetHTMLAttr(nsGkAtoms::placeholder, aValue, aRv);
650
  }
651
652
  bool ReadOnly() const
653
  {
654
    return GetBoolAttr(nsGkAtoms::readonly);
655
  }
656
657
  void SetReadOnly(bool aValue, ErrorResult& aRv)
658
  {
659
    SetHTMLBoolAttr(nsGkAtoms::readonly, aValue, aRv);
660
  }
661
662
  bool Required() const
663
  {
664
    return GetBoolAttr(nsGkAtoms::required);
665
  }
666
667
  void SetRequired(bool aValue, ErrorResult& aRv)
668
  {
669
    SetHTMLBoolAttr(nsGkAtoms::required, aValue, aRv);
670
  }
671
672
  uint32_t Size() const
673
  {
674
    return GetUnsignedIntAttr(nsGkAtoms::size, DEFAULT_COLS);
675
  }
676
677
  void SetSize(uint32_t aValue, ErrorResult& aRv)
678
  {
679
    if (aValue == 0) {
680
      aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
681
      return;
682
    }
683
684
    SetUnsignedIntAttr(nsGkAtoms::size, aValue, DEFAULT_COLS, aRv);
685
  }
686
687
  void GetSrc(nsAString& aValue)
688
  {
689
    GetURIAttr(nsGkAtoms::src, nullptr, aValue);
690
  }
691
  void SetSrc(const nsAString& aValue, nsIPrincipal* aTriggeringPrincipal, ErrorResult& aRv)
692
  {
693
    SetHTMLAttr(nsGkAtoms::src, aValue, aTriggeringPrincipal, aRv);
694
  }
695
696
  void GetStep(nsAString& aValue)
697
  {
698
    GetHTMLAttr(nsGkAtoms::step, aValue);
699
  }
700
  void SetStep(const nsAString& aValue, ErrorResult& aRv)
701
  {
702
    SetHTMLAttr(nsGkAtoms::step, aValue, aRv);
703
  }
704
705
  void GetType(nsAString& aValue);
706
  void SetType(const nsAString& aValue, ErrorResult& aRv)
707
  {
708
    SetHTMLAttr(nsGkAtoms::type, aValue, aRv);
709
  }
710
711
  void GetDefaultValue(nsAString& aValue)
712
  {
713
    GetHTMLAttr(nsGkAtoms::value, aValue);
714
  }
715
  void SetDefaultValue(const nsAString& aValue, ErrorResult& aRv)
716
  {
717
    SetHTMLAttr(nsGkAtoms::value, aValue, aRv);
718
  }
719
720
  void SetValue(const nsAString& aValue, CallerType aCallerType,
721
                ErrorResult& aRv);
722
  void GetValue(nsAString& aValue, CallerType aCallerType);
723
724
  Nullable<Date> GetValueAsDate(ErrorResult& aRv);
725
726
  void SetValueAsDate(const Nullable<Date>& aDate, ErrorResult& aRv);
727
728
  double ValueAsNumber() const
729
  {
730
    return DoesValueAsNumberApply() ? GetValueAsDecimal().toDouble()
731
                                    : UnspecifiedNaN<double>();
732
  }
733
734
  void SetValueAsNumber(double aValue, ErrorResult& aRv);
735
736
  MOZ_CAN_RUN_SCRIPT uint32_t Width();
737
738
  void SetWidth(uint32_t aValue, ErrorResult& aRv)
739
  {
740
    SetUnsignedIntAttr(nsGkAtoms::width, aValue, 0, aRv);
741
  }
742
743
  void StepUp(int32_t aN, ErrorResult& aRv)
744
  {
745
    aRv = ApplyStep(aN);
746
  }
747
748
  void StepDown(int32_t aN, ErrorResult& aRv)
749
  {
750
    aRv = ApplyStep(-aN);
751
  }
752
753
  /**
754
   * Returns the current step value.
755
   * Returns kStepAny if the current step is "any" string.
756
   *
757
   * @return the current step value.
758
   */
759
  Decimal GetStep() const;
760
761
  already_AddRefed<nsINodeList> GetLabels();
762
763
  void Select();
764
765
  Nullable<uint32_t> GetSelectionStart(ErrorResult& aRv);
766
  void SetSelectionStart(const Nullable<uint32_t>& aValue, ErrorResult& aRv);
767
768
  Nullable<uint32_t> GetSelectionEnd(ErrorResult& aRv);
769
  void SetSelectionEnd(const Nullable<uint32_t>& aValue, ErrorResult& aRv);
770
771
  void GetSelectionDirection(nsAString& aValue, ErrorResult& aRv);
772
  void SetSelectionDirection(const nsAString& aValue, ErrorResult& aRv);
773
774
  void SetSelectionRange(uint32_t aStart, uint32_t aEnd,
775
                         const Optional< nsAString >& direction,
776
                         ErrorResult& aRv);
777
778
  void SetRangeText(const nsAString& aReplacement, ErrorResult& aRv);
779
780
  void SetRangeText(const nsAString& aReplacement, uint32_t aStart,
781
                    uint32_t aEnd, SelectionMode aSelectMode,
782
                    ErrorResult& aRv);
783
784
  bool Allowdirs() const
785
  {
786
    return HasAttr(kNameSpaceID_None, nsGkAtoms::allowdirs);
787
  }
788
789
  void SetAllowdirs(bool aValue, ErrorResult& aRv)
790
  {
791
    SetHTMLBoolAttr(nsGkAtoms::allowdirs, aValue, aRv);
792
  }
793
794
  bool WebkitDirectoryAttr() const
795
  {
796
    return HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory);
797
  }
798
799
  void SetWebkitDirectoryAttr(bool aValue, ErrorResult& aRv)
800
  {
801
    SetHTMLBoolAttr(nsGkAtoms::webkitdirectory, aValue, aRv);
802
  }
803
804
  void GetWebkitEntries(nsTArray<RefPtr<FileSystemEntry>>& aSequence);
805
806
  bool IsFilesAndDirectoriesSupported() const;
807
808
  already_AddRefed<Promise> GetFilesAndDirectories(ErrorResult& aRv);
809
810
  already_AddRefed<Promise> GetFiles(bool aRecursiveFlag, ErrorResult& aRv);
811
812
  void ChooseDirectory(ErrorResult& aRv);
813
814
  void GetAlign(nsAString& aValue)
815
  {
816
    GetHTMLAttr(nsGkAtoms::align, aValue);
817
  }
818
  void SetAlign(const nsAString& aValue, ErrorResult& aRv)
819
  {
820
    SetHTMLAttr(nsGkAtoms::align, aValue, aRv);
821
  }
822
823
  void GetUseMap(nsAString& aValue)
824
  {
825
    GetHTMLAttr(nsGkAtoms::usemap, aValue);
826
  }
827
  void SetUseMap(const nsAString& aValue, ErrorResult& aRv)
828
  {
829
    SetHTMLAttr(nsGkAtoms::usemap, aValue, aRv);
830
  }
831
832
  nsIControllers* GetControllers(ErrorResult& aRv);
833
  // XPCOM adapter function widely used throughout code, leaving it as is.
834
  nsresult GetControllers(nsIControllers** aResult);
835
836
  int32_t InputTextLength(CallerType aCallerType);
837
838
  void MozGetFileNameArray(nsTArray<nsString>& aFileNames, ErrorResult& aRv);
839
840
  void MozSetFileNameArray(const Sequence< nsString >& aFileNames, ErrorResult& aRv);
841
  void MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles);
842
  void MozSetDirectory(const nsAString& aDirectoryPath, ErrorResult& aRv);
843
844
  /*
845
   * The following functions are called from datetime picker to let input box
846
   * know the current state of the picker or to update the input box on changes.
847
   */
848
  void GetDateTimeInputBoxValue(DateTimeValue& aValue);
849
  void UpdateDateTimeInputBox(const DateTimeValue& aValue);
850
  void SetDateTimePickerState(bool aOpen);
851
852
  /*
853
   * The following functions are called from datetime input box XBL to control
854
   * and update the picker.
855
   */
856
  void OpenDateTimePicker(const DateTimeValue& aInitialValue);
857
  void UpdateDateTimePicker(const DateTimeValue& aValue);
858
  void CloseDateTimePicker();
859
860
  /*
861
   * Called from datetime input box binding when inner text fields are focused
862
   * or blurred.
863
   */
864
  void SetFocusState(bool aIsFocused);
865
866
  /*
867
   * Called from datetime input box binding when the the user entered value
868
   * becomes valid/invalid.
869
   */
870
  void UpdateValidityState();
871
872
  /*
873
   * The following are called from datetime input box binding to get the
874
   * corresponding computed values.
875
   */
876
  double GetStepAsDouble() { return GetStep().toDouble(); }
877
  double GetStepBaseAsDouble() { return GetStepBase().toDouble(); }
878
  double GetMinimumAsDouble() { return GetMinimum().toDouble(); }
879
  double GetMaximumAsDouble() { return GetMaximum().toDouble(); }
880
881
  HTMLInputElement* GetOwnerNumberControl();
882
883
  void StartNumberControlSpinnerSpin();
884
  enum SpinnerStopState {
885
    eAllowDispatchingEvents,
886
    eDisallowDispatchingEvents
887
  };
888
  void StopNumberControlSpinnerSpin(SpinnerStopState aState =
889
                                      eAllowDispatchingEvents);
890
  void StepNumberControlForUserEvent(int32_t aDirection);
891
892
  /**
893
   * The callback function used by the nsRepeatService that we use to spin the
894
   * spinner for <input type=number>.
895
   */
896
  static void HandleNumberControlSpin(void* aData);
897
898
  bool NumberSpinnerUpButtonIsDepressed() const
899
0
  {
900
0
    return mNumberControlSpinnerIsSpinning && mNumberControlSpinnerSpinsUp;
901
0
  }
902
903
  bool NumberSpinnerDownButtonIsDepressed() const
904
0
  {
905
0
    return mNumberControlSpinnerIsSpinning && !mNumberControlSpinnerSpinsUp;
906
0
  }
907
908
  bool MozIsTextField(bool aExcludePassword);
909
910
  /**
911
   * GetEditor() is for webidl bindings.
912
   */
913
  nsIEditor* GetEditor();
914
915
  void SetUserInput(const nsAString& aInput,
916
                    nsIPrincipal& aSubjectPrincipal);
917
918
  /**
919
   * If aValue contains a valid floating-point number in the format specified
920
   * by the HTML 5 spec:
921
   *
922
   *   http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#floating-point-numbers
923
   *
924
   * then this function will return the number parsed as a Decimal, otherwise
925
   * it will return a Decimal for which Decimal::isFinite() will return false.
926
   */
927
  static Decimal StringToDecimal(const nsAString& aValue);
928
929
  void UpdateEntries(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories);
930
931
  static void Shutdown();
932
933
  /**
934
   * Returns if the required attribute applies for the current type.
935
   */
936
  bool DoesRequiredApply() const;
937
938
  /**
939
   * Returns the current required state of the element. This function differs
940
   * from Required() in that this function only returns true for input types
941
   * that @required attribute applies and the attribute is set; in contrast,
942
   * Required() returns true whenever @required attribute is set.
943
   */
944
  bool IsRequired() const
945
  {
946
    return State().HasState(NS_EVENT_STATE_REQUIRED);
947
  }
948
949
protected:
950
  virtual ~HTMLInputElement();
951
952
  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
953
954
  // Pull IsSingleLineTextControl into our scope, otherwise it'd be hidden
955
  // by the nsITextControlElement version.
956
  using nsGenericHTMLFormElementWithState::IsSingleLineTextControl;
957
958
  /**
959
   * The ValueModeType specifies how the value IDL attribute should behave.
960
   *
961
   * See: http://dev.w3.org/html5/spec/forms.html#dom-input-value
962
   */
963
  enum ValueModeType
964
  {
965
    // On getting, returns the value.
966
    // On setting, sets value.
967
    VALUE_MODE_VALUE,
968
    // On getting, returns the value if present or the empty string.
969
    // On setting, sets the value.
970
    VALUE_MODE_DEFAULT,
971
    // On getting, returns the value if present or "on".
972
    // On setting, sets the value.
973
    VALUE_MODE_DEFAULT_ON,
974
    // On getting, returns "C:\fakepath\" followed by the file name of the
975
    // first file of the selected files if any.
976
    // On setting the empty string, empties the selected files list, otherwise
977
    // throw the INVALID_STATE_ERR exception.
978
    VALUE_MODE_FILENAME
979
  };
980
981
  /**
982
   * This helper method convert a sub-string that contains only digits to a
983
   * number (unsigned int given that it can't contain a minus sign).
984
   * This method will return whether the sub-string is correctly formatted
985
   * (ie. contains only digit) and it can be successfuly parsed to generate a
986
   * number).
987
   * If the method returns true, |aResult| will contained the parsed number.
988
   *
989
   * @param aValue  the string on which the sub-string will be extracted and parsed.
990
   * @param aStart  the beginning of the sub-string in aValue.
991
   * @param aLen    the length of the sub-string.
992
   * @param aResult the parsed number.
993
   * @return whether the sub-string has been parsed successfully.
994
   */
995
  static bool DigitSubStringToNumber(const nsAString& aValue, uint32_t aStart,
996
                                     uint32_t aLen, uint32_t* aResult);
997
998
  // Helper method
999
1000
  /**
1001
   * Setting the value.
1002
   *
1003
   * @param aValue      String to set.
1004
   * @param aOldValue   Previous value before setting aValue.
1005
                        If previous value is unknown, aOldValue can be nullptr.
1006
   * @param aFlags      See nsTextEditorState::SetValueFlags.
1007
   */
1008
  nsresult SetValueInternal(const nsAString& aValue,
1009
                            const nsAString* aOldValue,
1010
                            uint32_t aFlags);
1011
1012
  nsresult SetValueInternal(const nsAString& aValue,
1013
                            uint32_t aFlags)
1014
  {
1015
    return SetValueInternal(aValue, nullptr, aFlags);
1016
  }
1017
1018
  // Generic getter for the value that doesn't do experimental control type
1019
  // sanitization.
1020
  void GetValueInternal(nsAString& aValue, CallerType aCallerType) const;
1021
1022
  // A getter for callers that know we're not dealing with a file input, so they
1023
  // don't have to think about the caller type.
1024
  void GetNonFileValueInternal(nsAString& aValue) const;
1025
1026
  /**
1027
   * Returns whether the current value is the empty string.  This only makes
1028
   * sense for some input types; does NOT make sense for file inputs.
1029
   *
1030
   * @return whether the current value is the empty string.
1031
   */
1032
  bool IsValueEmpty() const;
1033
1034
  /**
1035
   * Returns whether the current placeholder value should be shown.
1036
   */
1037
  bool ShouldShowPlaceholder() const;
1038
1039
  void ClearFiles(bool aSetValueChanged);
1040
1041
  void SetIndeterminateInternal(bool aValue,
1042
                                bool aShouldInvalidate);
1043
1044
  /**
1045
   * Called when an attribute is about to be changed
1046
   */
1047
  virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsAtom* aName,
1048
                                 const nsAttrValueOrString* aValue,
1049
                                 bool aNotify) override;
1050
  /**
1051
   * Called when an attribute has just been changed
1052
   */
1053
  virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
1054
                                const nsAttrValue* aValue,
1055
                                const nsAttrValue* aOldValue,
1056
                                nsIPrincipal* aSubjectPrincipal,
1057
                                bool aNotify) override;
1058
1059
  virtual void BeforeSetForm(bool aBindToTree) override;
1060
1061
  virtual void AfterClearForm(bool aUnbindOrDelete) override;
1062
1063
  /**
1064
   * Dispatch a select event. Returns true if the event was not cancelled.
1065
   */
1066
  bool DispatchSelectEvent(nsPresContext* aPresContext);
1067
1068
  void SelectAll(nsPresContext* aPresContext);
1069
  bool IsImage() const
1070
  {
1071
    return AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
1072
                       nsGkAtoms::image, eIgnoreCase);
1073
  }
1074
1075
  /**
1076
   * Visit the group of radio buttons this radio belongs to
1077
   * @param aVisitor the visitor to visit with
1078
   */
1079
  nsresult VisitGroup(nsIRadioVisitor* aVisitor, bool aFlushContent);
1080
1081
  /**
1082
   * Do all the work that |SetChecked| does (radio button handling, etc.), but
1083
   * take an |aNotify| parameter.
1084
   */
1085
  void DoSetChecked(bool aValue, bool aNotify, bool aSetValueChanged);
1086
1087
  /**
1088
   * Do all the work that |SetCheckedChanged| does (radio button handling,
1089
   * etc.), but take an |aNotify| parameter that lets it avoid flushing content
1090
   * when it can.
1091
   */
1092
  void DoSetCheckedChanged(bool aCheckedChanged, bool aNotify);
1093
1094
  /**
1095
   * Actually set checked and notify the frame of the change.
1096
   * @param aValue the value of checked to set
1097
   */
1098
  void SetCheckedInternal(bool aValue, bool aNotify);
1099
1100
  void RadioSetChecked(bool aNotify);
1101
  void SetCheckedChanged(bool aCheckedChanged);
1102
1103
  /**
1104
   * MaybeSubmitForm looks for a submit input or a single text control
1105
   * and submits the form if either is present.
1106
   */
1107
  nsresult MaybeSubmitForm(nsPresContext* aPresContext);
1108
1109
  /**
1110
   * Update mFileList with the currently selected file.
1111
   */
1112
  void UpdateFileList();
1113
1114
  /**
1115
   * Called after calling one of the SetFilesOrDirectories() functions.
1116
   * This method can explore the directory recursively if needed.
1117
   */
1118
  void AfterSetFilesOrDirectories(bool aSetValueChanged);
1119
1120
  /**
1121
   * Recursively explore the directory and populate mFileOrDirectories correctly
1122
   * for webkitdirectory.
1123
   */
1124
  void ExploreDirectoryRecursively(bool aSetValuechanged);
1125
1126
  /**
1127
   * Determine whether the editor needs to be initialized explicitly for
1128
   * a particular event.
1129
   */
1130
  bool NeedToInitializeEditorForEvent(EventChainPreVisitor& aVisitor) const;
1131
1132
  /**
1133
   * Get the value mode of the element, depending of the type.
1134
   */
1135
  ValueModeType GetValueMode() const;
1136
1137
  /**
1138
   * Get the mutable state of the element.
1139
   * When the element isn't mutable (immutable), the value or checkedness
1140
   * should not be changed by the user.
1141
   *
1142
   * See: http://dev.w3.org/html5/spec/forms.html#concept-input-mutable
1143
   */
1144
  bool IsMutable() const;
1145
1146
  /**
1147
   * Returns if the min and max attributes apply for the current type.
1148
   */
1149
  bool DoesMinMaxApply() const;
1150
1151
  /**
1152
   * Returns if the step attribute apply for the current type.
1153
   */
1154
  bool DoesStepApply() const { return DoesMinMaxApply(); }
1155
1156
  /**
1157
   * Returns if stepDown and stepUp methods apply for the current type.
1158
   */
1159
  bool DoStepDownStepUpApply() const { return DoesStepApply(); }
1160
1161
  /**
1162
   * Returns if valueAsNumber attribute applies for the current type.
1163
   */
1164
  bool DoesValueAsNumberApply() const { return DoesMinMaxApply(); }
1165
1166
  /**
1167
   * Returns if autocomplete attribute applies for the current type.
1168
   */
1169
  bool DoesAutocompleteApply() const;
1170
1171
  void FreeData();
1172
  nsTextEditorState *GetEditorState() const;
1173
1174
  mozilla::TextEditor* GetTextEditorFromState();
1175
1176
  /**
1177
   * Manages the internal data storage across type changes.
1178
   */
1179
  void HandleTypeChange(uint8_t aNewType, bool aNotify);
1180
1181
  /**
1182
   * Sanitize the value of the element depending of its current type.
1183
   * See: http://www.whatwg.org/specs/web-apps/current-work/#value-sanitization-algorithm
1184
   */
1185
  void SanitizeValue(nsAString& aValue);
1186
1187
  /**
1188
   * Returns whether the placeholder attribute applies for the current type.
1189
   */
1190
  bool PlaceholderApplies() const;
1191
1192
  /**
1193
   * Set the current default value to the value of the input element.
1194
   * @note You should not call this method if GetValueMode() doesn't return
1195
   * VALUE_MODE_VALUE.
1196
   */
1197
  nsresult SetDefaultValueAsValue();
1198
1199
  void SetDirectionFromValue(bool aNotify);
1200
1201
  /**
1202
   * Return if an element should have a specific validity UI
1203
   * (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
1204
   *
1205
   * @return Whether the element should have a validity UI.
1206
   */
1207
  bool ShouldShowValidityUI() const {
1208
    /**
1209
     * Always show the validity UI if the form has already tried to be submitted
1210
     * but was invalid.
1211
     *
1212
     * Otherwise, show the validity UI if the element's value has been changed.
1213
     */
1214
    if (mForm && mForm->HasEverTriedInvalidSubmit()) {
1215
      return true;
1216
    }
1217
1218
    switch (GetValueMode()) {
1219
      case VALUE_MODE_DEFAULT:
1220
        return true;
1221
      case VALUE_MODE_DEFAULT_ON:
1222
        return GetCheckedChanged();
1223
      case VALUE_MODE_VALUE:
1224
      case VALUE_MODE_FILENAME:
1225
        return mValueChanged;
1226
    }
1227
1228
    MOZ_ASSERT_UNREACHABLE("We should not be there: there are no other modes.");
1229
    return false;
1230
  }
1231
1232
  /**
1233
   * Returns the radio group container if the element has one, null otherwise.
1234
   * The radio group container will be the form owner if there is one.
1235
   * The current document otherwise.
1236
   * @return the radio group container if the element has one, null otherwise.
1237
   */
1238
  nsIRadioGroupContainer* GetRadioGroupContainer() const;
1239
1240
  /**
1241
   * Parse a color string of the form #XXXXXX where X should be hexa characters
1242
   * @param the string to be parsed.
1243
   * @return whether the string is a valid simple color.
1244
   * Note : this function does not consider the empty string as valid.
1245
   */
1246
  bool IsValidSimpleColor(const nsAString& aValue) const;
1247
1248
  /**
1249
   * Parse a week string of the form yyyy-Www
1250
   * @param the string to be parsed.
1251
   * @return whether the string is a valid week.
1252
   * Note : this function does not consider the empty string as valid.
1253
   */
1254
  bool IsValidWeek(const nsAString& aValue) const;
1255
1256
  /**
1257
   * Parse a month string of the form yyyy-mm
1258
   * @param the string to be parsed.
1259
   * @return whether the string is a valid month.
1260
   * Note : this function does not consider the empty string as valid.
1261
   */
1262
  bool IsValidMonth(const nsAString& aValue) const;
1263
1264
  /**
1265
   * Parse a date string of the form yyyy-mm-dd
1266
   * @param the string to be parsed.
1267
   * @return whether the string is a valid date.
1268
   * Note : this function does not consider the empty string as valid.
1269
   */
1270
  bool IsValidDate(const nsAString& aValue) const;
1271
1272
  /**
1273
   * Parse a datetime-local string of the form yyyy-mm-ddThh:mm[:ss.s] or
1274
   * yyyy-mm-dd hh:mm[:ss.s], where fractions of seconds can be 1 to 3 digits.
1275
   *
1276
   * @param the string to be parsed.
1277
   * @return whether the string is a valid datetime-local string.
1278
   * Note : this function does not consider the empty string as valid.
1279
   */
1280
  bool IsValidDateTimeLocal(const nsAString& aValue) const;
1281
1282
  /**
1283
   * Parse a year string of the form yyyy
1284
   *
1285
   * @param the string to be parsed.
1286
   *
1287
   * @return the year in aYear.
1288
   * @return whether the parsing was successful.
1289
   */
1290
  bool ParseYear(const nsAString& aValue, uint32_t* aYear) const;
1291
1292
  /**
1293
   * Parse a month string of the form yyyy-mm
1294
   *
1295
   * @param the string to be parsed.
1296
   * @return the year and month in aYear and aMonth.
1297
   * @return whether the parsing was successful.
1298
   */
1299
  bool ParseMonth(const nsAString& aValue,
1300
                  uint32_t* aYear,
1301
                  uint32_t* aMonth) const;
1302
1303
  /**
1304
   * Parse a week string of the form yyyy-Www
1305
   *
1306
   * @param the string to be parsed.
1307
   * @return the year and week in aYear and aWeek.
1308
   * @return whether the parsing was successful.
1309
   */
1310
  bool ParseWeek(const nsAString& aValue,
1311
                 uint32_t* aYear,
1312
                 uint32_t* aWeek) const;
1313
  /**
1314
   * Parse a date string of the form yyyy-mm-dd
1315
   *
1316
   * @param the string to be parsed.
1317
   * @return the date in aYear, aMonth, aDay.
1318
   * @return whether the parsing was successful.
1319
   */
1320
  bool ParseDate(const nsAString& aValue,
1321
                 uint32_t* aYear,
1322
                 uint32_t* aMonth,
1323
                 uint32_t* aDay) const;
1324
1325
  /**
1326
   * Parse a datetime-local string of the form yyyy-mm-ddThh:mm[:ss.s] or
1327
   * yyyy-mm-dd hh:mm[:ss.s], where fractions of seconds can be 1 to 3 digits.
1328
   *
1329
   * @param the string to be parsed.
1330
   * @return the date in aYear, aMonth, aDay and time expressed in milliseconds
1331
   *         in aTime.
1332
   * @return whether the parsing was successful.
1333
   */
1334
  bool ParseDateTimeLocal(const nsAString& aValue,
1335
                          uint32_t* aYear,
1336
                          uint32_t* aMonth,
1337
                          uint32_t* aDay,
1338
                          uint32_t* aTime) const;
1339
1340
  /**
1341
   * Normalize the datetime-local string following the HTML specifications:
1342
   * https://html.spec.whatwg.org/multipage/infrastructure.html#valid-normalised-local-date-and-time-string
1343
   */
1344
  void NormalizeDateTimeLocal(nsAString& aValue) const;
1345
1346
  /**
1347
   * This methods returns the number of days since epoch for a given year and
1348
   * week.
1349
   */
1350
  double DaysSinceEpochFromWeek(uint32_t aYear, uint32_t aWeek) const;
1351
1352
  /**
1353
   * This methods returns the number of days in a given month, for a given year.
1354
   */
1355
  uint32_t NumberOfDaysInMonth(uint32_t aMonth, uint32_t aYear) const;
1356
1357
  /**
1358
   * This methods returns the number of months between January 1970 and the
1359
   * given year and month.
1360
   */
1361
  int32_t MonthsSinceJan1970(uint32_t aYear, uint32_t aMonth) const;
1362
1363
  /**
1364
   * This methods returns the day of the week given a date. If @isoWeek is true,
1365
   * 7=Sunday, otherwise, 0=Sunday.
1366
   */
1367
  uint32_t DayOfWeek(uint32_t aYear, uint32_t aMonth, uint32_t aDay,
1368
                     bool isoWeek) const;
1369
1370
  /**
1371
   * This methods returns the maximum number of week in a given year, the
1372
   * result is either 52 or 53.
1373
   */
1374
  uint32_t MaximumWeekInYear(uint32_t aYear) const;
1375
1376
  /**
1377
   * This methods returns true if it's a leap year.
1378
   */
1379
  bool IsLeapYear(uint32_t aYear) const;
1380
1381
  /**
1382
   * Returns whether aValue is a valid time as described by HTML specifications:
1383
   * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-time-string
1384
   *
1385
   * @param aValue the string to be tested.
1386
   * @return Whether the string is a valid time per HTML specifications.
1387
   */
1388
  bool IsValidTime(const nsAString& aValue) const;
1389
1390
  /**
1391
   * Returns the time expressed in milliseconds of |aValue| being parsed as a
1392
   * time following the HTML specifications:
1393
   * http://www.whatwg.org/specs/web-apps/current-work/#parse-a-time-string
1394
   *
1395
   * Note: |aResult| can be null.
1396
   *
1397
   * @param aValue  the string to be parsed.
1398
   * @param aResult the time expressed in milliseconds representing the time [out]
1399
   * @return Whether the parsing was successful.
1400
   */
1401
  static bool ParseTime(const nsAString& aValue, uint32_t* aResult);
1402
1403
  /**
1404
   * Sets the value of the element to the string representation of the Decimal.
1405
   *
1406
   * @param aValue The Decimal that will be used to set the value.
1407
   */
1408
  void SetValue(Decimal aValue, CallerType aCallerType);
1409
1410
  /**
1411
   * Update the HAS_RANGE bit field value.
1412
   */
1413
  void UpdateHasRange();
1414
1415
   /**
1416
    * Get the step scale value for the current type.
1417
    * See:
1418
    * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#concept-input-step-scale
1419
    */
1420
  Decimal GetStepScaleFactor() const;
1421
1422
  /**
1423
   * Return the base used to compute if a value matches step.
1424
   * Basically, it's the min attribute if present and a default value otherwise.
1425
   *
1426
   * @return The step base.
1427
   */
1428
  Decimal GetStepBase() const;
1429
1430
  /**
1431
   * Returns the default step for the current type.
1432
   * @return the default step for the current type.
1433
   */
1434
  Decimal GetDefaultStep() const;
1435
1436
  enum StepCallerType {
1437
    CALLED_FOR_USER_EVENT,
1438
    CALLED_FOR_SCRIPT
1439
  };
1440
1441
  /**
1442
   * Sets the aValue outparam to the value that this input would take if
1443
   * someone tries to step aStep steps and this input's value would change as
1444
   * a result. Leaves aValue untouched if this inputs value would not change
1445
   * (e.g. already at max, and asking for the next step up).
1446
   *
1447
   * Negative aStep means step down, positive means step up.
1448
   *
1449
   * Returns NS_OK or else the error values that should be thrown if this call
1450
   * was initiated by a stepUp()/stepDown() call from script under conditions
1451
   * that such a call should throw.
1452
   */
1453
  nsresult GetValueIfStepped(int32_t aStepCount,
1454
                             StepCallerType aCallerType,
1455
                             Decimal* aNextStep);
1456
1457
  /**
1458
   * Apply a step change from stepUp or stepDown by multiplying aStep by the
1459
   * current step value.
1460
   *
1461
   * @param aStep The value used to be multiplied against the step value.
1462
   */
1463
  nsresult ApplyStep(int32_t aStep);
1464
1465
  /**
1466
   * Returns if the current type is an experimental mobile type.
1467
   */
1468
  static bool IsExperimentalMobileType(uint8_t aType);
1469
1470
  /*
1471
   * Returns if the current type is one of the date/time input types: date,
1472
   * time and month. TODO: week and datetime-local.
1473
   */
1474
  static bool IsDateTimeInputType(uint8_t aType);
1475
1476
  /**
1477
   * Flushes the layout frame tree to make sure we have up-to-date frames.
1478
   */
1479
  void FlushFrames();
1480
1481
  /**
1482
   * Returns true if the element should prevent dispatching another DOMActivate.
1483
   * This is used in situations where the anonymous subtree should already have
1484
   * sent a DOMActivate and prevents firing more than once.
1485
   */
1486
  bool ShouldPreventDOMActivateDispatch(EventTarget* aOriginalTarget);
1487
1488
  /**
1489
   * Some input type (color and file) let user choose a value using a picker:
1490
   * this function checks if it is needed, and if so, open the corresponding
1491
   * picker (color picker or file picker).
1492
   */
1493
  nsresult MaybeInitPickers(EventChainPostVisitor& aVisitor);
1494
1495
  enum FilePickerType {
1496
    FILE_PICKER_FILE,
1497
    FILE_PICKER_DIRECTORY
1498
  };
1499
  nsresult InitFilePicker(FilePickerType aType);
1500
  nsresult InitColorPicker();
1501
1502
  /**
1503
   * Use this function before trying to open a picker.
1504
   * It checks if the page is allowed to open a new pop-up.
1505
   * If it returns true, you should not create the picker.
1506
   *
1507
   * @return true if popup should be blocked, false otherwise
1508
   */
1509
  bool IsPopupBlocked() const;
1510
1511
  GetFilesHelper* GetOrCreateGetFilesHelper(bool aRecursiveFlag,
1512
                                            ErrorResult& aRv);
1513
1514
  void ClearGetFilesHelpers();
1515
1516
  /**
1517
   * nsINode::SetMayBeApzAware() will be invoked in this function if necessary
1518
   * to prevent default action of APZC so that we can increase/decrease the
1519
   * value of this InputElement when mouse wheel event comes without scrolling
1520
   * the page.
1521
   *
1522
   * SetMayBeApzAware() will set flag MayBeApzAware which is checked by apzc to
1523
   * decide whether to add this element into its dispatch-to-content region.
1524
   */
1525
  void UpdateApzAwareFlag();
1526
1527
  /**
1528
   * A helper to get the current selection range.  Will throw on the ErrorResult
1529
   * if we have no editor state.
1530
   */
1531
  void GetSelectionRange(uint32_t* aSelectionStart,
1532
                         uint32_t* aSelectionEnd,
1533
                         ErrorResult& aRv);
1534
1535
  /**
1536
   * Override for nsImageLoadingContent.
1537
   */
1538
  nsIContent* AsContent() override { return this; }
1539
1540
  nsCOMPtr<nsIControllers> mControllers;
1541
1542
  /*
1543
   * In mInputData, the mState field is used if IsSingleLineTextControl returns
1544
   * true and mValue is used otherwise.  We have to be careful when handling it
1545
   * on a type change.
1546
   *
1547
   * Accessing the mState member should be done using the GetEditorState function,
1548
   * which returns null if the state is not present.
1549
   */
1550
  union InputData {
1551
    /**
1552
     * The current value of the input if it has been changed from the default
1553
     */
1554
    char16_t*               mValue;
1555
    /**
1556
     * The state of the text editor associated with the text/password input
1557
     */
1558
    nsTextEditorState*       mState;
1559
  } mInputData;
1560
1561
  struct FileData;
1562
  UniquePtr<FileData> mFileData;
1563
1564
  /**
1565
   * The value of the input element when first initialized and it is updated
1566
   * when the element is either changed through a script, focused or dispatches
1567
   * a change event. This is to ensure correct future change event firing.
1568
   * NB: This is ONLY applicable where the element is a text control. ie,
1569
   * where type= "text", "email", "search", "tel", "url" or "password".
1570
   */
1571
  nsString mFocusedValue;
1572
1573
  /**
1574
   * If mIsDraggingRange is true, this is the value that the input had before
1575
   * the drag started. Used to reset the input to its old value if the drag is
1576
   * canceled.
1577
   */
1578
  Decimal mRangeThumbDragStartValue;
1579
1580
  /**
1581
   * Current value in the input box, in DateTimeValue dictionary format, see
1582
   * HTMLInputElement.webidl for details.
1583
   */
1584
  nsAutoPtr<DateTimeValue> mDateTimeInputBoxValue;
1585
1586
  /**
1587
   * The selection properties cache for number controls.  This is needed because
1588
   * the number controls don't recycle their text field, so the normal cache in
1589
   * nsTextEditorState cannot do its job.
1590
   */
1591
  nsTextEditorState::SelectionProperties mSelectionProperties;
1592
1593
  /**
1594
   * The triggering principal for the src attribute.
1595
   */
1596
  nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal;
1597
1598
  /*
1599
   * InputType object created based on input type.
1600
   */
1601
  UniquePtr<InputType, DoNotDelete> mInputType;
1602
1603
  // Memory allocated for mInputType, reused when type changes.
1604
  char mInputTypeMem[INPUT_TYPE_SIZE];
1605
1606
  // Step scale factor values, for input types that have one.
1607
  static const Decimal kStepScaleFactorDate;
1608
  static const Decimal kStepScaleFactorNumberRange;
1609
  static const Decimal kStepScaleFactorTime;
1610
  static const Decimal kStepScaleFactorMonth;
1611
  static const Decimal kStepScaleFactorWeek;
1612
1613
  // Default step base value when a type do not have specific one.
1614
  static const Decimal kDefaultStepBase;
1615
  // Default step base value when type=week does not not have a specific one,
1616
  // which is −259200000, the start of week 1970-W01.
1617
  static const Decimal kDefaultStepBaseWeek;
1618
1619
  // Default step used when there is no specified step.
1620
  static const Decimal kDefaultStep;
1621
  static const Decimal kDefaultStepTime;
1622
1623
  // Float value returned by GetStep() when the step attribute is set to 'any'.
1624
  static const Decimal kStepAny;
1625
1626
  // Minimum year limited by HTML standard, year >= 1.
1627
  static const double kMinimumYear;
1628
  // Maximum year limited by ECMAScript date object range, year <= 275760.
1629
  static const double kMaximumYear;
1630
  // Maximum valid week is 275760-W37.
1631
  static const double kMaximumWeekInMaximumYear;
1632
  // Maximum valid day is 275760-09-13.
1633
  static const double kMaximumDayInMaximumYear;
1634
  // Maximum valid month is 275760-09.
1635
  static const double kMaximumMonthInMaximumYear;
1636
  // Long years in a ISO calendar have 53 weeks in them.
1637
  static const double kMaximumWeekInYear;
1638
  // Milliseconds in a day.
1639
  static const double kMsPerDay;
1640
1641
  nsContentUtils::AutocompleteAttrState mAutocompleteAttrState;
1642
  nsContentUtils::AutocompleteAttrState mAutocompleteInfoState;
1643
  bool                     mDisabledChanged     : 1;
1644
  bool                     mValueChanged        : 1;
1645
  bool                     mLastValueChangeWasInteractive : 1;
1646
  bool                     mCheckedChanged      : 1;
1647
  bool                     mChecked             : 1;
1648
  bool                     mHandlingSelectEvent : 1;
1649
  bool                     mShouldInitChecked   : 1;
1650
  bool                     mDoneCreating        : 1;
1651
  bool                     mInInternalActivate  : 1;
1652
  bool                     mCheckedIsToggled    : 1;
1653
  bool                     mIndeterminate       : 1;
1654
  bool                     mInhibitRestoration  : 1;
1655
  bool                     mCanShowValidUI      : 1;
1656
  bool                     mCanShowInvalidUI    : 1;
1657
  bool                     mHasRange            : 1;
1658
  bool                     mIsDraggingRange     : 1;
1659
  bool                     mNumberControlSpinnerIsSpinning : 1;
1660
  bool                     mNumberControlSpinnerSpinsUp : 1;
1661
  bool                     mPickerRunning : 1;
1662
  bool                     mSelectionCached : 1;
1663
  bool                     mIsPreviewEnabled : 1;
1664
  bool                     mHasPatternAttribute : 1;
1665
1666
private:
1667
  static void ImageInputMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
1668
                                              MappedDeclarations&);
1669
1670
  /**
1671
   * Returns true if this input's type will fire a DOM "change" event when it
1672
   * loses focus if its value has changed since it gained focus.
1673
   */
1674
  bool MayFireChangeOnBlur() const {
1675
    return MayFireChangeOnBlur(mType);
1676
  }
1677
1678
  /**
1679
   * Returns true if selection methods can be called on element
1680
   */
1681
  bool SupportsTextSelection() const {
1682
    return mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_SEARCH ||
1683
           mType == NS_FORM_INPUT_URL || mType == NS_FORM_INPUT_TEL ||
1684
           mType == NS_FORM_INPUT_PASSWORD;
1685
  }
1686
1687
  static bool MayFireChangeOnBlur(uint8_t aType) {
1688
    return IsSingleLineTextControl(false, aType) ||
1689
           aType == NS_FORM_INPUT_RANGE ||
1690
           aType == NS_FORM_INPUT_NUMBER ||
1691
           aType == NS_FORM_INPUT_TIME ||
1692
           aType == NS_FORM_INPUT_DATE;
1693
  }
1694
1695
  /**
1696
   * Checks if aDateTimeInputType should be supported based on "dom.forms.datetime",
1697
   * and "dom.experimental_forms".
1698
   */
1699
  static bool
1700
  IsDateTimeTypeSupported(uint8_t aDateTimeInputType);
1701
1702
  /**
1703
   * Checks preference "dom.webkitBlink.filesystem.enabled" to determine if
1704
   * webkitEntries should be supported.
1705
   */
1706
  static bool
1707
  IsWebkitFileSystemEnabled();
1708
1709
  /**
1710
   * Checks preference "dom.input.dirpicker" to determine if file and directory
1711
   * entries API should be supported.
1712
   */
1713
  static bool
1714
  IsDirPickerEnabled();
1715
1716
  /**
1717
   * Checks preference "dom.experimental_forms" to determine if experimental
1718
   * implementation of input element should be enabled.
1719
   */
1720
  static bool
1721
  IsExperimentalFormsEnabled();
1722
1723
  /**
1724
   * Checks preference "dom.forms.datetime" to determine if input date and time
1725
   * should be supported.
1726
   */
1727
  static bool
1728
  IsInputDateTimeEnabled();
1729
1730
  /**
1731
   * Checks preference "dom.forms.datetime.others" to determine if input week,
1732
   * month and datetime-local should be supported.
1733
   */
1734
  static bool
1735
  IsInputDateTimeOthersEnabled();
1736
1737
  /**
1738
   * Checks preference "dom.forms.color" to determine if date/time related
1739
   * types should be supported.
1740
   */
1741
  static bool
1742
  IsInputColorEnabled();
1743
1744
  struct nsFilePickerFilter {
1745
    nsFilePickerFilter()
1746
      : mFilterMask(0) {}
1747
1748
    explicit nsFilePickerFilter(int32_t aFilterMask)
1749
      : mFilterMask(aFilterMask) {}
1750
1751
    nsFilePickerFilter(const nsString& aTitle,
1752
                       const nsString& aFilter)
1753
      : mFilterMask(0), mTitle(aTitle), mFilter(aFilter) {}
1754
1755
    nsFilePickerFilter(const nsFilePickerFilter& other) {
1756
      mFilterMask = other.mFilterMask;
1757
      mTitle = other.mTitle;
1758
      mFilter = other.mFilter;
1759
    }
1760
1761
    bool operator== (const nsFilePickerFilter& other) const {
1762
      if ((mFilter == other.mFilter) && (mFilterMask == other.mFilterMask)) {
1763
        return true;
1764
      } else {
1765
        return false;
1766
      }
1767
    }
1768
1769
    // Filter mask, using values defined in nsIFilePicker
1770
    int32_t mFilterMask;
1771
    // If mFilterMask is defined, mTitle and mFilter are useless and should be
1772
    // ignored
1773
    nsString mTitle;
1774
    nsString mFilter;
1775
  };
1776
1777
  class nsFilePickerShownCallback
1778
    : public nsIFilePickerShownCallback
1779
  {
1780
    virtual ~nsFilePickerShownCallback()
1781
    { }
1782
1783
  public:
1784
    nsFilePickerShownCallback(HTMLInputElement* aInput,
1785
                              nsIFilePicker* aFilePicker);
1786
    NS_DECL_ISUPPORTS
1787
1788
    NS_IMETHOD Done(int16_t aResult) override;
1789
1790
  private:
1791
    nsCOMPtr<nsIFilePicker> mFilePicker;
1792
    RefPtr<HTMLInputElement> mInput;
1793
  };
1794
1795
  static void ReleaseTextEditorState(nsTextEditorState* aState);
1796
1797
  static nsTextEditorState* sCachedTextEditorState;
1798
  static bool sShutdown;
1799
};
1800
1801
} // namespace dom
1802
} // namespace mozilla
1803
1804
#endif