srctree

Robin Linden parent 9ef768ae 9ab90744
html2: Start creating body elements in the new parser

inlinesplit
html/parser.cpp added: 33, removed: 13, total 20
@@ -96,16 +96,25 @@ constexpr std::array kDisallowsParagraphEndTagOmissionWhenClosed{
} // namespace
 
void Parser::on_token(html2::Tokenizer &, html2::Token &&token) {
static constexpr auto kHandledByOldParser = [](html2::InsertionMode const &mode) {
return std::holds_alternative<html2::InBody>(mode) || std::holds_alternative<html2::AfterHead>(mode);
};
 
// Everything in <head> and earlier is handled by the new parser.
if (!std::holds_alternative<html2::AfterHead>(insertion_mode_)) {
if (!kHandledByOldParser(insertion_mode_)) {
insertion_mode_ = std::visit([&](auto &mode) { return mode.process(actions_, token); }, insertion_mode_)
.value_or(insertion_mode_);
if (auto const *end = std::get_if<html2::EndTagToken>(&token); end != nullptr && end->tag_name == "head") {
return;
}
 
if (auto const *start = std::get_if<html2::StartTagToken>(&token);
start != nullptr && start->tag_name == "body") {
return;
}
}
 
if (std::holds_alternative<html2::AfterHead>(insertion_mode_)) {
if (kHandledByOldParser(insertion_mode_)) {
std::visit(*this, token);
}
}
 
html/parser_actions.h added: 33, removed: 13, total 20
@@ -94,6 +94,10 @@ public:
 
html2::InsertionMode current_insertion_mode() const override { return current_insertion_mode_; }
 
void set_frameset_ok(bool) override {
// TODO(robinlinden): Implement.
}
 
private:
void insert(dom::Element element) {
if (element.name == "html") {
 
html2/iparser_actions.h added: 33, removed: 13, total 20
@@ -35,6 +35,7 @@ public:
virtual void set_tokenizer_state(html2::State) = 0;
virtual void store_original_insertion_mode(InsertionMode) = 0;
virtual InsertionMode original_insertion_mode() = 0;
virtual void set_frameset_ok(bool) = 0;
 
virtual InsertionMode current_insertion_mode() const = 0;
};
 
html2/parser_states.cpp added: 33, removed: 13, total 20
@@ -41,6 +41,7 @@ public:
void store_original_insertion_mode(InsertionMode mode) override { wrapped_.store_original_insertion_mode(mode); }
InsertionMode original_insertion_mode() override { return wrapped_.original_insertion_mode(); }
InsertionMode current_insertion_mode() const override { return current_insertion_mode_override_; }
void set_frameset_ok(bool ok) override { wrapped_.set_frameset_ok(ok); }
 
private:
IActions &wrapped_;
@@ -394,7 +395,13 @@ std::optional<InsertionMode> InHeadNoscript::process(IActions &a, html2::Token c
return InHead{}.process(a, token).value_or(InHead{});
}
 
std::optional<InsertionMode> AfterHead::process(IActions &, html2::Token const &) {
std::optional<InsertionMode> AfterHead::process(IActions &a, html2::Token const &token) {
if (auto const *start = std::get_if<html2::StartTagToken>(&token); start && start->tag_name == "body") {
a.insert_element_for(*start);
a.set_frameset_ok(false);
return InBody{};
}
 
return {};
}
 
 
html2/parser_states.h added: 33, removed: 13, total 20
@@ -43,8 +43,8 @@ using InsertionMode = std::variant<Initial,
InHead,
InHeadNoscript,
AfterHead,
// InBody,
Text
InBody,
Text //
#if 0
InTable,
InTableText,
 
html2/parser_states_test.cpp added: 33, removed: 13, total 20
@@ -273,10 +273,9 @@ void in_head_noscript_tests() {
}
 
void after_head_tests() {
// TODO(robinlinden): This is where this parser ends for now. :(
etest::test("AfterHead: body", [] {
auto res = parse("<body>", {});
expect_eq(res.document.html(), dom::Element{"html", {}, {dom::Element{"head"}}});
expect_eq(res.document.html(), dom::Element{"html", {}, {dom::Element{"head"}, dom::Element{"body"}}});
});
}