///|
fn is_table_section_name(name : StringView) -> Bool {
match name {
"tbody" | "thead" | "tfoot" => true
_ => false
}
}
///|
fn is_table_cell_name(name : StringView) -> Bool {
match name {
"td" | "th" => true
_ => false
}
}
///|
fn normalize_table_section(section : @dom.Node) -> Unit {
let original = section.children.copy()
section.children.clear()
let mut current_row : @dom.Node? = None
for child in original {
normalize_tables(child)
if child.kind == Element && is_table_cell_name(child.name) {
let row = match current_row {
Some(row) => row
None => {
let row = @dom.element("tr")
section.append_child(row)
current_row = Some(row)
row
}
}
row.append_child(child)
} else {
section.append_child(child)
current_row = None
}
}
}
///|
fn table_implicit_body(
table : @dom.Node,
current_body : @dom.Node?,
) -> (@dom.Node, @dom.Node?) {
match current_body {
Some(body) => (body, current_body)
None => {
let body = @dom.element("tbody")
table.append_child(body)
(body, Some(body))
}
}
}
///|
fn table_implicit_colgroup(
table : @dom.Node,
current_colgroup : @dom.Node?,
) -> (@dom.Node, @dom.Node?) {
match current_colgroup {
Some(colgroup) => (colgroup, current_colgroup)
None => {
let colgroup = @dom.element("colgroup")
table.append_child(colgroup)
(colgroup, Some(colgroup))
}
}
}
///|
fn normalize_table(table : @dom.Node) -> Unit {
let original = table.children.copy()
table.children.clear()
let mut current_body : @dom.Node? = None
let mut current_row : @dom.Node? = None
let mut current_colgroup : @dom.Node? = None
for child in original {
normalize_tables(child)
if child.kind == Element && child.name == "col" {
let (colgroup, next_colgroup) = table_implicit_colgroup(
table, current_colgroup,
)
current_colgroup = next_colgroup
colgroup.append_child(child)
current_body = None
current_row = None
} else if child.kind == Text &&
current_colgroup is Some(colgroup) &&
!text_has_non_ascii_whitespace(child.data) {
colgroup.append_child(child)
current_body = None
current_row = None
} else if child.kind == Element && child.name == "tr" {
let (body, next_body) = table_implicit_body(table, current_body)
current_body = next_body
body.append_child(child)
current_row = None
current_colgroup = None
} else if child.kind == Element && is_table_cell_name(child.name) {
let (body, next_body) = table_implicit_body(table, current_body)
current_body = next_body
let row = match current_row {
Some(row) => row
None => {
let row = @dom.element("tr")
body.append_child(row)
current_row = Some(row)
row
}
}
row.append_child(child)
current_colgroup = None
} else {
table.append_child(child)
current_body = None
current_row = None
current_colgroup = None
}
}
}
///|
fn normalize_tables(node : @dom.Node) -> Unit {
match node.kind {
Element if node.name == "table" => normalize_table(node)
Element if is_table_section_name(node.name) => normalize_table_section(node)
_ =>
for child in node.children {
normalize_tables(child)
}
}
}