diff --git a/Tests/LibWeb/Layout/expected/table/table-header-and-footer-groups.txt b/Tests/LibWeb/Layout/expected/table/table-header-and-footer-groups.txt
new file mode 100644
index 0000000000..a51f328ae7
--- /dev/null
+++ b/Tests/LibWeb/Layout/expected/table/table-header-and-footer-groups.txt
@@ -0,0 +1,18 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+ BlockContainer at (1,1) content-size 798x216 [BFC] children: not-inline
+ TableWrapper <(anonymous)> at (9,9) content-size 300x200 [BFC] children: not-inline
+ Box
at (10,10) content-size 298x198 table-box [TFC] children: not-inline
+ Box at (10,10) content-size 298x0 table-footer-group children: inline
+ Box <(anonymous)> at (10,10) content-size 298x0 table-row children: inline
+ BlockContainer <(anonymous)> at (10,10) content-size 298x0 table-cell [BFC] children: inline
+ line 0 width: 56.109375, height: 0, bottom: 0, baseline: 4.796875
+ frag 0 from TextNode start: 0, length: 6, rect: [10,10 56.109375x0]
+ "bottom"
+ TextNode <#text>
+ Box at (10,10) content-size 298x0 table-header-group children: inline
+ Box <(anonymous)> at (10,10) content-size 298x0 table-row children: inline
+ BlockContainer <(anonymous)> at (10,10) content-size 298x0 table-cell [BFC] children: inline
+ line 0 width: 26.640625, height: 0, bottom: 0, baseline: 4.796875
+ frag 0 from TextNode start: 0, length: 3, rect: [10,10 26.640625x0]
+ "top"
+ TextNode <#text>
diff --git a/Tests/LibWeb/Layout/input/table/table-header-and-footer-groups.html b/Tests/LibWeb/Layout/input/table/table-header-and-footer-groups.html
new file mode 100644
index 0000000000..f59e18269a
--- /dev/null
+++ b/Tests/LibWeb/Layout/input/table/table-header-and-footer-groups.html
@@ -0,0 +1,24 @@
+bottom
top
\ No newline at end of file
diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp
index 34c2e9015d..3e85cb5d9d 100644
--- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp
+++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp
@@ -258,9 +258,6 @@ void InlineLevelIterator::enter_text_node(Layout::TextNode const& text_node)
if (text_node.dom_node().is_editable() && !text_node.dom_node().is_uninteresting_whitespace_node())
do_collapse = false;
- // FIXME: The const_cast here is gross.
- const_cast(text_node).compute_text_for_rendering(do_collapse);
-
m_text_node_context = TextNodeContext {
.do_collapse = do_collapse,
.do_wrap_lines = do_wrap_lines,
diff --git a/Userland/Libraries/LibWeb/Layout/TextNode.cpp b/Userland/Libraries/LibWeb/Layout/TextNode.cpp
index 67ccb5d15f..d191072ad1 100644
--- a/Userland/Libraries/LibWeb/Layout/TextNode.cpp
+++ b/Userland/Libraries/LibWeb/Layout/TextNode.cpp
@@ -41,9 +41,32 @@ static ErrorOr apply_text_transform(DeprecatedString const& st
return string;
}
-// NOTE: This collapses whitespace into a single ASCII space if collapse is true.
-void TextNode::compute_text_for_rendering(bool collapse)
+DeprecatedString const& TextNode::text_for_rendering() const
{
+ if (m_text_for_rendering.is_null())
+ const_cast(this)->compute_text_for_rendering();
+ return m_text_for_rendering;
+}
+
+// NOTE: This collapses whitespace into a single ASCII space if the CSS white-space property tells us to.
+void TextNode::compute_text_for_rendering()
+{
+ bool collapse = [](CSS::WhiteSpace white_space) {
+ switch (white_space) {
+ case CSS::WhiteSpace::Normal:
+ case CSS::WhiteSpace::Nowrap:
+ case CSS::WhiteSpace::PreLine:
+ return true;
+ case CSS::WhiteSpace::Pre:
+ case CSS::WhiteSpace::PreWrap:
+ return false;
+ }
+ VERIFY_NOT_REACHED();
+ }(computed_values().white_space());
+
+ if (dom_node().is_editable() && !dom_node().is_uninteresting_whitespace_node())
+ collapse = false;
+
auto data = apply_text_transform(dom_node().data(), computed_values().text_transform()).release_value_but_fixme_should_propagate_errors();
if (dom_node().is_password_input()) {
diff --git a/Userland/Libraries/LibWeb/Layout/TextNode.h b/Userland/Libraries/LibWeb/Layout/TextNode.h
index cc72d91bab..0201973272 100644
--- a/Userland/Libraries/LibWeb/Layout/TextNode.h
+++ b/Userland/Libraries/LibWeb/Layout/TextNode.h
@@ -23,7 +23,7 @@ public:
const DOM::Text& dom_node() const { return static_cast(*Node::dom_node()); }
- DeprecatedString const& text_for_rendering() const { return m_text_for_rendering; }
+ DeprecatedString const& text_for_rendering() const;
struct Chunk {
Utf8View view;
@@ -48,7 +48,7 @@ public:
Utf8View::Iterator m_iterator;
};
- void compute_text_for_rendering(bool collapse);
+ void compute_text_for_rendering();
virtual JS::GCPtr create_paintable() const override;