1 /*
2  * Copyright (C) 2018-2020 Alexander Borisov
3  *
4  * Author: Alexander Borisov <borisov@lexbor.com>
5  */
6 
7 #define LEXBOR_TOKENIZER_CHARS_MAP
8 #include "lexbor/core/str_res.h"
9 
10 #include "lexbor/html/tree/insertion_mode.h"
11 #include "lexbor/html/tree/open_elements.h"
12 #include "lexbor/html/tree/active_formatting.h"
13 #include "lexbor/html/interfaces/head_element.h"
14 #include "lexbor/html/tokenizer/state.h"
15 #include "lexbor/html/tokenizer/state_rcdata.h"
16 
17 
18 /*
19  * User case insertion mode.
20  *
21  * After "pre" and "listing" tag we need skip one newline in text tag.
22  * Since we have a stream of tokens,
23  * we can "look into the future" only in this way.
24  */
25 bool
lxb_html_tree_insertion_mode_in_body_skip_new_line(lxb_html_tree_t * tree,lxb_html_token_t * token)26 lxb_html_tree_insertion_mode_in_body_skip_new_line(lxb_html_tree_t *tree,
27                                                    lxb_html_token_t *token)
28 {
29     tree->mode = tree->original_mode;
30 
31     if (token->tag_id != LXB_TAG__TEXT) {
32         return false;
33     }
34 
35     tree->status = lxb_html_token_data_skip_one_newline_begin(token);
36     if (tree->status != LXB_STATUS_OK) {
37         return lxb_html_tree_process_abort(tree);
38     }
39 
40     if (token->text_start == token->text_end) {
41         return true;
42     }
43 
44     return false;
45 }
46 
47 /*
48  * User case insertion mode.
49  *
50  * After "textarea" tag we need skip one newline in text tag.
51  */
52 bool
lxb_html_tree_insertion_mode_in_body_skip_new_line_textarea(lxb_html_tree_t * tree,lxb_html_token_t * token)53 lxb_html_tree_insertion_mode_in_body_skip_new_line_textarea(lxb_html_tree_t *tree,
54                                                             lxb_html_token_t *token)
55 {
56     tree->mode = tree->original_mode;
57 
58     if (token->tag_id != LXB_TAG__TEXT) {
59         return false;
60     }
61 
62     tree->status = lxb_html_token_data_skip_one_newline_begin(token);
63     if (tree->status != LXB_STATUS_OK) {
64         return lxb_html_tree_process_abort(tree);
65     }
66 
67     if (token->text_start == token->text_end) {
68         return true;
69     }
70 
71     return false;
72 }
73 
74 /* Open */
75 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_text(lxb_html_tree_t * tree,lxb_html_token_t * token)76 lxb_html_tree_insertion_mode_in_body_text(lxb_html_tree_t *tree,
77                                           lxb_html_token_t *token)
78 {
79     lexbor_str_t str;
80 
81     if (token->null_count != 0) {
82         lxb_html_tree_parse_error(tree, token,
83                                   LXB_HTML_RULES_ERROR_NUCH);
84 
85         tree->status = lxb_html_token_make_text_drop_null(token, &str,
86                                                           tree->document->dom_document.text);
87     }
88     else {
89         tree->status = lxb_html_token_make_text(token, &str,
90                                                 tree->document->dom_document.text);
91     }
92 
93     if (tree->status != LXB_STATUS_OK) {
94         return lxb_html_tree_process_abort(tree);
95     }
96 
97     /* Can be zero only if all NULL are gone */
98     if (str.length == 0) {
99         lexbor_str_destroy(&str, tree->document->dom_document.text, false);
100 
101         return true;
102     }
103 
104     lxb_html_tree_insertion_mode_in_body_text_append(tree, &str);
105     if (tree->status != LXB_STATUS_OK) {
106         return lxb_html_tree_process_abort(tree);
107     }
108 
109     return true;
110 }
111 
112 lxb_status_t
lxb_html_tree_insertion_mode_in_body_text_append(lxb_html_tree_t * tree,lexbor_str_t * str)113 lxb_html_tree_insertion_mode_in_body_text_append(lxb_html_tree_t *tree,
114                                                  lexbor_str_t *str)
115 {
116     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
117     if (tree->status != LXB_STATUS_OK) {
118         return tree->status;
119     }
120 
121     if (tree->frameset_ok) {
122         const lxb_char_t *pos = str->data;
123         const lxb_char_t *end = str->data + str->length;
124 
125         while (pos != end) {
126             if (lexbor_tokenizer_chars_map[*pos]
127                 != LEXBOR_STR_RES_MAP_CHAR_WHITESPACE)
128             {
129                 tree->frameset_ok = false;
130                 break;
131             }
132 
133             pos++;
134         }
135     }
136 
137     tree->status = lxb_html_tree_insert_character_for_data(tree, str, NULL);
138     if (tree->status != LXB_STATUS_OK) {
139         return tree->status;
140     }
141 
142     return LXB_STATUS_OK;
143 }
144 
145 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_comment(lxb_html_tree_t * tree,lxb_html_token_t * token)146 lxb_html_tree_insertion_mode_in_body_comment(lxb_html_tree_t *tree,
147                                              lxb_html_token_t *token)
148 {
149     lxb_dom_comment_t *comment;
150 
151     comment = lxb_html_tree_insert_comment(tree, token, NULL);
152     if (comment == NULL) {
153         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
154 
155         return lxb_html_tree_process_abort(tree);
156     }
157 
158     return true;
159 }
160 
161 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_doctype(lxb_html_tree_t * tree,lxb_html_token_t * token)162 lxb_html_tree_insertion_mode_in_body_doctype(lxb_html_tree_t *tree,
163                                              lxb_html_token_t *token)
164 {
165     lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_DOTOINBOMO);
166 
167     return true;
168 }
169 
170 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_html(lxb_html_tree_t * tree,lxb_html_token_t * token)171 lxb_html_tree_insertion_mode_in_body_html(lxb_html_tree_t *tree,
172                                           lxb_html_token_t *token)
173 {
174     lxb_dom_node_t *temp_node;
175     lxb_dom_element_t *html;
176 
177     lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO);
178 
179     temp_node = lxb_html_tree_open_elements_find(tree, LXB_TAG_TEMPLATE,
180                                                  LXB_NS_HTML, NULL);
181     if (temp_node != NULL) {
182         return true;
183     }
184 
185     html = lxb_dom_interface_element(lxb_html_tree_open_elements_first(tree));
186 
187     tree->status = lxb_html_tree_append_attributes(tree, html, token,
188                                                    html->node.ns);
189     if (tree->status != LXB_HTML_STATUS_OK) {
190         return lxb_html_tree_process_abort(tree);
191     }
192 
193     return true;
194 }
195 
196 /*
197  * Start tag:
198  *      "base", "basefont", "bgsound", "link", "meta", "noframes",
199  *      "script", "style", "template", "title"
200  * End Tag:
201  *      "template"
202  */
203 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_blmnst(lxb_html_tree_t * tree,lxb_html_token_t * token)204 lxb_html_tree_insertion_mode_in_body_blmnst(lxb_html_tree_t *tree,
205                                             lxb_html_token_t *token)
206 {
207     return lxb_html_tree_insertion_mode_in_head(tree, token);
208 }
209 
210 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_body(lxb_html_tree_t * tree,lxb_html_token_t * token)211 lxb_html_tree_insertion_mode_in_body_body(lxb_html_tree_t *tree,
212                                           lxb_html_token_t *token)
213 {
214     lxb_dom_node_t *node, *temp;
215     lxb_dom_element_t *body;
216 
217     lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO);
218 
219     node = lxb_html_tree_open_elements_get(tree, 1);
220     if (node == NULL || node->local_name != LXB_TAG_BODY) {
221         return true;
222     }
223 
224     temp = lxb_html_tree_open_elements_find_reverse(tree, LXB_TAG_TEMPLATE,
225                                                     LXB_NS_HTML, NULL);
226     if (temp != NULL) {
227         return true;
228     }
229 
230     tree->frameset_ok = false;
231 
232     body = lxb_dom_interface_element(node);
233 
234     tree->status = lxb_html_tree_append_attributes(tree, body, token, node->ns);
235     if (tree->status != LXB_HTML_STATUS_OK) {
236         return lxb_html_tree_process_abort(tree);
237     }
238 
239     return true;
240 }
241 
242 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_frameset(lxb_html_tree_t * tree,lxb_html_token_t * token)243 lxb_html_tree_insertion_mode_in_body_frameset(lxb_html_tree_t *tree,
244                                               lxb_html_token_t *token)
245 {
246     lxb_dom_node_t *node;
247     lxb_html_element_t *element;
248 
249     lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO);
250 
251     node = lxb_html_tree_open_elements_get(tree, 1);
252     if (node == NULL || node->local_name != LXB_TAG_BODY) {
253         return true;
254     }
255 
256     if (tree->frameset_ok == false) {
257         return true;
258     }
259 
260     lxb_html_tree_node_delete_deep(tree, node);
261 
262     /* node is HTML */
263     node = lxb_html_tree_open_elements_get(tree, 0);
264     lxb_html_tree_open_elements_pop_until_node(tree, node, false);
265 
266     element = lxb_html_tree_insert_html_element(tree, token);
267     if (element == NULL) {
268         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
269 
270         return lxb_html_tree_process_abort(tree);
271     }
272 
273     tree->mode = lxb_html_tree_insertion_mode_in_frameset;
274 
275     return true;
276 }
277 
278 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_eof(lxb_html_tree_t * tree,lxb_html_token_t * token)279 lxb_html_tree_insertion_mode_in_body_eof(lxb_html_tree_t *tree,
280                                          lxb_html_token_t *token)
281 {
282     if (lexbor_array_obj_length(tree->template_insertion_modes) != 0) {
283         return lxb_html_tree_insertion_mode_in_template(tree, token);
284     }
285 
286     bool it_is = lxb_html_tree_check_scope_element(tree);
287     if (it_is == false) {
288         lxb_html_tree_parse_error(tree, token,
289                                   LXB_HTML_RULES_ERROR_BAENOPELISWR);
290     }
291 
292     tree->status = lxb_html_tree_stop_parsing(tree);
293     if (tree->status != LXB_HTML_STATUS_OK) {
294         return lxb_html_tree_process_abort(tree);
295     }
296 
297     return true;
298 }
299 
300 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_body_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)301 lxb_html_tree_insertion_mode_in_body_body_closed(lxb_html_tree_t *tree,
302                                                  lxb_html_token_t *token)
303 {
304     lxb_dom_node_t *body_node;
305 
306     body_node = lxb_html_tree_element_in_scope(tree, LXB_TAG_BODY, LXB_NS_HTML,
307                                                LXB_HTML_TAG_CATEGORY_SCOPE);
308     if (body_node == NULL) {
309         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_NOBOELINSC);
310 
311         return true;
312     }
313 
314     bool it_is = lxb_html_tree_check_scope_element(tree);
315     if (it_is == false) {
316         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_OPELISWR);
317     }
318 
319     tree->mode = lxb_html_tree_insertion_mode_after_body;
320 
321     return true;
322 }
323 
324 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_html_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)325 lxb_html_tree_insertion_mode_in_body_html_closed(lxb_html_tree_t *tree,
326                                                  lxb_html_token_t *token)
327 {
328     lxb_dom_node_t *body_node;
329 
330     body_node = lxb_html_tree_element_in_scope(tree, LXB_TAG_BODY, LXB_NS_HTML,
331                                                LXB_HTML_TAG_CATEGORY_SCOPE);
332     if (body_node == NULL) {
333         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_NOBOELINSC);
334 
335         return true;
336     }
337 
338     bool it_is = lxb_html_tree_check_scope_element(tree);
339     if (it_is == false) {
340         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_OPELISWR);
341     }
342 
343     tree->mode = lxb_html_tree_insertion_mode_after_body;
344 
345     return false;
346 }
347 
348 /*
349  * "address", "article", "aside", "blockquote", "center", "details", "dialog",
350  * "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header",
351  * "hgroup", "main", "menu", "nav", "ol", "p", "section", "summary", "ul"
352  */
353 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_abcdfhmnopsu(lxb_html_tree_t * tree,lxb_html_token_t * token)354 lxb_html_tree_insertion_mode_in_body_abcdfhmnopsu(lxb_html_tree_t *tree,
355                                                   lxb_html_token_t *token)
356 {
357     lxb_dom_node_t *body_node;
358     lxb_html_element_t *element;
359 
360     body_node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
361                                                LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
362     if (body_node != NULL) {
363         lxb_html_tree_close_p_element(tree, token);
364     }
365 
366     element = lxb_html_tree_insert_html_element(tree, token);
367     if (element == NULL) {
368         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
369 
370         return lxb_html_tree_process_abort(tree);
371     }
372 
373     return true;
374 }
375 
376 /*
377  * "h1", "h2", "h3", "h4", "h5", "h6"
378  */
379 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_h123456(lxb_html_tree_t * tree,lxb_html_token_t * token)380 lxb_html_tree_insertion_mode_in_body_h123456(lxb_html_tree_t *tree,
381                                              lxb_html_token_t *token)
382 {
383     lxb_dom_node_t *node;
384     lxb_html_element_t *element;
385 
386     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
387                                           LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
388     if (node != NULL) {
389         lxb_html_tree_close_p_element(tree, token);
390     }
391 
392     node = lxb_html_tree_current_node(tree);
393 
394     switch (node->local_name) {
395         case LXB_TAG_H1:
396         case LXB_TAG_H2:
397         case LXB_TAG_H3:
398         case LXB_TAG_H4:
399         case LXB_TAG_H5:
400         case LXB_TAG_H6:
401             lxb_html_tree_parse_error(tree, token,
402                                       LXB_HTML_RULES_ERROR_UNELINOPELST);
403 
404             lxb_html_tree_open_elements_pop(tree);
405             break;
406 
407         default:
408             break;
409     }
410 
411     element = lxb_html_tree_insert_html_element(tree, token);
412     if (element == NULL) {
413         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
414 
415         return lxb_html_tree_process_abort(tree);
416     }
417 
418     return true;
419 }
420 
421 /*
422  * "pre", "listing"
423  */
424 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_pre_listing(lxb_html_tree_t * tree,lxb_html_token_t * token)425 lxb_html_tree_insertion_mode_in_body_pre_listing(lxb_html_tree_t *tree,
426                                                  lxb_html_token_t *token)
427 {
428     lxb_dom_node_t *node;
429     lxb_html_element_t *element;
430 
431     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
432                                           LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
433     if (node != NULL) {
434         lxb_html_tree_close_p_element(tree, token);
435     }
436 
437     element = lxb_html_tree_insert_html_element(tree, token);
438     if (element == NULL) {
439         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
440 
441         return lxb_html_tree_process_abort(tree);
442     }
443 
444     tree->original_mode = tree->mode;
445     tree->mode = lxb_html_tree_insertion_mode_in_body_skip_new_line;
446     tree->frameset_ok = false;
447 
448     return true;
449 }
450 
451 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_form(lxb_html_tree_t * tree,lxb_html_token_t * token)452 lxb_html_tree_insertion_mode_in_body_form(lxb_html_tree_t *tree,
453                                           lxb_html_token_t *token)
454 {
455     lxb_dom_node_t *node, *temp;
456     lxb_html_element_t *element;
457 
458     temp = lxb_html_tree_open_elements_find_reverse(tree, LXB_TAG_TEMPLATE,
459                                                     LXB_NS_HTML, NULL);
460 
461     if (tree->form != NULL && temp == NULL) {
462         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO);
463 
464         return true;
465     }
466 
467     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
468                                           LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
469     if (node != NULL) {
470         lxb_html_tree_close_p_element(tree, token);
471     }
472 
473     element = lxb_html_tree_insert_html_element(tree, token);
474     if (element == NULL) {
475         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
476 
477         return lxb_html_tree_process_abort(tree);
478     }
479 
480     if (temp == NULL) {
481         tree->form = lxb_html_interface_form(element);
482     }
483 
484     return true;
485 }
486 
487 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_li(lxb_html_tree_t * tree,lxb_html_token_t * token)488 lxb_html_tree_insertion_mode_in_body_li(lxb_html_tree_t *tree,
489                                         lxb_html_token_t *token)
490 {
491     bool is_special;
492     lxb_dom_node_t *node;
493     lxb_html_element_t *element;
494 
495     void **list = tree->open_elements->list;
496     size_t idx = tree->open_elements->length;
497 
498     tree->frameset_ok = false;
499 
500     while (idx != 0) {
501         idx--;
502 
503         node = list[idx];
504 
505         if (lxb_html_tree_node_is(node, LXB_TAG_LI)) {
506             lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG_LI,
507                                                     LXB_NS_HTML);
508 
509             node = lxb_html_tree_current_node(tree);
510 
511             if (lxb_html_tree_node_is(node, LXB_TAG_LI) == false) {
512                 lxb_html_tree_parse_error(tree, token,
513                                           LXB_HTML_RULES_ERROR_UNELINOPELST);
514             }
515 
516             lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_LI,
517                                                          LXB_NS_HTML, true);
518             break;
519         }
520 
521         is_special = lxb_html_tag_is_category(node->local_name, node->ns,
522                                               LXB_HTML_TAG_CATEGORY_SPECIAL);
523         if (is_special
524             && lxb_html_tree_node_is(node, LXB_TAG_ADDRESS) == false
525             && lxb_html_tree_node_is(node, LXB_TAG_DIV) == false
526             && lxb_html_tree_node_is(node, LXB_TAG_P) == false)
527         {
528             break;
529         }
530     }
531 
532     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
533                                           LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
534     if (node != NULL) {
535         lxb_html_tree_close_p_element(tree, token);
536     }
537 
538     element = lxb_html_tree_insert_html_element(tree, token);
539     if (element == NULL) {
540         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
541 
542         return lxb_html_tree_process_abort(tree);
543     }
544 
545     return true;
546 }
547 
548 /*
549  * "dd", "dt"
550  */
551 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_dd_dt(lxb_html_tree_t * tree,lxb_html_token_t * token)552 lxb_html_tree_insertion_mode_in_body_dd_dt(lxb_html_tree_t *tree,
553                                            lxb_html_token_t *token)
554 {
555     bool is_special;
556     lxb_dom_node_t *node;
557     lxb_html_element_t *element;
558 
559     void **list = tree->open_elements->list;
560     size_t idx = tree->open_elements->length;
561 
562     tree->frameset_ok = false;
563 
564     while (idx != 0) {
565         idx--;
566 
567         node = list[idx];
568 
569         if (lxb_html_tree_node_is(node, LXB_TAG_DD)) {
570             lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG_DD,
571                                                     LXB_NS_HTML);
572 
573             node = lxb_html_tree_current_node(tree);
574 
575             if (lxb_html_tree_node_is(node, LXB_TAG_DD) == false) {
576                 lxb_html_tree_parse_error(tree, token,
577                                           LXB_HTML_RULES_ERROR_UNELINOPELST);
578             }
579 
580             lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_DD,
581                                                          LXB_NS_HTML, true);
582             break;
583         }
584 
585         if (lxb_html_tree_node_is(node, LXB_TAG_DT)) {
586             lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG_DT,
587                                                     LXB_NS_HTML);
588 
589             node = lxb_html_tree_current_node(tree);
590 
591             if (lxb_html_tree_node_is(node, LXB_TAG_DT) == false) {
592                 lxb_html_tree_parse_error(tree, token,
593                                           LXB_HTML_RULES_ERROR_UNELINOPELST);
594             }
595 
596             lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_DT,
597                                                          LXB_NS_HTML, true);
598             break;
599         }
600 
601         is_special = lxb_html_tag_is_category(node->local_name, node->ns,
602                                               LXB_HTML_TAG_CATEGORY_SPECIAL);
603         if (is_special
604             && lxb_html_tree_node_is(node, LXB_TAG_ADDRESS) == false
605             && lxb_html_tree_node_is(node, LXB_TAG_DIV) == false
606             && lxb_html_tree_node_is(node, LXB_TAG_P) == false)
607         {
608             break;
609         }
610     }
611 
612     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
613                                           LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
614     if (node != NULL) {
615         lxb_html_tree_close_p_element(tree, token);
616     }
617 
618     element = lxb_html_tree_insert_html_element(tree, token);
619     if (element == NULL) {
620         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
621 
622         return lxb_html_tree_process_abort(tree);
623     }
624 
625     return true;
626 }
627 
628 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_plaintext(lxb_html_tree_t * tree,lxb_html_token_t * token)629 lxb_html_tree_insertion_mode_in_body_plaintext(lxb_html_tree_t *tree,
630                                                lxb_html_token_t *token)
631 {
632     lxb_dom_node_t *node;
633     lxb_html_element_t *element;
634 
635     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
636                                           LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
637     if (node != NULL) {
638         lxb_html_tree_close_p_element(tree, token);
639     }
640 
641     element = lxb_html_tree_insert_html_element(tree, token);
642     if (element == NULL) {
643         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
644 
645         return lxb_html_tree_process_abort(tree);
646     }
647 
648     lxb_html_tokenizer_state_set(tree->tkz_ref,
649                                  lxb_html_tokenizer_state_plaintext_before);
650 
651     return true;
652 }
653 
654 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_button(lxb_html_tree_t * tree,lxb_html_token_t * token)655 lxb_html_tree_insertion_mode_in_body_button(lxb_html_tree_t *tree,
656                                             lxb_html_token_t *token)
657 {
658     lxb_dom_node_t *node;
659     lxb_html_element_t *element;
660 
661     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_BUTTON, LXB_NS_HTML,
662                                           LXB_HTML_TAG_CATEGORY_SCOPE);
663     if (node != NULL) {
664         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO);
665 
666         lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF,
667                                                 LXB_NS__UNDEF);
668 
669         lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_BUTTON,
670                                                      LXB_NS_HTML, true);
671     }
672 
673     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
674     if (tree->status != LXB_STATUS_OK) {
675         return lxb_html_tree_process_abort(tree);
676     }
677 
678     element = lxb_html_tree_insert_html_element(tree, token);
679     if (element == NULL) {
680         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
681 
682         return lxb_html_tree_process_abort(tree);
683     }
684 
685     tree->frameset_ok = false;
686 
687     return true;
688 }
689 
690 /*
691  * "address", "article", "aside", "blockquote", "button",  "center", "details",
692  * "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer",
693  * "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", "section",
694  * "summary", "ul"
695  */
696 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_abcdfhlmnopsu_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)697 lxb_html_tree_insertion_mode_in_body_abcdfhlmnopsu_closed(lxb_html_tree_t *tree,
698                                                           lxb_html_token_t *token)
699 {
700     lxb_dom_node_t *node;
701 
702     node = lxb_html_tree_element_in_scope(tree, token->tag_id,
703                                           LXB_NS_HTML, LXB_HTML_TAG_CATEGORY_SCOPE);
704     if (node == NULL) {
705         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO);
706 
707         return true;
708     }
709 
710     lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF,
711                                             LXB_NS__UNDEF);
712 
713     node = lxb_html_tree_current_node(tree);
714 
715     if (lxb_html_tree_node_is(node, token->tag_id) == false) {
716         lxb_html_tree_parse_error(tree, token,
717                                   LXB_HTML_RULES_ERROR_UNELINOPELST);
718     }
719 
720     lxb_html_tree_open_elements_pop_until_tag_id(tree, token->tag_id,
721                                                  LXB_NS_HTML, true);
722 
723     return true;
724 }
725 
726 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_form_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)727 lxb_html_tree_insertion_mode_in_body_form_closed(lxb_html_tree_t *tree,
728                                                  lxb_html_token_t *token)
729 {
730     lxb_dom_node_t *node, *current;
731 
732     node = lxb_html_tree_open_elements_find_reverse(tree, LXB_TAG_TEMPLATE,
733                                                     LXB_NS_HTML, NULL);
734     if (node == NULL) {
735         node = lxb_dom_interface_node(tree->form);
736 
737         tree->form = NULL;
738 
739         if (node == NULL) {
740             lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO);
741 
742             return true;
743         }
744 
745         node = lxb_html_tree_element_in_scope_by_node(tree, node,
746                                                       LXB_HTML_TAG_CATEGORY_SCOPE);
747         if (node == NULL) {
748             lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO);
749 
750             return true;
751         }
752 
753         lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF,
754                                                 LXB_NS__UNDEF);
755 
756         current = lxb_html_tree_current_node(tree);
757 
758         if (current != node) {
759             lxb_html_tree_parse_error(tree, token,
760                                       LXB_HTML_RULES_ERROR_UNELINOPELST);
761         }
762 
763         lxb_html_tree_open_elements_remove_by_node(tree, node);
764 
765         return true;
766     }
767 
768     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_FORM, LXB_NS_HTML,
769                                           LXB_HTML_TAG_CATEGORY_SCOPE);
770     if (node == NULL) {
771         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO);
772 
773         return true;
774     }
775 
776     lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF,
777                                             LXB_NS__UNDEF);
778 
779     node = lxb_html_tree_current_node(tree);
780 
781     if (lxb_html_tree_node_is(node, LXB_TAG_FORM) == false) {
782         lxb_html_tree_parse_error(tree, token,
783                                   LXB_HTML_RULES_ERROR_UNELINOPELST);
784     }
785 
786     lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_FORM,
787                                                  LXB_NS_HTML, true);
788 
789     return true;
790 }
791 
792 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_p_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)793 lxb_html_tree_insertion_mode_in_body_p_closed(lxb_html_tree_t *tree,
794                                               lxb_html_token_t *token)
795 {
796     lxb_dom_node_t *node;
797 
798     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
799                                           LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
800     if (node == NULL) {
801         lxb_html_token_t fake_token = {0};
802         lxb_html_element_t *element;
803 
804         lxb_html_tree_parse_error(tree, token,
805                                   LXB_HTML_RULES_ERROR_UNCLTO);
806 
807         fake_token.tag_id = LXB_TAG_P;
808 
809         element = lxb_html_tree_insert_html_element(tree, &fake_token);
810         if (element == NULL) {
811             tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
812 
813             return lxb_html_tree_process_abort(tree);
814         }
815     }
816 
817     lxb_html_tree_close_p_element(tree, token);
818 
819     return true;
820 }
821 
822 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_li_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)823 lxb_html_tree_insertion_mode_in_body_li_closed(lxb_html_tree_t *tree,
824                                                lxb_html_token_t *token)
825 {
826     lxb_dom_node_t *node;
827 
828     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_LI, LXB_NS_HTML,
829                                           LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM);
830     if (node == NULL) {
831         lxb_html_tree_parse_error(tree, token,
832                                   LXB_HTML_RULES_ERROR_UNCLTO);
833         return true;
834     }
835 
836     lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG_LI, LXB_NS_HTML);
837 
838     node = lxb_html_tree_current_node(tree);
839 
840     if (lxb_html_tree_node_is(node, LXB_TAG_LI) == false) {
841         lxb_html_tree_parse_error(tree, token,
842                                   LXB_HTML_RULES_ERROR_UNELINOPELST);
843     }
844 
845     lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_LI, LXB_NS_HTML,
846                                                  true);
847 
848     return true;
849 }
850 
851 /*
852  * "dd", "dt"
853  */
854 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_dd_dt_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)855 lxb_html_tree_insertion_mode_in_body_dd_dt_closed(lxb_html_tree_t *tree,
856                                                   lxb_html_token_t *token)
857 {
858     lxb_dom_node_t *node;
859 
860     node = lxb_html_tree_element_in_scope(tree, token->tag_id, LXB_NS_HTML,
861                                           LXB_HTML_TAG_CATEGORY_SCOPE);
862     if (node == NULL) {
863         lxb_html_tree_parse_error(tree, token,
864                                   LXB_HTML_RULES_ERROR_UNCLTO);
865         return true;
866     }
867 
868     lxb_html_tree_generate_implied_end_tags(tree, token->tag_id, LXB_NS_HTML);
869 
870     node = lxb_html_tree_current_node(tree);
871 
872     if (lxb_html_tree_node_is(node, token->tag_id) == false) {
873         lxb_html_tree_parse_error(tree, token,
874                                   LXB_HTML_RULES_ERROR_UNELINOPELST);
875     }
876 
877     lxb_html_tree_open_elements_pop_until_tag_id(tree, token->tag_id,
878                                                  LXB_NS_HTML, true);
879 
880     return true;
881 }
882 
883 /*
884  * "h1", "h2", "h3", "h4", "h5", "h6"
885  */
886 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_h123456_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)887 lxb_html_tree_insertion_mode_in_body_h123456_closed(lxb_html_tree_t *tree,
888                                                     lxb_html_token_t *token)
889 {
890     lxb_dom_node_t *node;
891 
892     node = lxb_html_tree_element_in_scope_h123456(tree);
893     if (node == NULL) {
894         lxb_html_tree_parse_error(tree, token,
895                                   LXB_HTML_RULES_ERROR_UNCLTO);
896         return true;
897     }
898 
899     lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF,
900                                             LXB_NS__UNDEF);
901 
902     node = lxb_html_tree_current_node(tree);
903 
904     if (lxb_html_tree_node_is(node, token->tag_id) == false) {
905         lxb_html_tree_parse_error(tree, token,
906                                   LXB_HTML_RULES_ERROR_UNELINOPELST);
907     }
908 
909     lxb_html_tree_open_elements_pop_until_h123456(tree);
910 
911     return true;
912 }
913 
914 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_a(lxb_html_tree_t * tree,lxb_html_token_t * token)915 lxb_html_tree_insertion_mode_in_body_a(lxb_html_tree_t *tree,
916                                        lxb_html_token_t *token)
917 {
918     lxb_dom_node_t *node;
919     lxb_html_element_t *element;
920 
921     node = lxb_html_tree_active_formatting_between_last_marker(tree,
922                                                                token->tag_id,
923                                                                NULL);
924     if (node != NULL) {
925         /* bool is; */
926 
927         lxb_html_tree_parse_error(tree, token,
928                                   LXB_HTML_RULES_ERROR_UNELINACFOST);
929 
930         lxb_html_tree_adoption_agency_algorithm(tree, token,
931                                                 &tree->status);
932         if (tree->status != LXB_STATUS_OK) {
933             return lxb_html_tree_process_abort(tree);
934         }
935 
936 /*
937         if (is) {
938             return lxb_html_tree_insertion_mode_in_body_anything_else_closed(tree,
939                                                                              token);
940         }
941 */
942 
943         lxb_html_tree_active_formatting_remove_by_node(tree, node);
944         lxb_html_tree_open_elements_remove_by_node(tree, node);
945     }
946 
947     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
948     if (tree->status != LXB_STATUS_OK) {
949         return lxb_html_tree_process_abort(tree);
950     }
951 
952     element = lxb_html_tree_insert_html_element(tree, token);
953     if (element == NULL) {
954         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
955 
956         return lxb_html_tree_process_abort(tree);
957     }
958 
959     node = lxb_dom_interface_node(element);
960 
961     lxb_html_tree_active_formatting_push_with_check_dupl(tree, node);
962 
963     return true;
964 }
965 
966 /*
967  * "b", "big", "code", "em", "font", "i", "s", "small", "strike", "strong",
968  * "tt", "u"
969  */
970 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_bcefistu(lxb_html_tree_t * tree,lxb_html_token_t * token)971 lxb_html_tree_insertion_mode_in_body_bcefistu(lxb_html_tree_t *tree,
972                                               lxb_html_token_t *token)
973 {
974     lxb_dom_node_t *node;
975     lxb_html_element_t *element;
976 
977     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
978     if (tree->status != LXB_STATUS_OK) {
979         return lxb_html_tree_process_abort(tree);
980     }
981 
982     element = lxb_html_tree_insert_html_element(tree, token);
983     if (element == NULL) {
984         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
985 
986         return lxb_html_tree_process_abort(tree);
987     }
988 
989     node = lxb_dom_interface_node(element);
990 
991     lxb_html_tree_active_formatting_push_with_check_dupl(tree, node);
992 
993     return true;
994 }
995 
996 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_nobr(lxb_html_tree_t * tree,lxb_html_token_t * token)997 lxb_html_tree_insertion_mode_in_body_nobr(lxb_html_tree_t *tree,
998                                           lxb_html_token_t *token)
999 {
1000     lxb_dom_node_t *node;
1001     lxb_html_element_t *element;
1002 
1003     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1004     if (tree->status != LXB_STATUS_OK) {
1005         return lxb_html_tree_process_abort(tree);
1006     }
1007 
1008     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_NOBR, LXB_NS_HTML,
1009                                           LXB_HTML_TAG_CATEGORY_SCOPE);
1010     if (node != NULL) {
1011         /* bool is; */
1012 
1013         lxb_html_tree_parse_error(tree, token,
1014                                   LXB_HTML_RULES_ERROR_UNELINSC);
1015 
1016         lxb_html_tree_adoption_agency_algorithm(tree, token, &tree->status);
1017         if (tree->status != LXB_STATUS_OK) {
1018             return lxb_html_tree_process_abort(tree);
1019         }
1020 /*
1021         if (is) {
1022             return lxb_html_tree_insertion_mode_in_body_anything_else_closed(tree,
1023                                                                              token);
1024         }
1025 */
1026         tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1027         if (tree->status != LXB_STATUS_OK) {
1028             return lxb_html_tree_process_abort(tree);
1029         }
1030     }
1031 
1032     element = lxb_html_tree_insert_html_element(tree, token);
1033     if (element == NULL) {
1034         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1035 
1036         return lxb_html_tree_process_abort(tree);
1037     }
1038 
1039     node = lxb_dom_interface_node(element);
1040 
1041     lxb_html_tree_active_formatting_push_with_check_dupl(tree, node);
1042 
1043     return true;
1044 }
1045 
1046 /*
1047  * "a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", "strike",
1048  * "strong", "tt", "u"
1049  */
1050 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_abcefinstu_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)1051 lxb_html_tree_insertion_mode_in_body_abcefinstu_closed(lxb_html_tree_t *tree,
1052                                                        lxb_html_token_t *token)
1053 {
1054     /* bool is; */
1055 
1056     lxb_html_tree_adoption_agency_algorithm(tree, token, &tree->status);
1057     if (tree->status != LXB_STATUS_OK) {
1058         return lxb_html_tree_process_abort(tree);
1059     }
1060 
1061 /*
1062     if (is) {
1063         return lxb_html_tree_insertion_mode_in_body_anything_else_closed(tree,
1064                                                                          token);
1065     }
1066 */
1067 
1068     return true;
1069 }
1070 
1071 /*
1072  * "applet", "marquee", "object"
1073  */
1074 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_amo(lxb_html_tree_t * tree,lxb_html_token_t * token)1075 lxb_html_tree_insertion_mode_in_body_amo(lxb_html_tree_t *tree,
1076                                          lxb_html_token_t *token)
1077 {
1078     lxb_html_element_t *element;
1079 
1080     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1081     if (tree->status != LXB_STATUS_OK) {
1082         return lxb_html_tree_process_abort(tree);
1083     }
1084 
1085     element = lxb_html_tree_insert_html_element(tree, token);
1086     if (element == NULL) {
1087         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1088 
1089         return lxb_html_tree_process_abort(tree);
1090     }
1091 
1092     tree->status = lxb_html_tree_active_formatting_push_marker(tree);
1093     if (tree->status != LXB_STATUS_OK) {
1094         return lxb_html_tree_process_abort(tree);
1095     }
1096 
1097     tree->frameset_ok = false;
1098 
1099     return true;
1100 }
1101 
1102 /*
1103  * "applet", "marquee", "object"
1104  */
1105 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_amo_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)1106 lxb_html_tree_insertion_mode_in_body_amo_closed(lxb_html_tree_t *tree,
1107                                                 lxb_html_token_t *token)
1108 {
1109     lxb_dom_node_t *node;
1110 
1111     node = lxb_html_tree_element_in_scope(tree, token->tag_id, LXB_NS_HTML,
1112                                           LXB_HTML_TAG_CATEGORY_SCOPE);
1113     if (node == NULL) {
1114         lxb_html_tree_parse_error(tree, token,
1115                                   LXB_HTML_RULES_ERROR_UNCLTO);
1116         return true;
1117     }
1118 
1119     lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF,
1120                                             LXB_NS__UNDEF);
1121 
1122     node = lxb_html_tree_current_node(tree);
1123 
1124     if (lxb_html_tree_node_is(node, token->tag_id) == false) {
1125         lxb_html_tree_parse_error(tree, token,
1126                                   LXB_HTML_RULES_ERROR_UNELINOPELST);
1127     }
1128 
1129     lxb_html_tree_open_elements_pop_until_tag_id(tree, token->tag_id,
1130                                                  LXB_NS_HTML, true);
1131 
1132     lxb_html_tree_active_formatting_up_to_last_marker(tree);
1133 
1134     return true;
1135 }
1136 
1137 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_table(lxb_html_tree_t * tree,lxb_html_token_t * token)1138 lxb_html_tree_insertion_mode_in_body_table(lxb_html_tree_t *tree,
1139                                            lxb_html_token_t *token)
1140 {
1141     lxb_dom_node_t *node;
1142     lxb_html_element_t *element;
1143 
1144     if (lxb_dom_interface_document(tree->document)->compat_mode
1145         != LXB_DOM_DOCUMENT_CMODE_QUIRKS)
1146     {
1147         node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
1148                                               LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
1149         if (node != NULL) {
1150             lxb_html_tree_close_p_element(tree, token);
1151         }
1152     }
1153 
1154     element = lxb_html_tree_insert_html_element(tree, token);
1155     if (element == NULL) {
1156         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1157 
1158         return lxb_html_tree_process_abort(tree);
1159     }
1160 
1161     tree->frameset_ok = false;
1162     tree->mode = lxb_html_tree_insertion_mode_in_table;
1163 
1164     return true;
1165 }
1166 
1167 /*
1168  * "area", "br", "embed", "img", "keygen", "wbr"
1169  */
1170 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_abeikw(lxb_html_tree_t * tree,lxb_html_token_t * token)1171 lxb_html_tree_insertion_mode_in_body_abeikw(lxb_html_tree_t *tree,
1172                                             lxb_html_token_t *token)
1173 {
1174     lxb_html_element_t *element;
1175 
1176     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1177     if (tree->status != LXB_STATUS_OK) {
1178         return lxb_html_tree_process_abort(tree);
1179     }
1180 
1181     element = lxb_html_tree_insert_html_element(tree, token);
1182     if (element == NULL) {
1183         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1184 
1185         return lxb_html_tree_process_abort(tree);
1186     }
1187 
1188     lxb_html_tree_open_elements_pop(tree);
1189     lxb_html_tree_acknowledge_token_self_closing(tree, token);
1190 
1191     tree->frameset_ok = false;
1192 
1193     return true;
1194 }
1195 
1196 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_br_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)1197 lxb_html_tree_insertion_mode_in_body_br_closed(lxb_html_tree_t *tree,
1198                                                lxb_html_token_t *token)
1199 {
1200     token->type ^= (token->type & LXB_HTML_TOKEN_TYPE_CLOSE);
1201     token->attr_first = NULL;
1202     token->attr_last = NULL;
1203 
1204     return lxb_html_tree_insertion_mode_in_body_abeikw(tree, token);
1205 }
1206 
1207 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_input(lxb_html_tree_t * tree,lxb_html_token_t * token)1208 lxb_html_tree_insertion_mode_in_body_input(lxb_html_tree_t *tree,
1209                                            lxb_html_token_t *token)
1210 {
1211     lxb_dom_attr_t *attr;
1212     lxb_html_element_t *element;
1213 
1214     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1215     if (tree->status != LXB_STATUS_OK) {
1216         return lxb_html_tree_process_abort(tree);
1217     }
1218 
1219     element = lxb_html_tree_insert_html_element(tree, token);
1220     if (element == NULL) {
1221         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1222 
1223         return lxb_html_tree_process_abort(tree);
1224     }
1225 
1226     lxb_html_tree_open_elements_pop(tree);
1227     lxb_html_tree_acknowledge_token_self_closing(tree, token);
1228 
1229     attr = lxb_dom_element_attr_is_exist(lxb_dom_interface_element(element),
1230                                          (lxb_char_t *) "type", 4);
1231     if (attr != NULL) {
1232         if (attr->value == NULL || attr->value->length != 6
1233             || lexbor_str_data_cmp(attr->value->data, (lxb_char_t *) "hidden") == false)
1234         {
1235             tree->frameset_ok = false;
1236         }
1237     }
1238     else {
1239         tree->frameset_ok = false;
1240     }
1241 
1242     return true;
1243 }
1244 
1245 /*
1246  * "param", "source", "track"
1247  */
1248 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_pst(lxb_html_tree_t * tree,lxb_html_token_t * token)1249 lxb_html_tree_insertion_mode_in_body_pst(lxb_html_tree_t *tree,
1250                                          lxb_html_token_t *token)
1251 {
1252     lxb_html_element_t *element;
1253 
1254     element = lxb_html_tree_insert_html_element(tree, token);
1255     if (element == NULL) {
1256         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1257 
1258         return lxb_html_tree_process_abort(tree);
1259     }
1260 
1261     lxb_html_tree_open_elements_pop(tree);
1262     lxb_html_tree_acknowledge_token_self_closing(tree, token);
1263 
1264     return true;
1265 }
1266 
1267 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_hr(lxb_html_tree_t * tree,lxb_html_token_t * token)1268 lxb_html_tree_insertion_mode_in_body_hr(lxb_html_tree_t *tree,
1269                                         lxb_html_token_t *token)
1270 {
1271     lxb_dom_node_t *node;
1272     lxb_html_element_t *element;
1273 
1274     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
1275                                           LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
1276     if (node != NULL) {
1277         lxb_html_tree_close_p_element(tree, token);
1278     }
1279 
1280     element = lxb_html_tree_insert_html_element(tree, token);
1281     if (element == NULL) {
1282         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1283 
1284         return lxb_html_tree_process_abort(tree);
1285     }
1286 
1287     lxb_html_tree_open_elements_pop(tree);
1288     lxb_html_tree_acknowledge_token_self_closing(tree, token);
1289 
1290     tree->frameset_ok = false;
1291 
1292     return true;
1293 }
1294 
1295 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_image(lxb_html_tree_t * tree,lxb_html_token_t * token)1296 lxb_html_tree_insertion_mode_in_body_image(lxb_html_tree_t *tree,
1297                                            lxb_html_token_t *token)
1298 {
1299     lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO);
1300 
1301     token->tag_id = LXB_TAG_IMG;
1302 
1303     return false;
1304 }
1305 
1306 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_textarea(lxb_html_tree_t * tree,lxb_html_token_t * token)1307 lxb_html_tree_insertion_mode_in_body_textarea(lxb_html_tree_t *tree,
1308                                               lxb_html_token_t *token)
1309 {
1310     lxb_html_element_t *element;
1311 
1312     element = lxb_html_tree_insert_html_element(tree, token);
1313     if (element == NULL) {
1314         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1315 
1316         return lxb_html_tree_process_abort(tree);
1317     }
1318 
1319     lxb_html_tokenizer_tmp_tag_id_set(tree->tkz_ref, LXB_TAG_TEXTAREA);
1320     lxb_html_tokenizer_state_set(tree->tkz_ref,
1321                                  lxb_html_tokenizer_state_rcdata_before);
1322 
1323     tree->frameset_ok = false;
1324 
1325     tree->original_mode = tree->mode;
1326     tree->mode = lxb_html_tree_insertion_mode_in_body_skip_new_line_textarea;
1327 
1328     return true;
1329 }
1330 
1331 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_xmp(lxb_html_tree_t * tree,lxb_html_token_t * token)1332 lxb_html_tree_insertion_mode_in_body_xmp(lxb_html_tree_t *tree,
1333                                          lxb_html_token_t *token)
1334 {
1335     lxb_dom_node_t *node;
1336     lxb_html_element_t *element;
1337 
1338     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_P, LXB_NS_HTML,
1339                                           LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON);
1340     if (node != NULL) {
1341         lxb_html_tree_close_p_element(tree, token);
1342     }
1343 
1344     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1345     if (tree->status != LXB_STATUS_OK) {
1346         return lxb_html_tree_process_abort(tree);
1347     }
1348 
1349     tree->frameset_ok = false;
1350 
1351     element = lxb_html_tree_generic_rawtext_parsing(tree, token);
1352     if (element == NULL) {
1353         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1354 
1355         return lxb_html_tree_process_abort(tree);
1356     }
1357 
1358     return true;
1359 }
1360 
1361 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_iframe(lxb_html_tree_t * tree,lxb_html_token_t * token)1362 lxb_html_tree_insertion_mode_in_body_iframe(lxb_html_tree_t *tree,
1363                                             lxb_html_token_t *token)
1364 {
1365     lxb_html_element_t *element;
1366 
1367     tree->frameset_ok = false;
1368 
1369     element = lxb_html_tree_generic_rawtext_parsing(tree, token);
1370     if (element == NULL) {
1371         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1372 
1373         return lxb_html_tree_process_abort(tree);
1374     }
1375 
1376     return true;
1377 }
1378 
1379 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_noembed(lxb_html_tree_t * tree,lxb_html_token_t * token)1380 lxb_html_tree_insertion_mode_in_body_noembed(lxb_html_tree_t *tree,
1381                                              lxb_html_token_t *token)
1382 {
1383     lxb_html_element_t *element;
1384 
1385     element = lxb_html_tree_generic_rawtext_parsing(tree, token);
1386     if (element == NULL) {
1387         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1388 
1389         return lxb_html_tree_process_abort(tree);
1390     }
1391 
1392     return true;
1393 }
1394 
1395 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_select(lxb_html_tree_t * tree,lxb_html_token_t * token)1396 lxb_html_tree_insertion_mode_in_body_select(lxb_html_tree_t *tree,
1397                                             lxb_html_token_t *token)
1398 {
1399     lxb_html_element_t *element;
1400 
1401     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1402     if (tree->status != LXB_STATUS_OK) {
1403         return lxb_html_tree_process_abort(tree);
1404     }
1405 
1406     element = lxb_html_tree_insert_html_element(tree, token);
1407     if (element == NULL) {
1408         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1409 
1410         return lxb_html_tree_process_abort(tree);
1411     }
1412 
1413     tree->frameset_ok = false;
1414 
1415     if (tree->mode == lxb_html_tree_insertion_mode_in_table
1416         || tree->mode == lxb_html_tree_insertion_mode_in_caption
1417         || tree->mode == lxb_html_tree_insertion_mode_in_table_body
1418         || tree->mode == lxb_html_tree_insertion_mode_in_row
1419         || tree->mode == lxb_html_tree_insertion_mode_in_cell)
1420     {
1421         tree->mode = lxb_html_tree_insertion_mode_in_select_in_table;
1422     }
1423     else {
1424         tree->mode = lxb_html_tree_insertion_mode_in_select;
1425     }
1426 
1427     return true;
1428 }
1429 
1430 /*
1431  * "optgroup", "option"
1432  */
1433 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_optopt(lxb_html_tree_t * tree,lxb_html_token_t * token)1434 lxb_html_tree_insertion_mode_in_body_optopt(lxb_html_tree_t *tree,
1435                                             lxb_html_token_t *token)
1436 {
1437     lxb_dom_node_t *node;
1438     lxb_html_element_t *element;
1439 
1440     node = lxb_html_tree_current_node(tree);
1441     if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) {
1442         lxb_html_tree_open_elements_pop(tree);
1443     }
1444 
1445     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1446     if (tree->status != LXB_STATUS_OK) {
1447         return lxb_html_tree_process_abort(tree);
1448     }
1449 
1450     element = lxb_html_tree_insert_html_element(tree, token);
1451     if (element == NULL) {
1452         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1453 
1454         return lxb_html_tree_process_abort(tree);
1455     }
1456 
1457     return true;
1458 }
1459 
1460 /*
1461  * "rb", "rtc"
1462  */
1463 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_rbrtc(lxb_html_tree_t * tree,lxb_html_token_t * token)1464 lxb_html_tree_insertion_mode_in_body_rbrtc(lxb_html_tree_t *tree,
1465                                            lxb_html_token_t *token)
1466 {
1467     lxb_dom_node_t *node;
1468     lxb_html_element_t *element;
1469 
1470     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_RUBY, LXB_NS_HTML,
1471                                           LXB_HTML_TAG_CATEGORY_SCOPE);
1472     if (node != NULL) {
1473         lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF,
1474                                                 LXB_NS__UNDEF);
1475     }
1476 
1477     node = lxb_html_tree_current_node(tree);
1478     if (lxb_html_tree_node_is(node, LXB_TAG_RUBY) == false) {
1479         lxb_html_tree_parse_error(tree, token,
1480                                   LXB_HTML_RULES_ERROR_MIELINOPELST);
1481     }
1482 
1483     element = lxb_html_tree_insert_html_element(tree, token);
1484     if (element == NULL) {
1485         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1486 
1487         return lxb_html_tree_process_abort(tree);
1488     }
1489 
1490     return true;
1491 }
1492 
1493 /*
1494  * "rp", "rt"
1495  */
1496 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_rprt(lxb_html_tree_t * tree,lxb_html_token_t * token)1497 lxb_html_tree_insertion_mode_in_body_rprt(lxb_html_tree_t *tree,
1498                                           lxb_html_token_t *token)
1499 {
1500     lxb_dom_node_t *node;
1501     lxb_html_element_t *element;
1502 
1503     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_RUBY, LXB_NS_HTML,
1504                                           LXB_HTML_TAG_CATEGORY_SCOPE);
1505     if (node != NULL) {
1506         lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG_RTC,
1507                                                 LXB_NS_HTML);
1508     }
1509 
1510     node = lxb_html_tree_current_node(tree);
1511 
1512     if (lxb_html_tree_node_is(node, LXB_TAG_RTC) == false
1513         || lxb_html_tree_node_is(node, LXB_TAG_RUBY) == false)
1514     {
1515         lxb_html_tree_parse_error(tree, token,
1516                                   LXB_HTML_RULES_ERROR_MIELINOPELST);
1517     }
1518 
1519     element = lxb_html_tree_insert_html_element(tree, token);
1520     if (element == NULL) {
1521         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1522 
1523         return lxb_html_tree_process_abort(tree);
1524     }
1525 
1526     return true;
1527 }
1528 
1529 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_math(lxb_html_tree_t * tree,lxb_html_token_t * token)1530 lxb_html_tree_insertion_mode_in_body_math(lxb_html_tree_t *tree,
1531                                           lxb_html_token_t *token)
1532 {
1533     lxb_html_element_t *element;
1534 
1535     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1536     if (tree->status != LXB_STATUS_OK) {
1537         return lxb_html_tree_process_abort(tree);
1538     }
1539 
1540     tree->before_append_attr = lxb_html_tree_adjust_attributes_mathml;
1541 
1542     element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_MATH);
1543     if (element == NULL) {
1544         tree->before_append_attr = NULL;
1545         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1546 
1547         return lxb_html_tree_process_abort(tree);
1548     }
1549 
1550     tree->before_append_attr = NULL;
1551 
1552     if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE_SELF) {
1553         lxb_html_tree_open_elements_pop(tree);
1554         lxb_html_tree_acknowledge_token_self_closing(tree, token);
1555     }
1556 
1557     return true;
1558 }
1559 
1560 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_svg(lxb_html_tree_t * tree,lxb_html_token_t * token)1561 lxb_html_tree_insertion_mode_in_body_svg(lxb_html_tree_t *tree,
1562                                          lxb_html_token_t *token)
1563 {
1564     lxb_html_element_t *element;
1565 
1566     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1567     if (tree->status != LXB_STATUS_OK) {
1568         return lxb_html_tree_process_abort(tree);
1569     }
1570 
1571     tree->before_append_attr = lxb_html_tree_adjust_attributes_svg;
1572 
1573     element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_SVG);
1574     if (element == NULL) {
1575         tree->before_append_attr = NULL;
1576         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1577 
1578         return lxb_html_tree_process_abort(tree);
1579     }
1580 
1581     tree->before_append_attr = NULL;
1582 
1583     if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE_SELF) {
1584         lxb_html_tree_open_elements_pop(tree);
1585         lxb_html_tree_acknowledge_token_self_closing(tree, token);
1586     }
1587 
1588     return true;
1589 }
1590 
1591 /*
1592  * "caption", "col", "colgroup", "frame", "head", "tbody", "td", "tfoot", "th",
1593  * "thead", "tr"
1594  */
1595 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_cfht(lxb_html_tree_t * tree,lxb_html_token_t * token)1596 lxb_html_tree_insertion_mode_in_body_cfht(lxb_html_tree_t *tree,
1597                                           lxb_html_token_t *token)
1598 {
1599     lxb_html_tree_parse_error(tree, token,
1600                               LXB_HTML_RULES_ERROR_UNTO);
1601 
1602     return true;
1603 }
1604 
1605 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_anything_else(lxb_html_tree_t * tree,lxb_html_token_t * token)1606 lxb_html_tree_insertion_mode_in_body_anything_else(lxb_html_tree_t *tree,
1607                                                    lxb_html_token_t *token)
1608 {
1609     lxb_html_element_t *element;
1610 
1611     tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree);
1612     if (tree->status != LXB_STATUS_OK) {
1613         return lxb_html_tree_process_abort(tree);
1614     }
1615 
1616     element = lxb_html_tree_insert_html_element(tree, token);
1617     if (element == NULL) {
1618         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1619 
1620         return lxb_html_tree_process_abort(tree);
1621     }
1622 
1623     return true;
1624 }
1625 
1626 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_noscript(lxb_html_tree_t * tree,lxb_html_token_t * token)1627 lxb_html_tree_insertion_mode_in_body_noscript(lxb_html_tree_t *tree,
1628                                               lxb_html_token_t *token)
1629 {
1630     if (tree->document->dom_document.scripting == false) {
1631         return lxb_html_tree_insertion_mode_in_body_anything_else(tree, token);
1632     }
1633 
1634     lxb_html_element_t *element;
1635 
1636     element = lxb_html_tree_generic_rawtext_parsing(tree, token);
1637     if (element == NULL) {
1638         tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
1639 
1640         return lxb_html_tree_process_abort(tree);
1641     }
1642 
1643     return true;
1644 }
1645 
1646 lxb_inline bool
lxb_html_tree_insertion_mode_in_body_anything_else_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)1647 lxb_html_tree_insertion_mode_in_body_anything_else_closed(lxb_html_tree_t *tree,
1648                                                           lxb_html_token_t *token)
1649 {
1650     bool is;
1651     lxb_dom_node_t **list = (lxb_dom_node_t **) tree->open_elements->list;
1652     size_t len = tree->open_elements->length;
1653 
1654     while (len != 0) {
1655         len--;
1656 
1657         if (lxb_html_tree_node_is(list[len], token->tag_id)) {
1658             lxb_html_tree_generate_implied_end_tags(tree, token->tag_id,
1659                                                     LXB_NS_HTML);
1660 
1661             if (list[len] != lxb_html_tree_current_node(tree)) {
1662                 lxb_html_tree_parse_error(tree, token,
1663                                           LXB_HTML_RULES_ERROR_UNELINOPELST);
1664             }
1665 
1666             lxb_html_tree_open_elements_pop_until_node(tree, list[len], true);
1667 
1668             return true;
1669         }
1670 
1671         is = lxb_html_tag_is_category(list[len]->local_name, list[len]->ns,
1672                                       LXB_HTML_TAG_CATEGORY_SPECIAL);
1673         if (is) {
1674             lxb_html_tree_parse_error(tree, token,
1675                                       LXB_HTML_RULES_ERROR_UNCLTO);
1676             return true;
1677         }
1678     }
1679 
1680     return true;
1681 }
1682 
1683 
1684 bool
lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t * tree,lxb_html_token_t * token)1685 lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree,
1686                                      lxb_html_token_t *token)
1687 {
1688     if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) {
1689         switch (token->tag_id) {
1690             case LXB_TAG_TEMPLATE:
1691                 return lxb_html_tree_insertion_mode_in_body_blmnst(tree, token);
1692 
1693             case LXB_TAG_BODY:
1694                 return lxb_html_tree_insertion_mode_in_body_body_closed(tree,
1695                                                                         token);
1696             case LXB_TAG_HTML:
1697                 return lxb_html_tree_insertion_mode_in_body_html_closed(tree,
1698                                                                         token);
1699             case LXB_TAG_ADDRESS:
1700             case LXB_TAG_ARTICLE:
1701             case LXB_TAG_ASIDE:
1702             case LXB_TAG_BLOCKQUOTE:
1703             case LXB_TAG_BUTTON:
1704             case LXB_TAG_CENTER:
1705             case LXB_TAG_DETAILS:
1706             case LXB_TAG_DIALOG:
1707             case LXB_TAG_DIR:
1708             case LXB_TAG_DIV:
1709             case LXB_TAG_DL:
1710             case LXB_TAG_FIELDSET:
1711             case LXB_TAG_FIGCAPTION:
1712             case LXB_TAG_FIGURE:
1713             case LXB_TAG_FOOTER:
1714             case LXB_TAG_HEADER:
1715             case LXB_TAG_HGROUP:
1716             case LXB_TAG_LISTING:
1717             case LXB_TAG_MAIN:
1718             case LXB_TAG_MENU:
1719             case LXB_TAG_NAV:
1720             case LXB_TAG_OL:
1721             case LXB_TAG_PRE:
1722             case LXB_TAG_SECTION:
1723             case LXB_TAG_SUMMARY:
1724             case LXB_TAG_UL:
1725                 return lxb_html_tree_insertion_mode_in_body_abcdfhlmnopsu_closed(tree,
1726                                                                                  token);
1727             case LXB_TAG_FORM:
1728                 return lxb_html_tree_insertion_mode_in_body_form_closed(tree,
1729                                                                         token);
1730             case LXB_TAG_P:
1731                 return lxb_html_tree_insertion_mode_in_body_p_closed(tree,
1732                                                                      token);
1733             case LXB_TAG_LI:
1734                 return lxb_html_tree_insertion_mode_in_body_li_closed(tree,
1735                                                                       token);
1736             case LXB_TAG_DD:
1737             case LXB_TAG_DT:
1738                 return lxb_html_tree_insertion_mode_in_body_dd_dt_closed(tree,
1739                                                                          token);
1740             case LXB_TAG_H1:
1741             case LXB_TAG_H2:
1742             case LXB_TAG_H3:
1743             case LXB_TAG_H4:
1744             case LXB_TAG_H5:
1745             case LXB_TAG_H6:
1746                 return lxb_html_tree_insertion_mode_in_body_h123456_closed(tree,
1747                                                                            token);
1748             case LXB_TAG_A:
1749             case LXB_TAG_B:
1750             case LXB_TAG_BIG:
1751             case LXB_TAG_CODE:
1752             case LXB_TAG_EM:
1753             case LXB_TAG_FONT:
1754             case LXB_TAG_I:
1755             case LXB_TAG_NOBR:
1756             case LXB_TAG_S:
1757             case LXB_TAG_SMALL:
1758             case LXB_TAG_STRIKE:
1759             case LXB_TAG_STRONG:
1760             case LXB_TAG_TT:
1761             case LXB_TAG_U:
1762                 return lxb_html_tree_insertion_mode_in_body_abcefinstu_closed(tree,
1763                                                                               token);
1764             case LXB_TAG_APPLET:
1765             case LXB_TAG_MARQUEE:
1766             case LXB_TAG_OBJECT:
1767                 return lxb_html_tree_insertion_mode_in_body_amo_closed(tree,
1768                                                                        token);
1769             case LXB_TAG_BR:
1770                 return lxb_html_tree_insertion_mode_in_body_br_closed(tree,
1771                                                                       token);
1772 
1773             default:
1774                 return lxb_html_tree_insertion_mode_in_body_anything_else_closed(tree,
1775                                                                                  token);
1776         }
1777     }
1778 
1779     switch (token->tag_id) {
1780         case LXB_TAG__TEXT:
1781             return lxb_html_tree_insertion_mode_in_body_text(tree, token);
1782 
1783         case LXB_TAG__EM_COMMENT:
1784             return lxb_html_tree_insertion_mode_in_body_comment(tree, token);
1785 
1786         case LXB_TAG__EM_DOCTYPE:
1787             return lxb_html_tree_insertion_mode_in_body_doctype(tree, token);
1788 
1789         case LXB_TAG_HTML:
1790             return lxb_html_tree_insertion_mode_in_body_html(tree, token);
1791 
1792         case LXB_TAG_BASE:
1793         case LXB_TAG_BASEFONT:
1794         case LXB_TAG_BGSOUND:
1795         case LXB_TAG_LINK:
1796         case LXB_TAG_META:
1797         case LXB_TAG_NOFRAMES:
1798         case LXB_TAG_SCRIPT:
1799         case LXB_TAG_STYLE:
1800         case LXB_TAG_TEMPLATE:
1801         case LXB_TAG_TITLE:
1802             return lxb_html_tree_insertion_mode_in_body_blmnst(tree, token);
1803 
1804         case LXB_TAG_BODY:
1805             return lxb_html_tree_insertion_mode_in_body_body(tree, token);
1806 
1807         case LXB_TAG_FRAMESET:
1808             return lxb_html_tree_insertion_mode_in_body_frameset(tree, token);
1809 
1810         case LXB_TAG__END_OF_FILE:
1811             return lxb_html_tree_insertion_mode_in_body_eof(tree, token);
1812 
1813         case LXB_TAG_ADDRESS:
1814         case LXB_TAG_ARTICLE:
1815         case LXB_TAG_ASIDE:
1816         case LXB_TAG_BLOCKQUOTE:
1817         case LXB_TAG_CENTER:
1818         case LXB_TAG_DETAILS:
1819         case LXB_TAG_DIALOG:
1820         case LXB_TAG_DIR:
1821         case LXB_TAG_DIV:
1822         case LXB_TAG_DL:
1823         case LXB_TAG_FIELDSET:
1824         case LXB_TAG_FIGCAPTION:
1825         case LXB_TAG_FIGURE:
1826         case LXB_TAG_FOOTER:
1827         case LXB_TAG_HEADER:
1828         case LXB_TAG_HGROUP:
1829         case LXB_TAG_MAIN:
1830         case LXB_TAG_MENU:
1831         case LXB_TAG_NAV:
1832         case LXB_TAG_OL:
1833         case LXB_TAG_P:
1834         case LXB_TAG_SECTION:
1835         case LXB_TAG_SUMMARY:
1836         case LXB_TAG_UL:
1837             return lxb_html_tree_insertion_mode_in_body_abcdfhmnopsu(tree,
1838                                                                      token);
1839 
1840         case LXB_TAG_H1:
1841         case LXB_TAG_H2:
1842         case LXB_TAG_H3:
1843         case LXB_TAG_H4:
1844         case LXB_TAG_H5:
1845         case LXB_TAG_H6:
1846             return lxb_html_tree_insertion_mode_in_body_h123456(tree, token);
1847 
1848         case LXB_TAG_PRE:
1849         case LXB_TAG_LISTING:
1850             return lxb_html_tree_insertion_mode_in_body_pre_listing(tree,
1851                                                                     token);
1852 
1853         case LXB_TAG_FORM:
1854             return lxb_html_tree_insertion_mode_in_body_form(tree, token);
1855 
1856         case LXB_TAG_LI:
1857             return lxb_html_tree_insertion_mode_in_body_li(tree, token);
1858 
1859         case LXB_TAG_DD:
1860         case LXB_TAG_DT:
1861             return lxb_html_tree_insertion_mode_in_body_dd_dt(tree, token);
1862 
1863         case LXB_TAG_PLAINTEXT:
1864             return lxb_html_tree_insertion_mode_in_body_plaintext(tree, token);
1865 
1866         case LXB_TAG_BUTTON:
1867             return lxb_html_tree_insertion_mode_in_body_button(tree, token);
1868 
1869         case LXB_TAG_A:
1870             return lxb_html_tree_insertion_mode_in_body_a(tree, token);
1871 
1872         case LXB_TAG_B:
1873         case LXB_TAG_BIG:
1874         case LXB_TAG_CODE:
1875         case LXB_TAG_EM:
1876         case LXB_TAG_FONT:
1877         case LXB_TAG_I:
1878         case LXB_TAG_S:
1879         case LXB_TAG_SMALL:
1880         case LXB_TAG_STRIKE:
1881         case LXB_TAG_STRONG:
1882         case LXB_TAG_TT:
1883         case LXB_TAG_U:
1884             return lxb_html_tree_insertion_mode_in_body_bcefistu(tree, token);
1885 
1886         case LXB_TAG_NOBR:
1887             return lxb_html_tree_insertion_mode_in_body_nobr(tree, token);
1888 
1889         case LXB_TAG_APPLET:
1890         case LXB_TAG_MARQUEE:
1891         case LXB_TAG_OBJECT:
1892             return lxb_html_tree_insertion_mode_in_body_amo(tree, token);
1893 
1894         case LXB_TAG_TABLE:
1895             return lxb_html_tree_insertion_mode_in_body_table(tree, token);
1896 
1897         case LXB_TAG_AREA:
1898         case LXB_TAG_BR:
1899         case LXB_TAG_EMBED:
1900         case LXB_TAG_IMG:
1901         case LXB_TAG_KEYGEN:
1902         case LXB_TAG_WBR:
1903             return lxb_html_tree_insertion_mode_in_body_abeikw(tree, token);
1904 
1905         case LXB_TAG_INPUT:
1906             return lxb_html_tree_insertion_mode_in_body_input(tree, token);
1907 
1908         case LXB_TAG_PARAM:
1909         case LXB_TAG_SOURCE:
1910         case LXB_TAG_TRACK:
1911             return lxb_html_tree_insertion_mode_in_body_pst(tree, token);
1912 
1913         case LXB_TAG_HR:
1914             return lxb_html_tree_insertion_mode_in_body_hr(tree, token);
1915 
1916         case LXB_TAG_IMAGE:
1917             return lxb_html_tree_insertion_mode_in_body_image(tree, token);
1918 
1919         case LXB_TAG_TEXTAREA:
1920             return lxb_html_tree_insertion_mode_in_body_textarea(tree, token);
1921 
1922         case LXB_TAG_XMP:
1923             return lxb_html_tree_insertion_mode_in_body_xmp(tree, token);
1924 
1925         case LXB_TAG_IFRAME:
1926             return lxb_html_tree_insertion_mode_in_body_iframe(tree, token);
1927 
1928         case LXB_TAG_NOEMBED:
1929             return lxb_html_tree_insertion_mode_in_body_noembed(tree, token);
1930 
1931         case LXB_TAG_NOSCRIPT:
1932             return lxb_html_tree_insertion_mode_in_body_noscript(tree, token);
1933 
1934         case LXB_TAG_SELECT:
1935             return lxb_html_tree_insertion_mode_in_body_select(tree, token);
1936 
1937         case LXB_TAG_OPTGROUP:
1938         case LXB_TAG_OPTION:
1939             return lxb_html_tree_insertion_mode_in_body_optopt(tree, token);
1940 
1941         case LXB_TAG_RB:
1942         case LXB_TAG_RTC:
1943             return lxb_html_tree_insertion_mode_in_body_rbrtc(tree, token);
1944 
1945         case LXB_TAG_RP:
1946         case LXB_TAG_RT:
1947             return lxb_html_tree_insertion_mode_in_body_rprt(tree, token);
1948 
1949         case LXB_TAG_MATH:
1950             return lxb_html_tree_insertion_mode_in_body_math(tree, token);
1951 
1952         case LXB_TAG_SVG:
1953             return lxb_html_tree_insertion_mode_in_body_svg(tree, token);
1954 
1955         case LXB_TAG_CAPTION:
1956         case LXB_TAG_COL:
1957         case LXB_TAG_COLGROUP:
1958         case LXB_TAG_FRAME:
1959         case LXB_TAG_HEAD:
1960         case LXB_TAG_TBODY:
1961         case LXB_TAG_TD:
1962         case LXB_TAG_TFOOT:
1963         case LXB_TAG_TH:
1964         case LXB_TAG_THEAD:
1965         case LXB_TAG_TR:
1966             return lxb_html_tree_insertion_mode_in_body_cfht(tree, token);
1967 
1968         default:
1969             return lxb_html_tree_insertion_mode_in_body_anything_else(tree,
1970                                                                       token);
1971     }
1972 }
1973