Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/html/HTMLFormElement.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_HTMLFormElement_h
8
#define mozilla_dom_HTMLFormElement_h
9
10
#include "mozilla/AsyncEventDispatcher.h"
11
#include "mozilla/Attributes.h"
12
#include "mozilla/dom/HTMLFormSubmission.h"
13
#include "nsAutoPtr.h"
14
#include "nsCOMPtr.h"
15
#include "nsIForm.h"
16
#include "nsIFormControl.h"
17
#include "nsGenericHTMLElement.h"
18
#include "nsIWebProgressListener.h"
19
#include "nsIRadioGroupContainer.h"
20
#include "nsIWeakReferenceUtils.h"
21
#include "nsThreadUtils.h"
22
#include "nsInterfaceHashtable.h"
23
#include "nsRefPtrHashtable.h"
24
#include "nsDataHashtable.h"
25
#include "jsfriendapi.h" // For js::ExpandoAndGeneration
26
27
class nsIMutableArray;
28
class nsIURI;
29
30
namespace mozilla {
31
class EventChainPostVisitor;
32
class EventChainPreVisitor;
33
namespace dom {
34
class HTMLFormControlsCollection;
35
class HTMLImageElement;
36
37
class HTMLFormElement final : public nsGenericHTMLElement,
38
                              public nsIWebProgressListener,
39
                              public nsIForm,
40
                              public nsIRadioGroupContainer
41
{
42
  friend class HTMLFormControlsCollection;
43
44
public:
45
  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLFormElement, form)
46
47
  explicit HTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
48
49
  enum {
50
    FORM_CONTROL_LIST_HASHTABLE_LENGTH = 8
51
  };
52
53
  // nsISupports
54
  NS_DECL_ISUPPORTS_INHERITED
55
56
  // nsIWebProgressListener
57
  NS_DECL_NSIWEBPROGRESSLISTENER
58
59
  // nsIForm
60
  NS_IMETHOD_(nsIFormControl*) GetElementAt(int32_t aIndex) const override;
61
  NS_IMETHOD_(uint32_t) GetElementCount() const override;
62
  NS_IMETHOD_(int32_t) IndexOfControl(nsIFormControl* aControl) override;
63
  NS_IMETHOD_(nsIFormControl*) GetDefaultSubmitElement() const override;
64
65
  // nsIRadioGroupContainer
66
  void SetCurrentRadioButton(const nsAString& aName,
67
                             HTMLInputElement* aRadio) override;
68
  HTMLInputElement* GetCurrentRadioButton(const nsAString& aName) override;
69
  NS_IMETHOD GetNextRadioButton(const nsAString& aName,
70
                                const bool aPrevious,
71
                                HTMLInputElement* aFocusedRadio,
72
                                HTMLInputElement** aRadioOut) override;
73
  NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor,
74
                            bool aFlushContent) override;
75
  void AddToRadioGroup(const nsAString& aName,
76
                       HTMLInputElement* aRadio) override;
77
  void RemoveFromRadioGroup(const nsAString& aName,
78
                            HTMLInputElement* aRadio) override;
79
  virtual uint32_t GetRequiredRadioCount(const nsAString& aName) const override;
80
  virtual void RadioRequiredWillChange(const nsAString& aName,
81
                                       bool aRequiredAdded) override;
82
  virtual bool GetValueMissingState(const nsAString& aName) const override;
83
  virtual void SetValueMissingState(const nsAString& aName, bool aValue) override;
84
85
  virtual EventStates IntrinsicState() const override;
86
87
  // EventTarget
88
  virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
89
90
  // nsIContent
91
  virtual bool ParseAttribute(int32_t aNamespaceID,
92
                                nsAtom* aAttribute,
93
                                const nsAString& aValue,
94
                                nsIPrincipal* aMaybeScriptedPrincipal,
95
                                nsAttrValue& aResult) override;
96
  void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
97
  void WillHandleEvent(EventChainPostVisitor& aVisitor) override;
98
  virtual nsresult PostHandleEvent(
99
                     EventChainPostVisitor& aVisitor) override;
100
101
  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
102
                              nsIContent* aBindingParent) override;
103
  virtual void UnbindFromTree(bool aDeep = true,
104
                              bool aNullParent = true) override;
105
  virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
106
                                 const nsAttrValueOrString* aValue,
107
                                 bool aNotify) override;
108
  virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
109
                                const nsAttrValue* aValue,
110
                                const nsAttrValue* aOldValue,
111
                                nsIPrincipal* aSubjectPrincipal,
112
                                bool aNotify) override;
113
114
  /**
115
   * Forget all information about the current submission (and the fact that we
116
   * are currently submitting at all).
117
   */
118
  void ForgetCurrentSubmission();
119
120
  virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
121
122
  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLFormElement,
123
                                           nsGenericHTMLElement)
124
125
  /**
126
   * Remove an element from this form's list of elements
127
   *
128
   * @param aElement the element to remove
129
   * @param aUpdateValidity If true, updates the form validity.
130
   * @return NS_OK if the element was successfully removed.
131
   */
132
  nsresult RemoveElement(nsGenericHTMLFormElement* aElement,
133
                         bool aUpdateValidity);
134
135
  /**
136
   * Remove an element from the lookup table maintained by the form.
137
   * We can't fold this method into RemoveElement() because when
138
   * RemoveElement() is called it doesn't know if the element is
139
   * removed because the id attribute has changed, or because the
140
   * name attribute has changed.
141
   *
142
   * @param aElement the element to remove
143
   * @param aName the name or id of the element to remove
144
   * @return NS_OK if the element was successfully removed.
145
   */
146
  nsresult RemoveElementFromTable(nsGenericHTMLFormElement* aElement,
147
                                  const nsAString& aName);
148
149
  /**
150
   * Add an element to end of this form's list of elements
151
   *
152
   * @param aElement the element to add
153
   * @param aUpdateValidity If true, the form validity will be updated.
154
   * @param aNotify If true, send nsIDocumentObserver notifications as needed.
155
   * @return NS_OK if the element was successfully added
156
   */
157
  nsresult AddElement(nsGenericHTMLFormElement* aElement, bool aUpdateValidity,
158
                      bool aNotify);
159
160
  /**
161
   * Add an element to the lookup table maintained by the form.
162
   *
163
   * We can't fold this method into AddElement() because when
164
   * AddElement() is called, the form control has no
165
   * attributes.  The name or id attributes of the form control
166
   * are used as a key into the table.
167
   */
168
  nsresult AddElementToTable(nsGenericHTMLFormElement* aChild,
169
                             const nsAString& aName);
170
171
  /**
172
   * Remove an image element from this form's list of image elements
173
   *
174
   * @param aElement the image element to remove
175
   * @return NS_OK if the element was successfully removed.
176
   */
177
  nsresult RemoveImageElement(HTMLImageElement* aElement);
178
179
  /**
180
   * Remove an image element from the lookup table maintained by the form.
181
   * We can't fold this method into RemoveImageElement() because when
182
   * RemoveImageElement() is called it doesn't know if the element is
183
   * removed because the id attribute has changed, or because the
184
   * name attribute has changed.
185
   *
186
   * @param aElement the image element to remove
187
   * @param aName the name or id of the element to remove
188
   * @return NS_OK if the element was successfully removed.
189
   */
190
  nsresult RemoveImageElementFromTable(HTMLImageElement* aElement,
191
                                      const nsAString& aName);
192
  /**
193
   * Add an image element to the end of this form's list of image elements
194
   *
195
   * @param aElement the element to add
196
   * @return NS_OK if the element was successfully added
197
   */
198
  nsresult AddImageElement(HTMLImageElement* aElement);
199
200
  /**
201
   * Add an image element to the lookup table maintained by the form.
202
   *
203
   * We can't fold this method into AddImageElement() because when
204
   * AddImageElement() is called, the image attributes can change.
205
   * The name or id attributes of the image are used as a key into the table.
206
   */
207
  nsresult AddImageElementToTable(HTMLImageElement* aChild,
208
                                  const nsAString& aName);
209
210
   /**
211
    * Returns true if implicit submission of this form is disabled. For more
212
    * on implicit submission see:
213
    *
214
    * http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#implicit-submission
215
    */
216
  bool ImplicitSubmissionIsDisabled() const;
217
218
  /**
219
  * Check whether a given nsIFormControl is the last single line input control
220
  * that is not disabled. aControl is expected to not be null.
221
  */
222
  bool IsLastActiveElement(const nsIFormControl* aControl) const;
223
224
  /**
225
   * Check whether a given nsIFormControl is the default submit
226
   * element.  This is different from just comparing to
227
   * GetDefaultSubmitElement() in certain situations inside an update
228
   * when GetDefaultSubmitElement() might not be up to date.  aControl
229
   * is expected to not be null.
230
   */
231
  bool IsDefaultSubmitElement(const nsIFormControl* aControl) const;
232
233
  /**
234
   * Flag the form to know that a button or image triggered scripted form
235
   * submission. In that case the form will defer the submission until the
236
   * script handler returns and the return value is known.
237
   */
238
  void OnSubmitClickBegin(Element* aOriginatingElement);
239
  void OnSubmitClickEnd();
240
241
  /**
242
   * This method will update the form validity so the submit controls states
243
   * will be updated (for -moz-submit-invalid pseudo-class).
244
   * This method has to be called by form elements whenever their validity state
245
   * or status regarding constraint validation changes.
246
   *
247
   * @note This method isn't used for CheckValidity().
248
   * @note If an element becomes barred from constraint validation, it has to be
249
   * considered as valid.
250
   *
251
   * @param aElementValidityState the new validity state of the element
252
   */
253
  void UpdateValidity(bool aElementValidityState);
254
255
  /**
256
   * Returns the form validity based on the last UpdateValidity() call.
257
   *
258
   * @return Whether the form was valid the last time UpdateValidity() was called.
259
   *
260
   * @note This method may not return the *current* validity state!
261
   */
262
  bool GetValidity() const { return !mInvalidElementsCount; }
263
264
  /**
265
   * This method check the form validity and make invalid form elements send
266
   * invalid event if needed.
267
   *
268
   * @return Whether the form is valid.
269
   *
270
   * @note Do not call this method if novalidate/formnovalidate is used.
271
   * @note This method might disappear with bug 592124, hopefuly.
272
   */
273
  bool CheckValidFormSubmission();
274
275
  /**
276
   * Check whether submission can proceed for this form.  This basically
277
   * implements steps 1-4 (more or less) of
278
   * <https://html.spec.whatwg.org/multipage/forms.html#concept-form-submit>.
279
   * aSubmitter, if not null, is the "submitter" from that algorithm.  Therefore
280
   * it must be a valid submit control.
281
   */
282
  bool SubmissionCanProceed(Element* aSubmitter);
283
284
  /**
285
   * Walk over the form elements and call SubmitNamesValues() on them to get
286
   * their data pumped into the FormSubmitter.
287
   *
288
   * @param aFormSubmission the form submission object
289
   */
290
  nsresult WalkFormElements(HTMLFormSubmission* aFormSubmission);
291
292
  /**
293
   * Whether the submission of this form has been ever prevented because of
294
   * being invalid.
295
   *
296
   * @return Whether the submission of this form has been prevented because of
297
   * being invalid.
298
   */
299
0
  bool HasEverTriedInvalidSubmit() const { return mEverTriedInvalidSubmit; }
300
301
  /**
302
   * Implements form[name]. Returns form controls in this form with the correct
303
   * value of the name attribute.
304
   */
305
  already_AddRefed<nsISupports>
306
  FindNamedItem(const nsAString& aName, nsWrapperCache** aCache);
307
308
  // WebIDL
309
310
  void GetAcceptCharset(DOMString& aValue)
311
  {
312
    GetHTMLAttr(nsGkAtoms::acceptcharset, aValue);
313
  }
314
315
  void SetAcceptCharset(const nsAString& aValue, ErrorResult& aRv)
316
  {
317
    SetHTMLAttr(nsGkAtoms::acceptcharset, aValue, aRv);
318
  }
319
320
  void GetAction(nsString& aValue);
321
  void SetAction(const nsAString& aValue, ErrorResult& aRv)
322
  {
323
    SetHTMLAttr(nsGkAtoms::action, aValue, aRv);
324
  }
325
326
  void GetAutocomplete(nsAString& aValue);
327
  void SetAutocomplete(const nsAString& aValue, ErrorResult& aRv)
328
  {
329
    SetHTMLAttr(nsGkAtoms::autocomplete, aValue, aRv);
330
  }
331
332
  void GetEnctype(nsAString& aValue);
333
  void SetEnctype(const nsAString& aValue, ErrorResult& aRv)
334
  {
335
    SetHTMLAttr(nsGkAtoms::enctype, aValue, aRv);
336
  }
337
338
  void GetEncoding(nsAString& aValue)
339
  {
340
    GetEnctype(aValue);
341
  }
342
  void SetEncoding(const nsAString& aValue, ErrorResult& aRv)
343
  {
344
    SetEnctype(aValue, aRv);
345
  }
346
347
  void GetMethod(nsAString& aValue);
348
  void SetMethod(const nsAString& aValue, ErrorResult& aRv)
349
  {
350
    SetHTMLAttr(nsGkAtoms::method, aValue, aRv);
351
  }
352
353
  void GetName(DOMString& aValue)
354
  {
355
    GetHTMLAttr(nsGkAtoms::name, aValue);
356
  }
357
358
  void SetName(const nsAString& aValue, ErrorResult& aRv)
359
  {
360
    SetHTMLAttr(nsGkAtoms::name, aValue, aRv);
361
  }
362
363
  bool NoValidate() const
364
  {
365
    return GetBoolAttr(nsGkAtoms::novalidate);
366
  }
367
368
  void SetNoValidate(bool aValue, ErrorResult& aRv)
369
  {
370
    SetHTMLBoolAttr(nsGkAtoms::novalidate, aValue, aRv);
371
  }
372
373
  void GetTarget(DOMString& aValue)
374
  {
375
    GetHTMLAttr(nsGkAtoms::target, aValue);
376
  }
377
378
  void SetTarget(const nsAString& aValue, ErrorResult& aRv)
379
  {
380
    SetHTMLAttr(nsGkAtoms::target, aValue, aRv);
381
  }
382
383
  // it's only out-of-line because the class definition is not available in the
384
  // header
385
  nsIHTMLCollection* Elements();
386
387
  int32_t Length();
388
389
  void Submit(ErrorResult& aRv);
390
  void Reset();
391
392
  bool CheckValidity()
393
  {
394
    return CheckFormValidity(nullptr);
395
  }
396
397
  bool ReportValidity()
398
  {
399
    return CheckValidFormSubmission();
400
  }
401
402
  Element*
403
  IndexedGetter(uint32_t aIndex, bool &aFound);
404
405
  already_AddRefed<nsISupports>
406
  NamedGetter(const nsAString& aName, bool &aFound);
407
408
  void GetSupportedNames(nsTArray<nsString>& aRetval);
409
410
  static int32_t
411
  CompareFormControlPosition(Element* aElement1, Element* aElement2,
412
                             const nsIContent* aForm);
413
#ifdef DEBUG
414
  static void
415
  AssertDocumentOrder(const nsTArray<nsGenericHTMLFormElement*>& aControls,
416
                      nsIContent* aForm);
417
  static void
418
  AssertDocumentOrder(const nsTArray<RefPtr<nsGenericHTMLFormElement>>& aControls,
419
                      nsIContent* aForm);
420
#endif
421
422
  js::ExpandoAndGeneration mExpandoAndGeneration;
423
424
protected:
425
  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
426
427
  void PostPasswordEvent();
428
429
  RefPtr<AsyncEventDispatcher> mFormPasswordEventDispatcher;
430
431
  class RemoveElementRunnable;
432
  friend class RemoveElementRunnable;
433
434
  class RemoveElementRunnable : public Runnable {
435
  public:
436
    explicit RemoveElementRunnable(HTMLFormElement* aForm)
437
      : Runnable("dom::HTMLFormElement::RemoveElementRunnable")
438
      , mForm(aForm)
439
0
    {}
440
441
0
    NS_IMETHOD Run() override {
442
0
      mForm->HandleDefaultSubmitRemoval();
443
0
      return NS_OK;
444
0
    }
445
446
  private:
447
    RefPtr<HTMLFormElement> mForm;
448
  };
449
450
  nsresult DoSubmitOrReset(WidgetEvent* aEvent,
451
                           EventMessage aMessage);
452
  nsresult DoReset();
453
454
  // Async callback to handle removal of our default submit
455
  void HandleDefaultSubmitRemoval();
456
457
  //
458
  // Submit Helpers
459
  //
460
  //
461
  /**
462
   * Attempt to submit (submission might be deferred)
463
   * (called by DoSubmitOrReset)
464
   *
465
   * @param aPresContext the presentation context
466
   * @param aEvent the DOM event that was passed to us for the submit
467
   */
468
  nsresult DoSubmit(WidgetEvent* aEvent);
469
470
  /**
471
   * Prepare the submission object (called by DoSubmit)
472
   *
473
   * @param aFormSubmission the submission object
474
   * @param aEvent the DOM event that was passed to us for the submit
475
   */
476
  nsresult BuildSubmission(HTMLFormSubmission** aFormSubmission,
477
                           WidgetEvent* aEvent);
478
  /**
479
   * Perform the submission (called by DoSubmit and FlushPendingSubmission)
480
   *
481
   * @param aFormSubmission the submission object
482
   */
483
  nsresult SubmitSubmission(HTMLFormSubmission* aFormSubmission);
484
485
  /**
486
   * Notify any submit observers of the submit.
487
   *
488
   * @param aActionURL the URL being submitted to
489
   * @param aCancelSubmit out param where submit observers can specify that the
490
   *        submit should be cancelled.
491
   */
492
  nsresult NotifySubmitObservers(nsIURI* aActionURL, bool* aCancelSubmit,
493
                                 bool aEarlyNotify);
494
495
  /**
496
   * If this form submission is secure -> insecure, ask the user if they want
497
   * to continue.
498
   *
499
   * @param aActionURL the URL being submitted to
500
   * @param aCancelSubmit out param: will be true if the user wants to cancel
501
   */
502
  nsresult DoSecureToInsecureSubmitCheck(nsIURI* aActionURL,
503
                                         bool* aCancelSubmit);
504
505
  /**
506
   * Find form controls in this form with the correct value in the name
507
   * attribute.
508
   */
509
  already_AddRefed<nsISupports> DoResolveName(const nsAString& aName, bool aFlushContent);
510
511
  /**
512
   * Check the form validity following this algorithm:
513
   * http://www.whatwg.org/specs/web-apps/current-work/#statically-validate-the-constraints
514
   *
515
   * @param aInvalidElements [out] parameter containing the list of unhandled
516
   * invalid controls.
517
   *
518
   * @return Whether the form is currently valid.
519
   */
520
  bool CheckFormValidity(nsTArray<RefPtr<Element>>* aInvalidElements) const;
521
522
  // Clear the mImageNameLookupTable and mImageElements.
523
  void Clear();
524
525
  // Insert a element into the past names map.
526
  void AddToPastNamesMap(const nsAString& aName, nsISupports* aChild);
527
528
  // Remove the given element from the past names map.  The element must be an
529
  // nsGenericHTMLFormElement or HTMLImageElement.
530
  void RemoveElementFromPastNamesMap(Element* aElement);
531
532
  nsresult
533
  AddElementToTableInternal(
534
    nsInterfaceHashtable<nsStringHashKey,nsISupports>& aTable,
535
    nsIContent* aChild, const nsAString& aName);
536
537
  nsresult
538
  RemoveElementFromTableInternal(
539
    nsInterfaceHashtable<nsStringHashKey,nsISupports>& aTable,
540
    nsIContent* aChild, const nsAString& aName);
541
542
public:
543
  /**
544
   * Flush a possible pending submission. If there was a scripted submission
545
   * triggered by a button or image, the submission was defered. This method
546
   * forces the pending submission to be submitted. (happens when the handler
547
   * returns false or there is an action/target change in the script)
548
   */
549
  void FlushPendingSubmission();
550
551
  /**
552
   * Get the full URL to submit to.  Do not submit if the returned URL is null.
553
   *
554
   * @param aActionURL the full, unadulterated URL you'll be submitting to [OUT]
555
   * @param aOriginatingElement the originating element of the form submission [IN]
556
   */
557
  nsresult GetActionURL(nsIURI** aActionURL, Element* aOriginatingElement);
558
protected:
559
560
  //
561
  // Data members
562
  //
563
  /** The list of controls (form.elements as well as stuff not in elements) */
564
  RefPtr<HTMLFormControlsCollection> mControls;
565
  /** The currently selected radio button of each group */
566
  nsRefPtrHashtable<nsStringHashKey, HTMLInputElement> mSelectedRadioButtons;
567
  /** The number of required radio button of each group */
568
  nsDataHashtable<nsStringCaseInsensitiveHashKey,uint32_t> mRequiredRadioButtonCounts;
569
  /** The value missing state of each group */
570
  nsDataHashtable<nsStringCaseInsensitiveHashKey,bool> mValueMissingRadioGroups;
571
572
  /** The pending submission object */
573
  nsAutoPtr<HTMLFormSubmission> mPendingSubmission;
574
  /** The request currently being submitted */
575
  nsCOMPtr<nsIRequest> mSubmittingRequest;
576
  /** The web progress object we are currently listening to */
577
  nsWeakPtr mWebProgress;
578
579
  /** The default submit element -- WEAK */
580
  nsGenericHTMLFormElement* mDefaultSubmitElement;
581
582
  /** The first submit element in mElements -- WEAK */
583
  nsGenericHTMLFormElement* mFirstSubmitInElements;
584
585
  /** The first submit element in mNotInElements -- WEAK */
586
  nsGenericHTMLFormElement* mFirstSubmitNotInElements;
587
588
  // This array holds on to all HTMLImageElement(s).
589
  // This is needed to properly clean up the bi-directional references
590
  // (both weak and strong) between the form and its HTMLImageElements.
591
592
  nsTArray<HTMLImageElement*> mImageElements;  // Holds WEAK references
593
594
  // A map from an ID or NAME attribute to the HTMLImageElement(s), this
595
  // hash holds strong references either to the named HTMLImageElement, or
596
  // to a list of named HTMLImageElement(s), in the case where this hash
597
  // holds on to a list of named HTMLImageElement(s) the list has weak
598
  // references to the HTMLImageElement.
599
600
  nsInterfaceHashtable<nsStringHashKey,nsISupports> mImageNameLookupTable;
601
602
  // A map from names to elements that were gotten by those names from this
603
  // form in that past.  See "past names map" in the HTML5 specification.
604
605
  nsInterfaceHashtable<nsStringHashKey,nsISupports> mPastNameLookupTable;
606
607
  /** Keep track of what the popup state was when the submit was initiated */
608
  PopupControlState mSubmitPopupState;
609
610
  /**
611
   * Number of invalid and candidate for constraint validation elements in the
612
   * form the last time UpdateValidity has been called.
613
   * @note Should only be used by UpdateValidity() and GetValidity()!
614
   */
615
  int32_t mInvalidElementsCount;
616
617
  /** Whether we are currently processing a submit event or not */
618
  bool mGeneratingSubmit;
619
  /** Whether we are currently processing a reset event or not */
620
  bool mGeneratingReset;
621
  /** Whether we are submitting currently */
622
  bool mIsSubmitting;
623
  /** Whether the submission is to be deferred in case a script triggers it */
624
  bool mDeferSubmission;
625
  /** Whether we notified NS_FORMSUBMIT_SUBJECT listeners already */
626
  bool mNotifiedObservers;
627
  /** If we notified the listeners early, what was the result? */
628
  bool mNotifiedObserversResult;
629
  /** Keep track of whether a submission was user-initiated or not */
630
  bool mSubmitInitiatedFromUserInput;
631
  /**
632
   * Whether the submission of this form has been ever prevented because of
633
   * being invalid.
634
   */
635
  bool mEverTriedInvalidSubmit;
636
637
protected:
638
  /** Detection of first form to notify observers */
639
  static bool gFirstFormSubmitted;
640
  /** Detection of first password input to initialize the password manager */
641
  static bool gPasswordManagerInitialized;
642
643
private:
644
  ~HTMLFormElement();
645
};
646
647
} // namespace dom
648
649
} // namespace mozilla
650
651
#endif // mozilla_dom_HTMLFormElement_h