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 | |
38 | namespace WebCore { |
39 | |
40 | class Event; |
41 | class FormAssociatedElement; |
42 | class HTMLFormControlElement; |
43 | class HTMLFormControlsCollection; |
44 | class HTMLImageElement; |
45 | |
46 | class HTMLFormElement final : public HTMLElement { |
47 | WTF_MAKE_ISO_ALLOCATED(HTMLFormElement); |
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 | Optional<Variant<RefPtr<RadioNodeList>, RefPtr<Element>>> namedItem(const AtomicString&); |
60 | Vector<AtomicString> 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 AtomicString&); |
68 | WEBCORE_EXPORT const AtomicString& 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 | |
130 | private: |
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 AtomicString&) 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 AtomicString&) const; |
162 | void addToPastNamesMap(FormNamedItem*, const AtomicString& 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<AtomicStringImpl>, 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 | |