summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRupinder Singh Khokhar <rsk1coder99@gmail.com>2014-07-01 22:19:22 (GMT)
committer Rupinder Singh Khokhar <rsk1coder99@gmail.com>2014-08-01 16:14:30 (GMT)
commit751b5c694e39f8c9c271061fbb4d518e27cee928 (patch)
tree864c5b6bb7c7e59a6378c4035d7c3b24ed9860e2
parent46802b46290a965d5828bb2a3402bba2393b178f (diff)
downloadlibhubbub-751b5c694e39f8c9c271061fbb4d518e27cee928.tar.gz
libhubbub-751b5c694e39f8c9c271061fbb4d518e27cee928.tar.bz2
Fixed The adoption agency & related things
-rw-r--r--src/treebuilder/in_body.c95
-rw-r--r--src/treebuilder/in_cell.c6
-rw-r--r--src/treebuilder/in_select.c4
-rw-r--r--src/treebuilder/in_select_in_table.c2
-rw-r--r--src/treebuilder/in_table_body.c8
-rw-r--r--src/treebuilder/internal.h2
-rw-r--r--src/treebuilder/treebuilder.c33
-rw-r--r--test/data/tree-construction/INDEX4
8 files changed, 107 insertions, 47 deletions
diff --git a/src/treebuilder/in_body.c b/src/treebuilder/in_body.c
index e685e0e..3e8650d 100644
--- a/src/treebuilder/in_body.c
+++ b/src/treebuilder/in_body.c
@@ -23,6 +23,7 @@ typedef struct bookmark {
formatting_list_entry *next; /**< Next entry */
} bookmark;
+static hubbub_error close_p_in_body(hubbub_treebuilder *treebuilder);
static hubbub_error process_character(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
static hubbub_error process_start_tag(hubbub_treebuilder *treebuilder,
@@ -564,8 +565,8 @@ hubbub_error process_container_in_body(hubbub_treebuilder *treebuilder,
{
hubbub_error err;
- if (element_in_scope(treebuilder, P, false)) {
- err = process_0p_in_body(treebuilder);
+ if (element_in_scope(treebuilder, P, false, true)) {
+ err = close_p_in_body(treebuilder);
if (err != HUBBUB_OK)
return err;
}
@@ -585,7 +586,7 @@ hubbub_error process_hN_in_body(hubbub_treebuilder *treebuilder,
hubbub_error err;
element_type type;
- if (element_in_scope(treebuilder, P, false)) {
+ if (element_in_scope(treebuilder, P, false, false)) {
err = process_0p_in_body(treebuilder);
if (err != HUBBUB_OK)
return err;
@@ -627,7 +628,7 @@ hubbub_error process_form_in_body(hubbub_treebuilder *treebuilder,
if (treebuilder->context.form_element != NULL) {
/** \todo parse error */
} else {
- if (element_in_scope(treebuilder, P, false)) {
+ if (element_in_scope(treebuilder, P, false, false)) {
err = process_0p_in_body(treebuilder);
if (err != HUBBUB_OK)
return err;
@@ -668,7 +669,7 @@ hubbub_error process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
treebuilder->context.frameset_ok = false;
- if (element_in_scope(treebuilder, P, false)) {
+ if (element_in_scope(treebuilder, P, false, false)) {
err = process_0p_in_body(treebuilder);
if (err != HUBBUB_OK)
return err;
@@ -731,7 +732,7 @@ hubbub_error process_plaintext_in_body(hubbub_treebuilder *treebuilder,
hubbub_error err;
hubbub_tokeniser_optparams params;
- if (element_in_scope(treebuilder, P, false)) {
+ if (element_in_scope(treebuilder, P, false, false)) {
err = process_0p_in_body(treebuilder);
if (err != HUBBUB_OK)
return err;
@@ -919,7 +920,7 @@ hubbub_error process_nobr_in_body(hubbub_treebuilder *treebuilder,
if (err != HUBBUB_OK)
return err;
- if (element_in_scope(treebuilder, NOBR, false)) {
+ if (element_in_scope(treebuilder, NOBR, false, false)) {
/** \todo parse error */
/* Act as if </nobr> were seen */
@@ -981,7 +982,7 @@ hubbub_error process_button_in_body(hubbub_treebuilder *treebuilder,
{
hubbub_error err;
- if (element_in_scope(treebuilder, BUTTON, false)) {
+ if (element_in_scope(treebuilder, BUTTON, false, false)) {
/** \todo parse error */
/* Act as if </button> has been seen */
@@ -1070,7 +1071,7 @@ hubbub_error process_hr_in_body(hubbub_treebuilder *treebuilder,
{
hubbub_error err;
- if (element_in_scope(treebuilder, P, false)) {
+ if (element_in_scope(treebuilder, P, false, false)) {
err = process_0p_in_body(treebuilder);
if (err != HUBBUB_OK)
return err;
@@ -1332,7 +1333,7 @@ hubbub_error process_opt_in_body(hubbub_treebuilder *treebuilder,
{
hubbub_error err;
- if (element_in_scope(treebuilder, OPTION, false)) {
+ if (element_in_scope(treebuilder, OPTION, false, false)) {
err = process_0generic_in_body(treebuilder, OPTION);
/* Cannot fail */
assert(err == HUBBUB_OK);
@@ -1373,7 +1374,7 @@ hubbub_error process_0body_in_body(hubbub_treebuilder *treebuilder)
{
hubbub_error err = HUBBUB_OK;
- if (!element_in_scope(treebuilder, BODY, false)) {
+ if (!element_in_scope(treebuilder, BODY, false, false)) {
/** \todo parse error */
} else {
element_context *stack = treebuilder->context.element_stack;
@@ -1412,7 +1413,7 @@ hubbub_error process_0body_in_body(hubbub_treebuilder *treebuilder)
hubbub_error process_0container_in_body(hubbub_treebuilder *treebuilder,
element_type type)
{
- if (!element_in_scope(treebuilder, type, false)) {
+ if (!element_in_scope(treebuilder, type, false, false)) {
/** \todo parse error */
} else {
uint32_t popped = 0;
@@ -1457,7 +1458,7 @@ hubbub_error process_0form_in_body(hubbub_treebuilder *treebuilder)
treebuilder->context.form_element);
treebuilder->context.form_element = NULL;
- idx = element_in_scope(treebuilder, FORM, false);
+ idx = element_in_scope(treebuilder, FORM, false, false);
if (idx == 0 || node == NULL ||
treebuilder->context.element_stack[idx].node != node) {
@@ -1486,25 +1487,27 @@ hubbub_error process_0form_in_body(hubbub_treebuilder *treebuilder)
return HUBBUB_OK;
}
-
/**
- * Process a p end tag as if in "in body"
- *
+ * Close a p Element by repeated popping
* \param treebuilder The treebuilder instance
*/
-hubbub_error process_0p_in_body(hubbub_treebuilder *treebuilder)
+hubbub_error close_p_in_body(hubbub_treebuilder *treebuilder)
{
hubbub_error err = HUBBUB_OK;
uint32_t popped = 0;
- if (treebuilder->context.element_stack[
+ close_implied_end_tags(treebuilder, P);
+
+ if(treebuilder->context.element_stack[
treebuilder->context.current_node].type != P) {
- /** \todo parse error */
+ /* todo parse error */
+
}
- while (element_in_scope(treebuilder, P, false)) {
+ element_type type;
+
+ do {
hubbub_ns ns;
- element_type type;
void *node;
err = element_stack_pop(treebuilder, &ns, &type, &node);
@@ -1514,7 +1517,7 @@ hubbub_error process_0p_in_body(hubbub_treebuilder *treebuilder)
treebuilder->tree_handler->ctx, node);
popped++;
- }
+ } while (type != P);
if (popped == 0) {
hubbub_token dummy;
@@ -1536,11 +1539,39 @@ hubbub_error process_0p_in_body(hubbub_treebuilder *treebuilder)
/* Cannot fail */
assert(err == HUBBUB_OK);
}
-
return err;
}
/**
+ * Process a p end tag as if in "in body"
+ *
+ * \param treebuilder The treebuilder instance
+ */
+hubbub_error process_0p_in_body(hubbub_treebuilder *treebuilder)
+{
+
+ if (!element_in_scope(treebuilder, P, false, true)) {
+ /** \todo parse error */
+
+ hubbub_tag tag;
+ hubbub_error err;
+
+ tag.ns = HUBBUB_NS_HTML;
+ tag.name.ptr = (const uint8_t *) "p";
+ tag.name.len = SLEN("p");
+ tag.n_attributes = 0;
+ tag.attributes = NULL;
+
+ err = insert_element(treebuilder, &tag, true);
+ if(err != HUBBUB_OK)
+ return err;
+
+ }
+
+ return close_p_in_body(treebuilder);
+}
+
+/**
* Process a dd, dt, or li end tag as if in "in body"
*
* \param treebuilder The treebuilder instance
@@ -1549,7 +1580,7 @@ hubbub_error process_0p_in_body(hubbub_treebuilder *treebuilder)
hubbub_error process_0dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
element_type type)
{
- if (!element_in_scope(treebuilder, type, false)) {
+ if (!element_in_scope(treebuilder, type, false, false)) {
/** \todo parse error */
} else {
uint32_t popped = 0;
@@ -1591,12 +1622,12 @@ hubbub_error process_0h_in_body(hubbub_treebuilder *treebuilder,
UNUSED(type);
/** \todo optimise this */
- if (element_in_scope(treebuilder, H1, false) ||
- element_in_scope(treebuilder, H2, false) ||
- element_in_scope(treebuilder, H3, false) ||
- element_in_scope(treebuilder, H4, false) ||
- element_in_scope(treebuilder, H5, false) ||
- element_in_scope(treebuilder, H6, false)) {
+ if (element_in_scope(treebuilder, H1, false, false) ||
+ element_in_scope(treebuilder, H2, false, false) ||
+ element_in_scope(treebuilder, H3, false, false) ||
+ element_in_scope(treebuilder, H4, false, false) ||
+ element_in_scope(treebuilder, H5, false, false) ||
+ element_in_scope(treebuilder, H6, false, false)) {
uint32_t popped = 0;
element_type otype;
@@ -1839,7 +1870,7 @@ hubbub_error aa_find_and_validate_formatting_element(
if (entry->stack_index != 0 &&
element_in_scope(treebuilder, entry->details.type,
- false) != entry->stack_index) {
+ false, false) != entry->stack_index) {
/** \todo parse error */
return HUBBUB_OK;
}
@@ -2291,7 +2322,7 @@ hubbub_error aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder,
hubbub_error process_0applet_button_marquee_object_in_body(
hubbub_treebuilder *treebuilder, element_type type)
{
- if (!element_in_scope(treebuilder, type, false)) {
+ if (!element_in_scope(treebuilder, type, false, false)) {
/** \todo parse error */
} else {
uint32_t popped = 0;
diff --git a/src/treebuilder/in_cell.c b/src/treebuilder/in_cell.c
index 416f988..6787c51 100644
--- a/src/treebuilder/in_cell.c
+++ b/src/treebuilder/in_cell.c
@@ -27,7 +27,7 @@ static inline void close_cell(hubbub_treebuilder *treebuilder)
element_type type;
- if (element_in_scope(treebuilder, TD, true)) {
+ if (element_in_scope(treebuilder, TD, true, false)) {
type = TD;
} else {
type = TH;
@@ -89,7 +89,7 @@ hubbub_error handle_in_cell(hubbub_treebuilder *treebuilder,
&token->data.tag.name);
if (type == TH || type == TD) {
- if (element_in_scope(treebuilder, type, true)) {
+ if (element_in_scope(treebuilder, type, true, false)) {
hubbub_ns ns;
element_type otype = UNKNOWN;
void *node;
@@ -118,7 +118,7 @@ hubbub_error handle_in_cell(hubbub_treebuilder *treebuilder,
/** \todo parse error */
} else if (type == TABLE || type == TBODY || type == TFOOT ||
type == THEAD || type == TR) {
- if (element_in_scope(treebuilder, type, true)) {
+ if (element_in_scope(treebuilder, type, true, false)) {
close_cell(treebuilder);
err = HUBBUB_REPROCESS;
} else {
diff --git a/src/treebuilder/in_select.c b/src/treebuilder/in_select.c
index ab40c6c..9f06b8f 100644
--- a/src/treebuilder/in_select.c
+++ b/src/treebuilder/in_select.c
@@ -86,7 +86,7 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
} else if (type == SELECT || type == INPUT ||
type == TEXTAREA) {
- if (element_in_scope(treebuilder, SELECT, true)) {
+ if (element_in_scope(treebuilder, SELECT, true, false)) {
element_stack_pop_until(treebuilder,
SELECT);
reset_insertion_mode(treebuilder);
@@ -142,7 +142,7 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
/** \todo parse error */
}
} else if (type == SELECT) {
- if (element_in_scope(treebuilder, SELECT, true)) {
+ if (element_in_scope(treebuilder, SELECT, true, false)) {
element_stack_pop_until(treebuilder,
SELECT);
reset_insertion_mode(treebuilder);
diff --git a/src/treebuilder/in_select_in_table.c b/src/treebuilder/in_select_in_table.c
index 7a299b2..69d4203 100644
--- a/src/treebuilder/in_select_in_table.c
+++ b/src/treebuilder/in_select_in_table.c
@@ -41,7 +41,7 @@ hubbub_error handle_in_select_in_table(hubbub_treebuilder *treebuilder,
if ((token->type == HUBBUB_TOKEN_END_TAG &&
element_in_scope(treebuilder, type,
- true)) ||
+ true, false)) ||
token->type == HUBBUB_TOKEN_START_TAG) {
/** \todo fragment case */
diff --git a/src/treebuilder/in_table_body.c b/src/treebuilder/in_table_body.c
index 8d1a6ab..7d4fb0f 100644
--- a/src/treebuilder/in_table_body.c
+++ b/src/treebuilder/in_table_body.c
@@ -50,9 +50,9 @@ static void table_clear_stack(hubbub_treebuilder *treebuilder)
*/
static hubbub_error table_sub_start_or_table_end(hubbub_treebuilder *treebuilder)
{
- if (element_in_scope(treebuilder, TBODY, true) ||
- element_in_scope(treebuilder, THEAD, true) ||
- element_in_scope(treebuilder, TFOOT, true)) {
+ if (element_in_scope(treebuilder, TBODY, true, false) ||
+ element_in_scope(treebuilder, THEAD, true, false) ||
+ element_in_scope(treebuilder, TFOOT, true, false)) {
hubbub_ns ns;
element_type otype;
void *node;
@@ -140,7 +140,7 @@ hubbub_error handle_in_table_body(hubbub_treebuilder *treebuilder,
&token->data.tag.name);
if (type == TBODY || type == TFOOT || type == THEAD) {
- if (!element_in_scope(treebuilder, type, true)) {
+ if (!element_in_scope(treebuilder, type, true, false)) {
/** \todo parse error */
/* Ignore the token */
} else {
diff --git a/src/treebuilder/internal.h b/src/treebuilder/internal.h
index 1b59267..d87e89e 100644
--- a/src/treebuilder/internal.h
+++ b/src/treebuilder/internal.h
@@ -137,7 +137,7 @@ hubbub_error parse_generic_rcdata(hubbub_treebuilder *treebuilder,
const hubbub_token *token, bool rcdata);
uint32_t element_in_scope(hubbub_treebuilder *treebuilder,
- element_type type, bool in_table);
+ element_type type, bool in_table, bool in_button);
hubbub_error reconstruct_active_formatting_list(
hubbub_treebuilder *treebuilder);
void clear_active_formatting_list_to_marker(
diff --git a/src/treebuilder/treebuilder.c b/src/treebuilder/treebuilder.c
index 2358ff9..45197b1 100644
--- a/src/treebuilder/treebuilder.c
+++ b/src/treebuilder/treebuilder.c
@@ -496,10 +496,11 @@ hubbub_error parse_generic_rcdata(hubbub_treebuilder *treebuilder,
* \param treebuilder Treebuilder to look in
* \param type Element type to find
* \param in_table Whether we're looking in table scope
+ * \param in_button Whether we're looking in button scope
* \return Element stack index, or 0 if not in scope
*/
uint32_t element_in_scope(hubbub_treebuilder *treebuilder,
- element_type type, bool in_table)
+ element_type type, bool in_table, bool in_button)
{
uint32_t node;
@@ -525,7 +526,8 @@ uint32_t element_in_scope(hubbub_treebuilder *treebuilder,
* in the previous conditional and HTML should only occur
* as the first node in the stack, which is never processed
* in this loop. */
- if (!in_table && node_type != BUTTON &&
+ if (!in_table && (node_type != BUTTON || (
+ in_button && node_type == BUTTON)) &&
(is_scoping_element(node_type) ||
(node_ns == HUBBUB_NS_SVG && (
node_type == FOREIGNOBJECT ||
@@ -1304,6 +1306,33 @@ hubbub_error formatting_list_append(hubbub_treebuilder *treebuilder,
uint32_t stack_index)
{
formatting_list_entry *entry;
+ uint32_t n_elements = 0;
+ formatting_list_entry *remove_entry;
+ for (entry = treebuilder->context.formatting_list_end;
+ entry != NULL; entry = entry->prev) {
+ /* Assumption: HTML and TABLE elements are not in the list */
+ if (is_scoping_element(entry->details.type))
+ break;
+
+ if(entry->details.type == type &&
+ entry->details.ns == ns)
+ {
+ remove_entry = entry;
+ n_elements += 1;
+ }
+ }
+ if(n_elements == 3) {
+ hubbub_ns ons;
+ element_type otype;
+ void *onode;
+ uint32_t oindex;
+
+ formatting_list_remove(treebuilder, remove_entry,
+ &ons, &otype, &onode, &oindex);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, onode);
+ }
entry = malloc(sizeof(formatting_list_entry));
if (entry == NULL)
diff --git a/test/data/tree-construction/INDEX b/test/data/tree-construction/INDEX
index 7e7e38b..49f0d0c 100644
--- a/test/data/tree-construction/INDEX
+++ b/test/data/tree-construction/INDEX
@@ -2,8 +2,8 @@
#
# Test Description
-#adoption01.dat NA
-#adoption02.dat NA
+adoption01.dat html5lib tests for the adoption agency algorithm
+adoption02.dat html5lib tests for the adoption agency algorithm
#after-after-body.dat NA
#after-after-frameset.dat NA
#after-body.dat NA