diff --git a/Tests/LibWeb/Text/expected/textarea-selection-start-selection-end.txt b/Tests/LibWeb/Text/expected/textarea-selection-start-selection-end.txt new file mode 100644 index 00000000000..4ad111b5fa7 --- /dev/null +++ b/Tests/LibWeb/Text/expected/textarea-selection-start-selection-end.txt @@ -0,0 +1,4 @@ +Well hello friends selectionStart: 0 +selectionEnd: 0 +selectionStart: 18 +selectionEnd: 18 diff --git a/Tests/LibWeb/Text/input/textarea-selection-start-selection-end.html b/Tests/LibWeb/Text/input/textarea-selection-start-selection-end.html new file mode 100644 index 00000000000..00aadd9015f --- /dev/null +++ b/Tests/LibWeb/Text/input/textarea-selection-start-selection-end.html @@ -0,0 +1,15 @@ + + + diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp index fc15d6cee38..c49bb17f064 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp @@ -201,6 +201,63 @@ void HTMLTextAreaElement::set_custom_validity(String const& error) dbgln("(STUBBED) HTMLTextAreaElement::set_custom_validity(\"{}\"). Called on: {}", error, debug_description()); } +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectionstart +WebIDL::UnsignedLong HTMLTextAreaElement::selection_start() const +{ + // 1. If this element is an input element, and selectionStart does not apply to this element, return null. + + // 2. If there is no selection, return the code unit offset within the relevant value to the character that + // immediately follows the text entry cursor. + if (auto const* browsing_context = document().browsing_context()) { + if (auto cursor = browsing_context->cursor_position()) + return cursor->offset(); + } + + // FIXME: 3. Return the code unit offset within the relevant value to the character that immediately follows the start of + // the selection. + return 0; +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#textFieldSelection:dom-textarea/input-selectionstart-2 +WebIDL::ExceptionOr HTMLTextAreaElement::set_selection_start(WebIDL::UnsignedLong) +{ + // 1. If this element is an input element, and selectionStart does not apply to this element, throw an + // "InvalidStateError" DOMException. + + // FIXME: 2. Let end be the value of this element's selectionEnd attribute. + // FIXME: 3. If end is less than the given value, set end to the given value. + // FIXME: 4. Set the selection range with the given value, end, and the value of this element's selectionDirection attribute. + return {}; +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectionend +WebIDL::UnsignedLong HTMLTextAreaElement::selection_end() const +{ + // 1. If this element is an input element, and selectionEnd does not apply to this element, return null. + + // 2. If there is no selection, return the code unit offset within the relevant value to the character that + // immediately follows the text entry cursor. + if (auto const* browsing_context = document().browsing_context()) { + if (auto cursor = browsing_context->cursor_position()) + return cursor->offset(); + } + + // FIXME: 3. Return the code unit offset within the relevant value to the character that immediately follows the end of + // the selection. + return 0; +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#textFieldSelection:dom-textarea/input-selectionend-3 +WebIDL::ExceptionOr HTMLTextAreaElement::set_selection_end(WebIDL::UnsignedLong) +{ + // 1. If this element is an input element, and selectionEnd does not apply to this element, throw an + // "InvalidStateError" DOMException. + + // FIXME: 2. Set the selection range with the value of this element's selectionStart attribute, the given value, and the + // value of this element's selectionDirection attribute. + return {}; +} + // https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-maxlength WebIDL::Long HTMLTextAreaElement::max_length() const { diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h index 7f254cec57d..44d8be94372 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h @@ -84,6 +84,12 @@ public: bool report_validity(); void set_custom_validity(String const& error); + WebIDL::UnsignedLong selection_start() const; + WebIDL::ExceptionOr set_selection_start(WebIDL::UnsignedLong); + + WebIDL::UnsignedLong selection_end() const; + WebIDL::ExceptionOr set_selection_end(WebIDL::UnsignedLong); + WebIDL::Long max_length() const; WebIDL::ExceptionOr set_max_length(WebIDL::Long); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.idl b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.idl index 5e7349437ab..52a2276f71f 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.idl +++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.idl @@ -35,8 +35,8 @@ interface HTMLTextAreaElement : HTMLElement { // FIXME: readonly attribute NodeList labels; // FIXME: undefined select(); - // FIXME: attribute unsigned long selectionStart; - // FIXME: attribute unsigned long selectionEnd; + attribute unsigned long selectionStart; + attribute unsigned long selectionEnd; // FIXME: attribute DOMString selectionDirection; // FIXME: undefined setRangeText(DOMString replacement); // FIXME: undefined setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve");