///|
fn is_table_start_foster_target(name : StringView) -> Bool {
match name {
"table" | "tbody" | "tfoot" | "thead" | "tr" => true
_ => false
}
}
///|
fn Parser::table_start_foster_mode(self : Parser, name : StringView) -> Int {
if name == "style" || name == "script" {
return 0
}
if is_table_internal_start_name(name) {
return 0
}
let table_index = self.table_context_without_cell_or_caption()
if table_index < 0 {
return 0
}
let current = self.current_node()
if current.kind != Element || !is_table_start_foster_target(current.name) {
return 0
}
if current.name == "tr" {
1
} else {
2
}
}
///|
fn Parser::table_index_is_fragment_context_table(
self : Parser,
table_index : Int,
) -> Bool {
if table_index < 0 {
return false
}
match self.fragment_context_table {
Some(table) => physical_equal(self.stack[table_index], table)
None => false
}
}
///|
fn Parser::insert_node_before_open_table(
self : Parser,
node : @dom.Node,
table_index : Int,
) -> Unit {
let table = self.stack[table_index]
match table.parent {
Some(parent) => parent.insert_before(node, Some(table))
None => self.root.append_child(node)
}
}
///|
fn Parser::append_start_tag_node(
self : Parser,
node : @dom.Node,
name : StringView,
start : Int,
) -> Unit {
let foster_mode = self.table_start_foster_mode(name)
if foster_mode == 0 {
self.current_node().append_child(node)
return
}
if foster_mode == 2 {
self.error_at("foster-parenting-start-tag", start)
self.foster_parented_start_error_nodes.push(node)
}
let table_index = self.last_open_table_index()
if self.table_index_is_fragment_context_table(table_index) {
self.current_node().append_child(node)
return
}
self.insert_node_before_open_table(node, self.last_open_table_index())
}
///|
fn Parser::remove_foster_parented_start_error_node(
self : Parser,
target : @dom.Node,
) -> Bool {
let mut index = 0
while index < self.foster_parented_start_error_nodes.length() {
if physical_equal(self.foster_parented_start_error_nodes[index], target) {
ignore(self.foster_parented_start_error_nodes.remove(index))
return true
}
index += 1
}
false
}
///|
fn Parser::handle_foster_parented_end_tag(
self : Parser,
name : String,
start : Int,
) -> Bool {
let table_index = self.table_context_without_cell_or_caption()
if table_index < 0 {
return false
}
let target_index = self.last_stack_index_of(name)
if target_index <= table_index {
return false
}
let target = self.stack[target_index]
if self.remove_foster_parented_start_error_node(target) {
self.error_at("unexpected-end-tag-implies-table-voodoo", start)
}
self.pop_until(name, start)
true
}