From 7167d6a1c885477ed577177190e452624156f7de Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sun, 3 Sep 2023 00:07:58 +1200 Subject: [PATCH] LibWeb: Support readonly attribute for input elements --- .../LibWeb/HTML/HTMLInputElement.cpp | 42 ++++++++++++++++++- .../Libraries/LibWeb/HTML/HTMLInputElement.h | 5 +++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index ac514b3730..497db27f09 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -379,6 +379,38 @@ void HTMLInputElement::update_placeholder_visibility() } } +// https://html.spec.whatwg.org/multipage/input.html#the-input-element:attr-input-readonly-3 +static bool is_allowed_to_be_readonly(HTML::HTMLInputElement::TypeAttributeState state) +{ + switch (state) { + case HTML::HTMLInputElement::TypeAttributeState::Text: + case HTML::HTMLInputElement::TypeAttributeState::Search: + case HTML::HTMLInputElement::TypeAttributeState::Telephone: + case HTML::HTMLInputElement::TypeAttributeState::URL: + case HTML::HTMLInputElement::TypeAttributeState::Email: + case HTML::HTMLInputElement::TypeAttributeState::Password: + case HTML::HTMLInputElement::TypeAttributeState::Date: + case HTML::HTMLInputElement::TypeAttributeState::Month: + case HTML::HTMLInputElement::TypeAttributeState::Week: + case HTML::HTMLInputElement::TypeAttributeState::Time: + case HTML::HTMLInputElement::TypeAttributeState::LocalDateAndTime: + case HTML::HTMLInputElement::TypeAttributeState::Number: + return true; + default: + return false; + } +} + +// https://html.spec.whatwg.org/multipage/input.html#attr-input-readonly +void HTMLInputElement::handle_readonly_attribute(DeprecatedFlyString const& value) +{ + // The readonly attribute is a boolean attribute that controls whether or not the user can edit the form control. When specified, the element is not mutable. + m_is_mutable = !(!value.is_null() && is_allowed_to_be_readonly(m_type)); + + if (m_text_node) + m_text_node->set_always_editable(m_is_mutable); +} + // https://html.spec.whatwg.org/multipage/input.html#the-input-element:attr-input-placeholder-3 static bool is_allowed_to_have_placeholder(HTML::HTMLInputElement::TypeAttributeState state) { @@ -476,7 +508,13 @@ void HTMLInputElement::create_shadow_tree_if_needed() MUST(m_inner_text_element->style_for_bindings()->set_property(CSS::PropertyID::Height, "1lh"sv)); m_text_node = heap().allocate(realm(), document(), initial_value); - m_text_node->set_always_editable(m_type != TypeAttributeState::FileUpload); + if (m_type == TypeAttributeState::FileUpload) { + // NOTE: file upload state is mutable, but we don't allow the text node to be modifed + m_text_node->set_always_editable(false); + } else { + handle_readonly_attribute(attribute(HTML::AttributeNames::readonly)); + } + m_text_node->set_owner_input_element({}, *this); if (m_type == TypeAttributeState::Password) @@ -541,6 +579,8 @@ void HTMLInputElement::attribute_changed(DeprecatedFlyString const& name, Deprec } else if (name == HTML::AttributeNames::placeholder) { if (m_placeholder_text_node) m_placeholder_text_node->set_data(value); + } else if (name == HTML::AttributeNames::readonly) { + handle_readonly_attribute(value); } } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h index 8231d30c85..9e1536a197 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -162,6 +162,8 @@ private: WebIDL::ExceptionOr run_input_activation_behavior(); void set_checked_within_group(); + void handle_readonly_attribute(DeprecatedFlyString const& value); + // https://html.spec.whatwg.org/multipage/input.html#value-sanitization-algorithm DeprecatedString value_sanitization_algorithm(DeprecatedString) const; @@ -182,6 +184,9 @@ private: // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-fe-dirty bool m_dirty_value { false }; + // https://html.spec.whatwg.org/multipage/input.html#the-input-element:concept-fe-mutable + bool m_is_mutable { true }; + // https://html.spec.whatwg.org/multipage/input.html#the-input-element:legacy-pre-activation-behavior bool m_before_legacy_pre_activation_behavior_checked { false }; bool m_before_legacy_pre_activation_behavior_indeterminate { false };