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/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;