From fab42cda1c4e8831c33f113e83f6966e38e47425 Mon Sep 17 00:00:00 2001 From: Rupinder Singh Khokhar Date: Wed, 2 Jul 2014 08:04:04 +0530 Subject: fixed dd,dt&li handler. Also fixed the scoping lists. Also added a missing summary tag to the start tag processor conditional. --- src/treebuilder/after_head.c | 1 - src/treebuilder/in_body.c | 64 +++++++++++++++++++----------------- src/treebuilder/in_cell.c | 6 ++-- src/treebuilder/in_select.c | 4 +-- src/treebuilder/in_select_in_table.c | 2 +- src/treebuilder/in_table_body.c | 8 ++--- src/treebuilder/internal.h | 7 +++- src/treebuilder/treebuilder.c | 30 +++++++++++------ test/data/tree-construction/INDEX | 2 +- 9 files changed, 70 insertions(+), 54 deletions(-) diff --git a/src/treebuilder/after_head.c b/src/treebuilder/after_head.c index bd6e004..40955a8 100644 --- a/src/treebuilder/after_head.c +++ b/src/treebuilder/after_head.c @@ -26,7 +26,6 @@ hubbub_error handle_after_head(hubbub_treebuilder *treebuilder, { hubbub_error err = HUBBUB_OK; bool handled = false; - switch (token->type) { case HUBBUB_TOKEN_CHARACTER: err = process_characters_expect_whitespace(treebuilder, diff --git a/src/treebuilder/in_body.c b/src/treebuilder/in_body.c index 3e8650d..33ab30a 100644 --- a/src/treebuilder/in_body.c +++ b/src/treebuilder/in_body.c @@ -272,7 +272,7 @@ hubbub_error process_start_tag(hubbub_treebuilder *treebuilder, type == FIGURE || type == FOOTER || type == HEADER || type == MENU || type == NAV || type == OL || type == P || type == SECTION || - type == UL) { + type == SUMMARY || type == UL) { err = process_container_in_body(treebuilder, token); } else if (type == H1 || type == H2 || type == H3 || type == H4 || type == H5 || type == H6) { @@ -565,7 +565,7 @@ hubbub_error process_container_in_body(hubbub_treebuilder *treebuilder, { hubbub_error err; - if (element_in_scope(treebuilder, P, false, true)) { + if (element_in_scope(treebuilder, P, BUTTON_SCOPE)) { err = close_p_in_body(treebuilder); if (err != HUBBUB_OK) return err; @@ -586,8 +586,8 @@ hubbub_error process_hN_in_body(hubbub_treebuilder *treebuilder, hubbub_error err; element_type type; - if (element_in_scope(treebuilder, P, false, false)) { - err = process_0p_in_body(treebuilder); + if (element_in_scope(treebuilder, P, BUTTON_SCOPE)) { + err = close_p_in_body(treebuilder); if (err != HUBBUB_OK) return err; } @@ -628,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, false)) { + if (element_in_scope(treebuilder, P, NONE)) { err = process_0p_in_body(treebuilder); if (err != HUBBUB_OK) return err; @@ -669,12 +669,6 @@ hubbub_error process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder, treebuilder->context.frameset_ok = false; - if (element_in_scope(treebuilder, P, false, false)) { - err = process_0p_in_body(treebuilder); - if (err != HUBBUB_OK) - return err; - } - /* Find last LI/(DD,DT) on stack, if any */ for (node = treebuilder->context.current_node; node > 0; node--) { element_type ntype = stack[node].type; @@ -689,13 +683,16 @@ hubbub_error process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder, if (!is_formatting_element(ntype) && !is_phrasing_element(ntype) && ntype != ADDRESS && - ntype != DIV) + ntype != DIV && + ntype != P) break; } /* If we found one, then pop all nodes up to and including it */ if (stack[node].type == LI || stack[node].type == DD || stack[node].type == DT) { + + close_implied_end_tags(treebuilder, type); /* Check that we're only popping one node * and emit a parse error if not */ if (treebuilder->context.current_node > node) { @@ -717,6 +714,11 @@ hubbub_error process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder, } while (treebuilder->context.current_node >= node); } + if(element_in_scope(treebuilder, P, BUTTON_SCOPE)) { + err = close_p_in_body(treebuilder); + if(err != HUBBUB_OK) + return err; + } return insert_element(treebuilder, &token->data.tag, true); } @@ -732,8 +734,8 @@ hubbub_error process_plaintext_in_body(hubbub_treebuilder *treebuilder, hubbub_error err; hubbub_tokeniser_optparams params; - if (element_in_scope(treebuilder, P, false, false)) { - err = process_0p_in_body(treebuilder); + if (element_in_scope(treebuilder, P, BUTTON_SCOPE)) { + err = close_p_in_body(treebuilder); if (err != HUBBUB_OK) return err; } @@ -920,7 +922,7 @@ hubbub_error process_nobr_in_body(hubbub_treebuilder *treebuilder, if (err != HUBBUB_OK) return err; - if (element_in_scope(treebuilder, NOBR, false, false)) { + if (element_in_scope(treebuilder, NOBR, NONE)) { /** \todo parse error */ /* Act as if were seen */ @@ -982,7 +984,7 @@ hubbub_error process_button_in_body(hubbub_treebuilder *treebuilder, { hubbub_error err; - if (element_in_scope(treebuilder, BUTTON, false, false)) { + if (element_in_scope(treebuilder, BUTTON, NONE)) { /** \todo parse error */ /* Act as if has been seen */ @@ -1071,7 +1073,7 @@ hubbub_error process_hr_in_body(hubbub_treebuilder *treebuilder, { hubbub_error err; - if (element_in_scope(treebuilder, P, false, false)) { + if (element_in_scope(treebuilder, P, BUTTON_SCOPE)) { err = process_0p_in_body(treebuilder); if (err != HUBBUB_OK) return err; @@ -1333,7 +1335,7 @@ hubbub_error process_opt_in_body(hubbub_treebuilder *treebuilder, { hubbub_error err; - if (element_in_scope(treebuilder, OPTION, false, false)) { + if (element_in_scope(treebuilder, OPTION, NONE)) { err = process_0generic_in_body(treebuilder, OPTION); /* Cannot fail */ assert(err == HUBBUB_OK); @@ -1374,7 +1376,7 @@ hubbub_error process_0body_in_body(hubbub_treebuilder *treebuilder) { hubbub_error err = HUBBUB_OK; - if (!element_in_scope(treebuilder, BODY, false, false)) { + if (!element_in_scope(treebuilder, BODY, NONE)) { /** \todo parse error */ } else { element_context *stack = treebuilder->context.element_stack; @@ -1413,7 +1415,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, false)) { + if (!element_in_scope(treebuilder, type, NONE)) { /** \todo parse error */ } else { uint32_t popped = 0; @@ -1458,7 +1460,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, false); + idx = element_in_scope(treebuilder, FORM, NONE); if (idx == 0 || node == NULL || treebuilder->context.element_stack[idx].node != node) { @@ -1550,7 +1552,7 @@ hubbub_error close_p_in_body(hubbub_treebuilder *treebuilder) hubbub_error process_0p_in_body(hubbub_treebuilder *treebuilder) { - if (!element_in_scope(treebuilder, P, false, true)) { + if (!element_in_scope(treebuilder, P, BUTTON_SCOPE)) { /** \todo parse error */ hubbub_tag tag; @@ -1580,7 +1582,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, false)) { + if (!element_in_scope(treebuilder, type, LIST_ITEM_SCOPE)) { /** \todo parse error */ } else { uint32_t popped = 0; @@ -1622,12 +1624,12 @@ hubbub_error process_0h_in_body(hubbub_treebuilder *treebuilder, UNUSED(type); /** \todo optimise this */ - 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)) { + if (element_in_scope(treebuilder, H1, NONE) || + element_in_scope(treebuilder, H2, NONE) || + element_in_scope(treebuilder, H3, NONE) || + element_in_scope(treebuilder, H4, NONE) || + element_in_scope(treebuilder, H5, NONE) || + element_in_scope(treebuilder, H6, NONE)) { uint32_t popped = 0; element_type otype; @@ -1870,7 +1872,7 @@ hubbub_error aa_find_and_validate_formatting_element( if (entry->stack_index != 0 && element_in_scope(treebuilder, entry->details.type, - false, false) != entry->stack_index) { + NONE) != entry->stack_index) { /** \todo parse error */ return HUBBUB_OK; } @@ -2322,7 +2324,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, false)) { + if (!element_in_scope(treebuilder, type, NONE)) { /** \todo parse error */ } else { uint32_t popped = 0; diff --git a/src/treebuilder/in_cell.c b/src/treebuilder/in_cell.c index 6787c51..90bdf53 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, false)) { + if (element_in_scope(treebuilder, TD, TABLE_SCOPE)) { 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, false)) { + if (element_in_scope(treebuilder, type, TABLE_SCOPE)) { 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, false)) { + if (element_in_scope(treebuilder, type, TABLE_SCOPE)) { close_cell(treebuilder); err = HUBBUB_REPROCESS; } else { diff --git a/src/treebuilder/in_select.c b/src/treebuilder/in_select.c index 9f06b8f..a49b568 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, false)) { + if (element_in_scope(treebuilder, SELECT, TABLE_SCOPE)) { 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, false)) { + if (element_in_scope(treebuilder, SELECT, TABLE_SCOPE)) { 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 69d4203..d6e1b8c 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, false)) || + TABLE_SCOPE)) || 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 7d4fb0f..c8c26cf 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, false) || - element_in_scope(treebuilder, THEAD, true, false) || - element_in_scope(treebuilder, TFOOT, true, false)) { + if (element_in_scope(treebuilder, TBODY, TABLE_SCOPE) || + element_in_scope(treebuilder, THEAD, TABLE_SCOPE) || + element_in_scope(treebuilder, TFOOT, TABLE_SCOPE)) { 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, false)) { + if (!element_in_scope(treebuilder, type, TABLE_SCOPE)) { /** \todo parse error */ /* Ignore the token */ } else { diff --git a/src/treebuilder/internal.h b/src/treebuilder/internal.h index d87e89e..ccec4ed 100644 --- a/src/treebuilder/internal.h +++ b/src/treebuilder/internal.h @@ -36,6 +36,11 @@ typedef enum UNKNOWN } element_type; +typedef enum +{ + NONE, LIST_ITEM_SCOPE, BUTTON_SCOPE, TABLE_SCOPE, SELECT_SCOPE +} element_scope; + /** * Item on the element stack */ @@ -137,7 +142,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, bool in_button); + element_type type, element_scope scope); 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 45197b1..9e5734b 100644 --- a/src/treebuilder/treebuilder.c +++ b/src/treebuilder/treebuilder.c @@ -495,12 +495,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 + * \param scope The scope we're looking in * \return Element stack index, or 0 if not in scope */ uint32_t element_in_scope(hubbub_treebuilder *treebuilder, - element_type type, bool in_table, bool in_button) + element_type type, element_scope scope) { uint32_t node; @@ -518,17 +517,28 @@ uint32_t element_in_scope(hubbub_treebuilder *treebuilder, if (node_type == type) return node; - if (node_type == TABLE) + if (scope == TABLE_SCOPE && ( + node_type == TABLE || + node_type == HTML || + node_type == TEMPLATE)) break; - /* The list of element types given in the spec here are the - * scoping elements excluding TABLE and HTML and BUTTON. TABLE is handled - * in the previous conditional and HTML should only occur + if (scope == SELECT_SCOPE && + node_type != OPTGROUP && + node_type != OPTION) + break; + + /* The list of element types of the normal scope given in the spec here are the + * scoping elements excluding HTML and BUTTON. HTML should only occur * as the first node in the stack, which is never processed * in this loop. */ - if (!in_table && (node_type != BUTTON || ( - in_button && node_type == BUTTON)) && - (is_scoping_element(node_type) || + if (scope != TABLE_SCOPE && scope != SELECT_SCOPE && + ((scope == BUTTON_SCOPE && + node_type == BUTTON) || + (scope == LIST_ITEM_SCOPE && + (node_type == OL || + node_type == UL)) || + (node_type != BUTTON && is_scoping_element(node_type)) || (node_ns == HUBBUB_NS_SVG && ( node_type == FOREIGNOBJECT || node_type == DESC || diff --git a/test/data/tree-construction/INDEX b/test/data/tree-construction/INDEX index 49f0d0c..7504628 100644 --- a/test/data/tree-construction/INDEX +++ b/test/data/tree-construction/INDEX @@ -36,7 +36,7 @@ adoption02.dat html5lib tests for the adoption agency algorithm #tests17.dat NA #tests18.dat NA #tests19.dat NA -#tests1.dat NA +tests1.dat html5lib treebuilder tests #tests20.dat NA #tests21.dat NA #tests22.dat NA -- cgit v1.2.3