diff options
Diffstat (limited to 'src/treebuilder/treebuilder.c')
-rw-r--r-- | src/treebuilder/treebuilder.c | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/src/treebuilder/treebuilder.c b/src/treebuilder/treebuilder.c index e6228db..e958098 100644 --- a/src/treebuilder/treebuilder.c +++ b/src/treebuilder/treebuilder.c @@ -620,6 +620,8 @@ void reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder) void *prev_node; uint32_t prev_stack_index; + element_type type = current_node(treebuilder); + success = treebuilder->tree_handler->clone_node( treebuilder->tree_handler->ctx, entry->details.node, @@ -630,30 +632,40 @@ void reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder) return; } - success = treebuilder->tree_handler->append_child( - treebuilder->tree_handler->ctx, - treebuilder->context.element_stack[ - treebuilder->context.current_node].node, - clone, - &appended); - if (success != 0) { - /** \todo handle errors */ - treebuilder->tree_handler->unref_node( + bool foster = treebuilder->context.in_table_foster && + (type == TABLE || type == TBODY || + type == TFOOT || type == THEAD || + type == TR); + + if (foster) { + aa_insert_into_foster_parent(treebuilder, clone); + } else { + success = treebuilder->tree_handler->append_child( treebuilder->tree_handler->ctx, - clone); - return; + treebuilder->context.element_stack[ + treebuilder->context.current_node].node, + clone, + &appended); + if (success != 0) { + /** \todo handle errors */ + treebuilder->tree_handler->unref_node( + treebuilder->tree_handler->ctx, + clone); + return; + } } if (!element_stack_push(treebuilder, entry->details.ns, entry->details.type, - appended)) { + clone)) { /** \todo handle memory exhaustion */ treebuilder->tree_handler->unref_node( treebuilder->tree_handler->ctx, - appended); - treebuilder->tree_handler->unref_node( - treebuilder->tree_handler->ctx, clone); + if (foster) + treebuilder->tree_handler->unref_node( + treebuilder->tree_handler->ctx, + appended); } if (!formatting_list_replace(treebuilder, entry, @@ -764,8 +776,6 @@ void insert_element_no_push(hubbub_treebuilder *treebuilder, int success; void *node, *appended; - /** \todo handle treebuilder->context.in_table_foster */ - success = treebuilder->tree_handler->create_element( treebuilder->tree_handler->ctx, tag, &node); if (success != 0) { @@ -1053,10 +1063,6 @@ bool element_stack_push(hubbub_treebuilder *treebuilder, treebuilder->context.current_node = slot; - /* Update current table index */ - if (type == TABLE) - treebuilder->context.current_table = slot; - return true; } @@ -1082,8 +1088,6 @@ bool element_stack_pop(hubbub_treebuilder *treebuilder, if (stack[t].type == TABLE) break; } - - treebuilder->context.current_table = t; } if (is_formatting_element(stack[slot].type) || @@ -1142,6 +1146,22 @@ bool element_stack_pop_until(hubbub_treebuilder *treebuilder, } /** + * Find the stack index of the current table. + */ +uint32_t current_table(hubbub_treebuilder *treebuilder) +{ + element_context *stack = treebuilder->context.element_stack; + + for (size_t t = treebuilder->context.current_node; t != 0; t--) { + if (stack[t].type == TABLE) + return t; + } + + /* fragment case */ + return 0; +} + +/** * Peek at the top element of the element stack. * * \param treebuilder Treebuilder instance |