From 2241b09cd079a70aa07e8fa151ad4349ec64233a Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 13 Jun 2020 05:09:54 +0100 Subject: [PATCH] LibWeb: Implement HTML parser "in caption" insertion mode --- .../LibWeb/Parser/HTMLDocumentParser.cpp | 57 ++++++++++++++++++- Libraries/LibWeb/Parser/HTMLDocumentParser.h | 1 + 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp index 3517fab440d..033d1654c22 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp @@ -149,6 +149,9 @@ void HTMLDocumentParser::process_using_the_rules_for(InsertionMode mode, HTMLTok case InsertionMode::InSelect: handle_in_select(token); break; + case InsertionMode::InCaption: + handle_in_caption(token); + break; default: ASSERT_NOT_REACHED(); } @@ -1740,7 +1743,11 @@ void HTMLDocumentParser::handle_in_table(HTMLToken& token) return; } if (token.is_start_tag() && token.tag_name() == HTML::TagNames::caption) { - TODO(); + clear_the_stack_back_to_a_table_context(); + m_list_of_active_formatting_elements.add_marker(); + insert_html_element(token); + m_insertion_mode = InsertionMode::InCaption; + return; } if (token.is_start_tag() && token.tag_name() == HTML::TagNames::colgroup) { TODO(); @@ -1908,6 +1915,54 @@ void HTMLDocumentParser::handle_in_select(HTMLToken& token) PARSE_ERROR(); } +void HTMLDocumentParser::handle_in_caption(HTMLToken& token) +{ + if (token.is_end_tag() && token.tag_name() == HTML::TagNames::caption) { + if (!m_stack_of_open_elements.has_in_table_scope(HTML::TagNames::caption)) { + PARSE_ERROR(); + return; + } + + generate_implied_end_tags(); + + if (current_node().tag_name() != HTML::TagNames::caption) + PARSE_ERROR(); + + m_stack_of_open_elements.pop_until_an_element_with_tag_name_has_been_popped(HTML::TagNames::caption); + m_list_of_active_formatting_elements.clear_up_to_the_last_marker(); + + m_insertion_mode = InsertionMode::InTable; + return; + } + + if ((token.is_start_tag() && token.tag_name().is_one_of(HTML::TagNames::caption, HTML::TagNames::col, HTML::TagNames::colgroup, HTML::TagNames::tbody, HTML::TagNames::td, HTML::TagNames::tfoot, HTML::TagNames::th, HTML::TagNames::thead, HTML::TagNames::tr)) + || (token.is_end_tag() && token.tag_name() == HTML::TagNames::table)) { + if (!m_stack_of_open_elements.has_in_table_scope(HTML::TagNames::caption)) { + PARSE_ERROR(); + return; + } + + generate_implied_end_tags(); + + if (current_node().tag_name() != HTML::TagNames::caption) + PARSE_ERROR(); + + m_stack_of_open_elements.pop_until_an_element_with_tag_name_has_been_popped(HTML::TagNames::caption); + m_list_of_active_formatting_elements.clear_up_to_the_last_marker(); + + m_insertion_mode = InsertionMode::InTable; + process_using_the_rules_for(m_insertion_mode, token); + return; + } + + if (token.is_end_tag() && token.tag_name().is_one_of(HTML::TagNames::body, HTML::TagNames::col, HTML::TagNames::colgroup, HTML::TagNames::html, HTML::TagNames::tbody, HTML::TagNames::td, HTML::TagNames::tfoot, HTML::TagNames::th, HTML::TagNames::thead, HTML::TagNames::tr)) { + PARSE_ERROR(); + return; + } + + process_using_the_rules_for(InsertionMode::InBody, token); +} + void HTMLDocumentParser::reset_the_insertion_mode_appropriately() { for (ssize_t i = m_stack_of_open_elements.elements().size() - 1; i >= 0; --i) { diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.h b/Libraries/LibWeb/Parser/HTMLDocumentParser.h index 199129606d9..12c205a03d8 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.h +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.h @@ -98,6 +98,7 @@ private: void handle_in_table_text(HTMLToken&); void handle_in_select_in_table(HTMLToken&); void handle_in_select(HTMLToken&); + void handle_in_caption(HTMLToken&); void stop_parsing() { m_stop_parsing = true; }