mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-23 11:04:40 +00:00
LibWeb: Add select and option collection set length
This commit is contained in:
parent
4e5ce7b63e
commit
5c277144d8
|
@ -7,3 +7,7 @@
|
|||
7. 45
|
||||
8. 0
|
||||
9. 0
|
||||
10. 3
|
||||
11. 999
|
||||
12. 10
|
||||
13. 10
|
||||
|
|
|
@ -95,5 +95,45 @@
|
|||
const select = document.createElement('select');
|
||||
return select.size;
|
||||
});
|
||||
|
||||
// 10. Use select set length to remove options
|
||||
testPart(() => {
|
||||
const select = document.createElement('select');
|
||||
for (let i = 0; i < 10; i++) {
|
||||
select.appendChild(document.createElement('option'));
|
||||
}
|
||||
select.length = 3;
|
||||
return select.length;
|
||||
});
|
||||
|
||||
// 11. Use select set length to add options
|
||||
testPart(() => {
|
||||
const select = document.createElement('select');
|
||||
for (let i = 0; i < 10; i++) {
|
||||
select.appendChild(document.createElement('option'));
|
||||
}
|
||||
select.length = 999;
|
||||
return select.length;
|
||||
});
|
||||
|
||||
// 12. Use select set length to add options with invalid large size
|
||||
testPart(() => {
|
||||
const select = document.createElement('select');
|
||||
for (let i = 0; i < 10; i++) {
|
||||
select.appendChild(document.createElement('option'));
|
||||
}
|
||||
select.length = 100_001;
|
||||
return select.length;
|
||||
});
|
||||
|
||||
// 13. Use select set length to add options with invalid small size
|
||||
testPart(() => {
|
||||
const select = document.createElement('select');
|
||||
for (let i = 0; i < 10; i++) {
|
||||
select.appendChild(document.createElement('option'));
|
||||
}
|
||||
select.length = -10;
|
||||
return select.length;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/ElementFactory.h>
|
||||
#include <LibWeb/HTML/HTMLOptGroupElement.h>
|
||||
#include <LibWeb/HTML/HTMLOptionElement.h>
|
||||
#include <LibWeb/HTML/HTMLOptionsCollection.h>
|
||||
#include <LibWeb/HTML/HTMLSelectElement.h>
|
||||
#include <LibWeb/Namespace.h>
|
||||
#include <LibWeb/WebIDL/DOMException.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
@ -33,6 +35,41 @@ void HTMLOptionsCollection::initialize(JS::Realm& realm)
|
|||
WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLOptionsCollection);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-htmloptionscollection-length
|
||||
WebIDL::ExceptionOr<void> HTMLOptionsCollection::set_length(WebIDL::UnsignedLong value)
|
||||
{
|
||||
// 1. Let current be the number of nodes represented by the collection.
|
||||
auto current = static_cast<WebIDL::UnsignedLong>(length());
|
||||
|
||||
// 2. If the given value is greater than current, then:
|
||||
if (value > current) {
|
||||
// 2.1. If the given value is greater than 100,000, then return.
|
||||
if (value > 100'000)
|
||||
return {};
|
||||
|
||||
// 2.2. Let n be value − current.
|
||||
auto n = value - current;
|
||||
|
||||
// 2.3. Append n new option elements with no attributes and no child nodes to the select element on which this is rooted.
|
||||
// Mutation events must be fired as if a DocumentFragment containing the new option elements had been inserted.
|
||||
auto root_element = root();
|
||||
for (WebIDL::UnsignedLong i = 0; i < n; i++)
|
||||
TRY(root_element->append_child(TRY(DOM::create_element(root_element->document(), HTML::TagNames::option, Namespace::HTML))));
|
||||
}
|
||||
|
||||
// 3. If the given value is less than current, then:
|
||||
if (value < current) {
|
||||
// 3.1. Let n be current − value.
|
||||
auto n = current - value;
|
||||
|
||||
// 3.2. Remove the last n nodes in the collection from their parent nodes.
|
||||
for (WebIDL::UnsignedLong i = current - 1; i >= current - n; i--)
|
||||
this->item(i)->remove();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-htmloptionscollection-add
|
||||
WebIDL::ExceptionOr<void> HTMLOptionsCollection::add(HTMLOptionOrOptGroupElement element, Optional<HTMLElementOrElementIndex> before)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <AK/Variant.h>
|
||||
#include <LibWeb/DOM/HTMLCollection.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
#include <LibWeb/WebIDL/Types.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
|
@ -23,6 +24,8 @@ public:
|
|||
[[nodiscard]] static JS::NonnullGCPtr<HTMLOptionsCollection> create(DOM::ParentNode& root, Function<bool(DOM::Element const&)> filter);
|
||||
virtual ~HTMLOptionsCollection() override;
|
||||
|
||||
WebIDL::ExceptionOr<void> set_length(WebIDL::UnsignedLong);
|
||||
|
||||
WebIDL::ExceptionOr<void> add(HTMLOptionOrOptGroupElement element, Optional<HTMLElementOrElementIndex> before = {});
|
||||
|
||||
private:
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// https://html.spec.whatwg.org/#htmloptionscollection
|
||||
[Exposed=Window]
|
||||
interface HTMLOptionsCollection : HTMLCollection {
|
||||
// [CEReactions] attribute unsigned long length; // shadows inherited length
|
||||
[CEReactions] attribute unsigned long length; // shadows inherited length
|
||||
// [CEReactions] setter undefined (unsigned long index, HTMLOptionElement? option);
|
||||
[CEReactions] undefined add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
|
||||
// [CEReactions] undefined remove(long index);
|
||||
|
|
|
@ -100,12 +100,18 @@ JS::GCPtr<HTMLOptionsCollection> const& HTMLSelectElement::options()
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-select-length
|
||||
size_t HTMLSelectElement::length()
|
||||
WebIDL::UnsignedLong HTMLSelectElement::length()
|
||||
{
|
||||
// The length IDL attribute must return the number of nodes represented by the options collection. On setting, it must act like the attribute of the same name on the options collection.
|
||||
return const_cast<HTMLOptionsCollection&>(*options()).length();
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> HTMLSelectElement::set_length(WebIDL::UnsignedLong length)
|
||||
{
|
||||
// On setting, it must act like the attribute of the same name on the options collection.
|
||||
return const_cast<HTMLOptionsCollection&>(*options()).set_length(length);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-select-item
|
||||
DOM::Element* HTMLSelectElement::item(size_t index)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,8 @@ public:
|
|||
|
||||
JS::GCPtr<HTMLOptionsCollection> const& options();
|
||||
|
||||
size_t length();
|
||||
WebIDL::UnsignedLong length();
|
||||
WebIDL::ExceptionOr<void> set_length(WebIDL::UnsignedLong);
|
||||
DOM::Element* item(size_t index);
|
||||
DOM::Element* named_item(FlyString const& name);
|
||||
WebIDL::ExceptionOr<void> add(HTMLOptionOrOptGroupElement element, Optional<HTMLElementOrElementIndex> before = {});
|
||||
|
|
|
@ -18,8 +18,7 @@ interface HTMLSelectElement : HTMLElement {
|
|||
readonly attribute DOMString type;
|
||||
|
||||
[SameObject] readonly attribute HTMLOptionsCollection options;
|
||||
// FIXME: This isn't readonly
|
||||
[CEReactions] readonly attribute unsigned long length;
|
||||
[CEReactions] attribute unsigned long length;
|
||||
// FIXME: Element is really HTMLOptionElement
|
||||
getter Element? item(unsigned long index);
|
||||
// FIXME: Element is really HTMLOptionElement
|
||||
|
|
Loading…
Reference in a new issue