mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-18 08:11:53 +00:00
LibWeb: Lazily merge text nodes when invoking HTML parser incrementally
Instead of always inserting a new text node, we now continue appending to an extisting text node if the parser's character insertion point is a suitable text node. This fixes an issue where multiple invocations of document.write() would create unnecessary sequences of text nodes. Such sequences are now merged automatically. 19 new passes in WPT/html/syntax/parsing/ :^)
This commit is contained in:
parent
0c0fe09e70
commit
611833429a
Notes:
github-actions[bot]
2025-02-20 13:33:25 +00:00
Author: https://github.com/awesomekling
Commit: 611833429a
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3626
Reviewed-by: https://github.com/shannonbooth
4 changed files with 30 additions and 29 deletions
|
@ -1209,16 +1209,16 @@ void HTMLParser::parse_generic_raw_text_element(HTMLToken& token)
|
|||
m_insertion_mode = InsertionMode::Text;
|
||||
}
|
||||
|
||||
static bool is_empty_text_node(DOM::Node const* node)
|
||||
static bool is_text_node(DOM::Node const* node)
|
||||
{
|
||||
return node && node->is_text() && static_cast<DOM::Text const*>(node)->data().is_empty();
|
||||
return node && node->is_text();
|
||||
}
|
||||
|
||||
DOM::Text* HTMLParser::find_character_insertion_node()
|
||||
{
|
||||
auto adjusted_insertion_location = find_appropriate_place_for_inserting_node();
|
||||
if (adjusted_insertion_location.insert_before_sibling) {
|
||||
if (is_empty_text_node(adjusted_insertion_location.insert_before_sibling->previous_sibling()))
|
||||
if (is_text_node(adjusted_insertion_location.insert_before_sibling->previous_sibling()))
|
||||
return static_cast<DOM::Text*>(adjusted_insertion_location.insert_before_sibling->previous_sibling());
|
||||
auto new_text_node = realm().create<DOM::Text>(document(), String {});
|
||||
adjusted_insertion_location.parent->insert_before(*new_text_node, *adjusted_insertion_location.insert_before_sibling);
|
||||
|
@ -1226,7 +1226,7 @@ DOM::Text* HTMLParser::find_character_insertion_node()
|
|||
}
|
||||
if (adjusted_insertion_location.parent->is_document())
|
||||
return nullptr;
|
||||
if (is_empty_text_node(adjusted_insertion_location.parent->last_child()))
|
||||
if (is_text_node(adjusted_insertion_location.parent->last_child()))
|
||||
return static_cast<DOM::Text*>(adjusted_insertion_location.parent->last_child());
|
||||
auto new_text_node = realm().create<DOM::Text>(document(), String {});
|
||||
MUST(adjusted_insertion_location.parent->append_child(*new_text_node));
|
||||
|
@ -1237,7 +1237,10 @@ void HTMLParser::flush_character_insertions()
|
|||
{
|
||||
if (m_character_insertion_builder.is_empty())
|
||||
return;
|
||||
m_character_insertion_node->set_data(MUST(m_character_insertion_builder.to_string()));
|
||||
if (m_character_insertion_node->data().is_empty())
|
||||
m_character_insertion_node->set_data(MUST(m_character_insertion_builder.to_string()));
|
||||
else
|
||||
(void)m_character_insertion_node->append_data(MUST(m_character_insertion_builder.to_string()));
|
||||
m_character_insertion_builder.clear();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue