From 43f9df0a35d46bfd4fd84b465b36d6173df7cf32 Mon Sep 17 00:00:00 2001 From: Andrew Sidwell Date: Fri, 11 Jul 2008 11:27:42 +0000 Subject: Fix up foster parenting a bit more. Make the current table calculated on-the-fly. svn path=/trunk/hubbub/; revision=4586 --- src/treebuilder/in_body.c | 28 ++++++------------ src/treebuilder/in_table.c | 4 +-- src/treebuilder/internal.h | 2 +- src/treebuilder/treebuilder.c | 66 ++++++++++++++++++++++++++++--------------- 4 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/treebuilder/in_body.c b/src/treebuilder/in_body.c index 31df8fd..9722ed3 100644 --- a/src/treebuilder/in_body.c +++ b/src/treebuilder/in_body.c @@ -275,7 +275,7 @@ bool process_start_tag(hubbub_treebuilder *treebuilder, * real-world pages. */ /* if (treebuilder->context.mode == IN_BODY) {*/ treebuilder->context.element_stack[ - treebuilder->context.current_table]. + current_table(treebuilder)]. tainted = false; treebuilder->context.mode = IN_TABLE; /* }*/ @@ -1685,16 +1685,6 @@ void aa_remove_element_stack_item(hubbub_treebuilder *treebuilder, /* Now, shuffle the stack up one, removing node in the process */ memmove(&stack[index], &stack[index + 1], (limit - index) * sizeof(element_context)); - - uint32_t t; - - /* Set current_table again properly */ - for (t = treebuilder->context.current_node; t != 0; t--) { - if (stack[t].type == TABLE) - break; - } - - treebuilder->context.current_table = t; } /** @@ -1746,9 +1736,11 @@ void aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node) bool insert = false; void *inserted; - stack[treebuilder->context.current_table].tainted = true; + uint32_t cur_table = current_table(treebuilder); + + stack[cur_table].tainted = true; - if (treebuilder->context.current_table == 0) { + if (cur_table == 0) { treebuilder->tree_handler->ref_node( treebuilder->tree_handler->ctx, stack[0].node); @@ -1759,7 +1751,7 @@ void aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node) treebuilder->tree_handler->get_parent( treebuilder->tree_handler->ctx, - stack[treebuilder->context.current_table].node, + stack[cur_table].node, true, &t_parent); if (t_parent != NULL) { @@ -1768,10 +1760,8 @@ void aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node) } else { treebuilder->tree_handler->ref_node( treebuilder->tree_handler->ctx, - stack[treebuilder->context. - current_table - 1].node); - foster_parent = stack[treebuilder->context. - current_table - 1].node; + stack[cur_table - 1].node); + foster_parent = stack[cur_table - 1].node; } } @@ -1779,7 +1769,7 @@ void aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node) treebuilder->tree_handler->insert_before( treebuilder->tree_handler->ctx, foster_parent, node, - stack[treebuilder->context.current_table].node, + stack[cur_table].node, &inserted); } else { treebuilder->tree_handler->append_child( diff --git a/src/treebuilder/in_table.c b/src/treebuilder/in_table.c index e6a81a6..3cc487f 100644 --- a/src/treebuilder/in_table.c +++ b/src/treebuilder/in_table.c @@ -90,7 +90,7 @@ bool handle_in_table(hubbub_treebuilder *treebuilder, switch (token->type) { case HUBBUB_TOKEN_CHARACTER: if (treebuilder->context.element_stack[ - treebuilder->context.current_table + current_table(treebuilder) ].tainted) { handled = false; } else { @@ -111,7 +111,7 @@ bool handle_in_table(hubbub_treebuilder *treebuilder, element_type type = element_type_from_name(treebuilder, &token->data.tag.name); bool tainted = treebuilder->context.element_stack[ - treebuilder->context.current_table + current_table(treebuilder) ].tainted; if (type == CAPTION) { diff --git a/src/treebuilder/internal.h b/src/treebuilder/internal.h index c43401e..b633fff 100644 --- a/src/treebuilder/internal.h +++ b/src/treebuilder/internal.h @@ -66,7 +66,6 @@ typedef struct hubbub_treebuilder_context element_context *element_stack; /**< Stack of open elements */ uint32_t stack_alloc; /**< Number of stack slots allocated */ uint32_t current_node; /**< Index of current node in stack */ - uint32_t current_table; /**< Index of current table in stack */ formatting_list_entry *formatting_list; /**< List of active formatting * elements */ @@ -156,6 +155,7 @@ bool element_stack_pop(hubbub_treebuilder *treebuilder, hubbub_ns *ns, element_type *type, void **node); bool element_stack_pop_until(hubbub_treebuilder *treebuilder, element_type type); +uint32_t current_table(hubbub_treebuilder *treebuilder); element_type current_node(hubbub_treebuilder *treebuilder); hubbub_ns current_node_ns(hubbub_treebuilder *treebuilder); element_type prev_node(hubbub_treebuilder *treebuilder); 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) || @@ -1141,6 +1145,22 @@ bool element_stack_pop_until(hubbub_treebuilder *treebuilder, return true; } +/** + * 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. * -- cgit v1.2.3