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-2019 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#include <wtf/IsoMalloc.h>
32#include <wtf/WeakHashSet.h>
33
34#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
35#include "Autocapitalize.h"
36#endif
37
38namespace WebCore {
39
40class Event;
41class FormAssociatedElement;
42class HTMLFormControlElement;
43class HTMLFormControlsCollection;
44class HTMLImageElement;
45
46class HTMLFormElement final : public HTMLElement {
47 WTF_MAKE_ISO_ALLOCATED(HTMLFormElement);
48public:
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 AtomString&);
56
57 WEBCORE_EXPORT unsigned length() const;
58 HTMLElement* item(unsigned index);
59 Optional<Variant<RefPtr<RadioNodeList>, RefPtr<Element>>> namedItem(const AtomString&);
60 Vector<AtomString> supportedPropertyNames() const;
61
62 String enctype() const { return m_attributes.encodingType(); }
63 WEBCORE_EXPORT void setEnctype(const String&);
64
65 bool shouldAutocomplete() const;
66
67 WEBCORE_EXPORT void setAutocomplete(const AtomString&);
68 WEBCORE_EXPORT const AtomString& autocomplete() const;
69
70#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
71 WEBCORE_EXPORT bool shouldAutocorrect() const final;
72#endif
73
74 // FIXME: Should rename these two functions to say "form control" or "form-associated element" instead of "form element".
75 void registerFormElement(FormAssociatedElement*);
76 void removeFormElement(FormAssociatedElement*);
77
78 void registerInvalidAssociatedFormControl(const HTMLFormControlElement&);
79 void removeInvalidAssociatedFormControlIfNeeded(const HTMLFormControlElement&);
80
81 void registerImgElement(HTMLImageElement*);
82 void removeImgElement(HTMLImageElement*);
83
84 void prepareForSubmission(Event&); // FIXME: This function doesn't only prepare, it sometimes calls submit() itself.
85 WEBCORE_EXPORT void submit();
86 void submitFromJavaScript();
87 WEBCORE_EXPORT void reset();
88
89 void setDemoted(bool demoted) { m_wasDemoted = demoted; }
90
91 void submitImplicitly(Event&, bool fromImplicitSubmissionTrigger);
92 bool formWouldHaveSecureSubmission(const String& url);
93
94 String name() const;
95
96 bool noValidate() const;
97
98 String acceptCharset() const { return m_attributes.acceptCharset(); }
99 void setAcceptCharset(const String&);
100
101 WEBCORE_EXPORT String action() const;
102 WEBCORE_EXPORT void setAction(const String&);
103
104 WEBCORE_EXPORT String method() const;
105 WEBCORE_EXPORT void setMethod(const String&);
106
107 String target() const final;
108 String effectiveTarget(const Event*) const;
109
110 bool wasUserSubmitted() const;
111
112 HTMLFormControlElement* findSubmitButton(const Event*) const;
113
114 HTMLFormControlElement* defaultButton() const;
115 void resetDefaultButton();
116
117 WEBCORE_EXPORT bool checkValidity();
118 bool reportValidity();
119
120 RadioButtonGroups& radioButtonGroups() { return m_radioButtonGroups; }
121
122 WEBCORE_EXPORT const Vector<FormAssociatedElement*>& unsafeAssociatedElements() const;
123 Vector<Ref<FormAssociatedElement>> copyAssociatedElementsVector() const;
124 const Vector<WeakPtr<HTMLImageElement>>& imageElements() const { return m_imageElements; }
125
126 StringPairVector textFieldValues() const;
127
128 static HTMLFormElement* findClosestFormAncestor(const Element&);
129
130private:
131 HTMLFormElement(const QualifiedName&, Document&);
132
133 bool rendererIsNeeded(const RenderStyle&) final;
134 InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) final;
135 void removedFromAncestor(RemovalType, ContainerNode&) final;
136 void finishParsingChildren() final;
137
138 void handleLocalEvents(Event&, EventInvokePhase) final;
139
140 void parseAttribute(const QualifiedName&, const AtomString&) final;
141 bool isURLAttribute(const Attribute&) const final;
142
143 void resumeFromDocumentSuspension() final;
144
145 void didMoveToNewDocument(Document& oldDocument, Document& newDocument) final;
146
147 void copyNonAttributePropertiesFromElement(const Element&) final;
148
149 void submit(Event*, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger);
150
151 unsigned formElementIndexWithFormAttribute(Element*, unsigned rangeStart, unsigned rangeEnd);
152 unsigned formElementIndex(FormAssociatedElement*);
153
154 bool validateInteractively();
155
156 // Validates each of the controls, and stores controls of which 'invalid'
157 // event was not canceled to the specified vector. Returns true if there
158 // are any invalid controls in this form.
159 bool checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<HTMLFormControlElement>>&);
160
161 RefPtr<HTMLElement> elementFromPastNamesMap(const AtomString&) const;
162 void addToPastNamesMap(FormNamedItem*, const AtomString& pastName);
163 void assertItemCanBeInPastNamesMap(FormNamedItem*) const;
164 void removeFromPastNamesMap(FormNamedItem*);
165
166 bool matchesValidPseudoClass() const final;
167 bool matchesInvalidPseudoClass() const final;
168
169 void resetAssociatedFormControlElements();
170
171 typedef HashMap<RefPtr<AtomStringImpl>, FormNamedItem*> PastNamesMap;
172
173 FormSubmission::Attributes m_attributes;
174 std::unique_ptr<PastNamesMap> m_pastNamesMap;
175
176 RadioButtonGroups m_radioButtonGroups;
177 mutable WeakPtr<HTMLFormControlElement> m_defaultButton;
178
179 unsigned m_associatedElementsBeforeIndex { 0 };
180 unsigned m_associatedElementsAfterIndex { 0 };
181 Vector<FormAssociatedElement*> m_associatedElements;
182 Vector<WeakPtr<HTMLImageElement>> m_imageElements;
183 WeakHashSet<HTMLFormControlElement> m_invalidAssociatedFormControls;
184
185 bool m_wasUserSubmitted { false };
186 bool m_isSubmittingOrPreparingForSubmission { false };
187 bool m_shouldSubmit { false };
188
189 bool m_isInResetFunction { false };
190
191 bool m_wasDemoted { false };
192};
193
194} // namespace WebCore
195