Преглед изворни кода

LibWeb: Look for first ID _or_ name in HTMLCollection::named_item

Previously we would look for a matching ID, and then for a matching
name. If there was an element in the collection which had a matching ID
as well as an element with a matching name, we would always return the
element with a matching ID irrespective of what order that element was
in.
Shannon Booth пре 1 година
родитељ
комит
baaaa0008e

+ 6 - 0
Tests/LibWeb/Text/expected/DOM/HTMLCollection-order.txt

@@ -0,0 +1,6 @@
+     HTMLCollection
+anchor1
+anchor2
+anchor3
+anchor1
+anchor2

+ 15 - 0
Tests/LibWeb/Text/input/DOM/HTMLCollection-order.html

@@ -0,0 +1,15 @@
+<a name="anchor1" id="foo"></a>
+<a name="anchor2" id="baz"></a>
+<a name="anchor3" id="anchor1"></a>
+
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        println(document.anchors.constructor.name);
+        println(document.anchors.namedItem('anchor1').name);
+        println(document.anchors.namedItem('anchor2').name);
+        println(document.anchors.namedItem('anchor3').name);
+        println(document.anchors.namedItem('foo').name);
+        println(document.anchors.namedItem('baz').name);
+    });
+</script>

+ 13 - 10
Userland/Libraries/LibWeb/DOM/HTMLCollection.cpp

@@ -100,23 +100,26 @@ Element* HTMLCollection::item(size_t index) const
 }
 
 // https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem-key
-Element* HTMLCollection::named_item(FlyString const& name) const
+Element* HTMLCollection::named_item(FlyString const& key) const
 {
     // 1. If key is the empty string, return null.
-    if (name.is_empty())
+    if (key.is_empty())
         return nullptr;
 
     update_cache_if_needed();
-    auto const& elements = m_cached_elements;
 
     // 2. Return the first element in the collection for which at least one of the following is true:
-    //      - it has an ID which is key;
-    if (auto it = elements.find_if([&](auto& entry) { return entry->id().has_value() && entry->id().value() == name; }); it != elements.end())
-        return *it;
-    //      - it is in the HTML namespace and has a name attribute whose value is key;
-    if (auto it = elements.find_if([&](auto& entry) { return entry->namespace_uri() == Namespace::HTML && entry->name() == name; }); it != elements.end())
-        return *it;
-    //    or null if there is no such element.
+    for (auto const& element : m_cached_elements) {
+        // - it has an ID which is key;
+        if (element->id() == key)
+            return element;
+
+        // - it is in the HTML namespace and has a name attribute whose value is key;
+        if (element->namespace_uri() == Namespace::HTML && element->name() == key)
+            return element;
+    }
+
+    // or null if there is no such element.
     return nullptr;
 }
 

+ 1 - 1
Userland/Libraries/LibWeb/DOM/HTMLCollection.h

@@ -36,7 +36,7 @@ public:
 
     size_t length() const;
     Element* item(size_t index) const;
-    Element* named_item(FlyString const& name) const;
+    Element* named_item(FlyString const& key) const;
 
     JS::MarkedVector<JS::NonnullGCPtr<Element>> collect_matching_elements() const;