Skip to content

Commit e80d1bc

Browse files
kalenikaliaksandrgmta
authored andcommitted
LibWeb: Avoid full DOM tree traversal in supported_property_names()
Instead, take advantage of `ElementByIdMap` and `m_potentially_named_elements` to gather named elements more efficiently.
1 parent 5fa3b48 commit e80d1bc

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

Libraries/LibWeb/DOM/ElementByIdMap.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ class ElementByIdMap {
1717
void remove(FlyString const& element_id, Element&);
1818
GC::Ptr<Element> get(FlyString const& element_id) const;
1919

20+
template<typename Callback>
21+
void for_each_id(Callback callback)
22+
{
23+
for (auto const& id : m_map.keys())
24+
callback(id);
25+
}
26+
2027
private:
2128
HashMap<FlyString, Vector<GC::Weak<Element>>> m_map;
2229
};

Libraries/LibWeb/HTML/Window.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,14 +1826,12 @@ Vector<FlyString> Window::supported_property_names() const
18261826
// that have a non-empty name content attribute and are in a document tree with window's associated Document as their root; and
18271827
// - the value of the id content attribute for all HTML elements that have a non-empty id content attribute
18281828
// and are in a document tree with window's associated Document as their root.
1829-
associated_document().for_each_in_subtree_of_type<DOM::Element>([&property_names](auto& element) -> TraversalDecision {
1830-
if (is<HTMLEmbedElement>(element) || is<HTMLFormElement>(element) || is<HTMLImageElement>(element) || is<HTMLObjectElement>(element)) {
1831-
if (element.name().has_value())
1832-
property_names.set(element.name().value(), AK::HashSetExistingEntryBehavior::Keep);
1833-
}
1834-
if (auto const& name = element.id(); name.has_value())
1835-
property_names.set(name.value().to_string(), AK::HashSetExistingEntryBehavior::Keep);
1836-
return TraversalDecision::Continue;
1829+
for (auto element : associated_document().potentially_named_elements()) {
1830+
if (auto name = element->name(); name.has_value())
1831+
property_names.set(*name, AK::HashSetExistingEntryBehavior::Keep);
1832+
}
1833+
associated_document().element_by_id().for_each_id([&](auto id) {
1834+
property_names.set(id, AK::HashSetExistingEntryBehavior::Keep);
18371835
});
18381836

18391837
return property_names.values();

0 commit comments

Comments
 (0)