summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRupinder Singh Khokhar <rsk1coder99@gmail.com>2014-07-20 07:05:25 (GMT)
committer Rupinder Singh Khokhar <rsk1coder99@gmail.com>2014-08-01 16:14:34 (GMT)
commit18e41840989de4f4705b4d56df7daa6ce7073491 (patch)
tree936c688ecc2d7c5b069e7f28e45f736a6c0f83cd
parent128ff208119c9ee95727a7df00607f024d573e91 (diff)
downloadlibhubbub-18e41840989de4f4705b4d56df7daa6ce7073491.tar.gz
libhubbub-18e41840989de4f4705b4d56df7daa6ce7073491.tar.bz2
Added support for template tag. However, the client currently doesn't support it. Hence, the only thing left to be done is to callback the client during insert_element, taking proper care of the template tags
-rw-r--r--src/treebuilder/Makefile2
-rw-r--r--src/treebuilder/after_head.c5
-rw-r--r--src/treebuilder/in_body.c69
-rw-r--r--src/treebuilder/in_column_group.c4
-rw-r--r--src/treebuilder/in_head.c64
-rw-r--r--src/treebuilder/in_row.c3
-rw-r--r--src/treebuilder/in_select.c4
-rw-r--r--src/treebuilder/in_table.c21
-rw-r--r--src/treebuilder/in_table_body.c3
-rw-r--r--src/treebuilder/internal.h2
-rw-r--r--src/treebuilder/modes.h3
-rw-r--r--src/treebuilder/treebuilder.c66
12 files changed, 193 insertions, 53 deletions
diff --git a/src/treebuilder/Makefile b/src/treebuilder/Makefile
index 31feae1..e48c0a9 100644
--- a/src/treebuilder/Makefile
+++ b/src/treebuilder/Makefile
@@ -6,6 +6,6 @@ DIR_SOURCES := treebuilder.c \
in_cell.c in_select.c in_select_in_table.c \
in_foreign_content.c after_body.c in_frameset.c \
after_frameset.c after_after_body.c after_after_frameset.c \
- generic_rcdata.c
+ in_template.c generic_rcdata.c
include $(NSBUILD)/Makefile.subdir
diff --git a/src/treebuilder/after_head.c b/src/treebuilder/after_head.c
index f39299f..3a5d4c9 100644
--- a/src/treebuilder/after_head.c
+++ b/src/treebuilder/after_head.c
@@ -58,7 +58,8 @@ hubbub_error handle_after_head(hubbub_treebuilder *treebuilder,
} else if (type == BASE || type == BASEFONT || type == BGSOUND ||
type == LINK || type == META ||
type == NOFRAMES || type == SCRIPT ||
- type == STYLE || type == TITLE) {
+ type == STYLE || type == TEMPLATE ||
+ type == TITLE) {
hubbub_ns ns;
element_type otype;
void *node;
@@ -98,6 +99,8 @@ hubbub_error handle_after_head(hubbub_treebuilder *treebuilder,
if (type == HTML || type == BODY || type == BR) {
err = HUBBUB_REPROCESS;
+ } else if(type == TEMPLATE) {
+ err = handle_in_head(treebuilder, token);
} else {
/** \todo parse error */
}
diff --git a/src/treebuilder/in_body.c b/src/treebuilder/in_body.c
index bd73f08..ca2a34b 100644
--- a/src/treebuilder/in_body.c
+++ b/src/treebuilder/in_body.c
@@ -164,6 +164,12 @@ hubbub_error handle_in_body(hubbub_treebuilder *treebuilder,
err = process_end_tag(treebuilder, token);
break;
case HUBBUB_TOKEN_EOF:
+ if (treebuilder->context.current_template_mode > -1) {
+ treebuilder->context.mode =
+ IN_TEMPLATE;
+ err = HUBBUB_REPROCESS;
+ break;
+ }
for (i = treebuilder->context.current_node;
i > 0; i--) {
element_type type =
@@ -211,7 +217,6 @@ hubbub_error process_character(hubbub_treebuilder *treebuilder,
err = reconstruct_active_formatting_list(treebuilder);
if (err != HUBBUB_OK)
return err;
-
if (treebuilder->context.strip_leading_lr) {
const uint8_t *str = dummy.ptr;
@@ -267,7 +272,8 @@ hubbub_error process_start_tag(hubbub_treebuilder *treebuilder,
err = process_html_in_body(treebuilder, token);
} else if (type == BASE || type == BASEFONT || type == BGSOUND ||
type == LINK || type == META || type == NOFRAMES ||
- type == SCRIPT || type == STYLE || type == TITLE) {
+ type == SCRIPT || type == STYLE || type == TEMPLATE
+ || type == TITLE) {
/* Process as "in head" */
err = handle_in_head(treebuilder, token);
} else if (type == BODY) {
@@ -519,6 +525,8 @@ hubbub_error process_end_tag(hubbub_treebuilder *treebuilder,
(treebuilder->context.enable_scripting &&
type == NOSCRIPT)) {
/** \todo parse error */
+ } else if (type == TEMPLATE) {
+ err = handle_in_head(treebuilder, token);
} else {
err = process_0generic_in_body(treebuilder, type);
}
@@ -591,6 +599,9 @@ hubbub_error process_html_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
/** \todo parse error */
+ if(template_in_stack(treebuilder))
+ return HUBBUB_OK;
+
return add_attributes_stack(treebuilder, token,
0);
}
@@ -607,7 +618,8 @@ hubbub_error process_body_in_body(hubbub_treebuilder *treebuilder,
/** \todo parse error */
if (treebuilder->context.current_node < 1 ||
- treebuilder->context.element_stack[1].type != BODY)
+ treebuilder->context.element_stack[1].type != BODY ||
+ template_in_stack(treebuilder))
return HUBBUB_OK;
treebuilder->context.frameset_ok = false;
@@ -721,18 +733,10 @@ hubbub_error process_form_in_body(hubbub_treebuilder *treebuilder,
{
hubbub_error err;
- element_context *stack = treebuilder->context.element_stack;
- bool template_in_stack = false;
- uint32_t n;
- for (n = treebuilder->context.current_node;
- n > 0; n--) {
- if(stack[n].type == TEMPLATE) {
- template_in_stack = true;
- break;
- }
- }
+ bool in_stack = template_in_stack(treebuilder);
+
if (treebuilder->context.form_element != NULL &&
- template_in_stack == false) {
+ in_stack == false) {
/** \todo parse error */
} else {
if (element_in_scope(treebuilder, P, BUTTON_SCOPE)) {
@@ -752,7 +756,7 @@ hubbub_error process_form_in_body(hubbub_treebuilder *treebuilder,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
- if(template_in_stack == false) {
+ if(in_stack == false) {
treebuilder->context.form_element =
treebuilder->context.element_stack[
treebuilder->context.current_node].node;
@@ -1236,26 +1240,18 @@ hubbub_error process_isindex_in_body(hubbub_treebuilder *treebuilder,
{
hubbub_error err;
hubbub_token dummy;
- element_context *stack = treebuilder->context.element_stack;
hubbub_attribute *action = NULL;
hubbub_attribute *prompt = NULL;
hubbub_attribute *attrs = NULL;
size_t n_attrs = 0;
- uint32_t n;
- bool template_in_stack = false;
+ bool in_stack = template_in_stack(
+ treebuilder);
hubbub_ns ns;
void *node;
element_type o_type;
- for (n = treebuilder->context.current_node;
- n > 0; n--) {
- if(stack[n].type == TEMPLATE) {
- template_in_stack = true;
- break;
- }
- }
- if (template_in_stack == false &&
+ if (in_stack == false &&
treebuilder->context.form_element != NULL)
return HUBBUB_OK;
@@ -1592,6 +1588,22 @@ hubbub_error process_0form_in_body(hubbub_treebuilder *treebuilder)
void *node = treebuilder->context.form_element;
uint32_t idx = 0;
+ if(template_in_stack (treebuilder)) {
+ if(!element_in_scope(treebuilder, FORM, NONE)) {
+ /** \todo parse error */
+ } else {
+ close_implied_end_tags(treebuilder,
+ UNKNOWN);
+
+ if(current_node(treebuilder) != FORM) {
+ /** \todo parse error */
+ }
+ element_stack_pop_until(treebuilder,
+ FORM);
+ }
+ return HUBBUB_OK;
+ }
+
if (treebuilder->context.form_element != NULL)
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -1600,8 +1612,7 @@ hubbub_error process_0form_in_body(hubbub_treebuilder *treebuilder)
idx = element_in_scope(treebuilder, FORM, NONE);
- if (idx == 0 || node == NULL ||
- treebuilder->context.element_stack[idx].node != node) {
+ if (idx == 0 || node == NULL) {
/** \todo parse error */
} else {
hubbub_ns ns;
@@ -1616,7 +1627,7 @@ hubbub_error process_0form_in_body(hubbub_treebuilder *treebuilder)
/** \todo parse error */
}
- element_stack_remove(treebuilder, idx,
+ element_stack_remove(treebuilder, idx,
&ns, &otype, &onode);
treebuilder->tree_handler->unref_node(
diff --git a/src/treebuilder/in_column_group.c b/src/treebuilder/in_column_group.c
index 9436fc6..b69332b 100644
--- a/src/treebuilder/in_column_group.c
+++ b/src/treebuilder/in_column_group.c
@@ -53,6 +53,8 @@ hubbub_error handle_in_column_group(hubbub_treebuilder *treebuilder,
false);
/** \todo ack sc flag */
+ } else if(type == TEMPLATE) {
+ err = handle_in_head(treebuilder, token);
} else {
err = HUBBUB_REPROCESS;
}
@@ -68,6 +70,8 @@ hubbub_error handle_in_column_group(hubbub_treebuilder *treebuilder,
handled = true;
} else if (type == COL) {
/** \todo parse error */
+ } else if(type == TEMPLATE) {
+ err = handle_in_head(treebuilder, token);
} else {
err = HUBBUB_REPROCESS;
}
diff --git a/src/treebuilder/in_head.c b/src/treebuilder/in_head.c
index 52a2e3f..a10ba23 100644
--- a/src/treebuilder/in_head.c
+++ b/src/treebuilder/in_head.c
@@ -19,7 +19,6 @@
#include "utils/utils.h"
#include "utils/string.h"
-
/**
* Process a meta tag as if "in head".
*
@@ -164,6 +163,47 @@ hubbub_error handle_in_head(hubbub_treebuilder *treebuilder,
err = parse_generic_rcdata(treebuilder, token, HUBBUB_CONTENT_MODEL_SCRIPTDATA);
} else if (type == HEAD) {
/** \todo parse error */
+ } else if (type == TEMPLATE) {
+ err = insert_element(treebuilder, &token->data.tag,
+ true);
+ if (err != HUBBUB_OK)
+ return err;
+
+ /* Insert a Marker */
+ treebuilder->tree_handler->ref_node(
+ treebuilder->tree_handler->ctx,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node);
+
+ err = formatting_list_append(treebuilder, token->data.tag.ns, type,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node,
+ token->data.tag.attributes, token->data.tag.n_attributes,
+ treebuilder->context.current_node);
+ if (err != HUBBUB_OK) {
+ hubbub_ns ns;
+ element_type type;
+ void *node;
+ remove_node_from_dom(treebuilder,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node);
+
+ element_stack_pop(treebuilder, &ns, &type, &node);
+
+ /* Unref twice (once for stack, once for formatting list) */
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ return err;
+ }
+
+ treebuilder->context.frameset_ok = false;
+ treebuilder->context.mode = IN_TEMPLATE;
+
+ err = template_stack_push(treebuilder, IN_TEMPLATE);
} else {
err = HUBBUB_REPROCESS;
}
@@ -176,9 +216,29 @@ hubbub_error handle_in_head(hubbub_treebuilder *treebuilder,
if (type == HEAD) {
handled = true;
+ } else if(type == TEMPLATE) {
+ /**todo parse error */
+ if(!template_in_stack(treebuilder)) {
+ /** \todo parse error */
+ break;
+ }
+ insertion_mode mode;
+ close_implied_end_tags_thorough(treebuilder);
+
+ err = element_stack_pop_until(treebuilder,
+ TEMPLATE);
+ if (err != HUBBUB_OK)
+ return err;
+
+ clear_active_formatting_list_to_marker(
+ treebuilder);
+ err = template_stack_pop (treebuilder, &mode);
+ reset_insertion_mode (treebuilder);
} else if (type == HTML || type == BODY || type == BR) {
err = HUBBUB_REPROCESS;
- } /** \todo parse error */
+ } else {
+ /** \todo parse error */
+ }
}
break;
case HUBBUB_TOKEN_EOF:
diff --git a/src/treebuilder/in_row.c b/src/treebuilder/in_row.c
index 0446e6f..c31d826 100644
--- a/src/treebuilder/in_row.c
+++ b/src/treebuilder/in_row.c
@@ -23,7 +23,8 @@ static void table_clear_stack(hubbub_treebuilder *treebuilder)
{
element_type cur_node = current_node(treebuilder);
- while (cur_node != TR && cur_node != HTML) {
+ while (cur_node != TR && cur_node != TEMPLATE &&
+ cur_node != HTML) {
hubbub_ns ns;
element_type type;
void *node;
diff --git a/src/treebuilder/in_select.c b/src/treebuilder/in_select.c
index 7675dc5..c3db89d 100644
--- a/src/treebuilder/in_select.c
+++ b/src/treebuilder/in_select.c
@@ -100,7 +100,7 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
if (type != SELECT)
err = HUBBUB_REPROCESS;
- } else if (type == SCRIPT) {
+ } else if (type == SCRIPT || type == TEMPLATE) {
err = handle_in_head(treebuilder, token);
} else {
/** \todo parse error */
@@ -153,6 +153,8 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
/* fragment case */
/** \todo parse error */
}
+ } else if (type == TEMPLATE) {
+ err = handle_in_head(treebuilder, token);
}
}
break;
diff --git a/src/treebuilder/in_table.c b/src/treebuilder/in_table.c
index cf61827..03dc4f7 100644
--- a/src/treebuilder/in_table.c
+++ b/src/treebuilder/in_table.c
@@ -26,7 +26,7 @@ static inline void clear_stack_table_context(hubbub_treebuilder *treebuilder)
element_type type = current_node(treebuilder);
void *node;
- while (type != TABLE && type != HTML) {
+ while (type != TABLE && type != HTML && type != TEMPLATE) {
element_stack_pop(treebuilder, &ns, &type, &node);
treebuilder->tree_handler->unref_node(
@@ -208,23 +208,16 @@ hubbub_error handle_in_table(hubbub_treebuilder *treebuilder,
reset_insertion_mode(treebuilder);
err = HUBBUB_REPROCESS;
- } else if (type == STYLE || type == SCRIPT) {
+ } else if (type == STYLE || type == SCRIPT ||
+ type == TEMPLATE) {
err = handle_in_head(treebuilder, token);
} else if (type == INPUT) {
err = process_input_in_table(treebuilder, token);
handled = (err == HUBBUB_OK);
} else if(type == FORM) {
- element_context *stack = treebuilder->context.element_stack;
- bool template_in_stack = false;
- uint32_t n;
- for (n = treebuilder->context.current_node;
- n > 0; n--) {
- if(stack[n].type == TEMPLATE) {
- template_in_stack = true;
- break;
- }
- }
- if(template_in_stack == true ||
+ bool in_stack = template_in_stack(treebuilder);
+
+ if(in_stack == true ||
treebuilder->context.form_element != NULL ) {
/* ignore the token*/
break;
@@ -268,6 +261,8 @@ hubbub_error handle_in_table(hubbub_treebuilder *treebuilder,
type == TBODY || type == TD || type == TFOOT ||
type == TH || type == THEAD || type == TR) {
/** \todo parse error */
+ } else if (type == TEMPLATE) {
+ err = handle_in_head(treebuilder, token);
} else {
handled = false;
}
diff --git a/src/treebuilder/in_table_body.c b/src/treebuilder/in_table_body.c
index c8c26cf..e6fbcc3 100644
--- a/src/treebuilder/in_table_body.c
+++ b/src/treebuilder/in_table_body.c
@@ -24,7 +24,8 @@ static void table_clear_stack(hubbub_treebuilder *treebuilder)
element_type cur_node = current_node(treebuilder);
while (cur_node != TBODY && cur_node != TFOOT &&
- cur_node != THEAD && cur_node != HTML) {
+ cur_node != THEAD && cur_node != HTML &&
+ cur_node != TEMPLATE) {
hubbub_ns ns;
element_type type;
void *node;
diff --git a/src/treebuilder/internal.h b/src/treebuilder/internal.h
index de371b0..18a34bd 100644
--- a/src/treebuilder/internal.h
+++ b/src/treebuilder/internal.h
@@ -166,6 +166,7 @@ hubbub_error insert_element(hubbub_treebuilder *treebuilder,
const hubbub_tag *tag_name, bool push);
void close_implied_end_tags(hubbub_treebuilder *treebuilder,
element_type except);
+void close_implied_end_tags_thorough(hubbub_treebuilder *treebuilder);
void reset_insertion_mode(hubbub_treebuilder *treebuilder);
hubbub_error append_text(hubbub_treebuilder *treebuilder,
const hubbub_string *string);
@@ -224,6 +225,7 @@ bool is_mathml_text_integration (element_type type,
bool is_html_integration (element_type type,
hubbub_ns ns, hubbub_attribute *attrs,
size_t n_attrs);
+bool template_in_stack (hubbub_treebuilder *treebuilder);
/* in_foreign_content.c */
void adjust_mathml_attributes(hubbub_treebuilder *treebuilder, hubbub_tag *tag);
diff --git a/src/treebuilder/modes.h b/src/treebuilder/modes.h
index 411e7a6..eefe18e 100644
--- a/src/treebuilder/modes.h
+++ b/src/treebuilder/modes.h
@@ -34,6 +34,7 @@ typedef enum
AFTER_FRAMESET,
AFTER_AFTER_BODY,
AFTER_AFTER_FRAMESET,
+ IN_TEMPLATE,
GENERIC_RCDATA
} insertion_mode;
@@ -86,5 +87,7 @@ hubbub_error handle_after_after_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
hubbub_error handle_after_after_frameset(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
+hubbub_error handle_in_template(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token);
#endif
diff --git a/src/treebuilder/treebuilder.c b/src/treebuilder/treebuilder.c
index 8f0e7e3..9cc4b12 100644
--- a/src/treebuilder/treebuilder.c
+++ b/src/treebuilder/treebuilder.c
@@ -389,6 +389,9 @@ hubbub_error hubbub_treebuilder_token_handler(const hubbub_token *token,
mode(AFTER_AFTER_FRAMESET)
err = handle_after_after_frameset(treebuilder, token);
break;
+ mode(IN_TEMPLATE)
+ err = handle_in_template(treebuilder, token);
+ break;
mode(GENERIC_RCDATA)
err = handle_generic_rcdata(treebuilder, token);
break;
@@ -934,11 +937,11 @@ hubbub_error insert_element(hubbub_treebuilder *treebuilder,
}
/**
- * Close implied end tags
+ * close implied end tags
*
- * \param treebuilder The treebuilder instance
- * \param except Tag type to exclude from processing [DD,DT,LI,OPTION,
- * OPTGROUP,P,RP,RT], UNKNOWN to exclude nothing
+ * \param treebuilder the treebuilder instance
+ * \param except tag type to exclude from processing [dd,dt,li,option,
+ * optgroup,p,rp,rt], unknown to exclude nothing
*/
void close_implied_end_tags(hubbub_treebuilder *treebuilder,
element_type except)
@@ -970,6 +973,39 @@ void close_implied_end_tags(hubbub_treebuilder *treebuilder,
}
/**
+ * close implied end tags "thoroughly"
+ *
+ * \param treebuilder the treebuilder instance
+ */
+void close_implied_end_tags_thorough(hubbub_treebuilder *treebuilder)
+{
+ element_type type;
+
+ type = treebuilder->context.element_stack[
+ treebuilder->context.current_node].type;
+
+ while(type == CAPTION || type == COLGROUP || type == DD ||
+ type == DT || type == LI || type == OPTION ||
+ type == OPTGROUP || type == P || type == RP ||
+ type == RT || type == TBODY || type == TD ||
+ type ==TFOOT || type == TH ||
+ type == THEAD || type == TR) {
+ hubbub_ns ns;
+ element_type otype;
+ void *node;
+
+ element_stack_pop(treebuilder, &ns, &otype, &node);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ node);
+
+ type = treebuilder->context.element_stack[
+ treebuilder->context.current_node].type;
+ }
+}
+
+/**
* Reset the insertion mode
*
* \param treebuilder The treebuilder to reset
@@ -1027,6 +1063,11 @@ void reset_insertion_mode(hubbub_treebuilder *treebuilder)
case TABLE:
treebuilder->context.mode = IN_TABLE;
return;
+ case TEMPLATE:
+ treebuilder->context.mode =
+ treebuilder->context.template_stack[
+ treebuilder->context.current_template_mode];
+ return;
case HEAD:
/* fragment case */
treebuilder->context.mode = IN_HEAD;
@@ -1820,6 +1861,23 @@ bool is_html_integration (element_type type,
return false;
}
+/**
+ * Check whether the stack of open elements has a template element
+ *
+ * \param treebuilder The treebuilder instance
+ */
+bool template_in_stack (hubbub_treebuilder *treebuilder) {
+ uint32_t i;
+ element_context* stack =
+ treebuilder->context.element_stack;
+ for(i = treebuilder->context.current_node; i > 0;
+ i--) {
+ if(stack[i].type == TEMPLATE) {
+ return true;
+ }
+ }
+ return false;
+}
#ifndef NDEBUG
/**