///|
fn document_html_element(root : @dom.Node) -> @dom.Node? {
for child in root.children {
if child.kind == Element && child.name == "html" {
return Some(child)
}
}
None
}
///|
fn append_children_to(target : @dom.Node, children : Array[@dom.Node]) -> Unit {
for child in children {
target.append_child(child)
}
}
///|
fn append_body_node_contents(
body_node : @dom.Node,
source : @dom.Node,
body_children : Array[@dom.Node],
) -> Unit {
merge_missing_attrs(body_node, source)
let existing = source.children.copy()
source.children.clear()
for child in existing {
if child.kind == Element && child.name == "body" {
append_body_node_contents(body_node, child, body_children)
} else {
body_children.push(child)
}
}
}
///|
fn append_html_node_contents(
html_node : @dom.Node,
source : @dom.Node,
html_children : Array[@dom.Node],
) -> Unit {
merge_missing_attrs(html_node, source)
let existing = source.children.copy()
source.children.clear()
for child in existing {
if child.kind == Element && child.name == "html" {
append_html_node_contents(html_node, child, html_children)
} else {
html_children.push(child)
}
}
}
///|
fn absorb_root_html_siblings(
root : @dom.Node,
html : @dom.Node,
forced_body_nodes : Array[@dom.Node],
after_head_whitespace? : Array[@dom.Node] = [],
) -> Unit {
let original = root.children.copy()
root.children.clear()
let mut saw_html = false
for child in original {
if child.kind == Element && child.name == "html" {
if saw_html {
append_html_node_contents(html, child, html.children)
} else {
root.append_child(child)
saw_html = true
}
} else if !saw_html &&
child.kind == Text &&
is_whitespace_text_node(child) &&
!nodes_contain(forced_body_nodes, child) {
if nodes_contain(after_head_whitespace, child) {
// Whitespace recorded after moves into the html element
// so the head/body classification places it between them.
child.parent = None
html.append_child(child)
} else {
// Whitespace before the html element is ignored by the
// before-html mode; a document node never holds text.
child.parent = None
}
} else if nodes_contain(forced_body_nodes, child) {
// Content reprocessed in body after a stray /