diff --git a/Tests/LibWeb/Text/expected/HTML/HTMLTableCellElement-cellIndex-attribute.txt b/Tests/LibWeb/Text/expected/HTML/HTMLTableCellElement-cellIndex-attribute.txt
new file mode 100644
index 00000000000..eed273bb679
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/HTML/HTMLTableCellElement-cellIndex-attribute.txt
@@ -0,0 +1,4 @@
+lone td.cellIndex = -1
+parented td.cellIndex = 0
+lone th.cellIndex = -1
+parented th.cellIndex = 0
diff --git a/Tests/LibWeb/Text/input/HTML/HTMLTableCellElement-cellIndex-attribute.html b/Tests/LibWeb/Text/input/HTML/HTMLTableCellElement-cellIndex-attribute.html
new file mode 100644
index 00000000000..f7cbe1587f9
--- /dev/null
+++ b/Tests/LibWeb/Text/input/HTML/HTMLTableCellElement-cellIndex-attribute.html
@@ -0,0 +1,22 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp
index 573e0fad175..d7f5e147b78 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020-2022, Andreas Kling
+ * Copyright (c) 2024, Jamie Mansfield
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -13,6 +14,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -150,6 +152,24 @@ WebIDL::ExceptionOr HTMLTableCellElement::set_row_span(unsigned int value)
return set_attribute(HTML::AttributeNames::rowspan, MUST(String::number(value)));
}
+// https://html.spec.whatwg.org/multipage/tables.html#dom-tdth-cellindex
+WebIDL::Long HTMLTableCellElement::cell_index() const
+{
+ // The cellIndex IDL attribute must, if the element has a parent tr element, return the index of the cell's
+ // element in the parent element's cells collection. If there is no such parent element, then the attribute
+ // must return −1.
+ auto const* parent = first_ancestor_of_type();
+ if (!parent)
+ return -1;
+
+ auto rows = parent->cells()->collect_matching_elements();
+ for (size_t i = 0; i < rows.size(); ++i) {
+ if (rows[i] == this)
+ return i;
+ }
+ return -1;
+}
+
Optional HTMLTableCellElement::default_role() const
{
// TODO: For td:
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.h b/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.h
index 64fa43eb61d..4e13a107080 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.h
@@ -7,6 +7,7 @@
#pragma once
#include
+#include
namespace Web::HTML {
@@ -23,6 +24,8 @@ public:
WebIDL::ExceptionOr set_col_span(unsigned);
WebIDL::ExceptionOr set_row_span(unsigned);
+ WebIDL::Long cell_index() const;
+
virtual Optional default_role() const override;
private:
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.idl b/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.idl
index 1e84585b399..a3c4c6d430a 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.idl
+++ b/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.idl
@@ -9,7 +9,7 @@ interface HTMLTableCellElement : HTMLElement {
[CEReactions] attribute unsigned long colSpan;
[CEReactions] attribute unsigned long rowSpan;
[CEReactions, Reflect] attribute DOMString headers;
- [FIXME] readonly attribute long cellIndex;
+ readonly attribute long cellIndex;
[FIXME, CEReactions] attribute DOMString scope; // only conforming for th elements
[CEReactions, Reflect] attribute DOMString abbr; // only conforming for th elements