Skip to content

Commit

Permalink
LibWeb: Implement the HTMLOptionElement.form attribute
Browse files Browse the repository at this point in the history
This returns the parent form of a HTMLOptionElement or null if the
element has no parent form.
  • Loading branch information
tcl3 authored and awesomekling committed May 16, 2024
1 parent fe7df98 commit 763b7f0
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Tests/LibWeb/Text/expected/HTML/HTMLOptionElement-form.txt
Original file line number Diff line number Diff line change
@@ -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" >
36 changes: 36 additions & 0 deletions Tests/LibWeb/Text/input/HTML/HTMLOptionElement-form.html
Original file line number Diff line number Diff line change
@@ -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>
19 changes: 19 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLOptionElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLOptionElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class HTMLOptionElement final : public HTMLElement {

bool disabled() const;

JS::GCPtr<HTML::HTMLFormElement> form() const;

virtual Optional<ARIA::Role> default_role() const override;

private:
Expand Down
2 changes: 1 addition & 1 deletion Userland/Libraries/LibWeb/HTML/HTMLOptionElement.idl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 763b7f0

Please sign in to comment.