diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp index ebb5d6e1ec..cd4a40c5dd 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp @@ -106,6 +106,9 @@ void HTMLDocumentParser::process_using_the_rules_for(InsertionMode mode, HTMLTok case InsertionMode::Text: handle_text(token); break; + case InsertionMode::InTable: + handle_in_table(token); + break; default: ASSERT_NOT_REACHED(); } @@ -567,6 +570,16 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) return; } + if (token.is_start_tag() && token.tag_name() == "table") { + // FIXME: If the Document is not set to quirks mode, + // and the stack of open elements has a p element in button scope, then close a p element. + + insert_html_element(token); + m_frameset_ok = false; + m_insertion_mode = InsertionMode::InTable; + return; + } + if (token.is_start_tag()) { reconstruct_the_active_formatting_elements(); insert_html_element(token); @@ -635,6 +648,58 @@ void HTMLDocumentParser::handle_text(HTMLToken& token) ASSERT_NOT_REACHED(); } +void HTMLDocumentParser::handle_in_table(HTMLToken& token) +{ + if (token.is_character() && current_node().tag_name().is_one_of("table", "tbody", "tfoot", "thead", "tr")) { + TODO(); + } + if (token.is_comment()) { + insert_comment(token); + return; + } + if (token.is_doctype()) { + PARSE_ERROR(); + return; + } + if (token.is_start_tag() && token.tag_name() == "caption") { + TODO(); + } + if (token.is_start_tag() && token.tag_name() == "colgroup") { + TODO(); + } + if (token.is_start_tag() && token.tag_name() == "col") { + TODO(); + } + if (token.is_start_tag() && token.tag_name().is_one_of("tbody", "tfoot", "thead")) { + TODO(); + } + if (token.is_start_tag() && token.tag_name().is_one_of("td", "th", "tr")) { + TODO(); + } + if (token.is_start_tag() && token.tag_name() == "table") { + PARSE_ERROR(); + TODO(); + } + if (token.is_end_tag()) { + if (!m_stack_of_open_elements.has_in_table_scope("table")) { + PARSE_ERROR(); + return; + } + while (current_node().tag_name() != "table") + m_stack_of_open_elements.pop(); + m_stack_of_open_elements.pop(); + + reset_the_insertion_mode_appropriately(); + return; + } + TODO(); +} + +void HTMLDocumentParser::reset_the_insertion_mode_appropriately() +{ + TODO(); +} + const char* HTMLDocumentParser::insertion_mode_name() const { switch (m_insertion_mode) { diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.h b/Libraries/LibWeb/Parser/HTMLDocumentParser.h index 0e7c09e207..a57826b00e 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.h +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.h @@ -88,6 +88,7 @@ private: void handle_after_body(HTMLToken&); void handle_after_after_body(HTMLToken&); void handle_text(HTMLToken&); + void handle_in_table(HTMLToken&); void generate_implied_end_tags(const FlyString& exception = {}); bool stack_of_open_elements_has_element_with_tag_name_in_scope(const FlyString& tag_name); @@ -104,6 +105,7 @@ private: void increment_script_nesting_level(); void decrement_script_nesting_level(); size_t script_nesting_level() const { return m_script_nesting_level; } + void reset_the_insertion_mode_appropriately(); InsertionMode m_insertion_mode { InsertionMode::Initial }; InsertionMode m_original_insertion_mode { InsertionMode::Initial }; diff --git a/Libraries/LibWeb/Parser/StackOfOpenElements.cpp b/Libraries/LibWeb/Parser/StackOfOpenElements.cpp index 82bd86b9c3..8834385300 100644 --- a/Libraries/LibWeb/Parser/StackOfOpenElements.cpp +++ b/Libraries/LibWeb/Parser/StackOfOpenElements.cpp @@ -35,7 +35,7 @@ StackOfOpenElements::~StackOfOpenElements() { } -bool StackOfOpenElements::has_in_scope_impl(const FlyString& tag_name, const Vector &list) const +bool StackOfOpenElements::has_in_scope_impl(const FlyString& tag_name, const Vector& list) const { for (ssize_t i = m_elements.size() - 1; i >= 0; --i) { auto& node = m_elements.at(i); @@ -59,6 +59,15 @@ bool StackOfOpenElements::has_in_button_scope(const FlyString& tag_name) const return has_in_scope_impl(tag_name, list); } +bool StackOfOpenElements::has_in_table_scope(const FlyString& tag_name) const +{ + auto list = s_base_list; + list.append("html"); + list.append("table"); + list.append("template"); + return has_in_scope_impl(tag_name, list); +} + bool StackOfOpenElements::contains(const Element& element) const { for (auto& element_on_stack : m_elements) { diff --git a/Libraries/LibWeb/Parser/StackOfOpenElements.h b/Libraries/LibWeb/Parser/StackOfOpenElements.h index 8403f36158..5e3ed6ae52 100644 --- a/Libraries/LibWeb/Parser/StackOfOpenElements.h +++ b/Libraries/LibWeb/Parser/StackOfOpenElements.h @@ -46,6 +46,7 @@ public: bool has_in_scope(const FlyString& tag_name) const; bool has_in_button_scope(const FlyString& tag_name) const; + bool has_in_table_scope(const FlyString& tag_name) const; bool contains(const Element&) const;