diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp
index 8e78a8a6dfb..3c991680621 100644
--- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp
@@ -166,18 +166,7 @@ void FormAssociatedElement::reset_form_owner()
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value
-String FormAssociatedElement::relevant_value() const
-{
- auto const& html_element = form_associated_element_to_html_element();
- if (is(html_element))
- return static_cast(html_element).value();
- if (is(html_element))
- return static_cast(html_element).api_value();
- VERIFY_NOT_REACHED();
-}
-
-// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value
-void FormAssociatedElement::relevant_value_was_changed(JS::GCPtr text_node)
+void FormAssociatedTextControlElement::relevant_value_was_changed(JS::GCPtr text_node)
{
auto the_relevant_value = relevant_value();
auto relevant_value_length = the_relevant_value.code_points().length();
@@ -214,7 +203,7 @@ void FormAssociatedElement::relevant_value_was_changed(JS::GCPtr text
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-select
-WebIDL::ExceptionOr FormAssociatedElement::select()
+WebIDL::ExceptionOr FormAssociatedTextControlElement::select()
{
// 1. If this element is an input element, and either select() does not apply to this element
// or the corresponding control has no selectable text, return.
@@ -232,7 +221,7 @@ WebIDL::ExceptionOr FormAssociatedElement::select()
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectionstart
-Optional FormAssociatedElement::selection_start() const
+Optional FormAssociatedTextControlElement::selection_start() const
{
// 1. If this element is an input element, and selectionStart does not apply to this element, return null.
auto const& html_element = form_associated_element_to_html_element();
@@ -255,7 +244,7 @@ Optional FormAssociatedElement::selection_start() const
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#textFieldSelection:dom-textarea/input-selectionstart-2
-WebIDL::ExceptionOr FormAssociatedElement::set_selection_start(Optional const& value)
+WebIDL::ExceptionOr FormAssociatedTextControlElement::set_selection_start(Optional const& value)
{
// 1. If this element is an input element, and selectionStart does not apply to this element,
// throw an "InvalidStateError" DOMException.
@@ -280,7 +269,7 @@ WebIDL::ExceptionOr FormAssociatedElement::set_selection_start(Optional FormAssociatedElement::selection_end() const
+Optional FormAssociatedTextControlElement::selection_end() const
{
// 1. If this element is an input element, and selectionEnd does not apply to this element, return
// null.
@@ -304,7 +293,7 @@ Optional FormAssociatedElement::selection_end() const
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#textFieldSelection:dom-textarea/input-selectionend-3
-WebIDL::ExceptionOr FormAssociatedElement::set_selection_end(Optional const& value)
+WebIDL::ExceptionOr FormAssociatedTextControlElement::set_selection_end(Optional const& value)
{
// 1. If this element is an input element, and selectionEnd does not apply to this element,
// throw an "InvalidStateError" DOMException.
@@ -322,7 +311,7 @@ WebIDL::ExceptionOr FormAssociatedElement::set_selection_end(Optional FormAssociatedElement::selection_direction() const
+Optional FormAssociatedTextControlElement::selection_direction() const
{
// 1. If this element is an input element, and selectionDirection does not apply to this
// element, return null.
@@ -347,7 +336,7 @@ Optional FormAssociatedElement::selection_direction() const
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#set-the-selection-direction
-void FormAssociatedElement::set_selection_direction(Optional direction)
+void FormAssociatedTextControlElement::set_selection_direction(Optional direction)
{
// To set the selection direction of an element to a given direction, update the element's
// selection direction to the given direction, unless the direction is "none" and the
@@ -357,7 +346,7 @@ void FormAssociatedElement::set_selection_direction(Optional direction)
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-setselectionrange
-WebIDL::ExceptionOr FormAssociatedElement::set_selection_range(Optional start, Optional end, Optional direction)
+WebIDL::ExceptionOr FormAssociatedTextControlElement::set_selection_range(Optional start, Optional end, Optional direction)
{
// 1. If this element is an input element, and setSelectionRange() does not apply to this
// element, throw an "InvalidStateError" DOMException.
@@ -371,7 +360,7 @@ WebIDL::ExceptionOr FormAssociatedElement::set_selection_range(Optional start, Optional end, SelectionDirection direction)
+void FormAssociatedTextControlElement::set_the_selection_range(Optional start, Optional end, SelectionDirection direction)
{
// 1. If start is null, let start be zero.
start = start.value_or(0);
diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h
index 30747c6d928..133facfea2e 100644
--- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h
+++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h
@@ -91,15 +91,40 @@ public:
virtual String value() const { return String {}; }
- // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value
- String relevant_value() const;
-
virtual HTMLElement& form_associated_element_to_html_element() = 0;
HTMLElement const& form_associated_element_to_html_element() const { return const_cast(*this).form_associated_element_to_html_element(); }
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-form-reset-control
virtual void reset_algorithm() {};
+protected:
+ FormAssociatedElement() = default;
+ virtual ~FormAssociatedElement() = default;
+
+ virtual void form_associated_element_was_inserted() { }
+ virtual void form_associated_element_was_removed(DOM::Node*) { }
+ virtual void form_associated_element_attribute_changed(FlyString const&, Optional const&) { }
+
+ void form_node_was_inserted();
+ void form_node_was_removed();
+ void form_node_attribute_changed(FlyString const&, Optional const&);
+
+ virtual void selection_was_changed() { }
+
+private:
+ void reset_form_owner();
+
+ WeakPtr m_form;
+
+ // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#parser-inserted-flag
+ bool m_parser_inserted { false };
+};
+
+class FormAssociatedTextControlElement : public FormAssociatedElement {
+public:
+ // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value
+ virtual String relevant_value() = 0;
+
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-select
WebIDL::ExceptionOr select();
@@ -123,30 +148,10 @@ public:
WebIDL::ExceptionOr set_selection_range(Optional start, Optional end, Optional direction);
protected:
- FormAssociatedElement() = default;
- virtual ~FormAssociatedElement() = default;
-
- virtual void form_associated_element_was_inserted() { }
- virtual void form_associated_element_was_removed(DOM::Node*) { }
- virtual void form_associated_element_attribute_changed(FlyString const&, Optional const&) { }
-
- void form_node_was_inserted();
- void form_node_was_removed();
- void form_node_attribute_changed(FlyString const&, Optional const&);
-
// 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();
-
- WeakPtr m_form;
-
- // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#parser-inserted-flag
- bool m_parser_inserted { false };
-
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-selection
WebIDL::UnsignedLong m_selection_start { 0 };
WebIDL::UnsignedLong m_selection_end { 0 };
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
index 9c75cb65c89..e3a6c0a0925 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
@@ -49,7 +49,7 @@ namespace Web::HTML {
class HTMLInputElement final
: public HTMLElement
- , public FormAssociatedElement
+ , public FormAssociatedTextControlElement
, public DOM::EditableTextNodeOwner
, public Layout::ImageProvider {
WEB_PLATFORM_OBJECT(HTMLInputElement, HTMLElement);
@@ -77,6 +77,9 @@ public:
virtual String value() const override;
WebIDL::ExceptionOr set_value(String const&);
+ // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value
+ virtual String relevant_value() override { return value(); }
+
void commit_pending_changes();
String placeholder() const;
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h
index be0d7683e2a..79948316761 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.h
@@ -20,7 +20,7 @@ namespace Web::HTML {
class HTMLTextAreaElement final
: public HTMLElement
- , public FormAssociatedElement
+ , public FormAssociatedTextControlElement
, public DOM::EditableTextNodeOwner {
WEB_PLATFORM_OBJECT(HTMLTextAreaElement, HTMLElement);
JS_DECLARE_ALLOCATOR(HTMLTextAreaElement);
@@ -84,6 +84,9 @@ public:
// https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element:concept-fe-api-value-3
String api_value() const;
+ // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value
+ virtual String relevant_value() override { return api_value(); }
+
u32 text_length() const;
bool check_validity();
diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp
index 92d2a920ea2..28c98f5698f 100644
--- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp
+++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp
@@ -1159,7 +1159,7 @@ void EventHandler::update_selection_range_for_input_or_textarea()
// FIXME: support selection directions other than ::Forward
auto direction = HTML::SelectionDirection::Forward;
- Optional target {};
+ Optional target {};
if (is(shadow_host))
target = static_cast(shadow_host);
else if (is(shadow_host))