summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2008-07-07 13:03:24 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2008-07-07 13:03:24 +0000
commit7ba8d4327b849aee00a71bfefa17f5fcf5bb1eaa (patch)
treee875ba2c1ecdeacca4fb2964def68f8453e46211
parentc5aab778cca9b8c579f4241ed76c5dfeac4c8553 (diff)
downloadlibhubbub-7ba8d4327b849aee00a71bfefa17f5fcf5bb1eaa.tar.gz
libhubbub-7ba8d4327b849aee00a71bfefa17f5fcf5bb1eaa.tar.bz2
A bunch of fixes to table handling
svn path=/trunk/hubbub/; revision=4525
-rw-r--r--src/treebuilder/in_body.c12
-rw-r--r--src/treebuilder/in_cell.c12
-rw-r--r--src/treebuilder/in_row.c8
-rw-r--r--src/treebuilder/in_table.c35
-rw-r--r--src/treebuilder/in_table_body.c6
-rw-r--r--src/treebuilder/treebuilder.c3
6 files changed, 56 insertions, 20 deletions
diff --git a/src/treebuilder/in_body.c b/src/treebuilder/in_body.c
index 739e0c2..64c6b5e 100644
--- a/src/treebuilder/in_body.c
+++ b/src/treebuilder/in_body.c
@@ -301,9 +301,17 @@ bool process_start_tag(hubbub_treebuilder *treebuilder,
} else if (type == TABLE) {
process_container_in_body(treebuilder, token);
- if (treebuilder->context.mode == IN_BODY) {
+ /** \todo Section 9.2.3.1 is really vague
+ * Are we meant to reset the insertion mode all the time or
+ * only when we're actually in body? I'd inferred the latter
+ * interpretation from the spec, but that causes breakage on
+ * real-world pages. */
+/* if (treebuilder->context.mode == IN_BODY) {*/
+ treebuilder->context.element_stack[
+ treebuilder->context.current_table].
+ tainted = false;
treebuilder->context.mode = IN_TABLE;
- }
+/* }*/
} else if (type == AREA || type == BASEFONT ||
type == BGSOUND || type == BR ||
type == EMBED || type == IMG || type == PARAM ||
diff --git a/src/treebuilder/in_cell.c b/src/treebuilder/in_cell.c
index 969345f..68a4f28 100644
--- a/src/treebuilder/in_cell.c
+++ b/src/treebuilder/in_cell.c
@@ -75,14 +75,14 @@ bool handle_in_cell(hubbub_treebuilder *treebuilder, const hubbub_token *token)
&token->data.tag.name);
if (type == CAPTION || type == COL ||
- type == COLGROUP || type == TBODY ||
- type == TFOOT || type == TH || type == THEAD ||
- type == TR) {
+ type == COLGROUP || type == TBODY ||
+ type == TD || type == TFOOT || type == TH ||
+ type == THEAD || type == TR) {
/** \todo fragment case */
close_cell(treebuilder);
reprocess = true;
} else {
- reprocess = handle_in_table(treebuilder, token);
+ reprocess = handle_in_body(treebuilder, token);
}
}
break;
@@ -130,7 +130,7 @@ bool handle_in_cell(hubbub_treebuilder *treebuilder, const hubbub_token *token)
/** \todo parse error */
}
} else {
- reprocess = handle_in_table(treebuilder, token);
+ reprocess = handle_in_body(treebuilder, token);
}
}
break;
@@ -138,7 +138,7 @@ bool handle_in_cell(hubbub_treebuilder *treebuilder, const hubbub_token *token)
case HUBBUB_TOKEN_COMMENT:
case HUBBUB_TOKEN_DOCTYPE:
case HUBBUB_TOKEN_EOF:
- reprocess = handle_in_table(treebuilder, token);
+ reprocess = handle_in_body(treebuilder, token);
break;
}
diff --git a/src/treebuilder/in_row.c b/src/treebuilder/in_row.c
index fce03b9..fdbaf83 100644
--- a/src/treebuilder/in_row.c
+++ b/src/treebuilder/in_row.c
@@ -93,12 +93,18 @@ bool handle_in_row(hubbub_treebuilder *treebuilder,
element_type type = element_type_from_name(treebuilder,
&token->data.tag.name);
- if (type == TH || TD) {
+ if (type == TH || type == TD) {
table_clear_stack(treebuilder);
insert_element(treebuilder, &token->data.tag);
treebuilder->context.mode = IN_CELL;
+ /* ref node for formatting list */
+ treebuilder->tree_handler->ref_node(
+ treebuilder->tree_handler->ctx,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node);
+
formatting_list_append(treebuilder, type,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
diff --git a/src/treebuilder/in_table.c b/src/treebuilder/in_table.c
index 229eba1..2fb9528 100644
--- a/src/treebuilder/in_table.c
+++ b/src/treebuilder/in_table.c
@@ -23,7 +23,7 @@
static inline void clear_stack_table_context(hubbub_treebuilder *treebuilder)
{
hubbub_ns ns;
- element_type type = UNKNOWN;
+ element_type type = current_node(treebuilder);
void *node;
while (type != TABLE && type != HTML) {
@@ -87,9 +87,10 @@ bool handle_in_table(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- treebuilder->context.element_stack[
+ if (treebuilder->context.element_stack[
treebuilder->context.current_table
- ].tainted = true;
+ ].tainted)
+ handled = false;
reprocess = process_characters_expect_whitespace(treebuilder,
token, true);
@@ -120,22 +121,37 @@ bool handle_in_table(hubbub_treebuilder *treebuilder,
insert_element(treebuilder, &token->data.tag);
treebuilder->context.mode = IN_CAPTION;
} else if (type == COLGROUP || type == COL) {
- clear_stack_table_context(treebuilder);
- insert_element(treebuilder, &token->data.tag);
- treebuilder->context.mode = IN_COLUMN_GROUP;
+ hubbub_tag tag = token->data.tag;
if (type == COL) {
+ /* Insert colgroup and reprocess */
+ tag.name.type = HUBBUB_STRING_PTR;
+ tag.name.data.ptr =
+ (const uint8_t *) "colgroup";
+ tag.name.len = SLEN("colgroup");
+
reprocess = true;
}
+
+ clear_stack_table_context(treebuilder);
+ insert_element(treebuilder, &tag);
+ treebuilder->context.mode = IN_COLUMN_GROUP;
} else if (type == TBODY || type == TFOOT || type == THEAD ||
type == TD || type == TH || type == TR) {
- clear_stack_table_context(treebuilder);
- insert_element(treebuilder, &token->data.tag);
- treebuilder->context.mode = IN_TABLE_BODY;
+ hubbub_tag tag = token->data.tag;
if (type == TD || type == TH || type == TR) {
+ /* Insert tbody and reprocess */
+ tag.name.type = HUBBUB_STRING_PTR;
+ tag.name.data.ptr = (const uint8_t *) "tbody";
+ tag.name.len = SLEN("tbody");
+
reprocess = true;
}
+
+ clear_stack_table_context(treebuilder);
+ insert_element(treebuilder, &tag);
+ treebuilder->context.mode = IN_TABLE_BODY;
} else if (type == TABLE) {
/** \todo parse error */
@@ -183,6 +199,7 @@ bool handle_in_table(hubbub_treebuilder *treebuilder,
if (cur_node == TABLE || cur_node == TBODY ||
cur_node == TFOOT || cur_node == THEAD ||
cur_node == TR) {
+ /** \todo in_body needs to take account of this flag */
treebuilder->context.in_table_foster = true;
}
diff --git a/src/treebuilder/in_table_body.c b/src/treebuilder/in_table_body.c
index 997c4c1..94d4fa2 100644
--- a/src/treebuilder/in_table_body.c
+++ b/src/treebuilder/in_table_body.c
@@ -50,6 +50,7 @@ static void table_clear_stack(hubbub_treebuilder *treebuilder)
* Handle the case common to some start tag and the table end tag cases.
*
* \param treebuilder The treebuilder instance
+ * \return Whether to reprocess the current token
*/
static bool table_sub_start_or_table_end(hubbub_treebuilder *treebuilder)
{
@@ -121,6 +122,7 @@ bool handle_in_table_body(hubbub_treebuilder *treebuilder,
tag.n_attributes = 0;
tag.attributes = NULL;
+ table_clear_stack(treebuilder);
insert_element(treebuilder, &tag);
treebuilder->context.mode = IN_ROW;
@@ -128,7 +130,7 @@ bool handle_in_table_body(hubbub_treebuilder *treebuilder,
} else if (type == CAPTION || type == COL ||
type == COLGROUP || type == TBODY ||
type == TFOOT || type == THEAD) {
- table_sub_start_or_table_end(treebuilder);
+ reprocess = table_sub_start_or_table_end(treebuilder);
} else {
reprocess = true;
}
@@ -161,7 +163,7 @@ bool handle_in_table_body(hubbub_treebuilder *treebuilder,
treebuilder->context.mode = IN_TABLE;
}
} else if (type == TABLE) {
- table_sub_start_or_table_end(treebuilder);
+ reprocess = table_sub_start_or_table_end(treebuilder);
} else if (type == BODY || type == CAPTION || type == COL ||
type == COLGROUP || type == HTML ||
type == TD || type == TH || type == TR) {
diff --git a/src/treebuilder/treebuilder.c b/src/treebuilder/treebuilder.c
index 2a6a3c1..39bc35b 100644
--- a/src/treebuilder/treebuilder.c
+++ b/src/treebuilder/treebuilder.c
@@ -1088,6 +1088,9 @@ bool element_stack_pop_until(hubbub_treebuilder *treebuilder,
/** \todo error -- never happens */
return false;
}
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
}
return true;