|
@@ -346,13 +346,27 @@ AnythingElse:
|
|
// FIXME: Reprocess the current token in InBody!
|
|
// 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();
|
|
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)
|
|
void HTMLDocumentParser::handle_after_body(HTMLToken& token)
|
|
{
|
|
{
|
|
if (token.is_character() && token.is_parser_whitespace()) {
|
|
if (token.is_character() && token.is_parser_whitespace()) {
|
|
@@ -403,6 +417,10 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token)
|
|
insert_character(token.codepoint());
|
|
insert_character(token.codepoint());
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ reconstruct_the_active_formatting_elements();
|
|
|
|
+ insert_character(token.codepoint());
|
|
|
|
+ m_frameset_ok = false;
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
|
|
if (token.is_end_tag() && token.tag_name() == "body") {
|
|
if (token.is_end_tag() && token.tag_name() == "body") {
|
|
@@ -421,6 +439,70 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ {
|
|
|
|
+ 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" };
|
|
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())) {
|
|
if (token.is_start_tag() && names.contains_slow(token.tag_name())) {
|
|
@@ -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();
|
|
ASSERT_NOT_REACHED();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -504,5 +592,4 @@ Document& HTMLDocumentParser::document()
|
|
{
|
|
{
|
|
return *m_document;
|
|
return *m_document;
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|