mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Add support for indexed setter of HTMLOptionsCollection
This commit is contained in:
parent
2c918b540d
commit
99824eae14
Notes:
sideshowbarker
2024-07-17 08:25:15 +09:00
Author: https://github.com/vpzomtrrfrt
Commit: 99824eae14
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/630
Reviewed-by: https://github.com/awesomekling
Reviewed-by: https://github.com/tcl3 ✅
6 changed files with 70 additions and 0 deletions
7
Tests/LibWeb/Ref/options-set-index.html
Normal file
7
Tests/LibWeb/Ref/options-set-index.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<link rel="match" href="reference/options-set-index.html" />
|
||||
<select id="select"></select>
|
||||
<script>
|
||||
const select = document.getElementById("select");
|
||||
select.options[0] = new Option("text");
|
||||
select.value = "text";
|
||||
</script>
|
1
Tests/LibWeb/Ref/reference/options-set-index.html
Normal file
1
Tests/LibWeb/Ref/reference/options-set-index.html
Normal file
|
@ -0,0 +1 @@
|
|||
<select><option>text</option></select>
|
1
Tests/LibWeb/Text/expected/select-options-limit.txt
Normal file
1
Tests/LibWeb/Text/expected/select-options-limit.txt
Normal file
|
@ -0,0 +1 @@
|
|||
0
|
11
Tests/LibWeb/Text/input/select-options-limit.html
Normal file
11
Tests/LibWeb/Text/input/select-options-limit.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<select id="select"></select>
|
||||
|
||||
<script src="include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const select = document.getElementById("select");
|
||||
select.options[100000] = new Option("0");
|
||||
|
||||
println(select.options.length);
|
||||
});
|
||||
</script>
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,8 @@ public:
|
|||
[[nodiscard]] static JS::NonnullGCPtr<HTMLOptionsCollection> create(DOM::ParentNode& root, ESCAPING Function<bool(DOM::Element const&)> filter);
|
||||
virtual ~HTMLOptionsCollection() override;
|
||||
|
||||
WebIDL::ExceptionOr<void> set_value_of_indexed_property(u32, JS::Value) override;
|
||||
|
||||
WebIDL::ExceptionOr<void> set_length(WebIDL::UnsignedLong);
|
||||
|
||||
WebIDL::ExceptionOr<void> add(HTMLOptionOrOptGroupElement element, Optional<HTMLElementOrElementIndex> before = {});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue