diff options
author | TheDumpap <petervivemail@gmail.com> | 2020-05-27 01:49:40 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-27 11:10:54 +0200 |
commit | c700a30ce86ce978d7f0e0a9d34e6e9182343d89 (patch) | |
tree | 6900cd2d87b0f19337e72d18ea7fcebdac68c30a | |
parent | 8d8c33833f18d285f73492dc0bf7a4fe2a8b21eb (diff) | |
download | serenity-c700a30ce86ce978d7f0e0a9d34e6e9182343d89.zip |
LibWeb: Handle additional parser inputs in "initial" and "before html".
-rw-r--r-- | Libraries/LibWeb/Parser/HTMLDocumentParser.cpp | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp index 2b84bbfa05..db0d6c804f 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp @@ -116,7 +116,17 @@ void HTMLDocumentParser::process_using_the_rules_for(InsertionMode mode, HTMLTok void HTMLDocumentParser::handle_initial(HTMLToken& token) { - if (token.type() == HTMLToken::Type::DOCTYPE) { + if (token.is_character() && token.is_parser_whitespace()) { + return; + } + + if (token.is_comment()) { + auto comment = adopt(*new Comment(document(), token.m_comment_or_character.data.to_string())); + document().append_child(move(comment)); + return; + } + + if (token.is_doctype()) { auto doctype = adopt(*new DocumentType(document())); doctype->set_name(token.m_doctype.name.to_string()); document().append_child(move(doctype)); @@ -128,6 +138,17 @@ void HTMLDocumentParser::handle_initial(HTMLToken& token) void HTMLDocumentParser::handle_before_html(HTMLToken& token) { + if (token.is_doctype()) { + PARSE_ERROR(); + return; + } + + if (token.is_comment()) { + auto comment = adopt(*new Comment(document(), token.m_comment_or_character.data.to_string())); + document().append_child(move(comment)); + return; + } + if (token.is_character() && token.is_parser_whitespace()) { return; } @@ -139,7 +160,23 @@ void HTMLDocumentParser::handle_before_html(HTMLToken& token) m_insertion_mode = InsertionMode::BeforeHead; return; } - ASSERT_NOT_REACHED(); + + if (token.is_end_tag() && token.tag_name().is_one_of("head", "body", "html", "br")) { + goto AnythingElse; + } + + if (token.is_end_tag()) { + PARSE_ERROR(); + return; + } + +AnythingElse: + auto element = create_element(document(), "html"); + m_stack_of_open_elements.push(element); + // FIXME: If the Document is being loaded as part of navigation of a browsing context, then: run the application cache selection algorithm with no manifest, passing it the Document object. + m_insertion_mode = InsertionMode::BeforeHead; + process_using_the_rules_for(InsertionMode::BeforeHead, token); + return; } Element& HTMLDocumentParser::current_node() @@ -181,13 +218,45 @@ void HTMLDocumentParser::handle_before_head(HTMLToken& token) return; } + if (token.is_comment()) { + insert_comment(token); + return; + } + + if (token.is_doctype()) { + PARSE_ERROR(); + return; + } + + if (token.is_start_tag() && token.tag_name() == "html") { + process_using_the_rules_for(InsertionMode::InBody, token); + return; + } + if (token.is_start_tag() && token.tag_name() == "head") { auto element = insert_html_element(token); m_head_element = to<HTMLHeadElement>(element); m_insertion_mode = InsertionMode::InHead; return; } - ASSERT_NOT_REACHED(); + + if (token.is_end_tag() && token.tag_name().is_one_of("head", "body", "html", "br")) { + goto AnythingElse; + } + + if (token.is_end_tag()) { + PARSE_ERROR(); + return; + } + +AnythingElse: + HTMLToken fake_head_token; + fake_head_token.m_type = HTMLToken::Type::StartTag; + fake_head_token.m_tag.tag_name.append("head"); + m_head_element = to<HTMLHeadElement>(insert_html_element(fake_head_token)); + m_insertion_mode = InsertionMode::InHead; + process_using_the_rules_for(InsertionMode::InHead, token); + return; } void HTMLDocumentParser::insert_comment(HTMLToken& token) @@ -593,8 +662,7 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) if (node->tag_name() == token.tag_name()) { generate_implied_end_tags(token.tag_name()); if (node != current_node()) { - // It's a parse error - TODO(); + PARSE_ERROR(); } while (¤t_node() != node) { m_stack_of_open_elements.pop(); |