LibWeb: Add support for indexed setter of HTMLOptionsCollection

This commit is contained in:
Colin Reeder 2024-07-14 15:24:02 -06:00 committed by Tim Ledbetter
parent 2c918b540d
commit 99824eae14
Notes: sideshowbarker 2024-07-17 08:25:15 +09:00
6 changed files with 70 additions and 0 deletions

View file

@ -26,6 +26,8 @@ JS::NonnullGCPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(DOM::Paren
HTMLOptionsCollection::HTMLOptionsCollection(DOM::ParentNode& root, Function<bool(DOM::Element const&)> filter)
: DOM::HTMLCollection(root, Scope::Descendants, move(filter))
{
m_legacy_platform_object_flags->has_indexed_property_setter = true;
m_legacy_platform_object_flags->indexed_property_setter_has_identifier = true;
}
HTMLOptionsCollection::~HTMLOptionsCollection() = default;
@ -71,6 +73,52 @@ WebIDL::ExceptionOr<void> HTMLOptionsCollection::set_length(WebIDL::UnsignedLong
return {};
}
// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-htmloptionscollection-setter
WebIDL::ExceptionOr<void> HTMLOptionsCollection::set_value_of_indexed_property(u32 index, JS::Value unconverted_option)
{
// The spec doesn't seem to require this, but it's consistent with length handling and other browsers
if (index >= 100'000) {
return {};
}
// 1. If value is null, invoke the steps for the remove method with index as the argument, and return.
if (unconverted_option.is_null()) {
remove(static_cast<WebIDL::Long>(index));
return {};
}
if (!unconverted_option.is_object() || !is<HTMLOptionElement>(unconverted_option.as_object())) {
return WebIDL::TypeMismatchError::create(realm(), "The value provided is not an HTMLOptionElement"_fly_string);
}
auto& option = static_cast<HTMLOptionElement&>(unconverted_option.as_object());
// 2. Let length be the number of nodes represented by the collection.
auto length = this->length();
auto root_element = root();
if (index >= length) {
// 3. Let n be index minus length.
auto n = index - length;
// 4. If n is greater than zero, then append a DocumentFragment consisting of n-1 new option elements with no attributes and no child nodes to the select element on which the HTMLOptionsCollection is rooted.
if (n > 0) {
for (WebIDL::UnsignedLong i = 0; i < n - 1; i++) {
TRY(root_element->append_child(TRY(DOM::create_element(root_element->document(), HTML::TagNames::option, Namespace::HTML))));
}
}
// 5. If n is greater than or equal to zero, append value to the select element.
TRY(root_element->append_child(option));
} else {
// 5 (cont). Otherwise, replace the indexth element in the collection by value.
TRY(root_element->replace_child(option, *item(index)));
}
return {};
}
// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-htmloptionscollection-add
WebIDL::ExceptionOr<void> HTMLOptionsCollection::add(HTMLOptionOrOptGroupElement element, Optional<HTMLElementOrElementIndex> before)
{