diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h index 82bf4b81e4..2dffbc7550 100644 --- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h +++ b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h @@ -65,6 +65,9 @@ public: virtual HTMLElement& form_associated_element_to_html_element() = 0; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-form-reset-control + virtual void reset_algorithm() {}; + protected: FormAssociatedElement() = default; virtual ~FormAssociatedElement() = default; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp index 93a39dea6a..9149a10c77 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -136,11 +137,49 @@ void HTMLFormElement::submit_form(JS::GCPtr submitter, bool from_su page->load(request); } +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#resetting-a-form +void HTMLFormElement::reset_form() +{ + // 1. Let reset be the result of firing an event named reset at form, with the bubbles and cancelable attributes initialized to true. + auto reset_event = DOM::Event::create(realm(), HTML::EventNames::reset); + reset_event->set_bubbles(true); + reset_event->set_cancelable(true); + + bool reset = dispatch_event(*reset_event); + + // 2. If reset is true, then invoke the reset algorithm of each resettable element whose form owner is form. + if (reset) { + for (auto element : m_associated_elements) { + VERIFY(is(*element)); + auto& form_associated_element = dynamic_cast(*element); + if (form_associated_element.is_resettable()) + form_associated_element.reset_algorithm(); + } + } +} + void HTMLFormElement::submit() { submit_form(this, true); } +// https://html.spec.whatwg.org/multipage/forms.html#dom-form-reset +void HTMLFormElement::reset() +{ + // 1. If the form element is marked as locked for reset, then return. + if (m_locked_for_reset) + return; + + // 2. Mark the form element as locked for reset. + m_locked_for_reset = true; + + // 3. Reset the form element. + reset_form(); + + // 4. Unmark the form element as locked for reset. + m_locked_for_reset = false; +} + void HTMLFormElement::add_associated_element(Badge, HTMLElement& element) { m_associated_elements.append(element); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.h b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.h index 67accd2fad..3c10fc05c6 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.h @@ -22,9 +22,14 @@ public: void submit_form(JS::GCPtr submitter, bool from_submit_binding = false); + void reset_form(); + // NOTE: This is for the JS bindings. Use submit_form instead. void submit(); + // NOTE: This is for the JS bindings. Use submit_form instead. + void reset(); + void add_associated_element(Badge, HTMLElement&); void remove_associated_element(Badge, HTMLElement&); @@ -38,6 +43,9 @@ private: bool m_firing_submission_events { false }; + // https://html.spec.whatwg.org/multipage/forms.html#locked-for-reset + bool m_locked_for_reset { false }; + Vector> m_associated_elements; JS::GCPtr mutable m_elements; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.idl b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.idl index d282712987..1e4cb3a2f3 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.idl +++ b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.idl @@ -11,6 +11,7 @@ interface HTMLFormElement : HTMLElement { [Reflect=novalidate] attribute boolean noValidate; undefined submit(); + [CEReactions] undefined reset(); // FIXME: Should be a HTMLFormControlsCollection [SameObject] readonly attribute HTMLCollection elements;