diff --git a/Libraries/LibWeb/HTML/HTMLElement.cpp b/Libraries/LibWeb/HTML/HTMLElement.cpp
index 45ebe83fc5a..0aa3bc6d08e 100644
--- a/Libraries/LibWeb/HTML/HTMLElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLElement.cpp
@@ -683,6 +683,58 @@ GC::Ptr HTMLElement::labels()
return m_labels;
}
+Variant HTMLElement::hidden() const
+{
+ // 1. If the hidden attribute is in the hidden until found state, then return "until-found".
+ if (get_attribute(HTML::AttributeNames::hidden) == "until-found")
+ return "until-found"_string;
+ // 2. If the hidden attribute is set, then return true.
+ if (has_attribute(HTML::AttributeNames::hidden))
+ return true;
+ // 3. Return false.
+ return false;
+}
+
+void HTMLElement::set_hidden(Variant const& given_value)
+{
+ // 1. If the given value is a string that is an ASCII case-insensitive match for "until-found", then set the hidden attribute to "until-found".
+ if (given_value.has()) {
+ auto const& string = given_value.get();
+ if (string.equals_ignoring_ascii_case("until-found"sv)) {
+ MUST(set_attribute(HTML::AttributeNames::hidden, "until-found"_string));
+ return;
+ }
+ // 3. Otherwise, if the given value is the empty string, then remove the hidden attribute.
+ if (string.is_empty()) {
+ remove_attribute(HTML::AttributeNames::hidden);
+ return;
+ }
+ // 4. Otherwise, if the given value is null, then remove the hidden attribute.
+ if (string.equals_ignoring_ascii_case("null"sv) || string.equals_ignoring_ascii_case("undefined"sv)) {
+ remove_attribute(HTML::AttributeNames::hidden);
+ return;
+ }
+ }
+ // 2. Otherwise, if the given value is false, then remove the hidden attribute.
+ else if (given_value.has()) {
+ if (!given_value.get()) {
+ remove_attribute(HTML::AttributeNames::hidden);
+ return;
+ }
+ }
+ // 5. Otherwise, if the given value is 0, then remove the hidden attribute.
+ // 6. Otherwise, if the given value is NaN, then remove the hidden attribute.
+ else if (given_value.has()) {
+ auto const& double_value = given_value.get();
+ if (double_value == 0 || isnan(double_value)) {
+ remove_attribute(HTML::AttributeNames::hidden);
+ return;
+ }
+ }
+ // 7. Otherwise, set the hidden attribute to the empty string.
+ MUST(set_attribute(HTML::AttributeNames::hidden, ""_string));
+}
+
// https://html.spec.whatwg.org/multipage/interaction.html#dom-click
void HTMLElement::click()
{
diff --git a/Libraries/LibWeb/HTML/HTMLElement.h b/Libraries/LibWeb/HTML/HTMLElement.h
index 5091d203968..b5d1d7f8d94 100644
--- a/Libraries/LibWeb/HTML/HTMLElement.h
+++ b/Libraries/LibWeb/HTML/HTMLElement.h
@@ -95,6 +95,9 @@ public:
bool cannot_navigate() const;
+ Variant hidden() const;
+ void set_hidden(Variant const&);
+
void click();
[[nodiscard]] String access_key_label() const;
diff --git a/Libraries/LibWeb/HTML/HTMLElement.idl b/Libraries/LibWeb/HTML/HTMLElement.idl
index 3d81cbc3c69..3c539fb4975 100644
--- a/Libraries/LibWeb/HTML/HTMLElement.idl
+++ b/Libraries/LibWeb/HTML/HTMLElement.idl
@@ -18,7 +18,7 @@ interface HTMLElement : Element {
[CEReactions] attribute DOMString dir;
// user interaction
- [Reflect, CEReactions] attribute boolean hidden;
+ [CEReactions] attribute (boolean or unrestricted double or DOMString)? hidden;
[Reflect, CEReactions] attribute boolean inert;
undefined click();
[Reflect=accesskey, CEReactions] attribute DOMString accessKey;
diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/editing/the-hidden-attribute/hidden-idl.txt b/Tests/LibWeb/Text/expected/wpt-import/html/editing/the-hidden-attribute/hidden-idl.txt
new file mode 100644
index 00000000000..b2ec72c00b6
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/wpt-import/html/editing/the-hidden-attribute/hidden-idl.txt
@@ -0,0 +1,22 @@
+Harness status: OK
+
+Found 17 tests
+
+17 Pass
+Pass div.hidden = false
+Pass div.hidden = true
+Pass div.hidden = "foo"
+Pass div.hidden = "false"
+Pass div.hidden = ""
+Pass div.setAttribute('hidden', "false") should make div.hidden return true
+Pass div.setAttribute('hidden', "foo") should make div.hidden return true
+Pass div.hidden = "until-found"
+Pass div.hidden = "UNTIL-FOUND"
+Pass div.hidden = "UnTiL-FoUnD"
+Pass div.hidden = "untıl-found"
+Pass div.hidden = "untİl-found"
+Pass div.hidden = null
+Pass div.hidden = undefined
+Pass div.hidden = 1
+Pass div.hidden = 0
+Pass div.hidden = NaN
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/input/wpt-import/html/editing/the-hidden-attribute/hidden-idl.html b/Tests/LibWeb/Text/input/wpt-import/html/editing/the-hidden-attribute/hidden-idl.html
new file mode 100644
index 00000000000..9f2987b55cb
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/html/editing/the-hidden-attribute/hidden-idl.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+hello
+