ソースを参照

LibWeb: Return document URL if formAction attribute is missing or empty

This change also ensures that relative URLs are resolved relative to
the document's base URL.
Tim Ledbetter 10 ヶ月 前
コミット
c25dda767e

+ 3 - 0
Tests/LibWeb/Text/expected/HTML/formAction-attribute.txt

@@ -0,0 +1,3 @@
+button.formAction initial value: http://www.example.com/
+Final segment of button.formAction after setting to the empty string: formAction-attribute.html
+Final segment of button.formAction after setting to "../test.html": test.html

+ 19 - 0
Tests/LibWeb/Text/input/HTML/formAction-attribute.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<script src="../include.js"></script>
+<button formaction="http://www.example.com/"></button>
+<script>
+    test(() => {
+        const elementNames = [
+            "button",
+        ];
+        for (const elementName of elementNames) {
+            const element = document.querySelector(elementName);
+            println(`${elementName}.formAction initial value: ${element.formAction}`);
+            element.formAction = "";
+            println(`Final segment of ${elementName}.formAction after setting to the empty string: ${element.formAction.split('/').pop()}`);
+            element.formAction = "../test.html";
+            println(`Final segment of ${elementName}.formAction after setting to "../test.html": ${element.formAction.split('/').pop()}`);
+            element.remove();
+        }
+    });
+</script>

+ 21 - 0
Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp

@@ -166,6 +166,27 @@ void FormAssociatedElement::reset_form_owner()
     }
 }
 
+// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-formaction
+String FormAssociatedElement::form_action() const
+{
+    // The formAction IDL attribute must reflect the formaction content attribute, except that on getting, when the content attribute is missing or its value is the empty string,
+    // the element's node document's URL must be returned instead.
+    auto& html_element = form_associated_element_to_html_element();
+    auto form_action_attribute = html_element.attribute(HTML::AttributeNames::formaction);
+    if (!form_action_attribute.has_value() || form_action_attribute.value().is_empty()) {
+        return html_element.document().url_string();
+    }
+
+    auto document_base_url = html_element.document().base_url();
+    return MUST(document_base_url.complete_url(form_action_attribute.value()).to_string());
+}
+
+WebIDL::ExceptionOr<void> FormAssociatedElement::set_form_action(String const& value)
+{
+    auto& html_element = form_associated_element_to_html_element();
+    return html_element.set_attribute(HTML::AttributeNames::formaction, value);
+}
+
 // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value
 void FormAssociatedTextControlElement::relevant_value_was_changed(JS::GCPtr<DOM::Text> text_node)
 {

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

@@ -98,6 +98,9 @@ public:
     // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-form-reset-control
     virtual void reset_algorithm() {};
 
+    String form_action() const;
+    WebIDL::ExceptionOr<void> set_form_action(String const&);
+
 protected:
     FormAssociatedElement() = default;
     virtual ~FormAssociatedElement() = default;

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

@@ -15,7 +15,7 @@ interface HTMLButtonElement : HTMLElement {
 
     [CEReactions, Reflect] attribute boolean disabled;
     readonly attribute HTMLFormElement? form;
-    [CEReactions, Reflect=formaction] attribute USVString formAction;
+    [CEReactions] attribute USVString formAction;
     [CEReactions, Reflect=formenctype] attribute DOMString formEnctype;
     [CEReactions, Reflect=formmethod] attribute DOMString formMethod;
     [CEReactions, Reflect=formnovalidate] attribute boolean formNoValidate;