diff options
author | Andreas Kling <kling@serenityos.org> | 2020-05-30 11:13:57 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-30 11:31:49 +0200 |
commit | fbd52047bb2f68c774834e6ec48b94b953433b09 (patch) | |
tree | cdacd925588cfd12ba34f41fd91614947576210f /Libraries/LibWeb | |
parent | 851a0f983ae03296ec95f12031c6b44affedd8f0 (diff) | |
download | serenity-fbd52047bb2f68c774834e6ec48b94b953433b09.zip |
LibWeb: Parse "form" tags during the "in body" insertion mode
Diffstat (limited to 'Libraries/LibWeb')
-rw-r--r-- | Libraries/LibWeb/Parser/HTMLDocumentParser.cpp | 28 | ||||
-rw-r--r-- | Libraries/LibWeb/Parser/StackOfOpenElements.cpp | 9 | ||||
-rw-r--r-- | Libraries/LibWeb/Parser/StackOfOpenElements.h | 1 |
3 files changed, 36 insertions, 2 deletions
diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp index 821ee3fc4e..e524fe0edd 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp +++ b/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") { - 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") { @@ -887,7 +896,22 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) } 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 (¤t_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") { diff --git a/Libraries/LibWeb/Parser/StackOfOpenElements.cpp b/Libraries/LibWeb/Parser/StackOfOpenElements.cpp index 807fc40c0e..5048b83fc8 100644 --- a/Libraries/LibWeb/Parser/StackOfOpenElements.cpp +++ b/Libraries/LibWeb/Parser/StackOfOpenElements.cpp @@ -103,6 +103,15 @@ bool StackOfOpenElements::contains(const Element& element) const 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) { while (m_elements.last().tag_name() != tag_name) diff --git a/Libraries/LibWeb/Parser/StackOfOpenElements.h b/Libraries/LibWeb/Parser/StackOfOpenElements.h index d6dbd18d27..6fb4455def 100644 --- a/Libraries/LibWeb/Parser/StackOfOpenElements.h +++ b/Libraries/LibWeb/Parser/StackOfOpenElements.h @@ -55,6 +55,7 @@ public: bool has_in_scope(const Element&) const; bool contains(const Element&) const; + bool contains(const FlyString& tag_name) const; const NonnullRefPtrVector<Element>& elements() const { return m_elements; } NonnullRefPtrVector<Element>& elements() { return m_elements; } |