diff --git a/Tests/LibWeb/Text/expected/HTML/formAction-attribute.txt b/Tests/LibWeb/Text/expected/HTML/formAction-attribute.txt new file mode 100644 index 00000000000..aa202b2f6c8 --- /dev/null +++ b/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 diff --git a/Tests/LibWeb/Text/input/HTML/formAction-attribute.html b/Tests/LibWeb/Text/input/HTML/formAction-attribute.html new file mode 100644 index 00000000000..9cdddbf95b9 --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/formAction-attribute.html @@ -0,0 +1,19 @@ + + + + diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp index 41ba8929b59..7cbe3e6e3d8 100644 --- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.cpp +++ b/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 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 text_node) { diff --git a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h b/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h index d1037faca2d..a43273efeb0 100644 --- a/Userland/Libraries/LibWeb/HTML/FormAssociatedElement.h +++ b/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 set_form_action(String const&); + protected: FormAssociatedElement() = default; virtual ~FormAssociatedElement() = default; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLButtonElement.idl b/Userland/Libraries/LibWeb/HTML/HTMLButtonElement.idl index 47f6769d78d..f373c070526 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLButtonElement.idl +++ b/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;