Просмотр исходного кода

LibWeb: Add select and options collection remove method

Bastiaan van der Plaat 1 год назад
Родитель
Сommit
7372c01786

+ 2 - 0
Tests/LibWeb/Text/expected/select.txt

@@ -12,3 +12,5 @@
 12. 10
 13. 10
 14. "5 5"
+15. 8
+16. 10

+ 22 - 0
Tests/LibWeb/Text/input/select.html

@@ -146,5 +146,27 @@
             }
             return `${select.options.selectedIndex} ${select.selectedIndex}`;
         });
+
+        // 15. Remove select options
+        testPart(() => {
+            const select = document.createElement('select');
+            for (let i = 0; i < 10; i++) {
+                select.appendChild(document.createElement('option'));
+            }
+            select.remove(5);
+            select.options.remove(6);
+            return select.length;
+        });
+
+        // 16. Remove select options invalid
+        testPart(() => {
+            const select = document.createElement('select');
+            for (let i = 0; i < 10; i++) {
+                select.appendChild(document.createElement('option'));
+            }
+            select.remove(-1);
+            select.options.remove(11);
+            return select.length;
+        });
     });
 </script>

+ 18 - 0
Userland/Libraries/LibWeb/HTML/HTMLOptionsCollection.cpp

@@ -111,6 +111,24 @@ WebIDL::ExceptionOr<void> HTMLOptionsCollection::add(HTMLOptionOrOptGroupElement
     return {};
 }
 
+// https://html.spec.whatwg.org/#dom-htmloptionscollection-remove
+void HTMLOptionsCollection::remove(WebIDL::Long index)
+{
+    // 1. If the number of nodes represented by the collection is zero, return.
+    if (length() == 0)
+        return;
+
+    // 2. If index is not a number greater than or equal to 0 and less than the number of nodes represented by the collection, return.
+    if (index < 0 || static_cast<WebIDL::UnsignedLong>(index) >= length())
+        return;
+
+    // 3. Let element be the indexth element in the collection.
+    auto* element = this->item(index);
+
+    // 4. Remove element from its parent node.
+    element->remove();
+}
+
 // https://html.spec.whatwg.org/#dom-htmloptionscollection-selectedindex
 WebIDL::Long HTMLOptionsCollection::selected_index() const
 {

+ 2 - 0
Userland/Libraries/LibWeb/HTML/HTMLOptionsCollection.h

@@ -28,6 +28,8 @@ public:
 
     WebIDL::ExceptionOr<void> add(HTMLOptionOrOptGroupElement element, Optional<HTMLElementOrElementIndex> before = {});
 
+    void remove(WebIDL::Long);
+
     WebIDL::Long selected_index() const;
     void set_selected_index(WebIDL::Long);
 

+ 1 - 1
Userland/Libraries/LibWeb/HTML/HTMLOptionsCollection.idl

@@ -8,6 +8,6 @@ interface HTMLOptionsCollection : HTMLCollection {
     [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);
+    [CEReactions] undefined remove(long index);
     attribute long selectedIndex;
 };

+ 13 - 0
Userland/Libraries/LibWeb/HTML/HTMLSelectElement.cpp

@@ -133,6 +133,19 @@ WebIDL::ExceptionOr<void> HTMLSelectElement::add(HTMLOptionOrOptGroupElement ele
     return const_cast<HTMLOptionsCollection&>(*options()).add(move(element), move(before));
 }
 
+// https://html.spec.whatwg.org/multipage/form-elements.html#dom-select-remove
+void HTMLSelectElement::remove()
+{
+    // The remove() method must act like its namesake method on that same options collection when it has arguments,
+    // and like its namesake method on the ChildNode interface implemented by the HTMLSelectElement ancestor interface Element when it has no arguments.
+    ChildNode::remove_binding();
+}
+
+void HTMLSelectElement::remove(WebIDL::Long index)
+{
+    const_cast<HTMLOptionsCollection&>(*options()).remove(index);
+}
+
 // https://html.spec.whatwg.org/multipage/form-elements.html#concept-select-option-list
 Vector<JS::Handle<HTMLOptionElement>> HTMLSelectElement::list_of_options() const
 {

+ 2 - 0
Userland/Libraries/LibWeb/HTML/HTMLSelectElement.h

@@ -39,6 +39,8 @@ public:
     DOM::Element* item(size_t index);
     DOM::Element* named_item(FlyString const& name);
     WebIDL::ExceptionOr<void> add(HTMLOptionOrOptGroupElement element, Optional<HTMLElementOrElementIndex> before = {});
+    void remove();
+    void remove(WebIDL::Long);
 
     int selected_index() const;
     void set_selected_index(int);

+ 2 - 2
Userland/Libraries/LibWeb/HTML/HTMLSelectElement.idl

@@ -24,8 +24,8 @@ interface HTMLSelectElement : HTMLElement {
     // FIXME: Element is really HTMLOptionElement
     Element? namedItem(DOMString name);
     [CEReactions] undefined add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
-    // FIXME: [CEReactions] undefined remove(); // ChildNode overload
-    // FIXME: [CEReactions] undefined remove(long index);
+    [CEReactions] undefined remove(); // ChildNode overload
+    [CEReactions] undefined remove(long index);
     // FIXME: [CEReactions] setter undefined (unsigned long index, HTMLOptionElement? option);
 
     // FIXME: [SameObject] readonly attribute HTMLCollection selectedOptions;