101 uint32_t *furthest_block);
103 void *node,
void *new_parent,
void **reparented);
106 uint32_t formatting_element, uint32_t *furthest_block,
110 uint32_t index, uint32_t limit);
129 #if !defined(NDEBUG) && defined(DEBUG_IN_BODY) 130 fprintf(stdout,
"Processing token %d\n", token->
type);
141 switch (token->
type) {
177 #if !defined(NDEBUG) && defined(DEBUG_IN_BODY) 178 fprintf(stdout,
"Processed\n");
205 const uint8_t *str = dummy.
ptr;
226 for (p = dummy.
ptr; p < dummy.
ptr + dummy.
len; p++) {
227 if (*p != 0x0009 && *p != 0x000a &&
228 *p != 0x000c && *p != 0x0020) {
291 }
else if (
type ==
A) {
442 }
else if (
type ==
P) {
684 (ntype ==
DD || ntype ==
DT)))
781 if (entry2 == entry && entry2->
details.
node == node) {
788 &ons, &otype, &onode, &oindex);
797 if (index <= treebuilder->context.current_node &&
1128 tag.
name.
ptr = (
const uint8_t *)
"img";
1174 if (strncmp((
const char *)
name,
"action",
1177 }
else if (strncmp((
const char *)
name,
"prompt",
1180 }
else if (strncmp((
const char *)
name,
"name",
1183 attrs[n_attrs++] = *attr;
1188 attrs[n_attrs].
name.
ptr = (
const uint8_t *)
"name";
1190 attrs[n_attrs].
value.
ptr = (
const uint8_t *)
"isindex";
1252 if (prompt != NULL) {
1256 #define PROMPT "This is a searchable index. Insert your search keywords here: " 1415 if (ntype !=
DD && ntype !=
DT && ntype !=
LI &&
1417 ntype !=
P && ntype !=
RP &&
1418 ntype !=
RT && ntype !=
TBODY &&
1419 ntype !=
TD && ntype !=
TFOOT &&
1420 ntype !=
TH && ntype !=
THEAD &&
1421 ntype !=
TR && ntype !=
BODY) {
1447 uint32_t popped = 0;
1463 }
while (otype !=
type);
1491 if (idx == 0 || node == NULL ||
1508 &ns, &otype, &onode);
1527 uint32_t popped = 0;
1584 uint32_t popped = 0;
1594 &ns, &otype, &node);
1601 }
while (otype !=
type);
1629 uint32_t popped = 0;
1645 }
while (otype !=
H1 && otype !=
H2 &&
1646 otype !=
H3 && otype !=
H4 &&
1647 otype !=
H5 && otype !=
H6);
1676 uint32_t formatting_element;
1677 uint32_t common_ancestor;
1678 uint32_t furthest_block;
1682 void *fe_clone = NULL;
1683 void *clone_appended = NULL;
1704 entry, &furthest_block);
1710 common_ancestor = formatting_element - 1;
1718 treebuilder, formatting_element,
1719 &furthest_block, &
bookmark, &last_node);
1724 if (stack[common_ancestor].
type ==
TABLE ||
1728 stack[common_ancestor].
type ==
TR) {
1730 stack[last_node].node, &reparented);
1733 stack[last_node].node,
1734 stack[common_ancestor].node,
1742 stack[last_node].
node);
1747 if (reparented != stack[last_node].node) {
1751 node_entry = node_entry->
prev) {
1759 stack[last_node].
node);
1765 stack[last_node].
node = reparented;
1778 stack[furthest_block].
node, fe_clone);
1789 stack[furthest_block].
node, fe_clone,
1798 if (clone_appended != fe_clone) {
1815 formatting_element, furthest_block);
1824 stack[furthest_block + 1].
node = clone_appended;
1828 &ons, &otype, &onode, &oindex);
1836 ons, otype, clone_appended, furthest_block + 1);
1882 &ns, &
type, &node, &index);
1912 entry != NULL; entry = entry->
prev) {
1938 uint32_t *furthest_block)
1940 uint32_t fe_index = formatting_element->
stack_index;
1968 &ns, &
type, &node, &index);
1976 *furthest_block = fb;
1991 void *new_parent,
void **reparented)
2001 new_parent, node, reparented);
2016 uint32_t formatting_element, uint32_t *furthest_block,
2021 uint32_t node, last, fb;
2024 node = last = fb = *furthest_block;
2035 node_entry = node_entry->
prev) {
2041 if (node_entry == NULL) {
2059 if (node == formatting_element)
2075 stack[node].node, &reparented);
2086 if (reparented != stack[last].node) {
2090 node_entry = node_entry->
prev) {
2104 stack[last].
node = reparented;
2113 *furthest_block = fb;
2130 uint32_t index, uint32_t limit)
2135 assert(index < limit);
2136 assert(limit <= treebuilder->context.current_node);
2143 for (n = index + 1; n <= limit; n++) {
2151 e != NULL; e = e->
prev) {
2163 memmove(&stack[index], &stack[index + 1],
2183 void *clone, *onode;
2196 &ons, &otype, &onode, &oindex);
2223 void *node,
void **inserted)
2227 void *foster_parent = NULL;
2228 bool insert =
false;
2232 stack[cur_table].
tainted =
true;
2234 if (cur_table == 0) {
2239 foster_parent = stack[0].
node;
2241 void *t_parent = NULL;
2245 stack[cur_table].
node,
2248 if (t_parent != NULL) {
2249 foster_parent = t_parent;
2254 stack[cur_table - 1].
node);
2255 foster_parent = stack[cur_table - 1].
node;
2270 foster_parent, node,
2271 stack[cur_table].
node,
2276 foster_parent, node,
2305 uint32_t popped = 0;
2321 }
while (otype !=
type);
2348 tag.
name.
ptr = (
const uint8_t *)
"br";
2375 uint32_t popped = 0;
2385 &ns, &otype, &node);
2407 }
while (--node > 0);
hubbub_ns ns
Element namespace.
bool tainted
Only for tables.
formatting_list_entry * prev
Previous entry.
hubbub_error process_comment_append(hubbub_treebuilder *treebuilder, const hubbub_token *token, void *parent)
Process a comment token, appending it to the given parent.
void formatting_list_dump(hubbub_treebuilder *treebuilder, FILE *fp)
Dump a formatting list to the given file pointer.
static hubbub_error process_0container_in_body(hubbub_treebuilder *treebuilder, element_type type)
Process a container end tag as if in "in body".
hubbub_token_type type
The token type.
struct hubbub_tokeniser_optparams::@11 content_model
Current content model.
static hubbub_error process_0presentational_in_body(hubbub_treebuilder *treebuilder, element_type type)
Process a presentational end tag as if in "in body".
void * ctx
Context pointer.
hubbub_ns ns
Tag namespace.
uint32_t stack_index
Index into element stack.
static hubbub_error process_start_tag(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a start tag.
hubbub_content_model model
bool is_scoping_element(element_type type)
Determine if a node is a scoping element.
hubbub_string name
Tag name.
static hubbub_error process_0form_in_body(hubbub_treebuilder *treebuilder)
Process a form end tag as if in "in body".
Entry in a formatting list.
void adjust_foreign_attributes(hubbub_treebuilder *treebuilder, hubbub_tag *tag)
Adjust foreign attributes.
hubbub_tree_handler * tree_handler
Callback table.
const uint8_t * ptr
Pointer to data.
static hubbub_error process_textarea_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a textarea start tag as if in "in body".
void close_implied_end_tags(hubbub_treebuilder *treebuilder, element_type except)
Close implied end tags.
hubbub_error aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node, void **inserted)
Adoption agency: locate foster parent and insert node into it.
bool is_phrasing_element(element_type type)
Determine if a node is a phrasing element.
static hubbub_error process_0br_in_body(hubbub_treebuilder *treebuilder)
Process a br end tag as if in "in body".
static hubbub_error process_hN_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a hN start tag as if in "in body".
static hubbub_error aa_reparent_node(hubbub_treebuilder *treebuilder, void *node, void *new_parent, void **reparented)
Adoption agency: reparent a node.
hubbub_string value
Attribute value.
static hubbub_error aa_remove_element_stack_item(hubbub_treebuilder *treebuilder, uint32_t index, uint32_t limit)
Adoption agency: remove an entry from the stack at the given index.
hubbub_error hubbub_tokeniser_setopt(hubbub_tokeniser *tokeniser, hubbub_tokeniser_opttype type, hubbub_tokeniser_optparams *params)
Configure a hubbub tokeniser.
void element_stack_dump(hubbub_treebuilder *treebuilder, FILE *fp)
Dump an element stack to the given file pointer.
bool is_formatting_element(element_type type)
Determine if a node is a formatting element.
struct formatting_list_entry * prev
Previous in list.
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.
static formatting_list_entry * aa_find_formatting_element(hubbub_treebuilder *treebuilder, element_type type)
Adoption agency: find formatting element.
bool strip_leading_lr
Whether to strip a LR from the start of the next character sequence received.
Bookmark for formatting list.
static hubbub_error process_image_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process an image start tag as if in "in body".
hubbub_string name
Attribute name.
static hubbub_error aa_clone_and_replace_entries(hubbub_treebuilder *treebuilder, formatting_list_entry *element)
Adoption agency: shallow clone a node and replace its formatting list and element stack entries...
static hubbub_error process_0applet_button_marquee_object_in_body(hubbub_treebuilder *treebuilder, element_type type)
Process an applet, button, marquee, or object end tag as if in "in body".
insertion_mode mode
The current insertion mode.
static hubbub_error process_isindex_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process an isindex start tag as if in "in body".
void * form_element
Pointer to most recently opened FORM element.
static hubbub_error process_phrasing_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a phrasing start tag as if in "in body".
Hubbub tokeniser option parameters.
hubbub_error reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder)
Reconstruct the list of active formatting elements.
size_t len
Byte length of string.
hubbub_tokeniser * tokeniser
Underlying tokeniser.
formatting_list_entry * next
Next entry.
bool self_closing
Whether the tag can have children.
static hubbub_error process_body_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a body start tag as if in "in body".
hubbub_error handle_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle tokens in "in body" insertion mode.
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.
struct bookmark bookmark
Bookmark for formatting list.
static hubbub_error process_character(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a character token.
static hubbub_error process_container_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a generic container start tag as if in "in body".
static hubbub_error process_0body_in_body(hubbub_treebuilder *treebuilder)
Process a body end tag as if in "in body".
hubbub_treebuilder_context context
Our context.
static hubbub_error process_hr_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process an hr start tag as if in "in body".
static hubbub_error aa_find_furthest_block(hubbub_treebuilder *treebuilder, formatting_list_entry *formatting_element, uint32_t *furthest_block)
Adoption agency: find furthest block.
hubbub_error remove_node_from_dom(hubbub_treebuilder *treebuilder, void *node)
Remove a node from the DOM.
hubbub_error insert_element(hubbub_treebuilder *treebuilder, const hubbub_tag *tag_name, bool push)
Create element and insert it into the DOM, potentially pushing it on the stack.
hubbub_error handle_in_head(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Handle token in "in head" insertion mode.
static hubbub_error process_0dd_dt_li_in_body(hubbub_treebuilder *treebuilder, element_type type)
Process a dd, dt, or li end tag as if in "in body".
hubbub_attribute * attributes
Array of attribute data.
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.
static hubbub_error process_frameset_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a frameset start tag as if in "in body".
static hubbub_error aa_find_and_validate_formatting_element(hubbub_treebuilder *treebuilder, element_type type, formatting_list_entry **element)
Adoption agency: find and validate the formatting element.
struct formatting_list_entry * next
Next in list.
hubbub_tree_reparent_children reparent_children
Reparent children.
hubbub_error element_stack_pop_until(hubbub_treebuilder *treebuilder, element_type type)
Pop elements until an element of type "element" has been popped.
static hubbub_error process_0p_in_body(hubbub_treebuilder *treebuilder)
Process a p end tag as if in "in body".
uint32_t current_table(hubbub_treebuilder *treebuilder)
Find the stack index of the current table.
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.
Item on the element stack.
hubbub_tree_ref_node ref_node
Reference node.
static hubbub_error process_form_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a form start tag as if in "in body".
hubbub_tree_get_parent get_parent
Get parent.
hubbub_tree_unref_node unref_node
Unreference node.
static hubbub_error process_presentational_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token, element_type type)
Process a b, big, em, font, i, s, small, strike, strong, tt, or u start tag as if in "in body"...
bool frameset_ok
Whether to process a frameset.
static hubbub_error process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token, element_type type)
Process a dd, dt or li start tag as if in "in body".
hubbub_tree_insert_before insert_before
Insert before.
hubbub_ns
Possible namespaces.
union hubbub_token::@3 data
Type-specific data.
static hubbub_error process_end_tag(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process an end tag.
hubbub_tree_add_attributes add_attributes
Add attributes.
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.
hubbub_ns ns
Attribute namespace.
static hubbub_error process_a_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process an "a" start tag as if in "in body".
static hubbub_error process_plaintext_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a plaintext start tag as if in "in body".
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.
static hubbub_error process_applet_marquee_object_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token, element_type type)
Process an applet, marquee or object start tag as if in "in body".
insertion_mode second_mode
The secondary insertion mode.
static hubbub_error process_nobr_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a nobr start tag as if in "in body".
static hubbub_error process_select_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a select start tag as if in "in body".
void adjust_mathml_attributes(hubbub_treebuilder *treebuilder, hubbub_tag *tag)
Adjust MathML attributes.
void adjust_svg_attributes(hubbub_treebuilder *treebuilder, hubbub_tag *tag)
Adjust SVG attributes.
element_type type
Element type.
static hubbub_error process_0h_in_body(hubbub_treebuilder *treebuilder, element_type type)
Process a h1, h2, h3, h4, h5, or h6 end tag as if in "in body".
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.
static hubbub_error process_0generic_in_body(hubbub_treebuilder *treebuilder, element_type type)
Process a generic end tag as if in "in body".
uint32_t element_in_scope(hubbub_treebuilder *treebuilder, element_type type, bool in_table)
Determine if an element is in (table) scope.
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.
static hubbub_error process_html_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a html start tag as if in "in body".
element_type element_type_from_name(hubbub_treebuilder *treebuilder, const hubbub_string *tag_name)
Convert an element name into an element type.
static hubbub_error process_opt_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process an option or optgroup start tag as if in "in body".
element_context details
Entry details.
hubbub_tree_append_child append_child
Append child.
static hubbub_error process_button_in_body(hubbub_treebuilder *treebuilder, const hubbub_token *token)
Process a button start tag as if in "in body".
element_context * element_stack
Stack of open elements.
void clear_active_formatting_list_to_marker(hubbub_treebuilder *treebuilder)
Clear the list of active formatting elements up to the last marker.
uint32_t n_attributes
Count of attributes.
uint32_t current_node
Index of current node in stack.
static hubbub_error aa_find_bookmark_location_reparenting_misnested(hubbub_treebuilder *treebuilder, uint32_t formatting_element, uint32_t *furthest_block, bookmark *bookmark, uint32_t *last_node)
Adoption agency: this is step 6.
hubbub_error parse_generic_rcdata(hubbub_treebuilder *treebuilder, const hubbub_token *token, bool rcdata)
Trigger parsing of generic (R)CDATA.