mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 20:29:18 +00:00
LibWeb/DOM: Implement Node.lookupPrefix
Adds https://dom.spec.whatwg.org/#dom-node-lookupprefix
This commit is contained in:
parent
9e32c9329a
commit
9624e0d2a2
Notes:
github-actions[bot]
2024-07-27 23:52:45 +00:00
Author: https://github.com/aescarias
Commit: 9624e0d2a2
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/870
Reviewed-by: https://github.com/tcl3 ✅
7 changed files with 109 additions and 1 deletions
9
Tests/LibWeb/Text/expected/DOM/Node-lookupPrefix.txt
Normal file
9
Tests/LibWeb/Text/expected/DOM/Node-lookupPrefix.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Prefix for namespace "test" on document: ex
|
||||||
|
Prefix for namespace "test" on document fragment: null
|
||||||
|
Prefix for namespace "test" on comment node 0: ex
|
||||||
|
Prefix null on document: null
|
||||||
|
Prefix for absent namespace "no" on document: null
|
||||||
|
Prefix for namespace "def" on child: abc
|
||||||
|
Prefix null on child: null
|
||||||
|
Prefix for namespace "test" (in parent) on child: ex
|
||||||
|
Prefix for namespace "def" (from attribute "x") on child: abc
|
21
Tests/LibWeb/Text/input/DOM/Node-lookupPrefix.html
Normal file
21
Tests/LibWeb/Text/input/DOM/Node-lookupPrefix.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
const xmlDoc = new DOMParser().parseFromString(`<root xmlns:ex="test"><!--abc--><child xmlns:abc="def" x="1"></child></root>`, "application/xml");
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
println(`Prefix for namespace "test" on document: ${xmlDoc.lookupPrefix("test")}`);
|
||||||
|
println(`Prefix for namespace "test" on document fragment: ${fragment.lookupPrefix("test")}`);
|
||||||
|
println(`Prefix for namespace "test" on comment node 0: ${xmlDoc.childNodes[0].lookupPrefix("test")}`);
|
||||||
|
println(`Prefix null on document: ${xmlDoc.lookupPrefix(null)}`);
|
||||||
|
println(`Prefix for absent namespace "no" on document: ${xmlDoc.lookupPrefix("no")}`);
|
||||||
|
|
||||||
|
const child = xmlDoc.querySelector("child");
|
||||||
|
println(`Prefix for namespace "def" on child: ${child.lookupPrefix("def")}`);
|
||||||
|
println(`Prefix null on child: ${child.lookupPrefix(null)}`);
|
||||||
|
println(`Prefix for namespace "test" (in parent) on child: ${child.lookupPrefix("test")}`);
|
||||||
|
|
||||||
|
const attrX = child.getAttributeNode("x");
|
||||||
|
println(`Prefix for namespace "def" (from attribute "x") on child: ${attrX.lookupPrefix("def")}`);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -2156,6 +2156,30 @@ void Element::set_prefix(Optional<FlyString> value)
|
||||||
m_qualified_name.set_prefix(move(value));
|
m_qualified_name.set_prefix(move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://dom.spec.whatwg.org/#locate-a-namespace-prefix
|
||||||
|
Optional<String> Element::locate_a_namespace_prefix(Optional<String> const& namespace_) const
|
||||||
|
{
|
||||||
|
// 1. If element’s namespace is namespace and its namespace prefix is non-null, then return its namespace prefix.
|
||||||
|
if (this->namespace_uri() == namespace_ && this->prefix().has_value())
|
||||||
|
return this->prefix()->to_string();
|
||||||
|
|
||||||
|
// 2. If element has an attribute whose namespace prefix is "xmlns" and value is namespace, then return element’s first such attribute’s local name.
|
||||||
|
if (auto* attributes = this->attributes()) {
|
||||||
|
for (size_t i = 0; i < attributes->length(); ++i) {
|
||||||
|
auto& attr = *attributes->item(i);
|
||||||
|
if (attr.prefix() == "xmlns" && attr.value() == namespace_)
|
||||||
|
return attr.local_name().to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. If element’s parent element is not null, then return the result of running locate a namespace prefix on that element using namespace.
|
||||||
|
if (auto* parent = this->parent_element())
|
||||||
|
return parent->locate_a_namespace_prefix(namespace_);
|
||||||
|
|
||||||
|
// 4. Return null
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void Element::for_each_attribute(Function<void(Attr const&)> callback) const
|
void Element::for_each_attribute(Function<void(Attr const&)> callback) const
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_attributes->length(); ++i)
|
for (size_t i = 0; i < m_attributes->length(); ++i)
|
||||||
|
|
|
@ -106,6 +106,8 @@ public:
|
||||||
|
|
||||||
void set_prefix(Optional<FlyString> value);
|
void set_prefix(Optional<FlyString> value);
|
||||||
|
|
||||||
|
Optional<String> locate_a_namespace_prefix(Optional<String> const& namespace_) const;
|
||||||
|
|
||||||
// NOTE: This is for the JS bindings
|
// NOTE: This is for the JS bindings
|
||||||
Optional<FlyString> const& namespace_uri() const { return m_qualified_name.namespace_(); }
|
Optional<FlyString> const& namespace_uri() const { return m_qualified_name.namespace_(); }
|
||||||
|
|
||||||
|
|
|
@ -1736,6 +1736,57 @@ Optional<String> Node::lookup_namespace_uri(Optional<String> prefix) const
|
||||||
return locate_a_namespace(prefix);
|
return locate_a_namespace(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://dom.spec.whatwg.org/#dom-node-lookupprefix
|
||||||
|
Optional<String> Node::lookup_prefix(Optional<String> namespace_) const
|
||||||
|
{
|
||||||
|
// 1. If namespace is null or the empty string, then return null.
|
||||||
|
if (!namespace_.has_value() || namespace_->is_empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 2. Switch on the interface this implements:
|
||||||
|
|
||||||
|
// Element
|
||||||
|
if (is<Element>(*this)) {
|
||||||
|
// Return the result of locating a namespace prefix for it using namespace.
|
||||||
|
auto& element = verify_cast<Element>(*this);
|
||||||
|
return element.locate_a_namespace_prefix(namespace_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Document
|
||||||
|
if (is<Document>(*this)) {
|
||||||
|
// Return the result of locating a namespace prefix for its document element, if its document element is non-null; otherwise null.
|
||||||
|
auto* document_element = verify_cast<Document>(*this).document_element();
|
||||||
|
if (!document_element)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return document_element->locate_a_namespace_prefix(namespace_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DocumentType
|
||||||
|
// DocumentFragment
|
||||||
|
if (is<DocumentType>(*this) || is<DocumentFragment>(*this))
|
||||||
|
// Return null
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// Attr
|
||||||
|
if (is<Attr>(*this)) {
|
||||||
|
// Return the result of locating a namespace prefix for its element, if its element is non-null; otherwise null.
|
||||||
|
auto* element = verify_cast<Attr>(*this).owner_element();
|
||||||
|
if (!element)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return element->locate_a_namespace_prefix(namespace_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise
|
||||||
|
// Return the result of locating a namespace prefix for its parent element, if its parent element is non-null; otherwise null.
|
||||||
|
auto* parent_element = this->parent_element();
|
||||||
|
if (!parent_element)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return parent_element->locate_a_namespace_prefix(namespace_);
|
||||||
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-node-isdefaultnamespace
|
// https://dom.spec.whatwg.org/#dom-node-isdefaultnamespace
|
||||||
bool Node::is_default_namespace(Optional<String> namespace_) const
|
bool Node::is_default_namespace(Optional<String> namespace_) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -698,6 +698,7 @@ public:
|
||||||
|
|
||||||
Optional<String> locate_a_namespace(Optional<String> const& prefix) const;
|
Optional<String> locate_a_namespace(Optional<String> const& prefix) const;
|
||||||
Optional<String> lookup_namespace_uri(Optional<String> prefix) const;
|
Optional<String> lookup_namespace_uri(Optional<String> prefix) const;
|
||||||
|
Optional<String> lookup_prefix(Optional<String> namespace_) const;
|
||||||
bool is_default_namespace(Optional<String> namespace_) const;
|
bool is_default_namespace(Optional<String> namespace_) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -54,7 +54,7 @@ interface Node : EventTarget {
|
||||||
unsigned short compareDocumentPosition(Node? otherNode);
|
unsigned short compareDocumentPosition(Node? otherNode);
|
||||||
boolean contains(Node? other);
|
boolean contains(Node? other);
|
||||||
|
|
||||||
[FIXME] DOMString? lookupPrefix(DOMString? namespace);
|
DOMString? lookupPrefix(DOMString? namespace);
|
||||||
DOMString? lookupNamespaceURI(DOMString? prefix);
|
DOMString? lookupNamespaceURI(DOMString? prefix);
|
||||||
boolean isDefaultNamespace(DOMString? namespace);
|
boolean isDefaultNamespace(DOMString? namespace);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue