diff options
author | Andreas Kling <kling@serenityos.org> | 2020-06-03 21:53:08 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-06-03 21:53:08 +0200 |
commit | c40de9275a9850034362877ccaf7a1a979960221 (patch) | |
tree | f7f6f9af52d5eacc2af0a8efbb4cd4c4e1d60543 /Libraries/LibWeb/Parser | |
parent | 214982026080f411ea38e1dbb1a51186d10362fe (diff) | |
download | serenity-c40de9275a9850034362877ccaf7a1a979960221.zip |
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.)
Diffstat (limited to 'Libraries/LibWeb/Parser')
-rw-r--r-- | Libraries/LibWeb/Parser/HTMLDocumentParser.cpp | 47 | ||||
-rw-r--r-- | Libraries/LibWeb/Parser/HTMLDocumentParser.h | 5 |
2 files changed, 38 insertions, 14 deletions
diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp index c71cc8ded1..d9a18c04a3 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp @@ -78,6 +78,8 @@ void HTMLDocumentParser::run(const URL& url) } } + flush_character_insertions(); + // "The end" 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; } -void HTMLDocumentParser::insert_character(u32 data) +Text* HTMLDocumentParser::find_character_insertion_node() { auto adjusted_insertion_location = find_appropriate_place_for_inserting_node(); if (adjusted_insertion_location->is_document()) + return nullptr; + if (adjusted_insertion_location->last_child() && adjusted_insertion_location->last_child()->is_text()) + return to<Text>(adjusted_insertion_location->last_child()); + auto new_text_node = adopt(*new Text(document(), "")); + adjusted_insertion_location->append_child(new_text_node); + return new_text_node; +} + +void HTMLDocumentParser::flush_character_insertions() +{ + if (m_character_insertion_builder.is_empty()) return; - if (adjusted_insertion_location->last_child() && adjusted_insertion_location->last_child()->is_text()) { - auto& existing_text_node = 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()); + 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; } - auto new_text_node = adopt(*new Text(document(), "")); - adjusted_insertion_location->append_child(new_text_node); - StringBuilder builder; - builder.append(Utf32View { &data, 1 }); - new_text_node->set_data(builder.to_string()); + 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) @@ -836,8 +855,8 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) if (token.is_start_tag() && token.tag_name() == "body") { PARSE_ERROR(); if (m_stack_of_open_elements.elements().size() == 1 - || node_before_current_node().tag_name() != "body" - || m_stack_of_open_elements.contains("template")) { + || node_before_current_node().tag_name() != "body" + || m_stack_of_open_elements.contains("template")) { return; } m_frameset_ok = false; diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.h b/Libraries/LibWeb/Parser/HTMLDocumentParser.h index 0a334bf31c..199129606d 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.h +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.h @@ -105,6 +105,8 @@ private: bool stack_of_open_elements_has_element_with_tag_name_in_scope(const FlyString& tag_name); NonnullRefPtr<Element> create_element_for(HTMLToken&); RefPtr<Node> find_appropriate_place_for_inserting_node(); + Text* find_character_insertion_node(); + void flush_character_insertions(); RefPtr<Element> insert_html_element(HTMLToken&); Element& current_node(); Element& node_before_current_node(); @@ -153,6 +155,9 @@ private: RefPtr<HTMLFormElement> m_form_element; Vector<HTMLToken> m_pending_table_character_tokens; + + RefPtr<Text> m_character_insertion_node; + StringBuilder m_character_insertion_builder; }; } |