21 #define S(x) x, SLEN(x)
31 {
S(
"body"),
BODY }, {
S(
"br"),
BR },
34 {
S(
"dir"),
DIR }, {
S(
"div"),
DIV },
35 {
S(
"dl"),
DL }, {
S(
"dt"),
DT },
39 {
S(
"h2"),
H2 }, {
S(
"h3"),
H3 },
40 {
S(
"h4"),
H4 }, {
S(
"h5"),
H5 },
41 {
S(
"h6"),
H6 }, {
S(
"head"),
HEAD },
45 {
S(
"li"),
LI }, {
S(
"link"),
LINK },
52 {
S(
"p"),
P }, {
S(
"param"),
PARAM },
59 {
S(
"ul"),
UL }, {
S(
"wbr"),
WBR },
65 {
S(
"a"),
A }, {
S(
"b"),
B },
66 {
S(
"big"),
BIG }, {
S(
"em"),
EM },
67 {
S(
"font"),
FONT }, {
S(
"i"),
I },
68 {
S(
"nobr"),
NOBR }, {
S(
"s"),
S },
71 {
S(
"u"),
U }, {
S(
"xmp"),
XMP },
75 {
S(
"mi"),
MI }, {
S(
"mo"),
MO },
76 {
S(
"mn"),
MN }, {
S(
"ms"),
MS },
101 if (tokeniser == NULL || treebuilder == NULL)
160 if (treebuilder == NULL)
236 if (treebuilder == NULL || params == NULL)
377 const hubbub_token *token,
bool insert_into_current_node)
383 for (c = 0; c <
len; c++) {
384 if (data[c] != 0x09 && data[c] != 0x0A &&
385 data[c] != 0x0C && data[c] != 0x20)
389 if (c > 0 && insert_into_current_node) {
426 void *comment, *appended;
436 type ==
THEAD || type ==
TR)) {
442 parent, comment, &appended);
516 if (node_type == type)
519 if (node_type ==
TABLE)
558 while (entry->
prev != NULL) {
569 initial_entry = entry;
573 while (entry != NULL) {
574 void *clone, *appended;
627 for (entry = initial_entry; entry != NULL; entry = entry->
next) {
632 uint32_t prev_stack_index;
642 &prev_ns, &prev_type, &prev_node,
689 node,
false, &parent);
693 if (parent != NULL) {
696 parent, node, &removed);
726 uint32_t stack_index;
732 &ns, &type, &node, &stack_index);
757 void *node, *appended;
766 type ==
THEAD || type ==
TR)) {
805 tag->
ns, type, appended);
837 while (type ==
DD || type ==
DT || type ==
LI || type ==
OPTION ||
844 if (except !=
UNKNOWN && type == except)
877 switch (stack[node].
type) {
949 void *text, *appended;
958 type ==
THEAD || type ==
TR)) {
990 const uint8_t *
name = tag_name->
ptr;
991 size_t len = tag_name->
len;
1003 (
const char *) name, len) == 0)
1018 return (type <=
WBR);
1029 return (type >=
APPLET && type <=
TH);
1040 return (type >=
A && type <=
U);
1121 if (stack[slot].type ==
TABLE) {
1123 for (t = slot - 1; t > 0; t--) {
1124 if (stack[t].type ==
TABLE)
1131 stack[slot].type !=
HTML &&
1132 stack[slot].type !=
TABLE)) {
1137 entry != NULL; entry = entry->
prev) {
1145 *ns = stack[slot].
ns;
1146 *type = stack[slot].
type;
1147 *node = stack[slot].
node;
1169 while (otype != type) {
1198 assert(index <= treebuilder->context.current_node);
1208 stack[n].type !=
HTML &&
1209 stack[n].type !=
TABLE)) {
1213 e != NULL; e = e->
prev) {
1220 *ns = stack[index].
ns;
1221 *type = stack[index].
type;
1222 *removed = stack[index].
node;
1225 if (index < treebuilder->context.current_node) {
1226 memmove(&stack[index], &stack[index + 1],
1294 uint32_t stack_index)
1310 if (entry->
prev != NULL)
1335 uint32_t stack_index)
1340 assert(prev->
next == next);
1344 assert(next->
prev == prev);
1359 if (entry->
prev != NULL)
1364 if (entry->
next != NULL)
1387 uint32_t *stack_index)
1394 if (entry->
prev == NULL)
1399 if (entry->
next == NULL)
1427 uint32_t stack_index,
1429 uint32_t *ostack_index)
1462 fprintf(fp,
"%u: %s %p\n",
1480 entry = entry->
next) {
1481 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.