Add support for reportValidity() on form and form control elements
[WebKit-https.git] / Source / WebCore / html / HTMLFormElement.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2004-2016 Apple Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  */
23
24 #pragma once
25
26 #include "FormState.h"
27 #include "FormSubmission.h"
28 #include "HTMLElement.h"
29 #include "RadioButtonGroups.h"
30 #include <memory>
31
32 #if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
33 #include "Autocapitalize.h"
34 #endif
35
36 namespace WebCore {
37
38 class Event;
39 class FormAssociatedElement;
40 class FormData;
41 class HTMLFormControlElement;
42 class HTMLFormControlsCollection;
43 class HTMLImageElement;
44 class HTMLInputElement;
45 class TextEncoding;
46
47 class HTMLFormElement final : public HTMLElement {
48 public:
49     static Ref<HTMLFormElement> create(Document&);
50     static Ref<HTMLFormElement> create(const QualifiedName&, Document&);
51     virtual ~HTMLFormElement();
52
53     Ref<HTMLFormControlsCollection> elements();
54     WEBCORE_EXPORT Ref<HTMLCollection> elementsForNativeBindings();
55     Vector<Ref<Element>> namedElements(const AtomicString&);
56
57     WEBCORE_EXPORT unsigned length() const;
58     HTMLElement* item(unsigned index);
59
60     String enctype() const { return m_attributes.encodingType(); }
61     WEBCORE_EXPORT void setEnctype(const String&);
62
63     bool shouldAutocomplete() const;
64
65     WEBCORE_EXPORT void setAutocomplete(const AtomicString&);
66     WEBCORE_EXPORT const AtomicString& autocomplete() const;
67
68 #if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
69     WEBCORE_EXPORT bool autocorrect() const;
70     WEBCORE_EXPORT void setAutocorrect(bool);
71
72     WEBCORE_EXPORT WebAutocapitalizeType autocapitalizeType() const;
73     WEBCORE_EXPORT const AtomicString& autocapitalize() const;
74     WEBCORE_EXPORT void setAutocapitalize(const AtomicString&);
75 #endif
76
77     // FIXME: Should rename these two functions to say "form control" or "form-associated element" instead of "form element".
78     void registerFormElement(FormAssociatedElement*);
79     void removeFormElement(FormAssociatedElement*);
80
81     void registerInvalidAssociatedFormControl(const HTMLFormControlElement&);
82     void removeInvalidAssociatedFormControlIfNeeded(const HTMLFormControlElement&);
83
84     void registerImgElement(HTMLImageElement*);
85     void removeImgElement(HTMLImageElement*);
86
87     void prepareForSubmission(Event&); // FIXME: This function doesn't only prepare, it sometimes calls submit() itself.
88     WEBCORE_EXPORT void submit();
89     void submitFromJavaScript();
90     WEBCORE_EXPORT void reset();
91
92     void setDemoted(bool demoted) { m_wasDemoted = demoted; }
93
94     void submitImplicitly(Event&, bool fromImplicitSubmissionTrigger);
95     bool formWouldHaveSecureSubmission(const String& url);
96
97     String name() const;
98
99     bool noValidate() const;
100
101     String acceptCharset() const { return m_attributes.acceptCharset(); }
102     void setAcceptCharset(const String&);
103
104     String action() const;
105     void setAction(const String&);
106
107     WEBCORE_EXPORT String method() const;
108     WEBCORE_EXPORT void setMethod(const String&);
109
110     String target() const final;
111
112     bool wasUserSubmitted() const;
113
114     HTMLFormControlElement* defaultButton() const;
115     void resetDefaultButton();
116
117     WEBCORE_EXPORT bool checkValidity();
118     bool reportValidity();
119
120 #if ENABLE(REQUEST_AUTOCOMPLETE)
121     enum class AutocompleteResult {
122         Success,
123         ErrorDisabled,
124         ErrorCancel,
125         ErrorInvalid,
126     };
127
128     void requestAutocomplete();
129     void finishRequestAutocomplete(AutocompleteResult);
130 #endif
131
132     RadioButtonGroups& radioButtonGroups() { return m_radioButtonGroups; }
133
134     const Vector<FormAssociatedElement*>& associatedElements() const { return m_associatedElements; }
135     const Vector<HTMLImageElement*>& imageElements() const { return m_imageElements; }
136
137     void getTextFieldValues(StringPairVector& fieldNamesAndValues) const;
138
139     static HTMLFormElement* findClosestFormAncestor(const Element&);
140
141 private:
142     HTMLFormElement(const QualifiedName&, Document&);
143
144     bool rendererIsNeeded(const RenderStyle&) final;
145     InsertionNotificationRequest insertedInto(ContainerNode&) final;
146     void removedFrom(ContainerNode&) final;
147     void finishParsingChildren() final;
148
149     void handleLocalEvents(Event&) final;
150
151     void parseAttribute(const QualifiedName&, const AtomicString&) final;
152     bool isURLAttribute(const Attribute&) const final;
153
154     void resumeFromDocumentSuspension() final;
155
156     void didMoveToNewDocument(Document* oldDocument) final;
157
158     void copyNonAttributePropertiesFromElement(const Element&) final;
159
160     void submit(Event*, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger);
161
162     unsigned formElementIndexWithFormAttribute(Element*, unsigned rangeStart, unsigned rangeEnd);
163     unsigned formElementIndex(FormAssociatedElement*);
164
165     bool validateInteractively();
166
167     // Validates each of the controls, and stores controls of which 'invalid'
168     // event was not canceled to the specified vector. Returns true if there
169     // are any invalid controls in this form.
170     bool checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<HTMLFormControlElement>>&);
171
172     HTMLElement* elementFromPastNamesMap(const AtomicString&) const;
173     void addToPastNamesMap(FormNamedItem*, const AtomicString& pastName);
174     void assertItemCanBeInPastNamesMap(FormNamedItem*) const;
175     void removeFromPastNamesMap(FormNamedItem*);
176
177     bool matchesValidPseudoClass() const final;
178     bool matchesInvalidPseudoClass() const final;
179
180     typedef HashMap<RefPtr<AtomicStringImpl>, FormNamedItem*> PastNamesMap;
181
182     FormSubmission::Attributes m_attributes;
183     std::unique_ptr<PastNamesMap> m_pastNamesMap;
184
185     RadioButtonGroups m_radioButtonGroups;
186     mutable HTMLFormControlElement* m_defaultButton { nullptr };
187
188     unsigned m_associatedElementsBeforeIndex;
189     unsigned m_associatedElementsAfterIndex;
190     Vector<FormAssociatedElement*> m_associatedElements;
191     Vector<HTMLImageElement*> m_imageElements;
192     HashSet<const HTMLFormControlElement*> m_invalidAssociatedFormControls;
193
194     bool m_wasUserSubmitted;
195     bool m_isSubmittingOrPreparingForSubmission;
196     bool m_shouldSubmit;
197
198     bool m_isInResetFunction;
199
200     bool m_wasDemoted;
201
202 #if ENABLE(REQUEST_AUTOCOMPLETE)
203     void requestAutocompleteTimerFired();
204
205     Vector<RefPtr<Event>> m_pendingAutocompleteEvents;
206     Timer m_requestAutocompleteTimer;
207 #endif
208 };
209
210 } // namespace WebCore