From d0b97873d421d092eb41e3b7a7d8959347b3b436 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Fri, 4 Oct 2024 12:12:39 +0100 Subject: [PATCH] LibWeb: Follow spec steps to set the selectionDirection attribute value --- .../DOM/FormAssociatedElement-selection.txt | 1 + ...sociatedElement-set-selectionDirection.txt | 2 ++ ...ociatedElement-set-selectionDirection.html | 25 +++++++++++++++++++ .../LibWeb/HTML/FormAssociatedElement.cpp | 16 ++++++++++++ .../LibWeb/HTML/FormAssociatedElement.h | 1 + .../LibWeb/HTML/HTMLInputElement.cpp | 15 +++++++++++ .../Libraries/LibWeb/HTML/HTMLInputElement.h | 3 +++ .../LibWeb/HTML/HTMLInputElement.idl | 2 +- .../LibWeb/HTML/HTMLTextAreaElement.cpp | 5 ++-- .../LibWeb/HTML/HTMLTextAreaElement.h | 2 +- 10 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/HTML/FormAssociatedElement-set-selectionDirection.txt create mode 100644 Tests/LibWeb/Text/input/HTML/FormAssociatedElement-set-selectionDirection.html diff --git a/Tests/LibWeb/Text/expected/DOM/FormAssociatedElement-selection.txt b/Tests/LibWeb/Text/expected/DOM/FormAssociatedElement-selection.txt index 85d6a681077..e1991cb4eff 100644 --- a/Tests/LibWeb/Text/expected/DOM/FormAssociatedElement-selection.txt +++ b/Tests/LibWeb/Text/expected/DOM/FormAssociatedElement-selection.txt @@ -15,4 +15,5 @@ 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 +select event fired: 6 6 textarea selectionStart: 0 selectionEnd: 9 selectionDirection: none diff --git a/Tests/LibWeb/Text/expected/HTML/FormAssociatedElement-set-selectionDirection.txt b/Tests/LibWeb/Text/expected/HTML/FormAssociatedElement-set-selectionDirection.txt new file mode 100644 index 00000000000..b3386c9f5fe --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/FormAssociatedElement-set-selectionDirection.txt @@ -0,0 +1,2 @@ +select event fired for input +select event fired for textarea diff --git a/Tests/LibWeb/Text/input/HTML/FormAssociatedElement-set-selectionDirection.html b/Tests/LibWeb/Text/input/HTML/FormAssociatedElement-set-selectionDirection.html new file mode 100644 index 00000000000..c2f4b26ca1b --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/FormAssociatedElement-set-selectionDirection.html @@ -0,0 +1,25 @@ + + + diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp index 9a8b4ea3fcb..aa43970d0d0 100644 --- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp @@ -366,6 +366,22 @@ void FormAssociatedTextControlElement::set_selection_direction(Optional m_selection_direction = string_to_selection_direction(direction); } +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectiondirection +WebIDL::ExceptionOr FormAssociatedTextControlElement::set_selection_direction_binding(Optional direction) +{ + // 1. If this element is an input element, and selectionDirection does not apply to this element, + // throw an "InvalidStateError" DOMException. + auto const& html_element = form_associated_element_to_html_element(); + if (is(html_element)) { + auto const& input_element = static_cast(html_element); + if (!input_element.selection_direction_applies()) + return WebIDL::InvalidStateError::create(input_element.realm(), "selectionDirection does not apply to element"_fly_string); + } + + set_the_selection_range(m_selection_start, m_selection_end, string_to_selection_direction(direction)); + return {}; +} + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-setrangetext WebIDL::ExceptionOr FormAssociatedTextControlElement::set_range_text(String const& replacement) { diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h index 5eb30e2f008..7f6714a30ad 100644 --- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h +++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h @@ -149,6 +149,7 @@ public: // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectiondirection Optional selection_direction() const; void set_selection_direction(Optional direction); + WebIDL::ExceptionOr set_selection_direction_binding(Optional direction); SelectionDirection selection_direction_state() const { return m_selection_direction; } // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-setrangetext diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 801e18b5b8b..df459fe4c35 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -2359,6 +2359,21 @@ bool HTMLInputElement::selection_or_range_applies() const return selection_or_range_applies_for_type_state(type_state()); } +// https://html.spec.whatwg.org/multipage/input.html#do-not-apply +bool HTMLInputElement::selection_direction_applies() const +{ + switch (type_state()) { + case TypeAttributeState::Text: + case TypeAttributeState::Search: + case TypeAttributeState::Telephone: + case TypeAttributeState::URL: + case TypeAttributeState::Password: + return true; + default: + return false; + } +} + bool HTMLInputElement::has_selectable_text() const { // Potential FIXME: Date, Month, Week, Time and LocalDateAndTime are rendered as a basic text input for now, diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h index abd8a2c3ca3..b021b2b33dc 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -204,10 +204,13 @@ public: bool step_up_or_down_applies() const; bool select_applies() const; bool selection_or_range_applies() const; + bool selection_direction_applies() const; bool has_selectable_text() const; static bool selection_or_range_applies_for_type_state(TypeAttributeState); + Optional selection_direction_binding() { return selection_direction(); } + protected: void selection_was_changed(size_t selection_start, size_t selection_end) override; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.idl b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.idl index 04ad87bd960..4b260ba24d0 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.idl +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.idl @@ -60,7 +60,7 @@ interface HTMLInputElement : HTMLElement { undefined select(); attribute unsigned long? selectionStart; attribute unsigned long? selectionEnd; - attribute DOMString? selectionDirection; + [ImplementedAs=selection_direction_binding] attribute DOMString? selectionDirection; undefined setRangeText(DOMString replacement); undefined setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve"); undefined setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp index f52e4de74e8..9c555bbefd6 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp @@ -329,9 +329,10 @@ String HTMLTextAreaElement::selection_direction_binding() const return selection_direction().value(); } -void HTMLTextAreaElement::set_selection_direction_binding(String direction) +void HTMLTextAreaElement::set_selection_direction_binding(String const& direction) { - set_selection_direction(direction); + // NOTE: The selectionDirection setter never returns an error for textarea elements. + MUST(static_cast(*this).set_selection_direction_binding(direction)); } void HTMLTextAreaElement::create_shadow_tree_if_needed() diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h index ab0c300ff09..726c8119786 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h @@ -118,7 +118,7 @@ public: // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectiondirection String selection_direction_binding() const; - void set_selection_direction_binding(String direction); + void set_selection_direction_binding(String const& direction); void set_dirty_value_flag(Badge, bool flag) { m_dirty_value = flag; }