diff --git a/Tests/LibWeb/Text/expected/HTML/relList-attribute.txt b/Tests/LibWeb/Text/expected/HTML/relList-attribute.txt
index 2b4030db33e..6e3f666715b 100644
--- a/Tests/LibWeb/Text/expected/HTML/relList-attribute.txt
+++ b/Tests/LibWeb/Text/expected/HTML/relList-attribute.txt
@@ -22,3 +22,9 @@ link.relList for after setting rel to "whatever": whatever
link.relList for after setting rel to "prefetch": prefetch
link.relList contains "prefetch": true
link.relList contains "whatever": false
+svg.a.relList initial length: 0
+svg.a.relList always returns the same value: true
+svg.a.relList for after setting rel to "whatever": whatever
+svg.a.relList for after setting rel to "prefetch": prefetch
+svg.a.relList contains "prefetch": true
+svg.a.relList contains "whatever": false
diff --git a/Tests/LibWeb/Text/input/HTML/relList-attribute.html b/Tests/LibWeb/Text/input/HTML/relList-attribute.html
index b6f292a0d70..16f2aa62fc3 100644
--- a/Tests/LibWeb/Text/input/HTML/relList-attribute.html
+++ b/Tests/LibWeb/Text/input/HTML/relList-attribute.html
@@ -1,8 +1,7 @@
diff --git a/Userland/Libraries/LibWeb/SVG/SVGAElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGAElement.cpp
index a2b480d894e..27abb867b50 100644
--- a/Userland/Libraries/LibWeb/SVG/SVGAElement.cpp
+++ b/Userland/Libraries/LibWeb/SVG/SVGAElement.cpp
@@ -1,10 +1,12 @@
/*
* Copyright (c) 2024, Andreas Kling
+ * Copyright (c) 2024, Jamie Mansfield
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include
+#include
#include
#include
@@ -25,6 +27,30 @@ void SVGAElement::initialize(JS::Realm& realm)
WEB_SET_PROTOTYPE_FOR_INTERFACE(SVGAElement);
}
+void SVGAElement::visit_edges(Cell::Visitor& visitor)
+{
+ Base::visit_edges(visitor);
+ visitor.visit(m_rel_list);
+}
+
+void SVGAElement::attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value)
+{
+ Base::attribute_changed(name, old_value, value);
+ if (name == HTML::AttributeNames::rel) {
+ if (m_rel_list)
+ m_rel_list->associated_attribute_changed(value.value_or(String {}));
+ }
+}
+
+// https://svgwg.org/svg2-draft/linking.html#__svg__SVGAElement__relList
+JS::NonnullGCPtr SVGAElement::rel_list()
+{
+ // The relList IDL attribute reflects the ‘rel’ content attribute.
+ if (!m_rel_list)
+ m_rel_list = DOM::DOMTokenList::create(*this, HTML::AttributeNames::rel);
+ return *m_rel_list;
+}
+
JS::GCPtr SVGAElement::create_layout_node(NonnullRefPtr style)
{
return heap().allocate_without_realm(document(), *this, move(style));
diff --git a/Userland/Libraries/LibWeb/SVG/SVGAElement.h b/Userland/Libraries/LibWeb/SVG/SVGAElement.h
index 98bc1d12f31..ea2f32867fe 100644
--- a/Userland/Libraries/LibWeb/SVG/SVGAElement.h
+++ b/Userland/Libraries/LibWeb/SVG/SVGAElement.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2024, Andreas Kling
+ * Copyright (c) 2024, Jamie Mansfield
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -17,11 +18,20 @@ class SVGAElement final : public SVGGraphicsElement {
public:
virtual ~SVGAElement() override;
+ JS::NonnullGCPtr rel_list();
+
virtual JS::GCPtr create_layout_node(NonnullRefPtr) override;
private:
SVGAElement(DOM::Document&, DOM::QualifiedName);
+
virtual void initialize(JS::Realm&) override;
+ virtual void visit_edges(Cell::Visitor&) override;
+
+ // ^DOM::Element
+ virtual void attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value) override;
+
+ JS::GCPtr m_rel_list;
};
}
diff --git a/Userland/Libraries/LibWeb/SVG/SVGAElement.idl b/Userland/Libraries/LibWeb/SVG/SVGAElement.idl
index 7d264a72a45..fb0929526bb 100644
--- a/Userland/Libraries/LibWeb/SVG/SVGAElement.idl
+++ b/Userland/Libraries/LibWeb/SVG/SVGAElement.idl
@@ -1,3 +1,4 @@
+#import
#import
#import