mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-30 20:59:16 +00:00
LibWeb: Take namespace into account when matching attribute
This commit is contained in:
parent
033cd9cab3
commit
d743fcb376
Notes:
github-actions[bot]
2024-11-30 16:48:12 +00:00
Author: https://github.com/netanel-haber 🔰
Commit: d743fcb376
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2613
Reviewed-by: https://github.com/AtkinsSJ ✅
5 changed files with 77 additions and 3 deletions
|
@ -213,13 +213,43 @@ static inline bool matches_indeterminate_pseudo_class(DOM::Element const& elemen
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline Web::DOM::Attr const* get_optionally_namespaced_attribute(CSS::Selector::SimpleSelector::Attribute const& attribute, Optional<CSS::CSSStyleSheet const&> style_sheet_for_rule, DOM::Element const& element)
|
||||
{
|
||||
auto const& qualified_name = attribute.qualified_name;
|
||||
auto const& attribute_name = qualified_name.name.name;
|
||||
auto const& namespace_type = qualified_name.namespace_type;
|
||||
|
||||
if (element.namespace_uri() == Namespace::HTML) {
|
||||
if (namespace_type == CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::Named) {
|
||||
return nullptr;
|
||||
}
|
||||
return element.attributes()->get_attribute(attribute_name);
|
||||
}
|
||||
|
||||
switch (namespace_type) {
|
||||
// "In keeping with the Namespaces in the XML recommendation, default namespaces do not apply to attributes,
|
||||
// therefore attribute selectors without a namespace component apply only to attributes that have no namespace (equivalent to "|attr")"
|
||||
case CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::Default:
|
||||
case CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::None:
|
||||
return element.attributes()->get_attribute(attribute_name);
|
||||
case CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::Any:
|
||||
return element.attributes()->get_attribute_namespace_agnostic(attribute_name);
|
||||
case CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::Named:
|
||||
if (!style_sheet_for_rule.has_value())
|
||||
return nullptr;
|
||||
auto const& selector_namespace = style_sheet_for_rule->namespace_uri(qualified_name.namespace_);
|
||||
if (!selector_namespace.has_value())
|
||||
return nullptr;
|
||||
return element.attributes()->get_attribute_ns(selector_namespace, attribute_name);
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
static inline bool matches_attribute(CSS::Selector::SimpleSelector::Attribute const& attribute, [[maybe_unused]] Optional<CSS::CSSStyleSheet const&> style_sheet_for_rule, DOM::Element const& element)
|
||||
{
|
||||
// FIXME: Check the attribute's namespace, once we support that in DOM::Element!
|
||||
|
||||
auto const& attribute_name = attribute.qualified_name.name.name;
|
||||
|
||||
auto const* attr = element.attributes()->get_attribute(attribute_name);
|
||||
auto const* attr = get_optionally_namespaced_attribute(attribute, style_sheet_for_rule, element);
|
||||
|
||||
if (attribute.match_type == CSS::Selector::SimpleSelector::Attribute::MatchType::HasAttribute) {
|
||||
// Early way out in case of an attribute existence selector.
|
||||
|
|
|
@ -194,6 +194,16 @@ Attr const* NamedNodeMap::get_attribute_ns(Optional<FlyString> const& namespace_
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Attr const* NamedNodeMap::get_attribute_namespace_agnostic(FlyString const& local_name) const
|
||||
{
|
||||
for (auto const& attribute : m_attributes) {
|
||||
if (attribute->local_name() == local_name)
|
||||
return attribute.ptr();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-set
|
||||
WebIDL::ExceptionOr<GC::Ptr<Attr>> NamedNodeMap::set_attribute(Attr& attribute)
|
||||
{
|
||||
|
|
|
@ -53,6 +53,8 @@ public:
|
|||
Attr const* remove_attribute(FlyString const& qualified_name);
|
||||
Attr const* remove_attribute_ns(Optional<FlyString> const& namespace_, FlyString const& local_name);
|
||||
|
||||
Attr const* get_attribute_namespace_agnostic(FlyString const& local_name) const;
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<Attr>> remove_attribute_node(GC::Ref<Attr>);
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Details
|
||||
Result Test Name MessagePass querySelectorAll must work with namespace attribute selectors on SVG
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>querySelectorAll must work with namespace attribute selectors on SVG</title>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<!-- Regression test for https://github.com/jsdom/jsdom/issues/2028 -->
|
||||
|
||||
<svg id="thesvg" xlink:href="foo"></svg>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
setup({ single_test: true });
|
||||
|
||||
const el = document.getElementById("thesvg");
|
||||
|
||||
assert_equals(document.querySelector("[*|href]"), el);
|
||||
assert_array_equals(document.querySelectorAll("[*|href]"), [el]);
|
||||
|
||||
done();
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue