///|
fn node_has_direct_element_child(node : @dom.Node, name : String) -> Bool {
for child in node.children {
if child.kind == Element && child.name == name {
return true
}
}
false
}
///|
fn Parser::handle_repeated_document_html_start_tag(
self : Parser,
name : StringView,
attrs : Map[String, String?],
start : Int,
) -> Bool {
if self.is_fragment_parser() ||
self.in_select_insertion_mode() ||
name != "html" {
return false
}
match self.open_html_element() {
Some(html) => {
self.error_at("unexpected-start-tag", start)
merge_missing_attrs_from_map(html, attrs)
self.repeated_document_html_shell = true
if !self.stack_contains_node(html) {
self.stack.push(html)
}
true
}
None => false
}
}
///|
fn Parser::report_body_start_after_repeated_document_html(
self : Parser,
name : StringView,
start : Int,
) -> Unit {
if !self.repeated_document_html_shell || name != "body" {
return
}
self.error_at("unexpected-start-tag", start)
self.repeated_document_html_shell = false
}
///|
fn Parser::is_fragment_parser(self : Parser) -> Bool {
self.root.kind == Fragment
}
///|
fn Parser::handle_document_after_body_html_end_tag(
self : Parser,
name : StringView,
start : Int,
) -> Bool {
if self.is_fragment_parser() ||
!self.document_after_body ||
name != "html" ||
self.has_open_element("html") {
return false
}
self.error_at("unexpected-token-after-body", start)
true
}
///|
fn Parser::handle_document_body_or_html_end_tag(
self : Parser,
name : String,
pos : Int,
) -> Bool {
if self.is_fragment_parser() || (name != "body" && name != "html") {
return false
}
if !self.has_open_element(name) {
if name == "body" && self.has_open_element("html") {
return true
}
return false
}
self.pop_until(name, pos)
self.document_after_body = true
true
}
///|
fn Parser::document_has_element_child(self : Parser) -> Bool {
for child in self.root.children {
if child.kind == Element {
return true
}
}
false
}
///|
fn Parser::handle_before_html_end_tag(
self : Parser,
name : StringView,
start : Int,
error_pos : Int,
) -> Bool {
if !self.before_html_phase ||
self.is_fragment_parser() ||
self.document_has_element_child() {
return false
}
self.before_html_phase = false
match name {
"html" | "head" | "body" => true
"br" => {
self.error_at("unexpected-end-tag", error_pos)
self.insert_body_mode_node(
self.node_with_origin(@dom.element("br"), start),
)
true
}
_ => {
self.error_at("unexpected-end-tag-before-html", error_pos)
true
}
}
}