summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/treebuilder/in_body.c28
-rw-r--r--src/treebuilder/in_table.c4
-rw-r--r--src/treebuilder/internal.h2
-rw-r--r--src/treebuilder/treebuilder.c66
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) ||
@@ -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