/src/serenity/Userland/Libraries/LibWeb/HTML/HTMLFormElement.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org> |
3 | | * Copyright (c) 2023, Kenneth Myhra <kennethmyhra@serenityos.org> |
4 | | * Copyright (c) 2023, Luke Wilde <lukew@serenityos.org> |
5 | | * |
6 | | * SPDX-License-Identifier: BSD-2-Clause |
7 | | */ |
8 | | |
9 | | #pragma once |
10 | | |
11 | | #include <AK/Time.h> |
12 | | #include <LibWeb/ARIA/Roles.h> |
13 | | #include <LibWeb/HTML/HTMLElement.h> |
14 | | #include <LibWeb/HTML/Navigable.h> |
15 | | |
16 | | namespace Web::HTML { |
17 | | |
18 | | // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fs-method |
19 | | #define ENUMERATE_FORM_METHOD_ATTRIBUTES \ |
20 | 0 | __ENUMERATE_FORM_METHOD_ATTRIBUTE(get, GET) \ |
21 | 0 | __ENUMERATE_FORM_METHOD_ATTRIBUTE(post, POST) \ |
22 | 0 | __ENUMERATE_FORM_METHOD_ATTRIBUTE(dialog, Dialog) |
23 | | |
24 | | // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fs-enctype |
25 | | #define ENUMERATE_FORM_METHOD_ENCODING_TYPES \ |
26 | 0 | __ENUMERATE_FORM_METHOD_ENCODING_TYPE("application/x-www-form-urlencoded", FormUrlEncoded) \ |
27 | 0 | __ENUMERATE_FORM_METHOD_ENCODING_TYPE("multipart/form-data", FormData) \ |
28 | 0 | __ENUMERATE_FORM_METHOD_ENCODING_TYPE("text/plain", PlainText) |
29 | | |
30 | | class HTMLFormElement final : public HTMLElement { |
31 | | WEB_PLATFORM_OBJECT(HTMLFormElement, HTMLElement); |
32 | | JS_DECLARE_ALLOCATOR(HTMLFormElement); |
33 | | |
34 | | public: |
35 | | virtual ~HTMLFormElement() override; |
36 | | |
37 | | String action_from_form_element(JS::NonnullGCPtr<HTMLElement> element) const; |
38 | | |
39 | | enum class MethodAttributeState { |
40 | | #define __ENUMERATE_FORM_METHOD_ATTRIBUTE(_, state) state, |
41 | | ENUMERATE_FORM_METHOD_ATTRIBUTES |
42 | | #undef __ENUMERATE_FORM_METHOD_ATTRIBUTE |
43 | | }; |
44 | | |
45 | | MethodAttributeState method_state_from_form_element(JS::NonnullGCPtr<HTMLElement const> element) const; |
46 | | |
47 | | enum class EncodingTypeAttributeState { |
48 | | #define __ENUMERATE_FORM_METHOD_ENCODING_TYPE(_, state) state, |
49 | | ENUMERATE_FORM_METHOD_ENCODING_TYPES |
50 | | #undef __ENUMERATE_FORM_METHOD_ENCODING_TYPE |
51 | | }; |
52 | | |
53 | | EncodingTypeAttributeState encoding_type_state_from_form_element(JS::NonnullGCPtr<HTMLElement> element) const; |
54 | | |
55 | | struct SubmitFormOptions { |
56 | | bool from_submit_binding = { false }; |
57 | | UserNavigationInvolvement user_involvement = { UserNavigationInvolvement::None }; |
58 | | }; |
59 | | WebIDL::ExceptionOr<void> submit_form(JS::NonnullGCPtr<HTMLElement> submitter, SubmitFormOptions); |
60 | | WebIDL::ExceptionOr<void> implicitly_submit_form(); |
61 | | |
62 | | void reset_form(); |
63 | | |
64 | | // NOTE: This is for the JS bindings. Use submit_form instead. |
65 | | WebIDL::ExceptionOr<void> submit(); |
66 | | |
67 | | // NOTE: This is for the JS bindings. Use submit_form instead. |
68 | | WebIDL::ExceptionOr<void> request_submit(JS::GCPtr<Element> submitter); |
69 | | |
70 | | // NOTE: This is for the JS bindings. Use submit_form instead. |
71 | | void reset(); |
72 | | |
73 | | void add_associated_element(Badge<FormAssociatedElement>, HTMLElement&); |
74 | | void remove_associated_element(Badge<FormAssociatedElement>, HTMLElement&); |
75 | | |
76 | | Vector<JS::NonnullGCPtr<DOM::Element>> get_submittable_elements(); |
77 | | |
78 | | JS::NonnullGCPtr<HTMLFormControlsCollection> elements() const; |
79 | | unsigned length() const; |
80 | | |
81 | | WebIDL::ExceptionOr<bool> check_validity(); |
82 | | WebIDL::ExceptionOr<bool> report_validity(); |
83 | | |
84 | | // https://www.w3.org/TR/html-aria/#el-form |
85 | 0 | virtual Optional<ARIA::Role> default_role() const override { return ARIA::Role::form; } |
86 | | |
87 | | // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-entry-list |
88 | 0 | bool constructing_entry_list() const { return m_constructing_entry_list; } |
89 | 0 | void set_constructing_entry_list(bool value) { m_constructing_entry_list = value; } |
90 | | |
91 | | WebIDL::ExceptionOr<void> set_method(String const&); |
92 | | |
93 | | JS::NonnullGCPtr<DOM::DOMTokenList> rel_list(); |
94 | | |
95 | | String action() const; |
96 | | WebIDL::ExceptionOr<void> set_action(String const&); |
97 | | |
98 | | private: |
99 | | HTMLFormElement(DOM::Document&, DOM::QualifiedName); |
100 | | |
101 | 0 | virtual bool is_html_form_element() const override { return true; } |
102 | | |
103 | | virtual void initialize(JS::Realm&) override; |
104 | | virtual void visit_edges(Cell::Visitor&) override; |
105 | | |
106 | | // ^PlatformObject |
107 | | virtual Optional<JS::Value> item_value(size_t index) const override; |
108 | | virtual JS::Value named_item_value(FlyString const& name) const override; |
109 | | virtual Vector<FlyString> supported_property_names() const override; |
110 | | |
111 | | virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value) override; |
112 | | |
113 | | ErrorOr<String> pick_an_encoding() const; |
114 | | |
115 | | ErrorOr<void> mutate_action_url(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement); |
116 | | ErrorOr<void> submit_as_entity_body(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement); |
117 | | void get_action_url(URL::URL parsed_action, JS::NonnullGCPtr<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement); |
118 | | ErrorOr<void> mail_with_headers(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement); |
119 | | ErrorOr<void> mail_as_body(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement); |
120 | | void plan_to_navigate_to(URL::URL url, Variant<Empty, String, POSTResource> post_resource, JS::NonnullGCPtr<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement); |
121 | | |
122 | | FormAssociatedElement* default_button(); |
123 | | size_t number_of_fields_blocking_implicit_submission() const; |
124 | | |
125 | | bool m_firing_submission_events { false }; |
126 | | |
127 | | // https://html.spec.whatwg.org/multipage/forms.html#locked-for-reset |
128 | | bool m_locked_for_reset { false }; |
129 | | |
130 | | Vector<JS::NonnullGCPtr<HTMLElement>> m_associated_elements; |
131 | | |
132 | | // https://html.spec.whatwg.org/multipage/forms.html#past-names-map |
133 | | struct PastNameEntry { |
134 | | JS::GCPtr<DOM::Node const> node; |
135 | | MonotonicTime insertion_time; |
136 | | }; |
137 | | HashMap<FlyString, PastNameEntry> mutable m_past_names_map; |
138 | | |
139 | | JS::GCPtr<HTMLFormControlsCollection> mutable m_elements; |
140 | | |
141 | | bool m_constructing_entry_list { false }; |
142 | | |
143 | | // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#planned-navigation |
144 | | // Each form element has a planned navigation, which is either null or a task; when the form is first created, |
145 | | // its planned navigation must be set to null. |
146 | | JS::GCPtr<Task const> m_planned_navigation; |
147 | | |
148 | | JS::GCPtr<DOM::DOMTokenList> m_rel_list; |
149 | | }; |
150 | | |
151 | | } |
152 | | |
153 | | namespace Web::DOM { |
154 | | template<> |
155 | 0 | inline bool Node::fast_is<HTML::HTMLFormElement>() const { return is_html_form_element(); } |
156 | | } |