diff options
author | Andreas Kling <kling@serenityos.org> | 2020-05-24 22:21:25 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-24 23:54:22 +0200 |
commit | 65d8d5e83e545db5c9c3d68ffd43704f368ed50b (patch) | |
tree | ef857ad17a95af55c1f5562d4101b7ab9c72a763 /Libraries | |
parent | 45da08a1e69728d58f3d9c29ca93dfaf43b672c2 (diff) | |
download | serenity-65d8d5e83e545db5c9c3d68ffd43704f368ed50b.zip |
LibWeb: Yet more work towards parsing www/welcome.html :^)
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibWeb/Parser/HTMLDocumentParser.cpp | 95 | ||||
-rw-r--r-- | Libraries/LibWeb/Parser/HTMLDocumentParser.h | 3 | ||||
-rw-r--r-- | Libraries/LibWeb/Parser/StackOfOpenElements.cpp | 17 | ||||
-rw-r--r-- | Libraries/LibWeb/Parser/StackOfOpenElements.h | 3 |
4 files changed, 111 insertions, 7 deletions
diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp index 3b7aad8ad3..08200a38f0 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp @@ -346,13 +346,27 @@ AnythingElse: // FIXME: Reprocess the current token in InBody! } -void HTMLDocumentParser::generate_implied_end_tags() +void HTMLDocumentParser::generate_implied_end_tags(const FlyString& exception) { - Vector<String> names { "dd", "dt", "li", "optgroup", "option", "p", "rb", "rp", "rt", "rtc" }; - while (names.contains_slow(current_node().tag_name())) + static Vector<FlyString> names { "dd", "dt", "li", "optgroup", "option", "p", "rb", "rp", "rt", "rtc" }; + while (current_node().tag_name() != exception && names.contains_slow(current_node().tag_name())) m_stack_of_open_elements.pop(); } +void HTMLDocumentParser::close_a_p_element() +{ + generate_implied_end_tags("p"); + if (current_node().tag_name() != "p") { + // Parse error. + TODO(); + } + for (;;) { + auto popped_element = m_stack_of_open_elements.pop(); + if (popped_element->tag_name() == "p") + break; + } +} + void HTMLDocumentParser::handle_after_body(HTMLToken& token) { if (token.is_character() && token.is_parser_whitespace()) { @@ -403,6 +417,10 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) insert_character(token.codepoint()); return; } + reconstruct_the_active_formatting_elements(); + insert_character(token.codepoint()); + m_frameset_ok = false; + return; } if (token.is_end_tag() && token.tag_name() == "body") { @@ -422,6 +440,70 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) } { + static Vector<FlyString> names { "h1", "h2", "h3", "h4", "h5", "h6" }; + if (token.is_start_tag() && names.contains_slow(token.tag_name())) { + if (m_stack_of_open_elements.has_in_button_scope("p")) + close_a_p_element(); + if (names.contains_slow(current_node().tag_name())) { + // FIXME: This is a parse error! + TODO(); + } + insert_html_element(token); + return; + } + } + + { + static Vector<FlyString> names { "h1", "h2", "h3", "h4", "h5", "h6" }; + if (token.is_end_tag() && names.contains_slow(token.tag_name())) { + if (!m_stack_of_open_elements.has_in_scope("h1") + && !m_stack_of_open_elements.has_in_scope("h2") + && !m_stack_of_open_elements.has_in_scope("h3") + && !m_stack_of_open_elements.has_in_scope("h4") + && !m_stack_of_open_elements.has_in_scope("h5") + && !m_stack_of_open_elements.has_in_scope("h6")) { + TODO(); + } + + generate_implied_end_tags(); + if (current_node().tag_name() != token.tag_name()) { + TODO(); + } + + for (;;) { + auto popped_element = m_stack_of_open_elements.pop(); + if (popped_element->tag_name() == "h1" + || popped_element->tag_name() == "h2" + || popped_element->tag_name() == "h3" + || popped_element->tag_name() == "h4" + || popped_element->tag_name() == "h5" + || popped_element->tag_name() == "h6") { + break; + } + } + return; + } + } + + if (token.is_end_tag() && token.tag_name() == "p") { + if (!m_stack_of_open_elements.has_in_button_scope("p")) { + TODO(); + } + close_a_p_element(); + return; + } + + { + static Vector<FlyString> names { "b", "big", "code", "em", "font", "i", "s", "small", "strike", "strong", "tt", "u" }; + if (token.is_start_tag() && names.contains_slow(token.tag_name())) { + reconstruct_the_active_formatting_elements(); + auto element = insert_html_element(token); + m_list_of_active_formatting_elements.append(*element); + return; + } + } + + { Vector<String> names { "address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", "section", "summary", "ul" }; if (token.is_start_tag() && names.contains_slow(token.tag_name())) { // FIXME: If the stack of open elements has a p element in button scope, then close a p element. @@ -447,6 +529,12 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) } } + if (token.is_start_tag()) { + reconstruct_the_active_formatting_elements(); + insert_html_element(token); + return; + } + ASSERT_NOT_REACHED(); } @@ -504,5 +592,4 @@ Document& HTMLDocumentParser::document() { return *m_document; } - } diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.h b/Libraries/LibWeb/Parser/HTMLDocumentParser.h index 09b92fbe20..0e7c09e207 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.h +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.h @@ -89,7 +89,7 @@ private: void handle_after_after_body(HTMLToken&); void handle_text(HTMLToken&); - void generate_implied_end_tags(); + void generate_implied_end_tags(const FlyString& exception = {}); bool stack_of_open_elements_has_element_with_tag_name_in_scope(const FlyString& tag_name); NonnullRefPtr<Element> create_element_for(HTMLToken&); RefPtr<Node> find_appropriate_place_for_inserting_node(); @@ -98,6 +98,7 @@ private: void insert_character(u32 data); void insert_comment(HTMLToken&); void reconstruct_the_active_formatting_elements(); + void close_a_p_element(); void process_using_the_rules_for(InsertionMode, HTMLToken&); void parse_generic_raw_text_element(HTMLToken&); void increment_script_nesting_level(); diff --git a/Libraries/LibWeb/Parser/StackOfOpenElements.cpp b/Libraries/LibWeb/Parser/StackOfOpenElements.cpp index ad607254d6..1c99624446 100644 --- a/Libraries/LibWeb/Parser/StackOfOpenElements.cpp +++ b/Libraries/LibWeb/Parser/StackOfOpenElements.cpp @@ -3,13 +3,14 @@ namespace Web { +static Vector<FlyString> s_base_list { "applet", "caption", "html", "table", "td", "th", "marquee", "object", "template" }; + StackOfOpenElements::~StackOfOpenElements() { } -bool StackOfOpenElements::has_in_scope(const FlyString& tag_name) const +bool StackOfOpenElements::has_in_scope_impl(const FlyString& tag_name, const Vector<FlyString> &list) const { - static Vector<FlyString> list { "applet", "caption", "html", "table", "td", "th", "marquee", "object", "template" }; for (ssize_t i = m_elements.size() - 1; i >= 0; --i) { auto& node = m_elements.at(i); if (node.tag_name() == tag_name) @@ -20,4 +21,16 @@ bool StackOfOpenElements::has_in_scope(const FlyString& tag_name) const ASSERT_NOT_REACHED(); } +bool StackOfOpenElements::has_in_scope(const FlyString& tag_name) const +{ + return has_in_scope_impl(tag_name, s_base_list); +} + +bool StackOfOpenElements::has_in_button_scope(const FlyString& tag_name) const +{ + auto list = s_base_list; + list.append("button"); + return has_in_scope_impl(tag_name, list); +} + } diff --git a/Libraries/LibWeb/Parser/StackOfOpenElements.h b/Libraries/LibWeb/Parser/StackOfOpenElements.h index 56eaad3115..98ac36434b 100644 --- a/Libraries/LibWeb/Parser/StackOfOpenElements.h +++ b/Libraries/LibWeb/Parser/StackOfOpenElements.h @@ -45,8 +45,11 @@ public: Element& current_node() { return m_elements.last(); } bool has_in_scope(const FlyString& tag_name) const; + bool has_in_button_scope(const FlyString& tag_name) const; private: + bool has_in_scope_impl(const FlyString& tag_name, const Vector<FlyString>&) const; + NonnullRefPtrVector<Element> m_elements; }; |