| 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 | |