diff --git a/src/libs/karm-base/rc.h b/src/libs/karm-base/rc.h index 8a702abdcf4..be7c9818af3 100644 --- a/src/libs/karm-base/rc.h +++ b/src/libs/karm-base/rc.h @@ -235,6 +235,14 @@ struct Strong { return true; return unwrap() == other.unwrap(); } + + auto operator<=>(T const &other) const { + return unwrap() <=> other; + } + + auto operator==(T const &other) const { + return unwrap() == other; + } }; template diff --git a/src/libs/karm-base/slice.h b/src/libs/karm-base/slice.h index 8c48f5ecde1..b36d94fec62 100644 --- a/src/libs/karm-base/slice.h +++ b/src/libs/karm-base/slice.h @@ -295,7 +295,7 @@ constexpr auto *end(MutSliceable auto &slice) { return slice.buf() + slice.len(); } -constexpr auto const &first(Sliceable auto &slice) { +constexpr auto const &first(Sliceable auto const &slice) { return slice.buf()[0]; } @@ -303,7 +303,7 @@ constexpr auto &first(MutSliceable auto &slice) { return slice.buf()[0]; } -constexpr auto const &last(Sliceable auto &slice) { +constexpr auto const &last(Sliceable auto const &slice) { return slice.buf()[slice.len() - 1]; } diff --git a/src/web/web-dom/character-data.h b/src/web/web-dom/character-data.h new file mode 100644 index 00000000000..0baeda1c1f0 --- /dev/null +++ b/src/web/web-dom/character-data.h @@ -0,0 +1,11 @@ +#pragma once + +#include "node.h" + +namespace Web::Dom { + +struct CharacterData : public Dom::Node { + String data; +}; + +} // namespace Web::Dom diff --git a/src/web/web-dom/comment.h b/src/web/web-dom/comment.h new file mode 100644 index 00000000000..cbc4659b393 --- /dev/null +++ b/src/web/web-dom/comment.h @@ -0,0 +1,13 @@ +#pragma once + +#include "character-data.h" + +namespace Web::Dom { + +struct Comment : public CharacterData { + virtual NodeType nodeType() override { + return NodeType::COMMENT_NODE; + } +}; + +} // namespace Web::Dom diff --git a/src/web/web-dom/document-type.h b/src/web/web-dom/document-type.h new file mode 100644 index 00000000000..cfcadf58de7 --- /dev/null +++ b/src/web/web-dom/document-type.h @@ -0,0 +1,17 @@ +#pragma once + +#include "node.h" + +namespace Web::Dom { + +struct DocumentType : public Node { + String name; + String publicId; + String systemId; + + virtual NodeType nodeType() override { + return NodeType::DOCUMENT_TYPE_NODE; + } +}; + +} // namespace Web::Dom diff --git a/src/web/web-dom/document.h b/src/web/web-dom/document.h new file mode 100644 index 00000000000..0f089f57c17 --- /dev/null +++ b/src/web/web-dom/document.h @@ -0,0 +1,21 @@ +#pragma once + +#include "node.h" + +namespace Web::Dom { + +enum struct QuirkMode { + NO, + LIMITED, + YES +}; + +struct Document : public Node { + QuirkMode quirkMode{QuirkMode::NO}; + + virtual NodeType nodeType() override { + return NodeType::DOCUMENT_NODE; + } +}; + +} // namespace Web::Dom diff --git a/src/web/web-dom/element.h b/src/web/web-dom/element.h new file mode 100644 index 00000000000..9f49ef70ef7 --- /dev/null +++ b/src/web/web-dom/element.h @@ -0,0 +1,13 @@ +#pragma once + +#include "node.h" + +namespace Web::Dom { + +struct Element : public Node { + virtual NodeType nodeType() override { + return NodeType::ELEMENT_NODE; + } +}; + +} // namespace Web::Dom diff --git a/src/web/web-dom/node.h b/src/web/web-dom/node.h index 3ff2891914c..839be97ab30 100644 --- a/src/web/web-dom/node.h +++ b/src/web/web-dom/node.h @@ -1,13 +1,31 @@ #pragma once #include +#include +#include namespace Web::Dom { +enum struct NodeType { + ELEMENT_NODE = 1, + ATTRIBUTE_NODE = 2, + TEXT_NODE = 3, + CDATA_SECTION_NODE = 4, + PROCESSING_INSTRUCTION_NODE = 7, + COMMENT_NODE = 8, + DOCUMENT_NODE = 9, + DOCUMENT_TYPE_NODE = 10, + DOCUMENT_FRAGMENT_NODE = 11, +}; + struct Node : public Meta::Static { Node *_parent = nullptr; LlItem _siblings; - Ll _children; + Vec> _children; + + virtual ~Node() = default; + + virtual NodeType nodeType() = 0; /* --- Parent --- */ @@ -17,74 +35,67 @@ struct Node : public Meta::Static { return *_parent; } - Node const &parentNode() const { - if (not _parent) - panic("node has no parent"); - return *_parent; + usize _parentIndex() { + return indexOf(parentNode()._children, *this).unwrap(); + } + + void _detachParent() { + if (_parent) { + _parent->_children.removeAt(_parentIndex()); + _parent = nullptr; + } } /* --- Children --- */ - bool hasChildren() const { + bool hasChildren() { return _children.len() > 0; } - Node &firstChild() { - auto *res = _children._head; - if (not res) + Strong firstChild() { + if (not _children.len()) panic("node has no children"); - return *res; + return first(_children); } - Node const &firstChild() const { - auto *res = _children._head; - if (not res) + Strong lastChild() { + if (not _children.len()) panic("node has no children"); - return *res; + return last(_children); } - Node &lastChild() { - auto *res = _children._tail; - if (not res) - panic("node has no children"); - return *res; + void appendChild(Strong child) { + child->_detachParent(); + _children.pushBack(child); + child->_parent = this; } - Node const &lastChild() const { - auto *res = _children._tail; - if (not res) - panic("node has no children"); - return *res; + void removeChild(Strong child) { + if (child->_parent != this) + panic("node is not a child"); + child->_detachParent(); } /* --- Siblings --- */ - Node &previousSibling() { - auto *res = _siblings.prev; - if (not res) - panic("node has no previous sibling"); - return *res; + Strong previousSibling() { + usize index = _parentIndex(); + return parentNode()._children[index - 1]; } - Node const &previousSibling() const { - auto *res = _siblings.prev; - if (not res) - panic("node has no previous sibling"); - return *res; + Strong nextSibling() { + usize index = _parentIndex(); + return parentNode()._children[index + 1]; } - Node &nextSibling() { - auto *res = _siblings.next; - if (not res) - panic("node has no next sibling"); - return *res; + /* --- Operators --- */ + + bool operator==(Node const &other) const { + return this == &other; } - Node const &nextSibling() const { - auto *res = _siblings.next; - if (not res) - panic("node has no next sibling"); - return *res; + auto operator<=>(Node const &other) const { + return this <=> &other; } }; diff --git a/src/web/web-dom/text.h b/src/web/web-dom/text.h new file mode 100644 index 00000000000..333c33f7dae --- /dev/null +++ b/src/web/web-dom/text.h @@ -0,0 +1,13 @@ +#pragma once + +#include "character-data.h" + +namespace Web::Dom { + +struct Text : public CharacterData { + virtual NodeType nodeType() override { + return NodeType::TEXT_NODE; + } +}; + +} // namespace Web::Dom diff --git a/src/web/web-html/builder.cpp b/src/web/web-html/builder.cpp new file mode 100644 index 00000000000..cee3dd8ea92 --- /dev/null +++ b/src/web/web-html/builder.cpp @@ -0,0 +1,221 @@ +#include +#include + +#include "builder.h" + +namespace Web::Html { + +void Builder::_switchTo(Mode mode) { + _mode = mode; +} + +void Builder::_raise(Str msg) { + logError("{}: {}", toStr(_mode), msg); +} + +// https://html.spec.whatwg.org/multipage/parsing.html#the-initial-insertion-mode +Dom::QuirkMode Builder::_whichQuirkMode(Token const &) { + // NOSPEC + return Dom::QuirkMode::NO; +} + +// https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token +Strong Builder::_createElementFor(Token const &t) { + auto el = makeStrong(t.name); + // NOSPEC + return el; +} + +// https://html.spec.whatwg.org/multipage/parsing.html#the-initial-insertion-mode +void Builder::_handleInitialMode(Token const &t) { + if (t.type == Token::CHARACTER and + (t.rune == '\t' or + t.rune == '\n' or + t.rune == '\f' or + t.rune == ' ')) { + // ignore + } else if (t.type == Token::COMMENT) { + _document->appendChild(makeStrong(t.data)); + } else if (t.type == Token::DOCTYPE) { + _document->appendChild(makeStrong( + tryOrElse(t.name, ""), + tryOrElse(t.publicIdent, ""), + tryOrElse(t.systemIdent, ""))); + _document->quirkMode = _whichQuirkMode(t); + _switchTo(Mode::BEFORE_HTML); + accept(t); + } else { + _raise(); + _switchTo(Mode::BEFORE_HTML); + accept(t); + } +} + +// https://html.spec.whatwg.org/multipage/parsing.html#the-before-html-insertion-mode +void Builder::_handleBeforeHtml(Token const &t) { + if (t.type == Token::CHARACTER and + (t.rune == '\t' or + t.rune == '\n' or + t.rune == '\f' or + t.rune == ' ')) { + // ignore + } else if (t.type == Token::DOCTYPE) { + // ignore + _raise(); + } else if (t.type == Token::COMMENT) { + _document->appendChild(makeStrong(t.data)); + } else if (t.type == Token::START_TAG and t.name == "html") { + auto el = _createElementFor(t); + _document->appendChild(el); + _openElements.pushBack(el); + _switchTo(Mode::BEFORE_HEAD); + } else if (t.type == Token::END_TAG and not(t.name == "head" or t.name == "body" or t.name == "html" or t.name == "br")) { + // ignore + _raise(); + } else { + auto el = makeStrong("html"); + _document->appendChild(el); + _openElements.pushBack(el); + _switchTo(Mode::BEFORE_HEAD); + accept(t); + } +} + +// https://html.spec.whatwg.org/multipage/parsing.html#the-before-head-insertion-mode +void Builder::_handleBeforeHead(Token const &t) { + if (t.type == Token::CHARACTER and + (t.rune == '\t' or + t.rune == '\n' or + t.rune == '\f' or + t.rune == ' ')) { + // ignore + } +} + +void Builder::_acceptIn(Mode mode, Token const &t) { + logDebug("{}: {}", toStr(mode), t); + + switch (mode) { + + case Mode::INITIAL: + _handleInitialMode(t); + break; + + case Mode::BEFORE_HTML: + _handleBeforeHtml(t); + break; + + case Mode::BEFORE_HEAD: + _handleBeforeHead(t); + break; + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inhead + case Mode::IN_HEAD: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inheadnoscript + case Mode::IN_HEAD_NOSCRIPT: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#the-after-head-insertion-mode + case Mode::AFTER_HEAD: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody + case Mode::IN_BODY: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intext + case Mode::TEXT: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intable + case Mode::IN_TABLE: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intabletext + case Mode::IN_TABLE_TEXT: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-incaption + case Mode::IN_CAPTION: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-incolumngroup + case Mode::IN_COLUMN_GROUP: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intablebody + case Mode::IN_TABLE_BODY: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inrow + case Mode::IN_ROW: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-incell + case Mode::IN_CELL: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inselect + case Mode::IN_SELECT: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inselectintable + case Mode::IN_SELECT_IN_TABLE: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intemplate + case Mode::IN_TEMPLATE: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#the-after-body-insertion-mode + case Mode::AFTER_BODY: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#the-in-frameset-insertion-mode + case Mode::IN_FRAMESET: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#the-after-frameset-insertion-mode + case Mode::AFTER_FRAMESET: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#the-after-after-body-insertion-mode + case Mode::AFTER_AFTER_BODY: { + break; + } + + // https://html.spec.whatwg.org/multipage/parsing.html#the-after-after-frameset-insertion-mode + case Mode::AFTER_AFTER_FRAMESET: { + break; + } + + default: + break; + } +} + +void Builder::accept(Token const &t) { + _acceptIn(_mode, t); +} + +} // namespace Web::Html diff --git a/src/web/web-html/builder.h b/src/web/web-html/builder.h new file mode 100644 index 00000000000..48d17adc166 --- /dev/null +++ b/src/web/web-html/builder.h @@ -0,0 +1,79 @@ +#pragma once + +#include +#include +#include + +#include "lexer.h" + +namespace Web::Html { + +#define FOREACH_INSERTION_MODE(MODE) \ + MODE(INITIAL) \ + MODE(BEFORE_HTML) \ + MODE(BEFORE_HEAD) \ + MODE(IN_HEAD) \ + MODE(IN_HEAD_NOSCRIPT) \ + MODE(AFTER_HEAD) \ + MODE(IN_BODY) \ + MODE(TEXT) \ + MODE(IN_TABLE) \ + MODE(IN_TABLE_TEXT) \ + MODE(IN_CAPTION) \ + MODE(IN_COLUMN_GROUP) \ + MODE(IN_TABLE_BODY) \ + MODE(IN_ROW) \ + MODE(IN_CELL) \ + MODE(IN_SELECT) \ + MODE(IN_SELECT_IN_TABLE) \ + MODE(IN_TEMPLATE) \ + MODE(AFTER_BODY) \ + MODE(IN_FRAMESET) \ + MODE(AFTER_FRAMESET) \ + MODE(AFTER_AFTER_BODY) \ + ITER(AFTER_AFTER_FRAMESET) + +struct Builder { + enum struct Mode { +#define ITER(NAME) NAME, + FOREACH_INSERTION_MODE(ITER) +#undef ITER + }; + + Mode _mode; + Lexer _lexer; + Strong _document = makeStrong(); + Vec> _openElements; + + void _switchTo(Mode mode); + + void _raise(Str msg = "parse-error"); + + Dom::QuirkMode _whichQuirkMode(Token const &); + + Strong _createElementFor(Token const &t); + + void _handleInitialMode(Token const &t); + + void _handleBeforeHtml(Token const &t); + + void _handleBeforeHead(Token const &t); + + void _acceptIn(Mode mode, Token const &t); + + void accept(Token const &t); +}; + +static inline Str toStr(Builder::Mode mode) { + switch (mode) { +#define ITER(NAME) \ + case Builder::Mode::NAME: \ + return #NAME; + FOREACH_INSERTION_MODE(ITER) +#undef ITER + default: + panic("invalid mode"); + } +} + +} // namespace Web::Html diff --git a/src/web/web-html/cli/main.cpp b/src/web/web-html/cli/main.cpp index c8fdc1d10f2..b2b8138094f 100644 --- a/src/web/web-html/cli/main.cpp +++ b/src/web/web-html/cli/main.cpp @@ -1,29 +1,33 @@ #include #include #include -#include +#include +#include Res<> entryPoint(Sys::Ctx &) { - auto file = try$(Sys::File::open("bundle://web-html-cli/index.html"_url)); + auto file = try$(Sys::File::open("bundle://web-html-cli/exemple.html"_url)); auto buf = try$(Io::readAllUtf8(file)); - // Sys::println("Orginal Source:"); - // Sys::println("{}", buf); + Sys::println("Orginal Source:"); + Sys::println("{}", buf); - struct : public Web::Html::Sink { - void accept(Web::Html::Token const &token) override { - Sys::println("{}", token); - } - } sink; + Sys::println("Lexing:"); + Web::Html::Lexer lexer; + for (auto r : iterRunes(buf)) + lexer.consume(r); - Sys::println("Tokens:"); - Web::Html::Tokenizer tokenizer{sink}; + lexer.consume(-1, true); + Sys::println("\t(no output if successful)"); - for (auto r : iterRunes(buf)) - tokenizer.consume(r); + Sys::println("Tokens:"); + for (auto const &t : lexer.tokens()) + Sys::println("{}", t); - tokenizer.consume(-1, true); + Sys::println("Building:"); + Web::Html::Builder builder; + for (auto const &t : lexer.tokens()) + builder.accept(t); return Ok(); } diff --git a/src/web/web-html/tokenizer.cpp b/src/web/web-html/lexer.cpp similarity index 99% rename from src/web/web-html/tokenizer.cpp rename to src/web/web-html/lexer.cpp index a2234ed0c05..4311d9135cc 100644 --- a/src/web/web-html/tokenizer.cpp +++ b/src/web/web-html/lexer.cpp @@ -1,7 +1,7 @@ #include #include -#include "tokenizer.h" +#include "lexer.h" namespace Web::Html { @@ -21,11 +21,11 @@ struct Entity { #undef ENTITY }; -void Tokenizer::_raise(Str msg) { +void Lexer::_raise(Str msg) { logError("{}: {}", toStr(_state), msg); } -void Tokenizer::consume(Rune rune, bool isEof) { +Slice Lexer::consume(Rune rune, bool isEof) { // logDebug("Consuming '{c}' {#x} in {}", rune, rune, toStr(_state)); switch (_state) { @@ -1424,7 +1424,7 @@ void Tokenizer::consume(Rune rune, bool isEof) { // that gets associated with it, if any, are never subsequently used // by the parser, and are therefore effectively discarded. Removing // the attribute in this way does not change its status as the - // "current attribute" for the purposes of the tokenizer, however. + // "current attribute" for the purposes of the lexer, however. else if (isAsciiLower(rune)) { _builder.append(rune); } @@ -1808,7 +1808,7 @@ void Tokenizer::consume(Rune rune, bool isEof) { // is the empty string, and switch to the comment start state. if (auto r = startWith(Str{"--"}, _temp.str()); r != Match::NO) { if (r == Match::PARTIAL) - return; + break; _temp.clear(); _begin(Token::COMMENT); @@ -1820,7 +1820,7 @@ void Tokenizer::consume(Rune rune, bool isEof) { else if (auto r = startWith(Str{"DOCTYPE"}, _temp.str()); r != Match::NO) { if (r == Match::PARTIAL) - return; + break; _temp.clear(); _switchTo(State::DOCTYPE); @@ -1836,7 +1836,7 @@ void Tokenizer::consume(Rune rune, bool isEof) { else if (auto r = startWith(Str{"[CDATA["}, _temp.str()); r != Match::NO) { if (r == Match::PARTIAL) - return; + break; // NOSPEC: This is in reallity more complicated _temp.clear(); @@ -3574,6 +3574,8 @@ void Tokenizer::consume(Rune rune, bool isEof) { panic("unknown-state"); break; } + + return sub(_sink); } } // namespace Web::Html diff --git a/src/web/web-html/tokenizer.h b/src/web/web-html/lexer.h similarity index 92% rename from src/web/web-html/tokenizer.h rename to src/web/web-html/lexer.h index 2a19d9b4305..33540af76ab 100644 --- a/src/web/web-html/tokenizer.h +++ b/src/web/web-html/lexer.h @@ -47,7 +47,7 @@ struct Sink { virtual void accept(Token const &token) = 0; }; -struct Tokenizer { +struct Lexer { enum struct State { #define STATE(NAME) NAME, #include "defs/states.inc" @@ -59,16 +59,12 @@ struct Tokenizer { Opt _token; Opt _last; + Vec _sink; Rune _currChar = 0; StringBuilder _builder; StringBuilder _temp; - Sink &_sink; - - Tokenizer(Sink &sink) - : _sink(sink) {} - Token &_begin(Token::Type type) { _token = Token{}; _token->type = type; @@ -89,7 +85,7 @@ struct Tokenizer { } void _emit() { - _sink.accept(_ensure()); + _sink.pushBack(_ensure()); _last = std::move(_token); } @@ -130,7 +126,15 @@ struct Tokenizer { debug("flushing code points consumed as a character reference"); } - void consume(Rune rune, bool isEof = false); + Slice consume(Rune rune, bool isEof = false); + + Slice tokens() { + return _sink; + } + + void flush() { + _sink.clear(); + } }; static inline Str toStr(Token::Type type) { @@ -145,10 +149,10 @@ static inline Str toStr(Token::Type type) { } } -static inline Str toStr(Tokenizer::State state) { +static inline Str toStr(Lexer::State state) { switch (state) { -#define STATE(NAME) \ - case Tokenizer::State::NAME: \ +#define STATE(NAME) \ + case Lexer::State::NAME: \ return #NAME; #include "defs/states.inc" #undef STATE diff --git a/src/web/web-html/parser.h b/src/web/web-html/parser.h deleted file mode 100644 index 2e38dd88207..00000000000 --- a/src/web/web-html/parser.h +++ /dev/null @@ -1,186 +0,0 @@ -#pragma once - -#include - -#include "tokenizer.h" - -namespace Web::Html { - -#define FOREACH_INSERTION_MODE(MODE) \ - MODE(INITIAL) \ - MODE(BEFORE_HTML) \ - MODE(BEFORE_HEAD) \ - MODE(IN_HEAD) \ - MODE(IN_HEAD_NOSCRIPT) \ - MODE(AFTER_HEAD) \ - MODE(IN_BODY) \ - MODE(TEXT) \ - MODE(IN_TABLE) \ - MODE(IN_TABLE_TEXT) \ - MODE(IN_CAPTION) \ - MODE(IN_COLUMN_GROUP) \ - MODE(IN_TABLE_BODY) \ - MODE(IN_ROW) \ - MODE(IN_CELL) \ - MODE(IN_SELECT) \ - MODE(IN_SELECT_IN_TABLE) \ - MODE(IN_TEMPLATE) \ - MODE(AFTER_BODY) \ - MODE(IN_FRAMESET) \ - MODE(AFTER_FRAMESET) \ - MODE(AFTER_AFTER_BODY) \ - ITER(AFTER_AFTER_FRAMESET) - -struct Parser : private Sink { - enum struct InsertionMode { -#define ITER(NAME) NAME, - FOREACH_INSERTION_MODE(ITER) -#undef ITER - }; - - InsertionMode _insertionMode; - Tokenizer _tokenizer{*this}; - - Strong _document; - - // https://html.spec.whatwg.org/multipage/parsing.html#the-initial-insertion-mode - void _handleInitialMode(Token const &t) { - if (t.type == Token::CHARACTER and - (t.rune == '\t' or - t.rune == '\n' or - t.rune == '\f' or - t.rune == ' ')) { - return; - } else if (t.type == Token::COMMENT) { - _document->appendChild(makeStrong(t.data)); - } - } - - void _acceptAs(InsertionMode mode, Token const &t) { - switch (mode) { - - case InsertionMode::INITIAL: - _handleInitialMode(t); - break; - - // https://html.spec.whatwg.org/multipage/parsing.html#the-before-html-insertion-mode - case InsertionMode::BEFORE_HTML: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#the-before-head-insertion-mode - case InsertionMode::BEFORE_HEAD: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inhead - case InsertionMode::IN_HEAD: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inheadnoscript - case InsertionMode::IN_HEAD_NOSCRIPT: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#the-after-head-insertion-mode - case InsertionMode::AFTER_HEAD: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody - case InsertionMode::IN_BODY: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intext - case InsertionMode::TEXT: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intable - case InsertionMode::IN_TABLE: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intabletext - case InsertionMode::IN_TABLE_TEXT: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-incaption - case InsertionMode::IN_CAPTION: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-incolumngroup - case InsertionMode::IN_COLUMN_GROUP: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intablebody - case InsertionMode::IN_TABLE_BODY: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inrow - case InsertionMode::IN_ROW: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-incell - case InsertionMode::IN_CELL: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inselect - case InsertionMode::IN_SELECT: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inselectintable - case InsertionMode::IN_SELECT_IN_TABLE: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intemplate - case InsertionMode::IN_TEMPLATE: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#the-after-body-insertion-mode - case InsertionMode::AFTER_BODY: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#the-in-frameset-insertion-mode - case InsertionMode::IN_FRAMESET: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#the-after-frameset-insertion-mode - case InsertionMode::AFTER_FRAMESET: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#the-after-after-body-insertion-mode - case InsertionMode::AFTER_AFTER_BODY: { - break; - } - - // https://html.spec.whatwg.org/multipage/parsing.html#the-after-after-frameset-insertion-mode - case InsertionMode::AFTER_AFTER_FRAMESET: { - break; - } - - default: - break; - } - } - - void accept(Token const &t) override { - _acceptAs(_insertionMode, t); - } -}; - -} // namespace Web::Html