Ver Fonte

LibWeb: Parse "form" tags during the "in body" insertion mode

Andreas Kling há 5 anos atrás
pai
commit
fbd52047bb

+ 26 - 2
Libraries/LibWeb/Parser/HTMLDocumentParser.cpp

@@ -817,7 +817,16 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token)
     }
     }
 
 
     if (token.is_start_tag() && token.tag_name() == "form") {
     if (token.is_start_tag() && token.tag_name() == "form") {
-        TODO();
+        if (m_form_element && m_stack_of_open_elements.contains("template")) {
+            PARSE_ERROR();
+            return;
+        }
+        if (m_stack_of_open_elements.has_in_button_scope("p"))
+            close_a_p_element();
+        auto element = insert_html_element(token);
+        if (!m_stack_of_open_elements.contains("template"))
+            m_form_element = to<HTMLFormElement>(*element);
+        return;
     }
     }
 
 
     if (token.is_start_tag() && token.tag_name() == "li") {
     if (token.is_start_tag() && token.tag_name() == "li") {
@@ -887,7 +896,22 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token)
     }
     }
 
 
     if (token.is_end_tag() && token.tag_name() == "form") {
     if (token.is_end_tag() && token.tag_name() == "form") {
-        TODO();
+        if (!m_stack_of_open_elements.contains("template")) {
+            auto node = m_form_element;
+            m_form_element = nullptr;
+            if (!node || m_stack_of_open_elements.has_in_scope(*node)) {
+                PARSE_ERROR();
+                return;
+            }
+            generate_implied_end_tags();
+            if (&current_node() != node) {
+                PARSE_ERROR();
+            }
+            m_stack_of_open_elements.elements().remove_first_matching([&](auto& entry) { return entry.ptr() == node.ptr(); });
+        } else {
+            TODO();
+        }
+        return;
     }
     }
 
 
     if (token.is_end_tag() && token.tag_name() == "p") {
     if (token.is_end_tag() && token.tag_name() == "p") {

+ 9 - 0
Libraries/LibWeb/Parser/StackOfOpenElements.cpp

@@ -103,6 +103,15 @@ bool StackOfOpenElements::contains(const Element& element) const
     return false;
     return false;
 }
 }
 
 
+bool StackOfOpenElements::contains(const FlyString& tag_name) const
+{
+    for (auto& element_on_stack : m_elements) {
+        if (element_on_stack.tag_name() == tag_name)
+            return true;
+    }
+    return false;
+}
+
 void StackOfOpenElements::pop_until_an_element_with_tag_name_has_been_popped(const FlyString& tag_name)
 void StackOfOpenElements::pop_until_an_element_with_tag_name_has_been_popped(const FlyString& tag_name)
 {
 {
     while (m_elements.last().tag_name() != tag_name)
     while (m_elements.last().tag_name() != tag_name)

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

@@ -55,6 +55,7 @@ public:
     bool has_in_scope(const Element&) const;
     bool has_in_scope(const Element&) const;
 
 
     bool contains(const Element&) const;
     bool contains(const Element&) const;
+    bool contains(const FlyString& tag_name) const;
 
 
     const NonnullRefPtrVector<Element>& elements() const { return m_elements; }
     const NonnullRefPtrVector<Element>& elements() const { return m_elements; }
     NonnullRefPtrVector<Element>& elements() { return m_elements; }
     NonnullRefPtrVector<Element>& elements() { return m_elements; }