diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp
index 66ba41d91bc74..8e78a8a6dfb0e 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 eea5b700ffdbb..30747c6d92889 100644
--- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h
+++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h
@@ -137,6 +137,8 @@ class FormAssociatedElement {
// 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 ada592c5e1dae..59759bcc1ca6d 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 5740e18332c36..9c75cb65c89b2 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
@@ -199,6 +199,9 @@ class HTMLInputElement final
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 22c6284beab04..5d3c84248087b 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 e69fe45abea13..be0d7683e2a09 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h
@@ -114,6 +114,9 @@ class HTMLTextAreaElement final
String selection_direction_binding() const;
void set_selection_direction_binding(String direction);
+protected:
+ void selection_was_changed() override;
+
private:
HTMLTextAreaElement(DOM::Document&, DOM::QualifiedName);