Skip to content

Commit

Permalink
LibWeb: Propagate input/textarea selection update to document selection
Browse files Browse the repository at this point in the history
Calling `.setSelectionRange()` or `.select()` now updates the document
selection as well, visualizing the text selection.
  • Loading branch information
gmta committed Aug 26, 2024
1 parent 16ebc23 commit 8f82b46
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 7 deletions.
21 changes: 14 additions & 7 deletions Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,14 +398,21 @@ void FormAssociatedElement::set_the_selection_range(Optional<WebIDL::UnsignedLon
// extent or direction), then queue an element task on the user interaction task source
// given the element to fire an event named select at the element, with the bubbles attribute
// initialized to true.
// AD-HOC: If there is no selection, we do not fire the event. This seems to correspond to how
// other browsers behave.
if (was_modified && m_selection_start != m_selection_end) {
if (was_modified) {
auto& html_element = form_associated_element_to_html_element();
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<DOM::EventTarget*>(&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<DOM::EventTarget*>(&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();
}
}

Expand Down
2 changes: 2 additions & 0 deletions Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<DOM::Text>);

virtual void selection_was_changed() { }

private:
void reset_form_owner();

Expand Down
10 changes: 10 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <LibWeb/MimeSniff/Resource.h>
#include <LibWeb/Namespace.h>
#include <LibWeb/Page/Page.h>
#include <LibWeb/Selection/Selection.h>
#include <LibWeb/UIEvents/EventNames.h>
#include <LibWeb/UIEvents/MouseEvent.h>
#include <LibWeb/WebIDL/DOMException.h>
Expand Down Expand Up @@ -2358,4 +2359,13 @@ bool HTMLInputElement::is_child_node_selectable(DOM::Node const& node) const
return !is_button() && (!m_placeholder_element || !m_placeholder_element->is_inclusive_ancestor_of(node));
}

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()));
}

}
3 changes: 3 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ class HTMLInputElement final
WebIDL::ExceptionOr<void> set_selection_end_for_bindings(Optional<WebIDL::UnsignedLong> const&);
Optional<WebIDL::UnsignedLong> selection_end_for_bindings() const;

protected:
void selection_was_changed() override;

private:
HTMLInputElement(DOM::Document&, DOM::QualifiedName);

Expand Down
10 changes: 10 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <LibWeb/HTML/Numbers.h>
#include <LibWeb/Infra/Strings.h>
#include <LibWeb/Namespace.h>
#include <LibWeb/Selection/Selection.h>

namespace Web::HTML {

Expand Down Expand Up @@ -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()));
}

}
3 changes: 3 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 8f82b46

Please sign in to comment.