///|
fn node_has_direct_element_child(node : @dom.Node, name : String) -> Bool {
node.children[:].any(child => child.kind == Element && child.name == name)
}
///|
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.push_open_element(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)
self.document_after_html = true
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
}
for node in self.stack {
if node.kind == Element && is_foreign_special_element(node) {
// Inside a foreign integration point body/html are not in scope:
// the end tag is ignored without entering the after-body modes.
self.error_at("unexpected-end-tag", pos)
return true
}
}
if !self.has_open_element(name) {
if name == "body" && self.has_open_element("html") {
// A stray with an explicit html element still runs the // after-head transition through body into after-body. self.document_after_body = true return true } if self.has_open_element("template") { // In-template end tags other than are ignored and must // not advance the outer document's insertion mode. return false } // A stray or