From 1d9c404b8cb898b351ee3c69840bf943e97d499c Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Tue, 10 Sep 2024 11:28:44 +1000 Subject: [PATCH] LibWeb: Don't move focus when setting input value --- .../DOM/FormAssociatedElement-selection.txt | 7 ++- .../DOM/FormAssociatedElement-selection.html | 51 ++++++++++++++----- .../LibWeb/HTML/FormAssociatedElement.cpp | 8 +-- .../LibWeb/HTML/FormAssociatedElement.h | 7 ++- .../LibWeb/HTML/HTMLInputElement.cpp | 4 +- .../LibWeb/HTML/HTMLTextAreaElement.cpp | 6 +-- .../Libraries/LibWeb/Page/EventHandler.cpp | 2 +- 7 files changed, 59 insertions(+), 26 deletions(-) diff --git a/Tests/LibWeb/Text/expected/DOM/FormAssociatedElement-selection.txt b/Tests/LibWeb/Text/expected/DOM/FormAssociatedElement-selection.txt index e163b3c7546..82e0f710803 100644 --- a/Tests/LibWeb/Text/expected/DOM/FormAssociatedElement-selection.txt +++ b/Tests/LibWeb/Text/expected/DOM/FormAssociatedElement-selection.txt @@ -4,11 +4,16 @@ date-input selectionStart: null selectionEnd: null selectionDirection: null textarea selectionStart: 0 selectionEnd: 0 selectionDirection: none text-input selectionStart: 18 selectionEnd: 18 selectionDirection: none date input setting selectionStart error: InvalidStateError: setSelectionStart does not apply to this input type +select event fired: 0 18 text-input selectionStart: 0 selectionEnd: 18 selectionDirection: none +select event fired: 2 4 text-input selectionStart: 2 selectionEnd: 4 selectionDirection: forward +select event fired: 1 4 text-input selectionStart: 1 selectionEnd: 4 selectionDirection: forward +select event fired: 1 5 text-input selectionStart: 1 selectionEnd: 5 selectionDirection: forward +select event fired: 6 6 text-input selectionStart: 6 selectionEnd: 6 selectionDirection: forward +select event fired: 6 6 text-input selectionStart: 6 selectionEnd: 6 selectionDirection: backward textarea selectionStart: 0 selectionEnd: 9 selectionDirection: none -select event fired: 9 9 diff --git a/Tests/LibWeb/Text/input/DOM/FormAssociatedElement-selection.html b/Tests/LibWeb/Text/input/DOM/FormAssociatedElement-selection.html index db560c01b9b..33a70c7135b 100644 --- a/Tests/LibWeb/Text/input/DOM/FormAssociatedElement-selection.html +++ b/Tests/LibWeb/Text/input/DOM/FormAssociatedElement-selection.html @@ -4,7 +4,7 @@ text diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp index 7cbe3e6e3d8..7bc201a9233 100644 --- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp @@ -508,7 +508,7 @@ WebIDL::ExceptionOr FormAssociatedTextControlElement::set_selection_range( } // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#set-the-selection-range -void FormAssociatedTextControlElement::set_the_selection_range(Optional start, Optional end, SelectionDirection direction) +void FormAssociatedTextControlElement::set_the_selection_range(Optional start, Optional end, SelectionDirection direction, SelectionSource source) { // 1. If start is null, let start be zero. start = start.value_or(0); @@ -551,9 +551,9 @@ void FormAssociatedTextControlElement::set_the_selection_range(Optional(&html_element)->dispatch_event(select_event); diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h index a43273efeb0..5770c551093 100644 --- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h +++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h @@ -122,6 +122,11 @@ private: bool m_parser_inserted { false }; }; +enum class SelectionSource { + UI, + DOM, +}; + class FormAssociatedTextControlElement : public FormAssociatedElement { public: // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value @@ -151,7 +156,7 @@ public: WebIDL::ExceptionOr set_range_text(String const& replacement, WebIDL::UnsignedLong start, WebIDL::UnsignedLong end, Bindings::SelectionMode = Bindings::SelectionMode::Preserve); // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-setselectionrange - void set_the_selection_range(Optional start, Optional end, SelectionDirection direction = SelectionDirection::None); + void set_the_selection_range(Optional start, Optional end, SelectionDirection direction = SelectionDirection::None, SelectionSource source = SelectionSource::DOM); // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-setselectionrange WebIDL::ExceptionOr set_selection_range(Optional start, Optional end, Optional direction); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index cd790e23ba7..643ce9b7068 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -562,7 +562,7 @@ WebIDL::ExceptionOr HTMLInputElement::set_value(String const& value) m_text_node->set_data(m_value); update_placeholder_visibility(); - document().set_cursor_position(DOM::Position::create(realm, *m_text_node, m_text_node->data().bytes().size())); + set_the_selection_range(m_text_node->length(), m_text_node->length()); } update_shadow_tree(); @@ -2429,7 +2429,7 @@ HTMLInputElement::ValueAttributeMode HTMLInputElement::value_attribute_mode() co void HTMLInputElement::selection_was_changed(size_t selection_start, size_t selection_end) { - if (!m_text_node) + if (!m_text_node || !document().cursor_position() || document().cursor_position()->node() != m_text_node) return; document().set_cursor_position(DOM::Position::create(realm(), *m_text_node, selection_end)); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp index 4c0cdb6a818..f52e4de74e8 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp @@ -164,8 +164,6 @@ String HTMLTextAreaElement::value() const // https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-value void HTMLTextAreaElement::set_value(String const& value) { - auto& realm = this->realm(); - // 1. Let oldAPIValue be this element's API value. auto old_api_value = api_value(); @@ -182,7 +180,7 @@ void HTMLTextAreaElement::set_value(String const& value) m_text_node->set_data(m_raw_value); update_placeholder_visibility(); - document().set_cursor_position(DOM::Position::create(realm, *m_text_node, m_text_node->data().bytes().size())); + set_the_selection_range(m_text_node->length(), m_text_node->length()); } } } @@ -463,7 +461,7 @@ void HTMLTextAreaElement::queue_firing_input_event() void HTMLTextAreaElement::selection_was_changed(size_t selection_start, size_t selection_end) { - if (!m_text_node) + if (!m_text_node || !document().cursor_position() || document().cursor_position()->node() != m_text_node) return; document().set_cursor_position(DOM::Position::create(realm(), *m_text_node, selection_end)); diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp index a3d6a4dbabb..42b235bb677 100644 --- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp @@ -1215,7 +1215,7 @@ void EventHandler::update_selection_range_for_input_or_textarea() target = static_cast(*shadow_host); if (target.has_value()) - target.value().set_the_selection_range(selection_start, selection_end, direction); + target.value().set_the_selection_range(selection_start, selection_end, direction, HTML::SelectionSource::UI); } Unicode::Segmenter& EventHandler::word_segmenter()