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;