mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:28:12 +00:00
LibWeb: Add getElementsByTagNameNS and add support for * in non-NS
This also moves getElementsByTagName to ParentNode to remove the code duplication between Document and Element. This additionally fixes a bug where getElementsByTagName did not check if the element was a descendant, meaning it would also include the context element if the condition matched.
This commit is contained in:
parent
5c7dca3526
commit
d47e431d54
8 changed files with 70 additions and 24 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <LibWeb/DOM/HTMLCollection.h>
|
||||
#include <LibWeb/DOM/ParentNode.h>
|
||||
#include <LibWeb/Dump.h>
|
||||
#include <LibWeb/Namespace.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
|
@ -87,4 +88,68 @@ NonnullRefPtr<HTMLCollection> ParentNode::children()
|
|||
});
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-getelementsbytagname
|
||||
// NOTE: This method is only exposed on Document and Element, but is in ParentNode to prevent code duplication.
|
||||
NonnullRefPtr<HTMLCollection> ParentNode::get_elements_by_tag_name(FlyString const& qualified_name)
|
||||
{
|
||||
// 1. If qualifiedName is "*" (U+002A), return a HTMLCollection rooted at root, whose filter matches only descendant elements.
|
||||
if (qualified_name == "*") {
|
||||
return HTMLCollection::create(*this, [this](Element const& element) {
|
||||
return element.is_descendant_of(*this);
|
||||
});
|
||||
}
|
||||
|
||||
// FIXME: 2. Otherwise, if root’s node document is an HTML document, return a HTMLCollection rooted at root, whose filter matches the following descendant elements:
|
||||
// (It is currently always a HTML document)
|
||||
return HTMLCollection::create(*this, [this, qualified_name](Element const& element) {
|
||||
if (!element.is_descendant_of(*this))
|
||||
return false;
|
||||
|
||||
// - Whose namespace is the HTML namespace and whose qualified name is qualifiedName, in ASCII lowercase.
|
||||
if (element.namespace_() == Namespace::HTML)
|
||||
return element.qualified_name().to_lowercase() == qualified_name.to_lowercase();
|
||||
|
||||
// - Whose namespace is not the HTML namespace and whose qualified name is qualifiedName.
|
||||
return element.qualified_name() == qualified_name;
|
||||
});
|
||||
|
||||
// FIXME: 3. Otherwise, return a HTMLCollection rooted at root, whose filter matches descendant elements whose qualified name is qualifiedName.
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-getelementsbytagnamens
|
||||
// NOTE: This method is only exposed on Document and Element, but is in ParentNode to prevent code duplication.
|
||||
NonnullRefPtr<HTMLCollection> ParentNode::get_elements_by_tag_name_ns(FlyString const& nullable_namespace, FlyString const& local_name)
|
||||
{
|
||||
// 1. If namespace is the empty string, set it to null.
|
||||
String namespace_ = nullable_namespace;
|
||||
if (namespace_.is_empty())
|
||||
namespace_ = {};
|
||||
|
||||
// 2. If both namespace and localName are "*" (U+002A), return a HTMLCollection rooted at root, whose filter matches descendant elements.
|
||||
if (namespace_ == "*" && local_name == "*") {
|
||||
return HTMLCollection::create(*this, [this](Element const& element) {
|
||||
return element.is_descendant_of(*this);
|
||||
});
|
||||
}
|
||||
|
||||
// 3. Otherwise, if namespace is "*" (U+002A), return a HTMLCollection rooted at root, whose filter matches descendant elements whose local name is localName.
|
||||
if (namespace_ == "*") {
|
||||
return HTMLCollection::create(*this, [this, local_name](Element const& element) {
|
||||
return element.is_descendant_of(*this) && element.local_name() == local_name;
|
||||
});
|
||||
}
|
||||
|
||||
// 4. Otherwise, if localName is "*" (U+002A), return a HTMLCollection rooted at root, whose filter matches descendant elements whose namespace is namespace.
|
||||
if (local_name == "*") {
|
||||
return HTMLCollection::create(*this, [this, namespace_](Element const& element) {
|
||||
return element.is_descendant_of(*this) && element.namespace_() == namespace_;
|
||||
});
|
||||
}
|
||||
|
||||
// 5. Otherwise, return a HTMLCollection rooted at root, whose filter matches descendant elements whose namespace is namespace and local name is localName.
|
||||
return HTMLCollection::create(*this, [this, namespace_, local_name](Element const& element) {
|
||||
return element.is_descendant_of(*this) && element.namespace_() == namespace_ && element.local_name() == local_name;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue