diff --git a/Tests/LibWeb/Text/expected/HTML/HTMLOptionElement-form.txt b/Tests/LibWeb/Text/expected/HTML/HTMLOptionElement-form.txt new file mode 100644 index 00000000000..78b9ec9053a --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/HTMLOptionElement-form.txt @@ -0,0 +1,6 @@ + Option element with no parent select returns null: true +Option element with no parent form returns null: true +Option element with no parent select returns null: true +Option element within optgroup with no parent select returns null: true +
+ diff --git a/Tests/LibWeb/Text/input/HTML/HTMLOptionElement-form.html b/Tests/LibWeb/Text/input/HTML/HTMLOptionElement-form.html new file mode 100644 index 00000000000..d13956ab3a0 --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/HTMLOptionElement-form.html @@ -0,0 +1,36 @@ + + + + + +
+
+ + + +
+
+ +
+
+ +
+ + diff --git a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.cpp index 27d19a1d007..bb1169b533d 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.cpp @@ -143,6 +143,25 @@ bool HTMLOptionElement::disabled() const || (parent() && is(parent()) && static_cast(*parent()).has_attribute(AttributeNames::disabled)); } +// https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-form +JS::GCPtr HTMLOptionElement::form() const +{ + // The form IDL attribute's behavior depends on whether the option element is in a select element or not. + // If the option has a select element as its parent, or has an optgroup element as its parent and that optgroup element has a select element as its parent, + // then the form IDL attribute must return the same value as the form IDL attribute on that select element. + // Otherwise, it must return null. + auto const* parent = parent_element(); + if (is(parent)) + parent = parent->parent_element(); + + if (is(parent)) { + auto const* select_element = verify_cast(parent); + return const_cast(select_element->form()); + } + + return {}; +} + Optional HTMLOptionElement::default_role() const { // https://www.w3.org/TR/html-aria/#el-option diff --git a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.h b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.h index 5f85725707b..32adc64acc3 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.h @@ -31,6 +31,8 @@ public: bool disabled() const; + JS::GCPtr form() const; + virtual Optional default_role() const override; private: diff --git a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.idl b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.idl index 94478a2d33f..6078be0d249 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.idl +++ b/Userland/Libraries/LibWeb/HTML/HTMLOptionElement.idl @@ -6,7 +6,7 @@ interface HTMLOptionElement : HTMLElement { [HTMLConstructor] constructor(); [CEReactions, Reflect] attribute boolean disabled; - // FIXME: readonly attribute HTMLFormElement? form; + readonly attribute HTMLFormElement? form; [CEReactions, Reflect] attribute DOMString label; [CEReactions, Reflect=selected] attribute boolean defaultSelected; attribute boolean selected;