diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index cb84f3cc87..27a2486ebb 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -22,6 +22,7 @@ namespace Web::HTML { HTMLInputElement::HTMLInputElement(DOM::Document& document, DOM::QualifiedName qualified_name) : FormAssociatedElement(document, move(qualified_name)) + , m_value(String::empty()) { activation_behavior = [this](auto&) { // The activation behavior for input elements are these steps: @@ -117,6 +118,10 @@ void HTMLInputElement::run_input_activation_behavior() void HTMLInputElement::did_edit_text_node(Badge) { + // An input element's dirty value flag must be set to true whenever the user interacts with the control in a way that changes the value. + m_value = value_sanitization_algorithm(m_text_node->data()); + m_dirty_value = true; + // NOTE: This is a bit ad-hoc, but basically implements part of "4.10.5.5 Common event behaviors" // https://html.spec.whatwg.org/multipage/input.html#common-input-element-events queue_an_element_task(HTML::Task::Source::UserInteraction, [this] { @@ -132,22 +137,33 @@ void HTMLInputElement::did_edit_text_node(Badge) }); } +// https://html.spec.whatwg.org/multipage/input.html#dom-input-value-value String HTMLInputElement::value() const { - if (m_text_node) - return m_text_node->data(); - return default_value(); + // Return the current value of the element. + return m_value; } +// https://html.spec.whatwg.org/multipage/input.html#dom-input-value-value void HTMLInputElement::set_value(String value) { - auto sanitised_value = value_sanitization_algorithm(move(value)); + // 1. Let oldValue be the element's value. + auto old_value = move(m_value); - if (m_text_node) { - m_text_node->set_data(sanitised_value); - return; - } - set_attribute(HTML::AttributeNames::value, sanitised_value); + // 2. Set the element's value to the new value. + // NOTE: This is done as part of step 4 below. + + // 3. Set the element's dirty value flag to true. + m_dirty_value = true; + + // 4. Invoke the value sanitization algorithm, if the element's type attribute's current state defines one. + m_value = value_sanitization_algorithm(move(value)); + + // 5. If the element's value (after applying the value sanitization algorithm) is different from oldValue, + // and the element has a text entry cursor position, move the text entry cursor position to the end of the + // text control, unselecting any selected text and resetting the selection direction to "none". + if (m_text_node && (m_value != old_value)) + m_text_node->set_data(m_value); } void HTMLInputElement::create_shadow_tree_if_needed() @@ -169,7 +185,7 @@ void HTMLInputElement::create_shadow_tree_if_needed() } auto shadow_root = adopt_ref(*new DOM::ShadowRoot(document(), *this)); - auto initial_value = attribute(HTML::AttributeNames::value); + auto initial_value = m_value; if (initial_value.is_null()) initial_value = String::empty(); auto element = document().create_element(HTML::TagNames::div).release_value(); @@ -207,6 +223,9 @@ void HTMLInputElement::parse_attribute(FlyString const& name, String const& valu set_checked(true, ChangeSource::Programmatic); } else if (name == HTML::AttributeNames::type) { m_type = parse_type_attribute(value); + } else if (name == HTML::AttributeNames::value) { + if (!m_dirty_value) + m_value = value_sanitization_algorithm(value); } } @@ -232,6 +251,9 @@ void HTMLInputElement::did_remove_attribute(FlyString const& name) // the user agent must set the checkedness of the element to false. if (!m_dirty_checkedness) set_checked(false, ChangeSource::Programmatic); + } else if (name == HTML::AttributeNames::value) { + if (!m_dirty_value) + m_value = String::empty(); } } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h index 78935804b6..75ddaa1cf0 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -119,11 +119,15 @@ private: // https://html.spec.whatwg.org/multipage/input.html#concept-input-checked-dirty-flag bool m_dirty_checkedness { false }; + // 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:legacy-pre-activation-behavior bool m_before_legacy_pre_activation_behavior_checked { false }; RefPtr m_legacy_pre_activation_behavior_checked_element_in_group; TypeAttributeState m_type { TypeAttributeState::Text }; + String m_value; }; }