diff --git a/Tests/LibWeb/Text/expected/HTML/HTMLOutputElement-htmlfor.txt b/Tests/LibWeb/Text/expected/HTML/HTMLOutputElement-htmlfor.txt
new file mode 100644
index 0000000000..697b1c1f2a
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/HTML/HTMLOutputElement-htmlfor.txt
@@ -0,0 +1,9 @@
+output.htmlFor is initially empty: true
+output.htmlFor always returns the same object: true
+output.htmlFor after setting output.htmlFor to "a": a
+for attribute value after setting output.htmlFor to "a": a
+output.htmlFor after calling output.setAttribute("for", "b"): b
+output.htmlFor after setting output.htmlFor to "c d": c d
+for attribute value after setting output.htmlFor to "c d": c d
+output.htmlFor.contains("c"): true
+output.htmlFor.contains("a"): false
diff --git a/Tests/LibWeb/Text/input/HTML/HTMLOutputElement-htmlfor.html b/Tests/LibWeb/Text/input/HTML/HTMLOutputElement-htmlfor.html
new file mode 100644
index 0000000000..3ea82894f5
--- /dev/null
+++ b/Tests/LibWeb/Text/input/HTML/HTMLOutputElement-htmlfor.html
@@ -0,0 +1,20 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.cpp
index c205502f39..9bd056a071 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.cpp
@@ -6,6 +6,7 @@
#include
#include
+#include
#include
namespace Web::HTML {
@@ -25,6 +26,29 @@ void HTMLOutputElement::initialize(JS::Realm& realm)
WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLOutputElement);
}
+void HTMLOutputElement::visit_edges(Cell::Visitor& visitor)
+{
+ Base::visit_edges(visitor);
+ visitor.visit(m_html_for);
+}
+
+void HTMLOutputElement::form_associated_element_attribute_changed(FlyString const& name, Optional const& value)
+{
+ if (name == HTML::AttributeNames::for_) {
+ if (m_html_for)
+ m_html_for->associated_attribute_changed(value.value_or(String {}));
+ }
+}
+
+// https://html.spec.whatwg.org/multipage/form-elements.html#dom-output-htmlfor
+JS::NonnullGCPtr HTMLOutputElement::html_for()
+{
+ // The htmlFor IDL attribute must reflect the for content attribute.
+ if (!m_html_for)
+ m_html_for = DOM::DOMTokenList::create(*this, HTML::AttributeNames::for_);
+ return *m_html_for;
+}
+
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-output-defaultvalue
String HTMLOutputElement::default_value() const
{
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.h b/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.h
index 4ed25de4c6..4e1cf36f1a 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.h
@@ -23,6 +23,8 @@ class HTMLOutputElement final
public:
virtual ~HTMLOutputElement() override;
+ JS::NonnullGCPtr html_for();
+
String const& type() const
{
static String const output = "output"_string;
@@ -58,6 +60,11 @@ private:
HTMLOutputElement(DOM::Document&, DOM::QualifiedName);
virtual void initialize(JS::Realm&) override;
+ virtual void visit_edges(Cell::Visitor& visitor) override;
+
+ virtual void form_associated_element_attribute_changed(FlyString const& name, Optional const& value) override;
+
+ JS::GCPtr m_html_for;
Optional m_default_value_override {};
};
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.idl b/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.idl
index c01264c2d7..7bb6cba010 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.idl
+++ b/Userland/Libraries/LibWeb/HTML/HTMLOutputElement.idl
@@ -6,7 +6,7 @@
interface HTMLOutputElement : HTMLElement {
[HTMLConstructor] constructor();
- // FIXME: [SameObject, PutForwards=value] readonly attribute DOMTokenList htmlFor;
+ [SameObject, PutForwards=value] readonly attribute DOMTokenList htmlFor;
readonly attribute HTMLFormElement? form;
[CEReactions, Reflect] attribute DOMString name;