Browse Source

LibWeb: Start fleshing out the "in table" parser insertion mode

Andreas Kling 5 years ago
parent
commit
1e30ef239b

+ 65 - 0
Libraries/LibWeb/Parser/HTMLDocumentParser.cpp

@@ -106,6 +106,9 @@ void HTMLDocumentParser::process_using_the_rules_for(InsertionMode mode, HTMLTok
     case InsertionMode::Text:
     case InsertionMode::Text:
         handle_text(token);
         handle_text(token);
         break;
         break;
+    case InsertionMode::InTable:
+        handle_in_table(token);
+        break;
     default:
     default:
         ASSERT_NOT_REACHED();
         ASSERT_NOT_REACHED();
     }
     }
@@ -567,6 +570,16 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token)
         return;
         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()) {
     if (token.is_start_tag()) {
         reconstruct_the_active_formatting_elements();
         reconstruct_the_active_formatting_elements();
         insert_html_element(token);
         insert_html_element(token);
@@ -635,6 +648,58 @@ void HTMLDocumentParser::handle_text(HTMLToken& token)
     ASSERT_NOT_REACHED();
     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
 const char* HTMLDocumentParser::insertion_mode_name() const
 {
 {
     switch (m_insertion_mode) {
     switch (m_insertion_mode) {

+ 2 - 0
Libraries/LibWeb/Parser/HTMLDocumentParser.h

@@ -88,6 +88,7 @@ private:
     void handle_after_body(HTMLToken&);
     void handle_after_body(HTMLToken&);
     void handle_after_after_body(HTMLToken&);
     void handle_after_after_body(HTMLToken&);
     void handle_text(HTMLToken&);
     void handle_text(HTMLToken&);
+    void handle_in_table(HTMLToken&);
 
 
     void generate_implied_end_tags(const FlyString& exception = {});
     void generate_implied_end_tags(const FlyString& exception = {});
     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);
@@ -104,6 +105,7 @@ private:
     void increment_script_nesting_level();
     void increment_script_nesting_level();
     void decrement_script_nesting_level();
     void decrement_script_nesting_level();
     size_t script_nesting_level() const { return m_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_insertion_mode { InsertionMode::Initial };
     InsertionMode m_original_insertion_mode { InsertionMode::Initial };
     InsertionMode m_original_insertion_mode { InsertionMode::Initial };

+ 10 - 1
Libraries/LibWeb/Parser/StackOfOpenElements.cpp

@@ -35,7 +35,7 @@ StackOfOpenElements::~StackOfOpenElements()
 {
 {
 }
 }
 
 
-bool StackOfOpenElements::has_in_scope_impl(const FlyString& tag_name, const Vector<FlyString> &list) const
+bool StackOfOpenElements::has_in_scope_impl(const FlyString& tag_name, const Vector<FlyString>& list) const
 {
 {
     for (ssize_t i = m_elements.size() - 1; i >= 0; --i) {
     for (ssize_t i = m_elements.size() - 1; i >= 0; --i) {
         auto& node = m_elements.at(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);
     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
 bool StackOfOpenElements::contains(const Element& element) const
 {
 {
     for (auto& element_on_stack : m_elements) {
     for (auto& element_on_stack : m_elements) {

+ 1 - 0
Libraries/LibWeb/Parser/StackOfOpenElements.h

@@ -46,6 +46,7 @@ public:
 
 
     bool has_in_scope(const FlyString& tag_name) const;
     bool has_in_scope(const FlyString& tag_name) const;
     bool has_in_button_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;
     bool contains(const Element&) const;