mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:17:44 +00:00
LibWeb: Buffer text node character insertions in the new parser
Instead of appending character-at-a-time, we now buffer character insertions in a StringBuilder, and flush them to the relevant node whenever we start inserting into a new node (and when parsing ends.)
This commit is contained in:
parent
2149820260
commit
c40de9275a
2 changed files with 39 additions and 15 deletions
|
@ -78,6 +78,8 @@ void HTMLDocumentParser::run(const URL& url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flush_character_insertions();
|
||||||
|
|
||||||
// "The end"
|
// "The end"
|
||||||
|
|
||||||
auto scripts_to_execute_when_parsing_has_finished = m_document->take_scripts_to_execute_when_parsing_has_finished({});
|
auto scripts_to_execute_when_parsing_has_finished = m_document->take_scripts_to_execute_when_parsing_has_finished({});
|
||||||
|
@ -431,24 +433,41 @@ void HTMLDocumentParser::parse_generic_raw_text_element(HTMLToken& token)
|
||||||
m_insertion_mode = InsertionMode::Text;
|
m_insertion_mode = InsertionMode::Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTMLDocumentParser::insert_character(u32 data)
|
Text* HTMLDocumentParser::find_character_insertion_node()
|
||||||
{
|
{
|
||||||
auto adjusted_insertion_location = find_appropriate_place_for_inserting_node();
|
auto adjusted_insertion_location = find_appropriate_place_for_inserting_node();
|
||||||
if (adjusted_insertion_location->is_document())
|
if (adjusted_insertion_location->is_document())
|
||||||
return;
|
return nullptr;
|
||||||
if (adjusted_insertion_location->last_child() && adjusted_insertion_location->last_child()->is_text()) {
|
if (adjusted_insertion_location->last_child() && adjusted_insertion_location->last_child()->is_text())
|
||||||
auto& existing_text_node = to<Text>(*adjusted_insertion_location->last_child());
|
return to<Text>(adjusted_insertion_location->last_child());
|
||||||
StringBuilder builder;
|
|
||||||
builder.append(existing_text_node.data());
|
|
||||||
builder.append(Utf32View { &data, 1 });
|
|
||||||
existing_text_node.set_data(builder.to_string());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto new_text_node = adopt(*new Text(document(), ""));
|
auto new_text_node = adopt(*new Text(document(), ""));
|
||||||
adjusted_insertion_location->append_child(new_text_node);
|
adjusted_insertion_location->append_child(new_text_node);
|
||||||
StringBuilder builder;
|
return new_text_node;
|
||||||
builder.append(Utf32View { &data, 1 });
|
}
|
||||||
new_text_node->set_data(builder.to_string());
|
|
||||||
|
void HTMLDocumentParser::flush_character_insertions()
|
||||||
|
{
|
||||||
|
if (m_character_insertion_builder.is_empty())
|
||||||
|
return;
|
||||||
|
m_character_insertion_node->set_data(m_character_insertion_builder.to_string());
|
||||||
|
m_character_insertion_builder.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HTMLDocumentParser::insert_character(u32 data)
|
||||||
|
{
|
||||||
|
auto node = find_character_insertion_node();
|
||||||
|
if (node == m_character_insertion_node) {
|
||||||
|
m_character_insertion_builder.append(Utf32View { &data, 1 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!m_character_insertion_node) {
|
||||||
|
m_character_insertion_node = node;
|
||||||
|
m_character_insertion_builder.append(Utf32View { &data, 1 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flush_character_insertions();
|
||||||
|
m_character_insertion_node = node;
|
||||||
|
m_character_insertion_builder.append(Utf32View { &data, 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTMLDocumentParser::handle_after_head(HTMLToken& token)
|
void HTMLDocumentParser::handle_after_head(HTMLToken& token)
|
||||||
|
@ -836,8 +855,8 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token)
|
||||||
if (token.is_start_tag() && token.tag_name() == "body") {
|
if (token.is_start_tag() && token.tag_name() == "body") {
|
||||||
PARSE_ERROR();
|
PARSE_ERROR();
|
||||||
if (m_stack_of_open_elements.elements().size() == 1
|
if (m_stack_of_open_elements.elements().size() == 1
|
||||||
|| node_before_current_node().tag_name() != "body"
|
|| node_before_current_node().tag_name() != "body"
|
||||||
|| m_stack_of_open_elements.contains("template")) {
|
|| m_stack_of_open_elements.contains("template")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_frameset_ok = false;
|
m_frameset_ok = false;
|
||||||
|
|
|
@ -105,6 +105,8 @@ private:
|
||||||
bool stack_of_open_elements_has_element_with_tag_name_in_scope(const FlyString& tag_name);
|
bool stack_of_open_elements_has_element_with_tag_name_in_scope(const FlyString& tag_name);
|
||||||
NonnullRefPtr<Element> create_element_for(HTMLToken&);
|
NonnullRefPtr<Element> create_element_for(HTMLToken&);
|
||||||
RefPtr<Node> find_appropriate_place_for_inserting_node();
|
RefPtr<Node> find_appropriate_place_for_inserting_node();
|
||||||
|
Text* find_character_insertion_node();
|
||||||
|
void flush_character_insertions();
|
||||||
RefPtr<Element> insert_html_element(HTMLToken&);
|
RefPtr<Element> insert_html_element(HTMLToken&);
|
||||||
Element& current_node();
|
Element& current_node();
|
||||||
Element& node_before_current_node();
|
Element& node_before_current_node();
|
||||||
|
@ -153,6 +155,9 @@ private:
|
||||||
RefPtr<HTMLFormElement> m_form_element;
|
RefPtr<HTMLFormElement> m_form_element;
|
||||||
|
|
||||||
Vector<HTMLToken> m_pending_table_character_tokens;
|
Vector<HTMLToken> m_pending_table_character_tokens;
|
||||||
|
|
||||||
|
RefPtr<Text> m_character_insertion_node;
|
||||||
|
StringBuilder m_character_insertion_builder;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue