瀏覽代碼

LibWeb: Implement `HTMLFormElement.requestSubmit()`

This can be used to submit a form using a specific submit button.
Tim Ledbetter 1 年之前
父節點
當前提交
816d24f647

+ 4 - 0
Tests/LibWeb/Text/expected/form-requestSubmit.txt

@@ -0,0 +1,4 @@
+       Submitter is null
+<INPUT id="form-associated-button" >
+Exception: NotFoundError
+Exception: TypeError

+ 41 - 0
Tests/LibWeb/Text/input/form-requestSubmit.html

@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<span id="not-a-submit-button"></span>
+<form>
+    <input type="Submit" id="form-associated-button"  />
+</form>
+<input type="Submit" id="other-button" />
+<script src="./include.js"></script>
+<script>
+    test(() => {
+        const form = document.forms[0];
+        form.addEventListener("submit", event => {
+            event.preventDefault();
+            if (event.submitter) {
+                printElement(event.submitter);
+            } else {
+                println("Submitter is null");
+            }
+        });
+        
+        form.requestSubmit();
+        
+        const formAssociatedButton = document.getElementById("form-associated-button");
+        form.requestSubmit(formAssociatedButton);
+
+        const otherButton = document.getElementById("other-button");
+        try {
+            form.requestSubmit(otherButton);
+            println("FAIL");
+        } catch (e) {
+            println(`Exception: ${e.name}`);
+        }
+
+        const notASubmitButton = document.getElementById("not-a-submit-button");
+        try {
+            form.requestSubmit(notASubmitButton);
+            println("FAIL");
+        } catch (e) {
+            println(`Exception: ${e.name}`);
+        }
+    });
+</script>

+ 23 - 0
Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp

@@ -319,6 +319,29 @@ WebIDL::ExceptionOr<void> HTMLFormElement::submit()
     return submit_form(*this, { .from_submit_binding = true });
 }
 
+// https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
+WebIDL::ExceptionOr<void> HTMLFormElement::request_submit(JS::GCPtr<Element> submitter)
+{
+    // 1. If submitter is not null, then:
+    if (submitter) {
+        // 1. If submitter is not a submit button, then throw a TypeError.
+        auto* form_associated_element = dynamic_cast<FormAssociatedElement*>(submitter.ptr());
+        if (!(form_associated_element && form_associated_element->is_submit_button()))
+            return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "The submitter is not a submit button"sv };
+
+        // 2. If submitter's form owner is not this form element, then throw a "NotFoundError" DOMException.
+        if (form_associated_element->form() != this)
+            return WebIDL::NotFoundError::create(realm(), "The submitter is not owned by this form element"_fly_string);
+    }
+    // 2. Otherwise, set submitter to this form element.
+    else {
+        submitter = this;
+    }
+
+    // 3. Submit this form element, from submitter.
+    return submit_form(static_cast<HTMLElement&>(*submitter), {});
+}
+
 // https://html.spec.whatwg.org/multipage/forms.html#dom-form-reset
 void HTMLFormElement::reset()
 {

+ 3 - 0
Userland/Libraries/LibWeb/HTML/HTMLFormElement.h

@@ -65,6 +65,9 @@ public:
     // NOTE: This is for the JS bindings. Use submit_form instead.
     WebIDL::ExceptionOr<void> submit();
 
+    // NOTE: This is for the JS bindings. Use submit_form instead.
+    WebIDL::ExceptionOr<void> request_submit(JS::GCPtr<Element> submitter);
+
     // NOTE: This is for the JS bindings. Use submit_form instead.
     void reset();
 

+ 1 - 1
Userland/Libraries/LibWeb/HTML/HTMLFormElement.idl

@@ -25,7 +25,7 @@ interface HTMLFormElement : HTMLElement {
     getter (RadioNodeList or Element) (DOMString name);
 
     undefined submit();
-    // FIXME: undefined requestSubmit(optional HTMLElement? submitter = null);
+    undefined requestSubmit(optional HTMLElement? submitter = null);
     [CEReactions] undefined reset();
     boolean checkValidity();
     boolean reportValidity();