LibWeb: Implement the HTMLOptionElement.form attribute

This returns the parent form of a HTMLOptionElement or null if the
element has no parent form.
This commit is contained in:
Tim Ledbetter 2024-05-15 22:54:17 +01:00 committed by Andreas Kling
parent fe7df98d7d
commit 763b7f0e0c
Notes: sideshowbarker 2024-07-18 00:41:35 +09:00
5 changed files with 64 additions and 1 deletions

View file

@ -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
<FORM id="form3" >
<FORM id="form4" >

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<option id="option-no-select"></option>
<select>
<option id="option-no-form"></option>
</select>
<form id="form1">
<option id="option-within-form-no-select"></option>
</form>
<form id="form2">
<optgroup>
<option id="option-within-optgroup-no-select"></option>
</optgroup>
</form>
<form id="form3">
<select>
<option id="option-within-select"></option>
</select>
</form>
<form id="form4">
<select>
<optgroup>
<option id="option-within-optgroup"></option>
</optgroup>
</select>
</form>
<script src="../include.js"></script>
<script>
test(() => {
println(`Option element with no parent select returns null: ${document.getElementById("option-no-select").form === null}`);
println(`Option element with no parent form returns null: ${document.getElementById("option-no-form").form === null}`);
println(`Option element with no parent select returns null: ${document.getElementById("option-within-form-no-select").form === null}`);
println(`Option element within optgroup with no parent select returns null: ${document.getElementById("option-within-optgroup-no-select").form === null}`);
printElement(document.getElementById("option-within-select").form);
printElement(document.getElementById("option-within-optgroup").form);
});
</script>

View file

@ -143,6 +143,25 @@ bool HTMLOptionElement::disabled() const
|| (parent() && is<HTMLOptGroupElement>(parent()) && static_cast<HTMLOptGroupElement const&>(*parent()).has_attribute(AttributeNames::disabled));
}
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-form
JS::GCPtr<HTMLFormElement> 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<HTMLOptGroupElement>(parent))
parent = parent->parent_element();
if (is<HTML::HTMLSelectElement>(parent)) {
auto const* select_element = verify_cast<HTMLSelectElement>(parent);
return const_cast<HTMLFormElement*>(select_element->form());
}
return {};
}
Optional<ARIA::Role> HTMLOptionElement::default_role() const
{
// https://www.w3.org/TR/html-aria/#el-option

View file

@ -31,6 +31,8 @@ public:
bool disabled() const;
JS::GCPtr<HTML::HTMLFormElement> form() const;
virtual Optional<ARIA::Role> default_role() const override;
private:

View file

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