diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp index 66ba41d91bc..8e78a8a6dfb 100644 --- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp @@ -411,14 +411,21 @@ void FormAssociatedElement::set_the_selection_range(Optional(&html_element)->dispatch_event(select_event); - }); + + // AD-HOC: If there is no selection, we do not fire the event. This seems to correspond to how + // other browsers behave. + if (m_selection_start != m_selection_end) { + html_element.queue_an_element_task(Task::Source::UserInteraction, [&html_element] { + auto select_event = DOM::Event::create(html_element.realm(), EventNames::select, { .bubbles = true }); + static_cast(&html_element)->dispatch_event(select_event); + }); + } + + // AD-HOC: Notify the element that the selection was changed, so it can perform + // element-specific updates. + selection_was_changed(); } } diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h index eea5b700ffd..30747c6d928 100644 --- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h +++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h @@ -137,6 +137,8 @@ protected: // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value void relevant_value_was_changed(JS::GCPtr); + virtual void selection_was_changed() { } + private: void reset_form_owner(); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index ada592c5e1d..59759bcc1ca 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -2353,4 +2354,13 @@ HTMLInputElement::ValueAttributeMode HTMLInputElement::value_attribute_mode() co VERIFY_NOT_REACHED(); } +void HTMLInputElement::selection_was_changed() +{ + auto selection = document().get_selection(); + if (!selection || selection->range_count() == 0) + return; + + MUST(selection->set_base_and_extent(*m_text_node, selection_start().value(), *m_text_node, selection_end().value())); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h index 5740e18332c..9c75cb65c89 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -199,6 +199,9 @@ public: bool select_applies() const; bool selection_or_range_applies() const; +protected: + void selection_was_changed() override; + private: HTMLInputElement(DOM::Document&, DOM::QualifiedName); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp index 22c6284beab..5d3c8424808 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp @@ -22,6 +22,7 @@ #include #include #include +#include namespace Web::HTML { @@ -452,4 +453,13 @@ void HTMLTextAreaElement::queue_firing_input_event() }); } +void HTMLTextAreaElement::selection_was_changed() +{ + auto selection = document().get_selection(); + if (!selection || selection->range_count() == 0) + return; + + MUST(selection->set_base_and_extent(*m_text_node, selection_start().value(), *m_text_node, selection_end().value())); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h index e69fe45abea..be0d7683e2a 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h @@ -114,6 +114,9 @@ public: String selection_direction_binding() const; void set_selection_direction_binding(String direction); +protected: + void selection_was_changed() override; + private: HTMLTextAreaElement(DOM::Document&, DOM::QualifiedName);