diff --git a/Tests/LibWeb/Text/expected/HTML/relList-attribute.txt b/Tests/LibWeb/Text/expected/HTML/relList-attribute.txt
index a8f13589868..663908f1fbb 100644
--- a/Tests/LibWeb/Text/expected/HTML/relList-attribute.txt
+++ b/Tests/LibWeb/Text/expected/HTML/relList-attribute.txt
@@ -4,3 +4,9 @@ a.relList for after setting rel to "whatever": whatever
a.relList for after setting rel to "prefetch": prefetch
a.relList contains "prefetch": true
a.relList contains "whatever": false
+area.relList initial length: 0
+area.relList always returns the same value: true
+area.relList for after setting rel to "whatever": whatever
+area.relList for after setting rel to "prefetch": prefetch
+area.relList contains "prefetch": true
+area.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 3ccbe06a7ef..74c14c44078 100644
--- a/Tests/LibWeb/Text/input/HTML/relList-attribute.html
+++ b/Tests/LibWeb/Text/input/HTML/relList-attribute.html
@@ -17,6 +17,7 @@
test(() => {
const tagNamesToTest = [
"a",
+ "area",
];
for (const tagName of tagNamesToTest) {
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.cpp
index 0aefac3d1e9..b48a4b044f2 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.cpp
@@ -6,6 +6,7 @@
#include
#include
+#include
#include
#include
@@ -31,9 +32,21 @@ void HTMLAreaElement::attribute_changed(FlyString const& name, Optional
HTMLElement::attribute_changed(name, value);
if (name == HTML::AttributeNames::href) {
set_the_url();
+ } else if (name == HTML::AttributeNames::rel) {
+ if (m_rel_list)
+ m_rel_list->associated_attribute_changed(value.value_or(String {}));
}
}
+// https://html.spec.whatwg.org/multipage/image-maps.html#dom-area-rellist
+JS::GCPtr HTMLAreaElement::rel_list()
+{
+ // The IDL attribute relList must reflect the rel content attribute.
+ if (!m_rel_list)
+ m_rel_list = DOM::DOMTokenList::create(*this, HTML::AttributeNames::rel);
+ return m_rel_list;
+}
+
Optional HTMLAreaElement::hyperlink_element_utils_href() const
{
return attribute(HTML::AttributeNames::href);
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h
index 3923d005576..5f63b2b8d0b 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h
@@ -20,6 +20,7 @@ class HTMLAreaElement final
public:
virtual ~HTMLAreaElement() override;
+ JS::GCPtr rel_list();
private:
HTMLAreaElement(DOM::Document&, DOM::QualifiedName);
@@ -50,6 +51,8 @@ private:
}
virtual Optional default_role() const override;
+
+ JS::GCPtr m_rel_list;
};
}
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.idl b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.idl
index 509cc72ec35..a37a4e65579 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.idl
+++ b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.idl
@@ -14,7 +14,7 @@ interface HTMLAreaElement : HTMLElement {
[CEReactions, Reflect] attribute DOMString download;
[CEReactions, Reflect] attribute USVString ping;
[CEReactions, Reflect] attribute DOMString rel;
- // FIXME: [SameObject, PutForwards=value] readonly attribute DOMTokenList relList;
+ [SameObject, PutForwards=value] readonly attribute DOMTokenList relList;
// FIXME: [CEReactions] attribute DOMString referrerPolicy;
// Obsolete