20 #define S(x) x, SLEN(x) 30 {
S(
"body"),
BODY }, {
S(
"br"),
BR },
33 {
S(
"dir"),
DIR }, {
S(
"div"),
DIV },
34 {
S(
"dl"),
DL }, {
S(
"dt"),
DT },
38 {
S(
"h2"),
H2 }, {
S(
"h3"),
H3 },
39 {
S(
"h4"),
H4 }, {
S(
"h5"),
H5 },
40 {
S(
"h6"),
H6 }, {
S(
"head"),
HEAD },
44 {
S(
"li"),
LI }, {
S(
"link"),
LINK },
51 {
S(
"p"),
P }, {
S(
"param"),
PARAM },
58 {
S(
"ul"),
UL }, {
S(
"wbr"),
WBR },
64 {
S(
"a"),
A }, {
S(
"b"),
B },
65 {
S(
"big"),
BIG }, {
S(
"em"),
EM },
66 {
S(
"font"),
FONT }, {
S(
"i"),
I },
67 {
S(
"nobr"),
NOBR }, {
S(
"s"),
S },
70 {
S(
"u"),
U }, {
S(
"xmp"),
XMP },
74 {
S(
"mi"),
MI }, {
S(
"mo"),
MO },
75 {
S(
"mn"),
MN }, {
S(
"ms"),
MS },
100 if (tokeniser == NULL || treebuilder == NULL)
159 if (treebuilder == NULL)
235 if (treebuilder == NULL || params == NULL)
376 const hubbub_token *token,
bool insert_into_current_node)
382 for (c = 0; c <
len; c++) {
383 if (data[c] != 0x09 && data[c] != 0x0A &&
384 data[c] != 0x0C && data[c] != 0x20)
388 if (c > 0 && insert_into_current_node) {
425 void *comment, *appended;
435 type ==
THEAD || type ==
TR)) {
441 parent, comment, &appended);
515 if (node_type == type)
518 if (node_type ==
TABLE)
557 while (entry->
prev != NULL) {
568 initial_entry = entry;
572 while (entry != NULL) {
573 void *clone, *appended;
626 for (entry = initial_entry; entry != NULL; entry = entry->
next) {
631 uint32_t prev_stack_index;
641 &prev_ns, &prev_type, &prev_node,
688 node,
false, &parent);
692 if (parent != NULL) {
695 parent, node, &removed);
725 uint32_t stack_index;
731 &ns, &type, &node, &stack_index);
756 void *node, *appended;
765 type ==
THEAD || type ==
TR)) {
804 tag->
ns, type, appended);
836 while (type ==
DD || type ==
DT || type ==
LI || type ==
OPTION ||
843 if (except !=
UNKNOWN && type == except)
876 switch (stack[node].
type) {
948 void *text, *appended;
957 type ==
THEAD || type ==
TR)) {
989 const uint8_t *
name = tag_name->
ptr;
990 size_t len = tag_name->
len;
1002 (
const char *) name, len) == 0)
1017 return (type <=
WBR);
1028 return (type >=
APPLET && type <=
TH);
1039 return (type >=
A && type <=
U);
1120 if (stack[slot].type ==
TABLE) {
1122 for (t = slot - 1; t > 0; t--) {
1123 if (stack[t].type ==
TABLE)
1130 stack[slot].type !=
HTML &&
1131 stack[slot].type !=
TABLE)) {
1136 entry != NULL; entry = entry->
prev) {
1144 *ns = stack[slot].
ns;
1145 *type = stack[slot].
type;
1146 *node = stack[slot].
node;
1168 while (otype != type) {
1197 assert(index <= treebuilder->context.current_node);
1207 stack[n].type !=
HTML &&
1208 stack[n].type !=
TABLE)) {
1212 e != NULL; e = e->
prev) {
1219 *ns = stack[index].
ns;
1220 *type = stack[index].
type;
1221 *removed = stack[index].
node;
1224 if (index < treebuilder->context.current_node) {
1225 memmove(&stack[index], &stack[index + 1],
1293 uint32_t stack_index)
1309 if (entry->
prev != NULL)
1334 uint32_t stack_index)
1339 assert(prev->
next == next);
1343 assert(next->
prev == prev);
1358 if (entry->
prev != NULL)
1363 if (entry->
next != NULL)
1386 uint32_t *stack_index)
1393 if (entry->
prev == NULL)
1398 if (entry->
next == NULL)
1426 uint32_t stack_index,
1428 uint32_t *ostack_index)
1461 fprintf(fp,
"%u: %s %p\n",
1479 entry = entry->
next) {
1480 fprintf(fp,
"%s %p %u\n",
struct hubbub_treebuilder_context::@13 collect
Context for character collecting.
bool is_formatting_element(element_type type)
Determine if a node is a formatting element.
hubbub_ns ns
Element namespace.
hubbub_error handle_after_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "after body" insertion mode.
void close_implied_end_tags(hubbub_treebuilder *treebuilder, element_type except)
Close implied end tags.
hubbub_error complete_script(hubbub_treebuilder *treebuilder)
Script processing and execution.
hubbub_token_handler handler
hubbub_error handle_after_after_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "after after body" insertion mode.
hubbub_error handle_in_frameset(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "in frameset" insertion mode.
struct hubbub_tokeniser_optparams::@11 content_model
Current content model.
hubbub_error element_stack_push(hubbub_treebuilder *treebuilder, hubbub_ns ns, element_type type, void *node)
Push an element onto the stack of open elements.
hubbub_error handle_in_column_group(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "in column group" insertion mode.
hubbub_error formatting_list_remove(hubbub_treebuilder *treebuilder, formatting_list_entry *entry, hubbub_ns *ns, element_type *type, void **node, uint32_t *stack_index)
Remove an element from the list of active formatting elements.
void * ctx
Context pointer.
hubbub_ns ns
Tag namespace.
hubbub_error formatting_list_replace(hubbub_treebuilder *treebuilder, formatting_list_entry *entry, hubbub_ns ns, element_type type, void *node, uint32_t stack_index, hubbub_ns *ons, element_type *otype, void **onode, uint32_t *ostack_index)
Remove an element from the list of active formatting elements.
hubbub_error handle_after_head(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "after head" insertion mode.
hubbub_error handle_in_select(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "in head" insertion mode.
hubbub_tree_form_associate form_associate
Form associate.
uint32_t stack_index
Index into element stack.
hubbub_content_model model
hubbub_error handle_in_table_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "in table body" insertion mode.
hubbub_error handle_generic_rcdata(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "generic rcdata" insertion mode.
hubbub_error hubbub_treebuilder_token_handler(const hubbub_token *token, void *pw)
Handle tokeniser emitting a token.
void * document_node
The document node.
bool is_phrasing_element(element_type type)
Determine if a node is a phrasing element.
void clear_active_formatting_list_to_marker(hubbub_treebuilder *treebuilder)
Clear the list of active formatting elements up to the last marker.
hubbub_string name
Tag name.
Entry in a formatting list.
hubbub_tree_handler * tree_handler
Callback table.
hubbub_error reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder)
Reconstruct the list of active formatting elements.
const uint8_t * ptr
Pointer to data.
hubbub_error aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node, void **inserted)
Adoption agency: locate foster parent and insert node into it.
hubbub_error remove_node_from_dom(hubbub_treebuilder *treebuilder, void *node)
Remove a node from the DOM.
struct hubbub_treebuilder_optparams::@15 error_handler
Error handling callback.
hubbub_error element_stack_pop_until(hubbub_treebuilder *treebuilder, element_type type)
Pop elements until an element of type "element" has been popped.
hubbub_error hubbub_tokeniser_setopt(hubbub_tokeniser *tokeniser, hubbub_tokeniser_opttype type, hubbub_tokeniser_optparams *params)
Configure a hubbub tokeniser.
hubbub_error formatting_list_append(hubbub_treebuilder *treebuilder, hubbub_ns ns, element_type type, void *node, uint32_t stack_index)
Append an element to the end of the list of active formatting elements.
hubbub_error process_characters_expect_whitespace(hubbub_treebuilder *treebuilder, const hubbub_token *token, bool insert_into_current_node)
Process a character token in cases where we expect only whitespace.
hubbub_error handle_in_caption(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "in caption" insertion mode.
struct formatting_list_entry * prev
Previous in list.
Hubbub treebuilder option parameters.
bool strip_leading_lr
Whether to strip a LR from the start of the next character sequence received.
bool in_table_foster
Whether nodes that would be inserted into the current node should be foster parented.
Tokeniser data structure.
uint32_t stack_alloc
Number of stack slots allocated.
void reset_insertion_mode(hubbub_treebuilder *treebuilder)
Reset the insertion mode.
insertion_mode mode
The current insertion mode.
hubbub_error append_text(hubbub_treebuilder *treebuilder, const hubbub_string *string)
Append text to the current node, inserting into the last child of the current node, iff it's a Text node.
hubbub_error element_stack_pop(hubbub_treebuilder *treebuilder, hubbub_ns *ns, element_type *type, void **node)
Pop an element off the stack of open elements.
void formatting_list_dump(hubbub_treebuilder *treebuilder, FILE *fp)
Dump a formatting list to the given file pointer.
const char * element_type_to_name(element_type type)
Convert an element type to a name.
void * form_element
Pointer to most recently opened FORM element.
Hubbub tokeniser option parameters.
hubbub_error handle_before_head(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "before head" insertion mode.
struct hubbub_tokeniser_optparams::@9 token_handler
Token handling callback.
size_t len
Byte length of string.
hubbub_tokeniser * tokeniser
Underlying tokeniser.
hubbub_error handle_in_row(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "in row" insertion mode.
uint32_t current_table(hubbub_treebuilder *treebuilder)
Find the stack index of the current table.
hubbub_error handle_in_select_in_table(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "in select in table" insertion mode.
hubbub_error handle_in_table(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "in table" insertion mode.
hubbub_error handle_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "in body" insertion mode.
hubbub_error process_comment_append(hubbub_treebuilder *treebuilder, const hubbub_token *token, void *parent)
Process a comment token, appending it to the given parent.
hubbub_tree_handler * tree_handler
Tree handling callbacks.
hubbub_tree_clone_node clone_node
Clone node.
formatting_list_entry * formatting_list_end
End of active formatting list.
bool enable_scripting
Whether scripting is enabled.
Context for a tree builder.
void * head_element
Pointer to HEAD element.
hubbub_error handle_initial(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in initial insertion mode.
element_type type
Type of node.
hubbub_treebuilder_context context
Our context.
#define ELEMENT_STACK_CHUNK
hubbub_error handle_before_html(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "before html" insertion mode.
hubbub_error handle_in_head(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "in head" insertion mode.
hubbub_error insert_element(hubbub_treebuilder *treebuilder, const hubbub_tag *tag, bool push)
Create element and insert it into the DOM, potentially pushing it on the stack.
hubbub_tree_create_comment create_comment
Create comment.
hubbub_tree_remove_child remove_child
Remove child.
hubbub_error handle_after_after_frameset(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "after after frameset" insertion mode.
hubbub_error parse_generic_rcdata(hubbub_treebuilder *treebuilder, const hubbub_token *token, bool rcdata)
Trigger parsing of generic (R)CDATA.
struct formatting_list_entry * next
Next in list.
formatting_list_entry * formatting_list
List of active formatting elements.
hubbub_error_handler error_handler
Error handler.
element_type element_type_from_name(hubbub_treebuilder *treebuilder, const hubbub_string *tag_name)
Convert an element name into an element type.
hubbub_error handle_in_head_noscript(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "in head noscript" insertion mode.
hubbub_error hubbub_treebuilder_destroy(hubbub_treebuilder *treebuilder)
Destroy a hubbub treebuilder.
hubbub_error handle_after_frameset(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "after frameset" insertion mode.
bool enable_scripting
Enable scripting.
Item on the element stack.
element_type current_node(hubbub_treebuilder *treebuilder)
Peek at the top element of the element stack.
hubbub_tree_ref_node ref_node
Reference node.
hubbub_tree_get_parent get_parent
Get parent.
hubbub_error hubbub_treebuilder_setopt(hubbub_treebuilder *treebuilder, hubbub_treebuilder_opttype type, hubbub_treebuilder_optparams *params)
Configure a hubbub treebuilder.
hubbub_tree_unref_node unref_node
Unreference node.
hubbub_error handle_in_cell(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "in cell" insertion mode.
bool frameset_ok
Whether to process a frameset.
hubbub_treebuilder_opttype
Hubbub treebuilder option types.
void * document
Pointer to the document node.
hubbub_tree_create_element create_element
Create element.
hubbub_error_handler handler
hubbub_ns
Possible namespaces.
union hubbub_token::@3 data
Type-specific data.
static bool is_form_associated(element_type type)
Determine if a node is form associated.
hubbub_tree_create_text create_text
Create text.
hubbub_tree_complete_script complete_script
Script Complete.
hubbub_error formatting_list_insert(hubbub_treebuilder *treebuilder, formatting_list_entry *prev, formatting_list_entry *next, hubbub_ns ns, element_type type, void *node, uint32_t stack_index)
Insert an element into the list of active formatting elements.
static const struct @14 name_type_map[]
insertion_mode second_mode
The secondary insertion mode.
bool is_scoping_element(element_type type)
Determine if a node is a scoping element.
void * error_pw
Error handler data.
element_type type
Element type.
uint32_t element_in_scope(hubbub_treebuilder *treebuilder, element_type type, bool in_table)
Determine if an element is in (table) scope.
void element_stack_dump(hubbub_treebuilder *treebuilder, FILE *fp)
Dump an element stack to the given file pointer.
hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "in foreign content" insertion mode.
element_type prev_node(hubbub_treebuilder *treebuilder)
Peek at the element below the top of the element stack.
element_context details
Entry details.
hubbub_tree_append_child append_child
Append child.
bool is_special_element(element_type type)
Determine if a node is a special element.
element_context * element_stack
Stack of open elements.
uint32_t current_node
Index of current node in stack.
hubbub_error hubbub_treebuilder_create(hubbub_tokeniser *tokeniser, hubbub_treebuilder **treebuilder)
Create a hubbub treebuilder.
hubbub_error element_stack_remove(hubbub_treebuilder *treebuilder, uint32_t index, hubbub_ns *ns, element_type *type, void **removed)
Remove a node from the stack of open elements.