summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke <luke.wilde@live.co.uk>2020-06-13 05:09:54 +0100
committerAndreas Kling <kling@serenityos.org>2020-06-14 14:07:07 +0200
commit2241b09cd079a70aa07e8fa151ad4349ec64233a (patch)
tree27ed62d5d0dd15624a698339607f2c0535046727
parenta1838f676eccdfc2efd67d5fc425628b5ab1c4c7 (diff)
downloadserenity-2241b09cd079a70aa07e8fa151ad4349ec64233a.zip
LibWeb: Implement HTML parser "in caption" insertion mode
-rw-r--r--Libraries/LibWeb/Parser/HTMLDocumentParser.cpp57
-rw-r--r--Libraries/LibWeb/Parser/HTMLDocumentParser.h1
2 files changed, 57 insertions, 1 deletions
diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp
index 3517fab440..033d1654c2 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 199129606d..12c205a03d 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; }