Serenity Operating System
at master 176 lines 7.4 kB view raw
1/* 2 * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org> 3 * Copyright (c) 2022, Adam Hodgen <ant1441@gmail.com> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <LibWeb/FileAPI/FileList.h> 11#include <LibWeb/HTML/FormAssociatedElement.h> 12#include <LibWeb/HTML/HTMLElement.h> 13#include <LibWeb/WebIDL/DOMException.h> 14 15namespace Web::HTML { 16 17// https://html.spec.whatwg.org/multipage/input.html#attr-input-type 18#define ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTES \ 19 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(hidden, Hidden) \ 20 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(text, Text) \ 21 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(search, Search) \ 22 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(tel, Telephone) \ 23 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(url, URL) \ 24 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(email, Email) \ 25 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(password, Password) \ 26 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(date, Date) \ 27 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(month, Month) \ 28 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(week, Week) \ 29 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(time, Time) \ 30 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE("datetime-local", LocalDateAndTime) \ 31 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(number, Number) \ 32 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(range, Range) \ 33 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(color, Color) \ 34 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(checkbox, Checkbox) \ 35 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(radio, RadioButton) \ 36 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(file, FileUpload) \ 37 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(submit, SubmitButton) \ 38 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(image, ImageButton) \ 39 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(reset, ResetButton) \ 40 __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(button, Button) 41 42class HTMLInputElement final 43 : public HTMLElement 44 , public FormAssociatedElement { 45 WEB_PLATFORM_OBJECT(HTMLInputElement, HTMLElement); 46 FORM_ASSOCIATED_ELEMENT(HTMLElement, HTMLInputElement) 47 48public: 49 virtual ~HTMLInputElement() override; 50 51 virtual JS::GCPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::StyleProperties>) override; 52 53 enum class TypeAttributeState { 54#define __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE(_, state) state, 55 ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTES 56#undef __ENUMERATE_HTML_INPUT_TYPE_ATTRIBUTE 57 }; 58 59 DeprecatedString type() const; 60 TypeAttributeState type_state() const { return m_type; } 61 void set_type(DeprecatedString const&); 62 63 DeprecatedString default_value() const { return attribute(HTML::AttributeNames::value); } 64 DeprecatedString name() const { return attribute(HTML::AttributeNames::name); } 65 66 DeprecatedString value() const; 67 WebIDL::ExceptionOr<void> set_value(DeprecatedString); 68 69 Optional<DeprecatedString> placeholder_value() const; 70 71 bool checked() const { return m_checked; } 72 enum class ChangeSource { 73 Programmatic, 74 User, 75 }; 76 void set_checked(bool, ChangeSource = ChangeSource::Programmatic); 77 78 bool checked_binding() const { return checked(); } 79 void set_checked_binding(bool); 80 81 void did_edit_text_node(Badge<BrowsingContext>); 82 83 JS::GCPtr<FileAPI::FileList> files(); 84 void set_files(JS::GCPtr<FileAPI::FileList>); 85 86 // NOTE: User interaction 87 // https://html.spec.whatwg.org/multipage/input.html#update-the-file-selection 88 void update_the_file_selection(JS::NonnullGCPtr<FileAPI::FileList>); 89 90 WebIDL::ExceptionOr<void> set_selection_range(u32 start, u32 end, DeprecatedString const& direction); 91 92 WebIDL::ExceptionOr<void> show_picker(); 93 94 // ^EventTarget 95 // https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute:the-input-element 96 virtual bool is_focusable() const override { return m_type != TypeAttributeState::Hidden; } 97 98 // ^HTMLElement 99 virtual void parse_attribute(DeprecatedFlyString const&, DeprecatedString const&) override; 100 virtual void did_remove_attribute(DeprecatedFlyString const&) override; 101 102 // ^FormAssociatedElement 103 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 104 virtual bool is_listed() const override { return true; } 105 106 // https://html.spec.whatwg.org/multipage/forms.html#category-submit 107 virtual bool is_submittable() const override { return true; } 108 109 // https://html.spec.whatwg.org/multipage/forms.html#category-reset 110 virtual bool is_resettable() const override { return true; } 111 112 // https://html.spec.whatwg.org/multipage/forms.html#category-autocapitalize 113 virtual bool is_auto_capitalize_inheriting() const override { return true; } 114 115 virtual void reset_algorithm() override; 116 117 virtual void form_associated_element_was_inserted() override; 118 119 // ^HTMLElement 120 // https://html.spec.whatwg.org/multipage/forms.html#category-label 121 virtual bool is_labelable() const override { return type_state() != TypeAttributeState::Hidden; } 122 123 virtual Optional<ARIA::Role> default_role() const override; 124 125private: 126 HTMLInputElement(DOM::Document&, DOM::QualifiedName); 127 128 // ^DOM::Node 129 virtual bool is_html_input_element() const final { return true; } 130 131 // ^DOM::EventTarget 132 virtual void did_receive_focus() override; 133 virtual void legacy_pre_activation_behavior() override; 134 virtual void legacy_cancelled_activation_behavior() override; 135 virtual void legacy_cancelled_activation_behavior_was_not_called() override; 136 137 // ^DOM::Element 138 virtual i32 default_tab_index_value() const override; 139 140 virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override; 141 virtual void visit_edges(Cell::Visitor&) override; 142 143 static TypeAttributeState parse_type_attribute(StringView); 144 void create_shadow_tree_if_needed(); 145 ErrorOr<void> run_input_activation_behavior(); 146 void set_checked_within_group(); 147 148 // https://html.spec.whatwg.org/multipage/input.html#value-sanitization-algorithm 149 DeprecatedString value_sanitization_algorithm(DeprecatedString) const; 150 151 JS::GCPtr<DOM::Text> m_text_node; 152 bool m_checked { false }; 153 154 // https://html.spec.whatwg.org/multipage/input.html#concept-input-checked-dirty-flag 155 bool m_dirty_checkedness { false }; 156 157 // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-fe-dirty 158 bool m_dirty_value { false }; 159 160 // https://html.spec.whatwg.org/multipage/input.html#the-input-element:legacy-pre-activation-behavior 161 bool m_before_legacy_pre_activation_behavior_checked { false }; 162 JS::GCPtr<HTMLInputElement> m_legacy_pre_activation_behavior_checked_element_in_group; 163 164 // https://html.spec.whatwg.org/multipage/input.html#concept-input-type-file-selected 165 JS::GCPtr<FileAPI::FileList> m_selected_files; 166 167 TypeAttributeState m_type { TypeAttributeState::Text }; 168 DeprecatedString m_value; 169}; 170 171} 172 173namespace Web::DOM { 174template<> 175inline bool Node::fast_is<HTML::HTMLInputElement>() const { return is_html_input_element(); } 176}