Forráskód Böngészése

LibWeb: Preserve order of HTMLCollection property names

The supported property names should be ordered in "tree order", though
m_cached_name_to_element_mappings doesn't preserve this ordering, which
breaks Object.getOwnPropertyNames.

Fixes at least the following WPT tests:
 - https://wpt.live/dom/nodes/Element-children.html
 - https://wpt.live/dom/collections/HTMLCollection-live-mutations.window.html
 - https://wpt.live/dom/collections/HTMLCollection-supported-property-names.html
scorpion-26 10 hónapja
szülő
commit
d00adabc3c

+ 1 - 0
Tests/LibWeb/Text/expected/DOM/HTMLCollection-property-names-iteration-order.txt

@@ -0,0 +1 @@
+0,1,2,foo,bar,baz

+ 10 - 0
Tests/LibWeb/Text/input/DOM/HTMLCollection-property-names-iteration-order.html

@@ -0,0 +1,10 @@
+<a name="foo"></a>
+<a name="bar"></a>
+<a name="baz"></a>
+
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        println(Object.getOwnPropertyNames(document.anchors));
+    });
+</script>

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

@@ -57,7 +57,7 @@ void HTMLCollection::update_name_to_element_mappings_if_needed() const
     update_cache_if_needed();
     if (m_cached_name_to_element_mappings)
         return;
-    m_cached_name_to_element_mappings = make<HashMap<FlyString, JS::NonnullGCPtr<Element>>>();
+    m_cached_name_to_element_mappings = make<OrderedHashMap<FlyString, JS::NonnullGCPtr<Element>>>();
     for (auto const& element : m_cached_elements) {
         // 1. If element has an ID which is not in result, append element’s ID to result.
         if (auto const& id = element->id(); id.has_value()) {

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

@@ -61,7 +61,7 @@ private:
 
     mutable u64 m_cached_dom_tree_version { 0 };
     mutable Vector<JS::NonnullGCPtr<Element>> m_cached_elements;
-    mutable OwnPtr<HashMap<FlyString, JS::NonnullGCPtr<Element>>> m_cached_name_to_element_mappings;
+    mutable OwnPtr<OrderedHashMap<FlyString, JS::NonnullGCPtr<Element>>> m_cached_name_to_element_mappings;
 
     JS::NonnullGCPtr<ParentNode> m_root;
     Function<bool(Element const&)> m_filter;