diff options
author | Andrew Sidwell <andy@entai.co.uk> | 2008-06-25 10:52:12 +0000 |
---|---|---|
committer | Andrew Sidwell <andy@entai.co.uk> | 2008-06-25 10:52:12 +0000 |
commit | 6ce05dca28507467ad92302dad9373dc4e82fd92 (patch) | |
tree | 24f12f6b85bf258e3dcaff8109526da28ea0ba1b | |
parent | bb412699cc7a87b875db1ae125e76712571d9ca1 (diff) | |
download | libhubbub-6ce05dca28507467ad92302dad9373dc4e82fd92.tar.gz libhubbub-6ce05dca28507467ad92302dad9373dc4e82fd92.tar.bz2 |
Implement the "in cell" insertion mode.
svn path=/trunk/hubbub/; revision=4444
-rw-r--r-- | src/treebuilder/Makefile | 1 | ||||
-rw-r--r-- | src/treebuilder/in_cell.c | 136 | ||||
-rw-r--r-- | src/treebuilder/modes.h | 2 |
3 files changed, 139 insertions, 0 deletions
diff --git a/src/treebuilder/Makefile b/src/treebuilder/Makefile index 9ebc700..aea3426 100644 --- a/src/treebuilder/Makefile +++ b/src/treebuilder/Makefile @@ -36,6 +36,7 @@ SRCS_$(d) := treebuilder.c \ initial.c before_html.c before_head.c in_head.c \ in_head_noscript.c after_head.c in_body.c \ in_caption.c in_column_group.c in_table_body.c in_row.c \ + in_cell.c \ generic_rcdata.c script_collect.c # Append to sources for component diff --git a/src/treebuilder/in_cell.c b/src/treebuilder/in_cell.c new file mode 100644 index 0000000..98913c6 --- /dev/null +++ b/src/treebuilder/in_cell.c @@ -0,0 +1,136 @@ +/* + * This file is part of Hubbub. + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * Copyright 2008 Andrew Sidwell + */ + +#include <assert.h> +#include <string.h> + +#include "treebuilder/modes.h" +#include "treebuilder/internal.h" +#include "treebuilder/treebuilder.h" +#include "utils/utils.h" + + +/** + * Clear the stack back to a table body context. + * + * \param treebuilder The treebuilder instance + */ +static inline void close_cell(hubbub_treebuilder *treebuilder) +{ + void *node; + element_type type; + element_type otype = UNKNOWN; + + if (element_in_scope(treebuilder, TD, true)) { + type = TD; + } else { + type = TH; + } + + /* Act as if an end tag token of type `type` has been seen */ + + close_implied_end_tags(treebuilder, UNKNOWN); + /** \todo parse error */ + + while (otype != type) { + if (!element_stack_pop(treebuilder, &otype, &node)) { + /** \todo errors */ + } + } + + clear_active_formatting_list_to_marker(treebuilder); + treebuilder->context.mode = IN_ROW; + + return; +} + + +/** + * Handle tokens in "in cell" insertion mode + * + * Up to date with the spec as of 25 June 2008 + * + * \param treebuilder The treebuilder instance + * \param token The token to process + * \return True to reprocess the token, false otherwise + */ +bool handle_in_cell(hubbub_treebuilder *treebuilder, const hubbub_token *token) +{ + bool reprocess = false; + + switch (token->type) { + case HUBBUB_TOKEN_START_TAG: + { + element_type type = element_type_from_name(treebuilder, + &token->data.tag.name); + + if (type == CAPTION || type == COL || + type == COLGROUP || type == TBODY || + type == TFOOT || type == TH || type == THEAD || + type == TR) { + /** \todo fragment case */ + close_cell(treebuilder); + reprocess = true; + } else { + reprocess = process_in_table(treebuilder, token); + } + } + break; + case HUBBUB_TOKEN_END_TAG: + { + element_type type = element_type_from_name(treebuilder, + &token->data.tag.name); + + if (type == TH || TD) { + if (element_in_scope(treebuilder, type, true)) { + element_type otype = UNKNOWN; + void *node; + + close_implied_end_tags(treebuilder, UNKNOWN); + /** \todo parse error */ + + while (otype != type) { + if (!element_stack_pop(treebuilder, + &otype, &node)) { + /** \todo errors */ + } + } + + clear_active_formatting_list_to_marker( + treebuilder); + + treebuilder->context.mode = IN_ROW; + } else { + /** \todo parse error */ + } + } else if (type == BODY || type == CAPTION || type == COL || + type == COLGROUP || type == HTML) { + /** \todo parse error */ + } else if (type == TABLE || type == TBODY || type == TFOOT || + type == THEAD || type == TR) { + if (element_in_scope(treebuilder, type, true)) { + close_cell(treebuilder); + reprocess = true; + } else { + /** \todo parse error */ + } + } else { + reprocess = process_in_table(treebuilder, token); + } + } + break; + case HUBBUB_TOKEN_CHARACTER: + case HUBBUB_TOKEN_COMMENT: + case HUBBUB_TOKEN_DOCTYPE: + case HUBBUB_TOKEN_EOF: + reprocess = process_in_table(treebuilder, token); + break; + } + + return reprocess; +} + diff --git a/src/treebuilder/modes.h b/src/treebuilder/modes.h index 104f6aa..4af9036 100644 --- a/src/treebuilder/modes.h +++ b/src/treebuilder/modes.h @@ -61,6 +61,8 @@ bool handle_in_column_group(hubbub_treebuilder *treebuilder, const hubbub_token *token); bool handle_in_row(hubbub_treebuilder *treebuilder, const hubbub_token *token); +bool handle_in_cell(hubbub_treebuilder *treebuilder, + const hubbub_token *token); bool handle_generic_rcdata(hubbub_treebuilder *treebuilder, const hubbub_token *token); bool handle_script_collect_characters(hubbub_treebuilder *treebuilder, |