summaryrefslogtreecommitdiff
path: root/Libraries/LibWeb
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-05-30 11:13:57 +0200
committerAndreas Kling <kling@serenityos.org>2020-05-30 11:31:49 +0200
commitfbd52047bb2f68c774834e6ec48b94b953433b09 (patch)
treecdacd925588cfd12ba34f41fd91614947576210f /Libraries/LibWeb
parent851a0f983ae03296ec95f12031c6b44affedd8f0 (diff)
downloadserenity-fbd52047bb2f68c774834e6ec48b94b953433b09.zip
LibWeb: Parse "form" tags during the "in body" insertion mode
Diffstat (limited to 'Libraries/LibWeb')
-rw-r--r--Libraries/LibWeb/Parser/HTMLDocumentParser.cpp28
-rw-r--r--Libraries/LibWeb/Parser/StackOfOpenElements.cpp9
-rw-r--r--Libraries/LibWeb/Parser/StackOfOpenElements.h1
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 (&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") {
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; }