mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 20:28:11 +00:00
LibWeb: Make Layout::TextNode::text_for_rendering() lazily computed
As it turns out, Layout::TreeBuilder never managed to wrap text within table boxes in anonymous wrapper boxes, since it relied on checking text_for_rendering(), and that was never initialized during that early stage of tree building. This patch fixes the issue by making text_for_rendering() compute the (potentially collapsed) text lazily when called. Note that the test included with this patch is still totally wrong, but that is now a TFC problem rather than a TreeBuilder problem. :^)
This commit is contained in:
parent
5cdb394400
commit
b918ce4022
5 changed files with 69 additions and 7 deletions
|
@ -0,0 +1,18 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (1,1) content-size 798x216 [BFC] children: not-inline
|
||||
TableWrapper <(anonymous)> at (9,9) content-size 300x200 [BFC] children: not-inline
|
||||
Box <body.table> at (10,10) content-size 298x198 table-box [TFC] children: not-inline
|
||||
Box <div.bottom> 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 <div.top> 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>
|
|
@ -0,0 +1,24 @@
|
|||
<!doctype html><style>
|
||||
* {
|
||||
border: 1px solid black;
|
||||
}
|
||||
html {
|
||||
background: white;
|
||||
}
|
||||
.table {
|
||||
display: table;
|
||||
background: pink;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
}
|
||||
.top {
|
||||
display: table-header-group;
|
||||
background: orange;
|
||||
height: 50px;
|
||||
}
|
||||
.bottom {
|
||||
display: table-footer-group;
|
||||
background: magenta;
|
||||
height: 50px;
|
||||
}
|
||||
</style><body class=table><div class=bottom>bottom</div><div class=top>top</div>
|
|
@ -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<TextNode&>(text_node).compute_text_for_rendering(do_collapse);
|
||||
|
||||
m_text_node_context = TextNodeContext {
|
||||
.do_collapse = do_collapse,
|
||||
.do_wrap_lines = do_wrap_lines,
|
||||
|
|
|
@ -41,9 +41,32 @@ static ErrorOr<DeprecatedString> 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<TextNode*>(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()) {
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
|
||||
const DOM::Text& dom_node() const { return static_cast<const DOM::Text&>(*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<Painting::Paintable> create_paintable() const override;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue