File Coverage

third_party/modest/source/myhtml/rules.c
Criterion Covered Total %
statement 224 1411 15.8
branch 77 624 12.3
condition n/a
subroutine n/a
pod n/a
total 301 2035 14.7


line stmt bran cond sub pod time code
1             /*
2             Copyright (C) 2015-2017 Alexander Borisov
3            
4             This library is free software; you can redistribute it and/or
5             modify it under the terms of the GNU Lesser General Public
6             License as published by the Free Software Foundation; either
7             version 2.1 of the License, or (at your option) any later version.
8            
9             This library is distributed in the hope that it will be useful,
10             but WITHOUT ANY WARRANTY; without even the implied warranty of
11             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12             Lesser General Public License for more details.
13            
14             You should have received a copy of the GNU Lesser General Public
15             License along with this library; if not, write to the Free Software
16             Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17            
18             Author: lex.borisov@gmail.com (Alexander Borisov)
19             */
20              
21             #include "myhtml/rules.h"
22              
23 45           void myhtml_insertion_fix_emit_for_text_begin_ws(myhtml_token_t* token, myhtml_token_node_t* node)
24             {
25 45           myhtml_token_node_wait_for_done(token, node);
26 45           mycore_string_crop_whitespace_from_begin(&node->str);
27 45           }
28              
29 30           myhtml_token_node_t * myhtml_insertion_fix_split_for_text_begin_ws(myhtml_tree_t* tree, myhtml_token_node_t* token)
30             {
31 30           myhtml_token_node_wait_for_done(tree->token, token);
32 30           size_t len = mycore_string_whitespace_from_begin(&token->str);
33            
34 30 50         if(len == 0)
35 30           return NULL;
36            
37             // create new ws token and insert
38 0           myhtml_token_node_t* new_token = myhtml_token_node_create(tree->token, tree->mcasync_rules_token_id);
39            
40 0 0         if(new_token == NULL)
41 0           return NULL;
42            
43 0           mycore_string_init(tree->mchar, tree->mchar_node_id, &new_token->str, (len + 2));
44            
45 0           mycore_string_append(&new_token->str, token->str.data, len);
46            
47 0           new_token->type |= MyHTML_TOKEN_TYPE_DONE;
48            
49             // and cut ws for original
50 0           token->str.data = mchar_async_crop_first_chars_without_cache(token->str.data, len);
51 0           token->str.length -= len;
52            
53 0           return new_token;
54             }
55              
56 0           void myhtml_insertion_fix_for_null_char_drop_all(myhtml_tree_t* tree, myhtml_token_node_t* token)
57             {
58 0           myhtml_token_node_wait_for_done(tree->token, token);
59            
60 0           mycore_string_t *str = &token->str;
61 0           size_t len = str->length;
62 0           size_t offset = 0;
63            
64 0 0         for (size_t i = 0; i < len; ++i)
65             {
66 0 0         if (str->data[i] == '\0')
67             {
68 0           size_t next_non_null = i;
69 0 0         while ((next_non_null < len) && str->data[next_non_null] == '\0') {++next_non_null;}
    0          
70            
71 0           str->length = str->length - (next_non_null - i);
72            
73 0           size_t next_null = next_non_null;
74 0 0         while ((next_null < len) && str->data[next_null] != '\0') {++next_null;}
    0          
75            
76 0           memmove(&str->data[(i - offset)], &str->data[next_non_null], (next_null - next_non_null));
77            
78 0           i = next_null - 1;
79            
80 0           offset++;
81             }
82             }
83 0           }
84              
85 172           bool myhtml_insertion_mode_initial(myhtml_tree_t* tree, myhtml_token_node_t* token)
86             {
87 172           switch (token->tag_id)
88             {
89             case MyHTML_TAG__TEXT:
90             {
91 59 100         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE) {
92             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:INFO */
93 44           return false;
94             }
95            
96 15           myhtml_insertion_fix_emit_for_text_begin_ws(tree->token, token);
97            
98             // default, other token
99 15           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
100 15           tree->insert_mode = MyHTML_INSERTION_MODE_BEFORE_HTML;
101 15           break;
102             }
103            
104             case MyHTML_TAG__COMMENT:
105             {
106 0           myhtml_tree_node_insert_comment(tree, token, tree->document);
107 0           return false;
108             }
109            
110             case MyHTML_TAG__DOCTYPE:
111             {
112 36           myhtml_token_node_wait_for_done(tree->token, token);
113            
114 36           myhtml_token_release_and_check_doctype_attributes(tree->token, token, &tree->doctype);
115            
116 36 50         if((tree->parse_flags & MyHTML_TREE_PARSE_FLAGS_WITHOUT_DOCTYPE_IN_TREE) == 0)
117 36           myhtml_tree_node_insert_doctype(tree, token);
118            
119             // fix for tokenizer
120 36 100         if(tree->doctype.is_html == false &&
    100          
121 1 50         (tree->doctype.attr_public == NULL ||
122 1           tree->doctype.attr_system == NULL))
123             {
124 4           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
125             }
126            
127 36           tree->insert_mode = MyHTML_INSERTION_MODE_BEFORE_HTML;
128 36           return false;
129             }
130            
131             default:
132 77           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
133 77           tree->insert_mode = MyHTML_INSERTION_MODE_BEFORE_HTML;
134 77           break;
135             }
136            
137 92           return true;
138             }
139              
140 130           bool myhtml_insertion_mode_before_html(myhtml_tree_t* tree, myhtml_token_node_t* token)
141             {
142 130 50         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
143             {
144 0 0         switch (token->tag_id) {
145             case MyHTML_TAG_BR:
146             case MyHTML_TAG_HTML:
147             case MyHTML_TAG_HEAD:
148             case MyHTML_TAG_BODY:
149             {
150 0           myhtml_tree_node_insert_root(tree, NULL, MyHTML_NAMESPACE_HTML);
151            
152             /* %EXTERNAL% VALIDATOR:RULES TAG STATUS:ELEMENT_MISSING_NEED LEVEL:INFO TAG_ID:MyHTML_TAG_HTML NS:MyHTML_NAMESPACE_HTML */
153            
154 0           tree->insert_mode = MyHTML_INSERTION_MODE_BEFORE_HEAD;
155 0           return true;
156             }
157            
158             default: {
159             // parse error
160             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:WARNING */
161 0           break;
162             }
163             }
164             }
165             else {
166 130           switch (token->tag_id)
167             {
168             case MyHTML_TAG__DOCTYPE: {
169             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:WARNING */
170 0           break;
171             }
172            
173             case MyHTML_TAG__COMMENT:
174             {
175 0           myhtml_tree_node_insert_comment(tree, token, tree->document);
176 0           break;
177             }
178            
179             case MyHTML_TAG__TEXT:
180             {
181 17 100         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE) {
182             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:INFO */
183 2           break;
184             }
185            
186 15           myhtml_insertion_fix_emit_for_text_begin_ws(tree->token, token);
187            
188             // default, other token
189 15           myhtml_tree_node_insert_root(tree, NULL, MyHTML_NAMESPACE_HTML);
190 15           tree->insert_mode = MyHTML_INSERTION_MODE_BEFORE_HEAD;
191 15           return true;
192             }
193            
194             case MyHTML_TAG_HTML:
195             {
196 0           myhtml_tree_node_insert_root(tree, token, MyHTML_NAMESPACE_HTML);
197 0           tree->insert_mode = MyHTML_INSERTION_MODE_BEFORE_HEAD;
198 0           break;
199             }
200            
201             default:
202             {
203 113           myhtml_tree_node_insert_root(tree, NULL, MyHTML_NAMESPACE_HTML);
204             /* %EXTERNAL% VALIDATOR:RULES TAG STATUS:ELEMENT_MISSING_NEED LEVEL:INFO TAG_ID:MyHTML_TAG_HTML NS:MyHTML_NAMESPACE_HTML */
205            
206 113           tree->insert_mode = MyHTML_INSERTION_MODE_BEFORE_HEAD;
207 113           return true;
208             }
209             }
210             }
211            
212 2           return false;
213             }
214              
215 128           bool myhtml_insertion_mode_before_head(myhtml_tree_t* tree, myhtml_token_node_t* token)
216             {
217 128 50         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
218             {
219 0 0         switch (token->tag_id) {
220             case MyHTML_TAG_BR:
221             case MyHTML_TAG_HTML:
222             case MyHTML_TAG_HEAD:
223             case MyHTML_TAG_BODY:
224             {
225 0           tree->node_head = myhtml_tree_node_insert(tree, MyHTML_TAG_HEAD, MyHTML_NAMESPACE_HTML);
226             /* %EXTERNAL% VALIDATOR:RULES TAG STATUS:ELEMENT_MISSING_NEED LEVEL:INFO TAG_ID:MyHTML_TAG_HEAD NS:MyHTML_NAMESPACE_HTML */
227            
228 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD;
229 0           return true;
230             }
231            
232             default: {
233             // parse error
234             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
235 0           break;
236             }
237             }
238             }
239             else {
240 128           switch (token->tag_id)
241             {
242             case MyHTML_TAG__TEXT:
243             {
244 15 50         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE) {
245             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:INFO */
246 0           break;
247             }
248            
249 15           myhtml_insertion_fix_emit_for_text_begin_ws(tree->token, token);
250            
251             // default, other token
252 15           tree->node_head = myhtml_tree_node_insert(tree, MyHTML_TAG_HEAD, MyHTML_NAMESPACE_HTML);
253 15           tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD;
254 15           return true;
255             }
256            
257             case MyHTML_TAG__COMMENT:
258             {
259 0           myhtml_tree_node_insert_comment(tree, token, 0);
260 0           break;
261             }
262            
263             case MyHTML_TAG__DOCTYPE: {
264             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
265 0           break;
266             }
267            
268             case MyHTML_TAG_HTML:
269             {
270 0           return myhtml_insertion_mode_in_body(tree, token);
271             }
272            
273             case MyHTML_TAG_HEAD:
274             {
275 0           tree->node_head = myhtml_tree_node_insert_html_element(tree, token);
276 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD;
277 0           break;
278             }
279            
280             default:
281             {
282 113           tree->node_head = myhtml_tree_node_insert(tree, MyHTML_TAG_HEAD, MyHTML_NAMESPACE_HTML);
283             /* %EXTERNAL% VALIDATOR:RULES TAG STATUS:ELEMENT_MISSING_NEED LEVEL:INFO TAG_ID:MyHTML_TAG_HEAD NS:MyHTML_NAMESPACE_HTML */
284            
285 113           tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD;
286 113           return true;
287             }
288             }
289             }
290            
291 0           return false;
292             }
293              
294 130           bool myhtml_insertion_mode_in_head(myhtml_tree_t* tree, myhtml_token_node_t* token)
295             {
296 130 50         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
297             {
298 0           switch (token->tag_id) {
299             case MyHTML_TAG_HEAD:
300             {
301 0           myhtml_tree_open_elements_pop(tree);
302 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_HEAD;
303 0           break;
304             }
305            
306             case MyHTML_TAG_BR:
307             case MyHTML_TAG_HTML:
308             case MyHTML_TAG_BODY:
309             {
310 0           myhtml_tree_open_elements_pop(tree);
311 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_HEAD;
312 0           return true;
313             }
314            
315             case MyHTML_TAG_TEMPLATE:
316             {
317 0 0         if(myhtml_tree_open_elements_find_by_tag_idx_reverse(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL) == NULL)
318             {
319             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:WARNING */
320             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_ANY NEED_TAG_ID:MyHTML_TAG_TEMPLATE NEED_NS:MyHTML_NAMESPACE_HTML */
321            
322 0           break;
323             }
324            
325             // oh God...
326 0           myhtml_tree_generate_all_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
327            
328 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
329 0 0         if(current_node && current_node->tag_id != MyHTML_TAG_TEMPLATE) {
330             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED_CLOSE_BEFORE LEVEL:WARNING */
331             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_TEMPLATE NEED_NS:MyHTML_NAMESPACE_HTML */
332             }
333            
334 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, false);
335 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
336 0           myhtml_tree_template_insertion_pop(tree);
337 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
338            
339 0           break;
340             }
341            
342             default: {
343             // parse error
344             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:WARNING */
345 0           break;
346             }
347             }
348             }
349             else {
350 130           switch (token->tag_id)
351             {
352             case MyHTML_TAG__TEXT:
353             {
354 15 50         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE)
355             {
356 0           myhtml_tree_node_insert_text(tree, token);
357 0           break;
358             }
359            
360 15           myhtml_token_node_t* new_token = myhtml_insertion_fix_split_for_text_begin_ws(tree, token);
361 15 50         if(new_token)
362 0           myhtml_tree_node_insert_text(tree, new_token);
363            
364             // default, other token
365 15           myhtml_tree_open_elements_pop(tree);
366 15           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_HEAD;
367 15           return true;
368             }
369            
370             case MyHTML_TAG__COMMENT:
371             {
372 0           myhtml_tree_node_insert_comment(tree, token, 0);
373 0           break;
374             }
375            
376             case MyHTML_TAG__DOCTYPE: {
377             // parse error
378             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
379 0           break;
380             }
381            
382             case MyHTML_TAG_HTML:
383             {
384 0           return myhtml_insertion_mode_in_body(tree, token);
385             }
386            
387             case MyHTML_TAG_BASE:
388             case MyHTML_TAG_BASEFONT:
389             case MyHTML_TAG_BGSOUND:
390             case MyHTML_TAG_LINK:
391             {
392 0           myhtml_tree_node_insert_html_element(tree, token);
393 0           myhtml_tree_open_elements_pop(tree);
394 0           break;
395             }
396            
397             case MyHTML_TAG_META:
398             {
399 2           myhtml_tree_node_insert_html_element(tree, token);
400 2           myhtml_tree_open_elements_pop(tree);
401            
402             // if the element has an http-equiv attribute
403 2           break;
404             }
405            
406             case MyHTML_TAG_TITLE:
407             {
408 0           myhtml_tree_node_insert_html_element(tree, token);
409            
410 0           tree->orig_insert_mode = tree->insert_mode;
411 0           tree->insert_mode = MyHTML_INSERTION_MODE_TEXT;
412 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RCDATA;
413            
414 0           break;
415             }
416            
417             case MyHTML_TAG_NOSCRIPT:
418             {
419 0 0         if(tree->flags & MyHTML_TREE_FLAGS_SCRIPT) {
420 0           myhtml_tree_node_insert_html_element(tree, token);
421            
422 0           tree->orig_insert_mode = tree->insert_mode;
423 0           tree->insert_mode = MyHTML_INSERTION_MODE_TEXT;
424 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
425             }
426             else {
427 0           myhtml_tree_node_insert_html_element(tree, token);
428 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD_NOSCRIPT;
429             }
430            
431 0           break;
432             }
433            
434             case MyHTML_TAG_STYLE:
435             case MyHTML_TAG_NOFRAMES:
436             {
437 0           myhtml_tree_node_insert_html_element(tree, token);
438            
439 0           tree->orig_insert_mode = tree->insert_mode;
440 0           tree->insert_mode = MyHTML_INSERTION_MODE_TEXT;
441 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
442            
443 0           break;
444             }
445            
446             case MyHTML_TAG_SCRIPT:
447             {
448             // state 1
449             enum myhtml_tree_insertion_mode insert_mode;
450 0           myhtml_tree_node_t* adjusted_location = myhtml_tree_appropriate_place_inserting(tree, NULL, &insert_mode);
451            
452             // state 2
453 0           myhtml_tree_node_t* node = myhtml_tree_node_create(tree);
454            
455 0           node->tag_id = MyHTML_TAG_SCRIPT;
456 0           node->token = token;
457 0           node->ns = MyHTML_NAMESPACE_HTML;
458 0           node->flags = MyHTML_TREE_NODE_PARSER_INSERTED|MyHTML_TREE_NODE_BLOCKING;
459            
460 0           myhtml_tree_node_insert_by_mode(adjusted_location, node, insert_mode);
461 0           myhtml_tree_open_elements_append(tree, node);
462            
463 0           tree->orig_insert_mode = tree->insert_mode;
464 0           tree->insert_mode = MyHTML_INSERTION_MODE_TEXT;
465 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_SCRIPT_DATA;
466            
467 0           break;
468             }
469            
470             case MyHTML_TAG_TEMPLATE:
471             {
472 0           myhtml_tree_node_insert_html_element(tree, token);
473 0           myhtml_tree_active_formatting_append(tree, tree->myhtml->marker); // set marker
474            
475 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
476            
477 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TEMPLATE;
478 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_TEMPLATE);
479            
480 0           break;
481             }
482            
483             case MyHTML_TAG_HEAD: {
484             // parse error
485             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:WARNING */
486 0           break;
487             }
488            
489             default:
490             {
491 113           myhtml_tree_open_elements_pop(tree);
492            
493 113           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_HEAD;
494 113           return true;
495             }
496             }
497             }
498            
499 2           return false;
500             }
501              
502 0           bool myhtml_insertion_mode_in_head_noscript(myhtml_tree_t* tree, myhtml_token_node_t* token)
503             {
504 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
505             {
506 0           switch (token->tag_id) {
507             case MyHTML_TAG_NOSCRIPT:
508             {
509 0           myhtml_tree_open_elements_pop(tree);
510 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD;
511 0           break;
512             }
513            
514             case MyHTML_TAG_BR:
515             {
516 0           myhtml_tree_open_elements_pop(tree);
517 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD;
518 0           return true;
519             }
520            
521             default: {
522             // parse error
523             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
524 0           break;
525             }
526             }
527             }
528             else {
529 0           switch (token->tag_id)
530             {
531             case MyHTML_TAG__DOCTYPE: {
532             // parse error
533             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
534 0           break;
535             }
536            
537             case MyHTML_TAG_HTML:
538             {
539 0           return myhtml_insertion_mode_in_body(tree, token);
540             }
541            
542             case MyHTML_TAG__TEXT:
543             {
544 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE)
545 0           return myhtml_insertion_mode_in_head(tree, token);
546            
547             // default, other token
548 0           myhtml_tree_open_elements_pop(tree);
549 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD;
550 0           return true;
551             }
552            
553             case MyHTML_TAG_BASEFONT:
554             case MyHTML_TAG_BGSOUND:
555             case MyHTML_TAG_LINK:
556             case MyHTML_TAG_META:
557             case MyHTML_TAG_NOFRAMES:
558             case MyHTML_TAG_STYLE:
559             case MyHTML_TAG__COMMENT:
560 0           return myhtml_insertion_mode_in_head(tree, token);
561            
562             case MyHTML_TAG_HEAD:
563             case MyHTML_TAG_NOSCRIPT: {
564             // parse error
565             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:WARNING */
566 0           break;
567             }
568            
569             default:
570             {
571             // parse error
572             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
573            
574 0           myhtml_tree_open_elements_pop(tree);
575 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD;
576 0           return true;
577             }
578             }
579             }
580            
581 0           return false;
582             }
583              
584 128           bool myhtml_insertion_mode_after_head(myhtml_tree_t* tree, myhtml_token_node_t* token)
585             {
586 128 50         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
587             {
588 0           switch (token->tag_id) {
589             case MyHTML_TAG_BR:
590             case MyHTML_TAG_HTML:
591             case MyHTML_TAG_BODY:
592             {
593 0           tree->node_body = myhtml_tree_node_insert(tree, MyHTML_TAG_BODY, MyHTML_NAMESPACE_HTML);
594 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
595            
596             /* %EXTERNAL% VALIDATOR:RULES TAG STATUS:ELEMENT_MISSING_NEED LEVEL:INFO TAG_ID:MyHTML_TAG_BODY NS:MyHTML_NAMESPACE_HTML */
597 0           return true;
598             }
599            
600             case MyHTML_TAG_TEMPLATE:
601             {
602 0           return myhtml_insertion_mode_in_head(tree, token);
603             }
604            
605             default: {
606             // parse error
607             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
608 0           break;
609             }
610             }
611             }
612             else {
613 128           switch (token->tag_id)
614             {
615             case MyHTML_TAG__TEXT:
616             {
617 15 50         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE)
618             {
619 0           myhtml_tree_node_insert_text(tree, token);
620 0           break;
621             }
622            
623 15           myhtml_token_node_t* new_token = myhtml_insertion_fix_split_for_text_begin_ws(tree, token);
624 15 50         if(new_token)
625 0           myhtml_tree_node_insert_text(tree, new_token);
626            
627             // default, other token
628 15           tree->node_body = myhtml_tree_node_insert(tree, MyHTML_TAG_BODY, MyHTML_NAMESPACE_HTML);
629 15           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
630 15           return true;
631             }
632            
633             case MyHTML_TAG__COMMENT:
634 0           myhtml_tree_node_insert_comment(tree, token, 0);
635 0           break;
636            
637             case MyHTML_TAG__DOCTYPE: {
638             // parse error
639             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
640 0           break;
641             }
642            
643             case MyHTML_TAG_HTML:
644 0           return myhtml_insertion_mode_in_body(tree, token);
645            
646             case MyHTML_TAG_BODY:
647             {
648 1           tree->node_body = myhtml_tree_node_insert_html_element(tree, token);
649            
650 1           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
651 1           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
652 1           break;
653             }
654            
655             case MyHTML_TAG_FRAMESET:
656 0           myhtml_tree_node_insert_html_element(tree, token);
657 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_FRAMESET;
658 0           break;
659            
660             case MyHTML_TAG_BASE:
661             case MyHTML_TAG_BASEFONT:
662             case MyHTML_TAG_BGSOUND:
663             case MyHTML_TAG_LINK:
664             case MyHTML_TAG_META:
665             case MyHTML_TAG_NOFRAMES:
666             case MyHTML_TAG_SCRIPT:
667             case MyHTML_TAG_STYLE:
668             case MyHTML_TAG_TEMPLATE:
669             case MyHTML_TAG_TITLE:
670             {
671             // parse error
672             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
673            
674 0           myhtml_tree_open_elements_append(tree, tree->node_head);
675 0           myhtml_insertion_mode_in_head(tree, token);
676 0           myhtml_tree_open_elements_remove(tree, tree->node_head);
677             }
678            
679             case MyHTML_TAG_HEAD: {
680             // parse error
681             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:WARNING */
682 0           break;
683             }
684            
685             default:
686             {
687 112           tree->node_body = myhtml_tree_node_insert(tree, MyHTML_TAG_BODY, MyHTML_NAMESPACE_HTML);
688             /* %EXTERNAL% VALIDATOR:RULES TAG STATUS:ELEMENT_MISSING_NEED LEVEL:INFO TAG_ID:MyHTML_TAG_BODY NS:MyHTML_NAMESPACE_HTML */
689            
690 112           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
691 112           return true;
692             }
693             }
694             }
695            
696 1           return false;
697             }
698              
699 19           bool myhtml_insertion_mode_in_body_other_end_tag(myhtml_tree_t* tree, myhtml_token_node_t* token)
700             {
701             // step 1
702 19           size_t i = tree->open_elements->length;
703 19 50         while(i) {
704 19           i--;
705            
706 19           myhtml_tree_node_t* node = tree->open_elements->list[i];
707            
708             // step 2
709 19 100         if(node->tag_id == token->tag_id && node->ns == MyHTML_NAMESPACE_HTML) {
    50          
710 18           myhtml_tree_generate_implied_end_tags(tree, token->tag_id, MyHTML_NAMESPACE_HTML);
711            
712 18           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
713 18           if(current_node->tag_id != node->tag_id) {
714             // parse error
715             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
716             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:node->tag_id NEED_NS:node->ns */
717             }
718            
719 18           myhtml_tree_open_elements_pop_until_by_node(tree, node, false);
720            
721 18           return false;
722             }
723            
724 1           const myhtml_tag_context_t *tag_ctx = myhtml_tag_get_by_id(tree->tags, node->tag_id);
725 1 50         if(tag_ctx->cats[ node->ns ] & MyHTML_TAG_CATEGORIES_SPECIAL) {
726             // parse error
727             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
728 1           break;
729             }
730             }
731            
732 1           return false;
733             }
734              
735 1601           bool myhtml_insertion_mode_in_body(myhtml_tree_t* tree, myhtml_token_node_t* token)
736             {
737 1601 100         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
738             {
739 375           switch (token->tag_id) {
740             case MyHTML_TAG_TEMPLATE:
741             {
742 0           return myhtml_insertion_mode_in_head(tree, token);
743             }
744            
745             case MyHTML_TAG_BODY:
746             {
747 1           myhtml_tree_node_t* body_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_BODY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE);
748            
749 1 50         if(body_node == NULL) {
750             // parse error
751             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
752 0           break;
753             }
754            
755 3 100         for (size_t i = 0; i < tree->open_elements->length; i++) {
756 2 50         switch (tree->open_elements->list[i]->tag_id) {
757             case MyHTML_TAG_DD:
758             case MyHTML_TAG_DT:
759             case MyHTML_TAG_LI:
760             case MyHTML_TAG_MENUITEM:
761             case MyHTML_TAG_OPTGROUP:
762             case MyHTML_TAG_OPTION:
763             case MyHTML_TAG_P:
764             case MyHTML_TAG_RB:
765             case MyHTML_TAG_RP:
766             case MyHTML_TAG_RT:
767             case MyHTML_TAG_RTC:
768             case MyHTML_TAG_TBODY:
769             case MyHTML_TAG_TD:
770             case MyHTML_TAG_TFOOT:
771             case MyHTML_TAG_TH:
772             case MyHTML_TAG_THEAD:
773             case MyHTML_TAG_TR:
774             case MyHTML_TAG_BODY:
775             case MyHTML_TAG_HTML:
776             // set parse error
777 2           break;
778            
779             default:
780 0           break;
781             }
782             }
783            
784 1           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_BODY;
785 1           break;
786             }
787            
788             case MyHTML_TAG_HTML:
789             {
790 0           myhtml_tree_node_t* body_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_BODY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE);
791            
792 0 0         if(body_node == NULL) {
793             // parse error
794             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
795 0           break;
796             }
797            
798 0 0         for (size_t i = 0; i < tree->open_elements->length; i++) {
799 0 0         switch (tree->open_elements->list[i]->tag_id) {
800             case MyHTML_TAG_DD:
801             case MyHTML_TAG_DT:
802             case MyHTML_TAG_LI:
803             case MyHTML_TAG_MENUITEM:
804             case MyHTML_TAG_OPTGROUP:
805             case MyHTML_TAG_OPTION:
806             case MyHTML_TAG_P:
807             case MyHTML_TAG_RB:
808             case MyHTML_TAG_RP:
809             case MyHTML_TAG_RT:
810             case MyHTML_TAG_RTC:
811             case MyHTML_TAG_TBODY:
812             case MyHTML_TAG_TD:
813             case MyHTML_TAG_TFOOT:
814             case MyHTML_TAG_TH:
815             case MyHTML_TAG_THEAD:
816             case MyHTML_TAG_TR:
817             case MyHTML_TAG_BODY:
818             case MyHTML_TAG_HTML:
819             // set parse error
820 0           break;
821            
822             default:
823 0           break;
824             }
825             }
826 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_BODY;
827            
828 0           return true;
829             }
830            
831             case MyHTML_TAG_ADDRESS:
832             case MyHTML_TAG_ARTICLE:
833             case MyHTML_TAG_ASIDE:
834             case MyHTML_TAG_BLOCKQUOTE:
835             case MyHTML_TAG_BUTTON:
836             case MyHTML_TAG_CENTER:
837             case MyHTML_TAG_DETAILS:
838             case MyHTML_TAG_DIALOG:
839             case MyHTML_TAG_DIR:
840             case MyHTML_TAG_DIV:
841             case MyHTML_TAG_DL:
842             case MyHTML_TAG_FIELDSET:
843             case MyHTML_TAG_FIGCAPTION:
844             case MyHTML_TAG_FIGURE:
845             case MyHTML_TAG_FOOTER:
846             case MyHTML_TAG_HEADER:
847             case MyHTML_TAG_HGROUP:
848             case MyHTML_TAG_LISTING:
849             case MyHTML_TAG_MAIN:
850             case MyHTML_TAG_MENU:
851             case MyHTML_TAG_NAV:
852             case MyHTML_TAG_OL:
853             case MyHTML_TAG_PRE:
854             case MyHTML_TAG_SECTION:
855             case MyHTML_TAG_SUMMARY:
856             case MyHTML_TAG_UL:
857             {
858 129 50         if(myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE) == NULL) {
859             // parse error
860             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
861            
862 0           break;
863             }
864            
865             // step 1
866 129           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
867            
868             // step 2
869 129           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
870 129           if(myhtml_is_html_node(current_node, token->tag_id) == false) {
871             // parse error
872             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
873             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:token->tag_id NEED_NS:MyHTML_NAMESPACE_HTML */
874             }
875            
876             // step 3
877 129           myhtml_tree_open_elements_pop_until(tree, token->tag_id, MyHTML_NAMESPACE_HTML, false);
878 356           break;
879             }
880            
881             case MyHTML_TAG_FORM:
882             {
883 0           myhtml_tree_node_t* template_node = myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL);
884            
885 0 0         if(template_node == NULL)
886             {
887             // step 1
888 0           myhtml_tree_node_t* node = tree->node_form;
889            
890             // step 2
891 0           tree->node_form = NULL;
892            
893             // step 3
894 0 0         if(node == NULL || myhtml_tree_element_in_scope_by_node(node, MyHTML_TAG_CATEGORIES_SCOPE) == false) {
    0          
895             // parse error
896             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
897            
898             break;
899             }
900            
901             // step 4
902 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
903            
904             // step 5
905 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
906             if(current_node != node) {
907             // parse error
908             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
909             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:node->tag_id NEED_NS:node->ns */
910             }
911            
912             // step 6
913 0           myhtml_tree_open_elements_remove(tree, node);
914             }
915             else {
916             // step 1
917 0           myhtml_tree_node_t* form_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_FORM, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE);
918            
919 0 0         if(form_node == NULL) {
920             // parse error
921             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
922            
923 0           break;
924             }
925            
926             // step 2
927 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
928            
929             // step 3
930 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
931 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_FORM) == false) {
932             // parse error
933             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
934             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_FORM NEED_NS:MyHTML_NAMESPACE_HTML */
935             }
936            
937             // step 4
938 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_FORM, MyHTML_NAMESPACE_HTML, false);
939             }
940            
941 0           break;
942             }
943            
944             case MyHTML_TAG_P:
945             {
946 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON) == NULL) {
947             // parse error
948 0           myhtml_tree_node_insert(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML);
949             }
950            
951 0           myhtml_tree_tags_close_p(tree, token);
952 0           break;
953             }
954            
955             case MyHTML_TAG_LI:
956             {
957 186 50         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_LI, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_LIST_ITEM) == NULL) {
958             // parse error
959             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
960 0           break;
961             }
962            
963             // step 1
964 186           myhtml_tree_generate_implied_end_tags(tree, MyHTML_TAG_LI, MyHTML_NAMESPACE_HTML);
965            
966             // step 2
967 186           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
968 186           if(myhtml_is_html_node(current_node, MyHTML_TAG_LI) == false) {
969             // parse error
970             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
971             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_LI NEED_NS:MyHTML_NAMESPACE_HTML */
972             }
973            
974             // step 3
975 186           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_LI, MyHTML_NAMESPACE_HTML, false);
976            
977 186           break;
978             }
979            
980             case MyHTML_TAG_DT:
981             case MyHTML_TAG_DD:
982             {
983 0 0         if(myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE) == NULL) {
984             // parse error
985             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
986 0           break;
987             }
988            
989             // step 1
990 0           myhtml_tree_generate_implied_end_tags(tree, token->tag_id, MyHTML_NAMESPACE_HTML);
991            
992             // step 2
993 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
994 0           if(myhtml_is_html_node(current_node, token->tag_id) == false) {
995             // parse error
996             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
997             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:token->tag_id NEED_NS:MyHTML_NAMESPACE_HTML */
998             }
999            
1000             // step 3
1001 0           myhtml_tree_open_elements_pop_until(tree, token->tag_id, MyHTML_NAMESPACE_HTML, false);
1002            
1003 0           break;
1004             }
1005            
1006             case MyHTML_TAG_H1:
1007             case MyHTML_TAG_H2:
1008             case MyHTML_TAG_H3:
1009             case MyHTML_TAG_H4:
1010             case MyHTML_TAG_H5:
1011             case MyHTML_TAG_H6:
1012             {
1013 0           myhtml_tree_node_t** list = tree->open_elements->list;
1014            
1015 0           myhtml_tree_node_t* node = NULL;
1016 0           size_t i = tree->open_elements->length;
1017 0 0         while(i) {
1018 0           i--;
1019            
1020 0           const myhtml_tag_context_t *tag_ctx = myhtml_tag_get_by_id(tree->tags, list[i]->tag_id);
1021            
1022 0 0         if((list[i]->tag_id == MyHTML_TAG_H1 ||
    0          
1023 0 0         list[i]->tag_id == MyHTML_TAG_H2 ||
1024 0 0         list[i]->tag_id == MyHTML_TAG_H3 ||
1025 0 0         list[i]->tag_id == MyHTML_TAG_H4 ||
1026 0 0         list[i]->tag_id == MyHTML_TAG_H5 ||
1027 0 0         list[i]->tag_id == MyHTML_TAG_H6) &&
1028 0           list[i]->ns == MyHTML_NAMESPACE_HTML) {
1029 0           node = list[i];
1030 0           break;
1031             }
1032 0 0         else if(tag_ctx->cats[list[i]->ns] & MyHTML_TAG_CATEGORIES_SCOPE)
1033 0           break;
1034             }
1035            
1036 0 0         if(node == NULL) {
1037             // parse error
1038             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
1039 0           break;
1040             }
1041            
1042             // step 1
1043 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
1044            
1045             // step 2
1046 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1047 0           if(myhtml_is_html_node(current_node, token->tag_id) == false) {
1048             // parse error
1049             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1050             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:token->tag_id NEED_NS:MyHTML_NAMESPACE_HTML */
1051             }
1052            
1053             // step 3
1054 0 0         while(tree->open_elements->length) {
1055 0           tree->open_elements->length--;
1056            
1057 0 0         if((list[tree->open_elements->length]->tag_id == MyHTML_TAG_H1 ||
    0          
1058 0 0         list[tree->open_elements->length]->tag_id == MyHTML_TAG_H2 ||
1059 0 0         list[tree->open_elements->length]->tag_id == MyHTML_TAG_H3 ||
1060 0 0         list[tree->open_elements->length]->tag_id == MyHTML_TAG_H4 ||
1061 0 0         list[tree->open_elements->length]->tag_id == MyHTML_TAG_H5 ||
1062 0 0         list[tree->open_elements->length]->tag_id == MyHTML_TAG_H6) &&
1063 0           list[tree->open_elements->length]->ns == MyHTML_NAMESPACE_HTML)
1064             {
1065 0           break;
1066             }
1067             }
1068            
1069 0           break;
1070             }
1071            
1072             case MyHTML_TAG_A:
1073             case MyHTML_TAG_B:
1074             case MyHTML_TAG_BIG:
1075             case MyHTML_TAG_CODE:
1076             case MyHTML_TAG_EM:
1077             case MyHTML_TAG_FONT:
1078             case MyHTML_TAG_I:
1079             case MyHTML_TAG_NOBR:
1080             case MyHTML_TAG_S:
1081             case MyHTML_TAG_SMALL:
1082             case MyHTML_TAG_STRIKE:
1083             case MyHTML_TAG_STRONG:
1084             case MyHTML_TAG_TT:
1085             case MyHTML_TAG_U:
1086             {
1087 40           myhtml_tree_adoption_agency_algorithm(tree, token, token->tag_id);
1088             //myhtml_insertion_mode_in_body_other_end_tag(tree, token);
1089            
1090 40           break;
1091             }
1092            
1093             case MyHTML_TAG_APPLET:
1094             case MyHTML_TAG_MARQUEE:
1095             case MyHTML_TAG_OBJECT:
1096             {
1097 0 0         if(myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE) == NULL) {
1098             // parse error
1099             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
1100 0           break;
1101             }
1102            
1103             // step 1
1104 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
1105            
1106             // step 2
1107 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1108 0           if(myhtml_is_html_node(current_node, token->tag_id) == false) {
1109             // parse error
1110             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1111             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:token->tag_id NEED_NS:MyHTML_NAMESPACE_HTML */
1112             }
1113            
1114             // step 3
1115 0           myhtml_tree_open_elements_pop_until(tree, token->tag_id, MyHTML_NAMESPACE_HTML, false);
1116            
1117             // step 4
1118 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
1119            
1120 0           break;
1121             }
1122            
1123             case MyHTML_TAG_BR:
1124             {
1125             // parse error
1126             /* %EXTERNAL% VALIDATOR:RULES CONVERT STATUS:ELEMENT_BAD LEVEL:ERROR FROM_TAG_ID:MyHTML_TAG_BR FROM_NS:MyHTML_NAMESPACE_HTML FROM_TYPE:MyHTML_TOKEN_TYPE_CLOSE TO_TAG_ID:MyHTML_TAG_BR TO_NS:MyHTML_NAMESPACE_HTML TO_TYPE:MyHTML_TOKEN_TYPE_OPEN */
1127            
1128 0 0         if(token->attr_first) {
1129 0           token->attr_first = NULL;
1130             }
1131            
1132 0 0         if(token->attr_last) {
1133 0           token->attr_last = NULL;
1134             }
1135            
1136 0           myhtml_tree_active_formatting_reconstruction(tree);
1137            
1138 0 0         if (token->type & MyHTML_TOKEN_TYPE_DONE) {
1139 0           token->type = MyHTML_TOKEN_TYPE_OPEN | MyHTML_TOKEN_TYPE_DONE;
1140             } else {
1141 0           token->type = MyHTML_TOKEN_TYPE_OPEN;
1142             }
1143            
1144 0           myhtml_tree_node_insert_html_element(tree, token);
1145 0           myhtml_tree_open_elements_pop(tree);
1146            
1147 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1148            
1149 0           break;
1150             }
1151            
1152             default:
1153             {
1154 19           return myhtml_insertion_mode_in_body_other_end_tag(tree, token);
1155             }
1156             }
1157             }
1158             // open elements
1159             else {
1160 1226           switch (token->tag_id)
1161             {
1162             case MyHTML_TAG__TEXT:
1163             {
1164 646 50         if(token->type & MyHTML_TOKEN_TYPE_NULL) {
1165             // parse error
1166             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:NULL_CHAR ACTION:IGNORE LEVEL:ERROR */
1167            
1168 0           myhtml_insertion_fix_for_null_char_drop_all(tree, token);
1169            
1170 0 0         if(token->str.length) {
1171 0           myhtml_tree_active_formatting_reconstruction(tree);
1172 0           myhtml_tree_node_insert_text(tree, token);
1173            
1174 0 0         if((token->type & MyHTML_TOKEN_TYPE_WHITESPACE) == 0)
1175 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1176             }
1177             }
1178             else {
1179 646           myhtml_tree_active_formatting_reconstruction(tree);
1180 646           myhtml_tree_node_insert_text(tree, token);
1181            
1182 646 100         if((token->type & MyHTML_TOKEN_TYPE_WHITESPACE) == 0)
1183 290           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1184             }
1185            
1186 646           break;
1187             }
1188            
1189             case MyHTML_TAG__COMMENT:
1190 61           myhtml_tree_node_insert_comment(tree, token, 0);
1191 61           break;
1192            
1193             case MyHTML_TAG__DOCTYPE: {
1194             // parse error
1195             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:WARNING */
1196 0           break;
1197             }
1198            
1199             case MyHTML_TAG_HTML:
1200             {
1201 0 0         if(myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL)) {
1202             // parse error
1203             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:WARNING */
1204 0           break;
1205             }
1206            
1207             // parse error
1208             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:WARNING */
1209            
1210 0 0         if(tree->open_elements->length > 0) {
1211 0           myhtml_tree_node_t* top_node = tree->open_elements->list[0];
1212            
1213 0 0         if(top_node->token) {
1214 0           myhtml_token_node_wait_for_done(tree->token, token);
1215 0           myhtml_token_node_wait_for_done(tree->token, top_node->token);
1216 0           myhtml_token_node_attr_copy_with_check(tree->token, token, top_node->token, tree->mcasync_rules_attr_id);
1217             }
1218             else {
1219 0           top_node->token = token;
1220             }
1221             }
1222            
1223 0           break;
1224             }
1225            
1226             case MyHTML_TAG_BASE:
1227             case MyHTML_TAG_BASEFONT:
1228             case MyHTML_TAG_BGSOUND:
1229             case MyHTML_TAG_LINK:
1230             case MyHTML_TAG_META:
1231             case MyHTML_TAG_NOFRAMES:
1232             case MyHTML_TAG_SCRIPT:
1233             case MyHTML_TAG_STYLE:
1234             case MyHTML_TAG_TEMPLATE:
1235             case MyHTML_TAG_TITLE:
1236             {
1237 2           return myhtml_insertion_mode_in_head(tree, token);
1238             }
1239            
1240             case MyHTML_TAG_BODY:
1241             {
1242             // parse error
1243             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:WARNING */
1244            
1245 0 0         if(tree->open_elements->length > 1)
1246             {
1247 0 0         if(!(tree->open_elements->list[1]->tag_id == MyHTML_TAG_BODY &&
    0          
1248 0 0         tree->open_elements->list[1]->ns == MyHTML_NAMESPACE_HTML) ||
1249 0           myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL))
1250             {
1251             // parse error
1252             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:WARNING */
1253            
1254             break;
1255             }
1256             }
1257             else
1258 0           break;
1259            
1260 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1261            
1262 0 0         if(tree->open_elements->length > 1) {
1263 0           myhtml_tree_node_t* top_node = tree->open_elements->list[1];
1264            
1265 0 0         if(top_node->token) {
1266 0           myhtml_token_node_wait_for_done(tree->token, token);
1267 0           myhtml_token_node_wait_for_done(tree->token, top_node->token);
1268 0           myhtml_token_node_attr_copy_with_check(tree->token, token, top_node->token, tree->mcasync_rules_attr_id);
1269             }
1270             else {
1271 0           top_node->token = token;
1272             }
1273             }
1274            
1275 0           break;
1276             }
1277            
1278             case MyHTML_TAG_FRAMESET:
1279             {
1280             // parse error
1281             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
1282            
1283 0 0         if(tree->open_elements->length > 1)
1284             {
1285 0 0         if(!(tree->open_elements->list[1]->tag_id == MyHTML_TAG_BODY &&
    0          
1286 0           tree->open_elements->list[1]->ns == MyHTML_NAMESPACE_HTML))
1287             {
1288             // parse error
1289             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
1290            
1291             break;
1292             }
1293             }
1294             else
1295 0           break;
1296            
1297 0 0         if((tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK) == 0) {
1298             // parse error
1299             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
1300            
1301 0           break;
1302             }
1303            
1304 0           myhtml_tree_node_t* node = tree->open_elements->list[1];
1305            
1306 0           myhtml_tree_node_remove(node);
1307 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_HTML, MyHTML_NAMESPACE_HTML, true);
1308            
1309 0           myhtml_tree_node_insert_html_element(tree, token);
1310            
1311 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_FRAMESET;
1312 0           break;
1313             }
1314            
1315             case MyHTML_TAG__END_OF_FILE:
1316             {
1317 144 50         if(tree->template_insertion->length)
1318 0           return myhtml_insertion_mode_in_template(tree, token);
1319            
1320 144           myhtml_tree_node_t** list = tree->open_elements->list;
1321 415 100         for(size_t i = 0; i < tree->open_elements->length; i++) {
1322 271 50         if(list[i]->tag_id != MyHTML_TAG_DD && list[i]->tag_id != MyHTML_TAG_DT &&
    50          
    50          
1323 271 50         list[i]->tag_id != MyHTML_TAG_LI && list[i]->tag_id != MyHTML_TAG_MENUITEM &&
    50          
1324 271 50         list[i]->tag_id != MyHTML_TAG_OPTGROUP && list[i]->tag_id != MyHTML_TAG_OPTION &&
    50          
1325 271 50         list[i]->tag_id != MyHTML_TAG_P && list[i]->tag_id != MyHTML_TAG_RB &&
    50          
1326 271 50         list[i]->tag_id != MyHTML_TAG_RP && list[i]->tag_id != MyHTML_TAG_RT &&
    50          
1327 271 50         list[i]->tag_id != MyHTML_TAG_RTC && list[i]->tag_id != MyHTML_TAG_TBODY &&
    50          
1328 271 50         list[i]->tag_id != MyHTML_TAG_TD && list[i]->tag_id != MyHTML_TAG_TFOOT &&
    50          
1329 271 50         list[i]->tag_id != MyHTML_TAG_TH && list[i]->tag_id != MyHTML_TAG_THEAD &&
    50          
1330 271 100         list[i]->tag_id != MyHTML_TAG_TR && list[i]->tag_id != MyHTML_TAG_BODY &&
    50          
1331 0           list[i]->tag_id != MyHTML_TAG_HTML && list[i]->ns != MyHTML_NAMESPACE_HTML)
1332             {
1333             // parse error
1334             }
1335             }
1336            
1337 144           myhtml_rules_stop_parsing(tree);
1338 144           break;
1339             }
1340            
1341             case MyHTML_TAG_ADDRESS:
1342             case MyHTML_TAG_ARTICLE:
1343             case MyHTML_TAG_ASIDE:
1344             case MyHTML_TAG_BLOCKQUOTE:
1345             case MyHTML_TAG_CENTER:
1346             case MyHTML_TAG_DETAILS:
1347             case MyHTML_TAG_DIALOG:
1348             case MyHTML_TAG_DIR:
1349             case MyHTML_TAG_DIV:
1350             case MyHTML_TAG_DL:
1351             case MyHTML_TAG_FIELDSET:
1352             case MyHTML_TAG_FIGCAPTION:
1353             case MyHTML_TAG_FIGURE:
1354             case MyHTML_TAG_FOOTER:
1355             case MyHTML_TAG_HEADER:
1356             case MyHTML_TAG_HGROUP:
1357             case MyHTML_TAG_MAIN:
1358             case MyHTML_TAG_NAV:
1359             case MyHTML_TAG_OL:
1360             case MyHTML_TAG_P:
1361             case MyHTML_TAG_SECTION:
1362             case MyHTML_TAG_SUMMARY:
1363             case MyHTML_TAG_UL:
1364             {
1365 129 50         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1366 0           myhtml_tree_tags_close_p(tree, token);
1367             }
1368            
1369 129           myhtml_tree_node_insert_html_element(tree, token);
1370 129           break;
1371             }
1372            
1373             case MyHTML_TAG_MENU:
1374             {
1375 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1376 0           myhtml_tree_tags_close_p(tree, token);
1377             }
1378            
1379 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1380            
1381 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_MENUITEM))
1382 0           myhtml_tree_open_elements_pop(tree);
1383            
1384 0           myhtml_tree_node_insert_html_element(tree, token);
1385 0           break;
1386             }
1387            
1388             case MyHTML_TAG_H1:
1389             case MyHTML_TAG_H2:
1390             case MyHTML_TAG_H3:
1391             case MyHTML_TAG_H4:
1392             case MyHTML_TAG_H5:
1393             case MyHTML_TAG_H6:
1394             {
1395 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1396 0           myhtml_tree_tags_close_p(tree, token);
1397             }
1398            
1399 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1400            
1401 0 0         switch (current_node->tag_id) {
1402             case MyHTML_TAG_H1:
1403             case MyHTML_TAG_H2:
1404             case MyHTML_TAG_H3:
1405             case MyHTML_TAG_H4:
1406             case MyHTML_TAG_H5:
1407             case MyHTML_TAG_H6:
1408            
1409 0 0         if(current_node->ns == MyHTML_NAMESPACE_HTML) {
1410             // parse error
1411             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:WARNING */
1412 0           myhtml_tree_open_elements_pop(tree);
1413             }
1414            
1415 0           break;
1416            
1417             default:
1418 0           break;
1419             }
1420            
1421 0           myhtml_tree_node_insert_html_element(tree, token);
1422 0           break;
1423             }
1424            
1425             case MyHTML_TAG_PRE:
1426             case MyHTML_TAG_LISTING:
1427             {
1428 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1429 0           myhtml_tree_tags_close_p(tree, token);
1430             }
1431            
1432 0           myhtml_tree_node_insert_html_element(tree, token);
1433            
1434             // If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move on to the next one.
1435             // (Newlines at the start of pre blocks are ignored as an authoring convenience.)
1436             // !!! see dispatcher (myhtml_rules_tree_dispatcher) for this
1437 0           tree->flags |= MyHTML_TREE_FLAGS_PARSE_FLAG|MyHTML_TREE_FLAGS_PARSE_FLAG_EMIT_NEWLINE;
1438            
1439 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1440 0           break;
1441             }
1442            
1443             case MyHTML_TAG_FORM:
1444             {
1445 0           myhtml_tree_node_t* is_in_node = myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL);
1446 0 0         if(tree->node_form && is_in_node == NULL) {
    0          
1447             // parse error
1448             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
1449 0           break;
1450             }
1451            
1452 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1453 0           myhtml_tree_tags_close_p(tree, token);
1454             }
1455            
1456 0           myhtml_tree_node_t* current = myhtml_tree_node_insert_html_element(tree, token);
1457            
1458 0 0         if(is_in_node == NULL)
1459 0           tree->node_form = current;
1460            
1461 0           break;
1462             }
1463            
1464             case MyHTML_TAG_LI:
1465             {
1466 186           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1467            
1468 186           size_t oel_index = tree->open_elements->length;
1469            
1470 186 50         while (oel_index) {
1471 186           oel_index--;
1472            
1473 186           myhtml_tree_node_t* node = tree->open_elements->list[oel_index];
1474 186           const myhtml_tag_context_t *tag_ctx = myhtml_tag_get_by_id(tree->tags, node->tag_id);
1475            
1476             /* 3 */
1477 186 50         if(myhtml_is_html_node(node, MyHTML_TAG_LI)) {
1478             /* 3.1 */
1479 0           myhtml_tree_generate_implied_end_tags(tree, MyHTML_TAG_LI, MyHTML_NAMESPACE_HTML);
1480            
1481             /* 3.2 */
1482 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1483 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_LI) == false) {
1484             // parse error
1485             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1486             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_LI NEED_NS:MyHTML_NAMESPACE_HTML */
1487             }
1488            
1489             /* 3.3 */
1490 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_LI, MyHTML_NAMESPACE_HTML, false);
1491 0           break;
1492             }
1493 186 50         else if(tag_ctx->cats[node->ns] & MyHTML_TAG_CATEGORIES_SPECIAL)
1494             {
1495 186 50         if(!((node->tag_id == MyHTML_TAG_ADDRESS || node->tag_id == MyHTML_TAG_DIV ||
    50          
    50          
    0          
1496 186           node->tag_id == MyHTML_TAG_P) && node->ns == MyHTML_NAMESPACE_HTML))
1497             break;
1498             }
1499             }
1500            
1501 186 50         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1502 0           myhtml_tree_tags_close_p(tree, token);
1503             }
1504            
1505 186           myhtml_tree_node_insert_html_element(tree, token);
1506 186           break;
1507             }
1508            
1509             case MyHTML_TAG_DT:
1510             case MyHTML_TAG_DD:
1511             {
1512             // this is copy/past
1513 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1514            
1515 0           size_t oel_index = tree->open_elements->length;
1516            
1517 0 0         while (oel_index) {
1518 0           oel_index--;
1519            
1520 0           myhtml_tree_node_t* node = tree->open_elements->list[oel_index];
1521 0           const myhtml_tag_context_t *tag_ctx = myhtml_tag_get_by_id(tree->tags, node->tag_id);
1522            
1523 0 0         if(myhtml_is_html_node(node, MyHTML_TAG_DD)) {
1524 0           myhtml_tree_generate_implied_end_tags(tree, MyHTML_TAG_DD, MyHTML_NAMESPACE_HTML);
1525            
1526             /* 3.2 */
1527 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1528 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_DD)) {
1529             // parse error
1530             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1531             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_DD NEED_NS:MyHTML_NAMESPACE_HTML */
1532             }
1533            
1534 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_DD, MyHTML_NAMESPACE_HTML, false);
1535 0           break;
1536             }
1537 0 0         else if(myhtml_is_html_node(node, MyHTML_TAG_DT)) {
1538 0           myhtml_tree_generate_implied_end_tags(tree, MyHTML_TAG_DT, MyHTML_NAMESPACE_HTML);
1539            
1540             /* 3.2 */
1541 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1542 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_DT)) {
1543             // parse error
1544             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1545             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_DT NEED_NS:MyHTML_NAMESPACE_HTML */
1546             }
1547            
1548 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_DT, MyHTML_NAMESPACE_HTML, false);
1549 0           break;
1550             }
1551 0 0         else if(tag_ctx->cats[node->ns] & MyHTML_TAG_CATEGORIES_SPECIAL)
1552             {
1553 0 0         if(!((node->tag_id == MyHTML_TAG_ADDRESS || node->tag_id == MyHTML_TAG_DIV ||
    0          
    0          
    0          
1554 0           node->tag_id == MyHTML_TAG_P) && node->ns == MyHTML_NAMESPACE_HTML))
1555             break;
1556             }
1557             }
1558            
1559 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1560 0           myhtml_tree_tags_close_p(tree, token);
1561             }
1562            
1563 0           myhtml_tree_node_insert_html_element(tree, token);
1564 0           break;
1565             }
1566            
1567             case MyHTML_TAG_PLAINTEXT:
1568             {
1569 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1570 0           myhtml_tree_tags_close_p(tree, token);
1571             }
1572            
1573 0           myhtml_tree_node_insert_html_element(tree, token);
1574            
1575 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_PLAINTEXT;
1576 0           break;
1577             }
1578            
1579             case MyHTML_TAG_BUTTON:
1580             {
1581 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_BUTTON, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE)) {
1582             // parse error
1583             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
1584            
1585 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
1586 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_BUTTON, MyHTML_NAMESPACE_HTML, false);
1587             }
1588            
1589 0           myhtml_tree_active_formatting_reconstruction(tree);
1590 0           myhtml_tree_node_insert_html_element(tree, token);
1591            
1592 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1593 0           break;
1594             }
1595            
1596             case MyHTML_TAG_A:
1597             {
1598 0           myhtml_tree_node_t* node = myhtml_tree_active_formatting_between_last_marker(tree, MyHTML_TAG_A, NULL);
1599            
1600 0 0         if(node) {
1601             // parse error
1602             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
1603            
1604 0           myhtml_tree_adoption_agency_algorithm(tree, token, MyHTML_TAG_A);
1605 0           node = myhtml_tree_active_formatting_between_last_marker(tree, MyHTML_TAG_A, NULL);
1606            
1607 0 0         if(node) {
1608 0           myhtml_tree_open_elements_remove(tree, node);
1609 0           myhtml_tree_active_formatting_remove(tree, node);
1610             }
1611             }
1612            
1613 0           myhtml_tree_active_formatting_reconstruction(tree);
1614            
1615 0           myhtml_tree_node_t* current = myhtml_tree_node_insert_html_element(tree, token);
1616 0           myhtml_tree_active_formatting_append_with_check(tree, current);
1617 0           break;
1618             }
1619            
1620             case MyHTML_TAG_B:
1621             case MyHTML_TAG_BIG:
1622             case MyHTML_TAG_CODE:
1623             case MyHTML_TAG_EM:
1624             case MyHTML_TAG_FONT:
1625             case MyHTML_TAG_I:
1626             case MyHTML_TAG_S:
1627             case MyHTML_TAG_SMALL:
1628             case MyHTML_TAG_STRIKE:
1629             case MyHTML_TAG_STRONG:
1630             case MyHTML_TAG_TT:
1631             case MyHTML_TAG_U:
1632             {
1633 40           myhtml_tree_active_formatting_reconstruction(tree);
1634            
1635 40           myhtml_tree_node_t* current = myhtml_tree_node_insert_html_element(tree, token);
1636 40           myhtml_tree_active_formatting_append_with_check(tree, current);
1637 40           break;
1638             }
1639              
1640             case MyHTML_TAG_NOBR:
1641             {
1642 0           myhtml_tree_active_formatting_reconstruction(tree);
1643            
1644 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_NOBR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE)) {
1645             // parse error
1646             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
1647            
1648 0           myhtml_tree_adoption_agency_algorithm(tree, token, MyHTML_TAG_NOBR);
1649 0           myhtml_tree_active_formatting_reconstruction(tree);
1650             }
1651            
1652 0           myhtml_tree_node_t* current = myhtml_tree_node_insert_html_element(tree, token);
1653 0           myhtml_tree_active_formatting_append_with_check(tree, current);
1654 0           break;
1655             }
1656              
1657             case MyHTML_TAG_APPLET:
1658             case MyHTML_TAG_MARQUEE:
1659             case MyHTML_TAG_OBJECT:
1660             {
1661 0           myhtml_tree_active_formatting_reconstruction(tree);
1662            
1663 0           myhtml_tree_node_insert_html_element(tree, token);
1664 0           myhtml_tree_active_formatting_append(tree, tree->myhtml->marker); // marker
1665            
1666 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1667 0           break;
1668             }
1669            
1670             case MyHTML_TAG_TABLE:
1671             {
1672 0           if((tree->compat_mode & MyHTML_TREE_COMPAT_MODE_QUIRKS) == 0 &&
1673 0           myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON))
1674             {
1675 0           myhtml_tree_tags_close_p(tree, token);
1676             }
1677            
1678 0           myhtml_tree_node_insert_html_element(tree, token);
1679 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1680            
1681 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
1682 0           break;
1683             }
1684            
1685             case MyHTML_TAG_AREA:
1686             case MyHTML_TAG_BR:
1687             case MyHTML_TAG_EMBED:
1688             case MyHTML_TAG_IMG:
1689             case MyHTML_TAG_KEYGEN:
1690             case MyHTML_TAG_WBR:
1691             {
1692 0           myhtml_tree_active_formatting_reconstruction(tree);
1693            
1694 0           myhtml_tree_node_insert_html_element(tree, token);
1695 0           myhtml_tree_open_elements_pop(tree);
1696            
1697 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1698 0           break;
1699             }
1700            
1701             case MyHTML_TAG_INPUT:
1702             {
1703 0           myhtml_tree_active_formatting_reconstruction(tree);
1704            
1705 0           myhtml_tree_node_insert_html_element(tree, token);
1706 0           myhtml_tree_open_elements_pop(tree);
1707            
1708 0           myhtml_token_node_wait_for_done(tree->token, token);
1709 0 0         if(myhtml_token_attr_match_case(tree->token, token, "type", 4, "hidden", 6) == NULL) {
1710 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1711             }
1712            
1713 0           break;
1714             }
1715            
1716             case MyHTML_TAG_PARAM:
1717             case MyHTML_TAG_SOURCE:
1718             case MyHTML_TAG_TRACK:
1719             {
1720 0           myhtml_tree_node_insert_html_element(tree, token);
1721 0           myhtml_tree_open_elements_pop(tree);
1722 0           break;
1723             }
1724            
1725             case MyHTML_TAG_HR:
1726             {
1727 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1728 0           myhtml_tree_tags_close_p(tree, token);
1729             }
1730            
1731 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1732            
1733 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_MENUITEM))
1734 0           myhtml_tree_open_elements_pop(tree);
1735            
1736 0           myhtml_tree_node_insert_html_element(tree, token);
1737 0           myhtml_tree_open_elements_pop(tree);
1738            
1739 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1740 0           break;
1741             }
1742            
1743             case MyHTML_TAG_IMAGE:
1744             {
1745             // parse error
1746             /* %EXTERNAL% VALIDATOR:RULES CONVERT STATUS:ELEMENT_CONVERT LEVEL:ERROR FROM_TAG_ID:MyHTML_TAG_IMAGE FROM_NS:MyHTML_NAMESPACE_ANY FROM_TYPE:MyHTML_TOKEN_TYPE_OPEN TO_TAG_ID:MyHTML_TAG_IMG TO_NS:MyHTML_NAMESPACE_ANY TO_TYPE:MyHTML_TOKEN_TYPE_OPEN */
1747            
1748 0           token->tag_id = MyHTML_TAG_IMG;
1749 0           return true;
1750             }
1751            
1752             case MyHTML_TAG_TEXTAREA:
1753             {
1754 0           myhtml_tree_node_insert_html_element(tree, token);
1755            
1756             // If the next token is a U+000A LINE FEED (LF) character token,
1757             // then ignore that token and move on to the next one.
1758             // (Newlines at the start of textarea elements are ignored as an authoring convenience.)
1759             // !!! see dispatcher (myhtml_rules_tree_dispatcher) for this
1760 0           tree->flags |= MyHTML_TREE_FLAGS_PARSE_FLAG|MyHTML_TREE_FLAGS_PARSE_FLAG_EMIT_NEWLINE;
1761            
1762 0           tree->orig_insert_mode = tree->insert_mode;
1763 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1764 0           tree->insert_mode = MyHTML_INSERTION_MODE_TEXT;
1765 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RCDATA;
1766            
1767 0           break;
1768             }
1769              
1770             case MyHTML_TAG_XMP:
1771             {
1772 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1773 0           myhtml_tree_tags_close_p(tree, token);
1774             }
1775            
1776 0           myhtml_tree_active_formatting_reconstruction(tree);
1777            
1778 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1779 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
1780            
1781 0           myhtml_tree_generic_raw_text_element_parsing_algorithm(tree, token);
1782 0           break;
1783             }
1784              
1785             case MyHTML_TAG_IFRAME:
1786             {
1787 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1788 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
1789            
1790 0           myhtml_tree_generic_raw_text_element_parsing_algorithm(tree, token);
1791 0           break;
1792             }
1793            
1794             case MyHTML_TAG_NOEMBED:
1795             {
1796 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
1797 0           myhtml_tree_generic_raw_text_element_parsing_algorithm(tree, token);
1798 0           break;
1799             }
1800            
1801             case MyHTML_TAG_NOSCRIPT:
1802             {
1803 0 0         if(tree->flags & MyHTML_TREE_FLAGS_SCRIPT) {
1804 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
1805 0           myhtml_tree_generic_raw_text_element_parsing_algorithm(tree, token);
1806             }
1807             else {
1808 0           myhtml_tree_active_formatting_reconstruction(tree);
1809 0           myhtml_tree_node_insert_html_element(tree, token);
1810             }
1811             // else {
1812             // myhtml_tree_node_insert_html_element(tree, token);
1813             // tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD_NOSCRIPT;
1814             // }
1815            
1816 0           break;
1817             }
1818            
1819             case MyHTML_TAG_SELECT:
1820             {
1821 0           myhtml_tree_active_formatting_reconstruction(tree);
1822            
1823 0           myhtml_tree_node_insert_html_element(tree, token);
1824            
1825 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1826            
1827 0 0         if(tree->insert_mode == MyHTML_INSERTION_MODE_IN_TABLE ||
    0          
1828 0 0         tree->insert_mode == MyHTML_INSERTION_MODE_IN_CAPTION ||
1829 0 0         tree->insert_mode == MyHTML_INSERTION_MODE_IN_TABLE_BODY ||
1830 0 0         tree->insert_mode == MyHTML_INSERTION_MODE_IN_ROW ||
1831 0           tree->insert_mode == MyHTML_INSERTION_MODE_IN_CELL)
1832             {
1833 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_SELECT_IN_TABLE;
1834             }
1835             else
1836 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_SELECT;
1837            
1838 0           break;
1839             }
1840            
1841             case MyHTML_TAG_OPTGROUP:
1842             case MyHTML_TAG_OPTION:
1843             {
1844 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1845            
1846 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_OPTION))
1847 0           myhtml_tree_open_elements_pop(tree);
1848            
1849 0           myhtml_tree_active_formatting_reconstruction(tree);
1850            
1851 0           myhtml_tree_node_insert_html_element(tree, token);
1852 0           break;
1853             }
1854            
1855             case MyHTML_TAG_MENUITEM:
1856             {
1857 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1858            
1859 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_MENUITEM))
1860 0           myhtml_tree_open_elements_pop(tree);
1861            
1862 0           myhtml_tree_active_formatting_reconstruction(tree);
1863            
1864 0           myhtml_tree_node_insert_html_element(tree, token);
1865 0           break;
1866             }
1867            
1868             case MyHTML_TAG_RB:
1869             case MyHTML_TAG_RTC:
1870             {
1871 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_RUBY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE)) {
1872 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
1873             }
1874            
1875 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1876 0           if(current_node->tag_id != MyHTML_TAG_RUBY) {
1877             // parse error
1878             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1879             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_RUBY NEED_NS:MyHTML_NAMESPACE_HTML */
1880             }
1881            
1882 0           myhtml_tree_node_insert_html_element(tree, token);
1883 0           break;
1884             }
1885            
1886             case MyHTML_TAG_RP:
1887             case MyHTML_TAG_RT:
1888             {
1889 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_RUBY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE)) {
1890 0           myhtml_tree_generate_implied_end_tags(tree, MyHTML_TAG_RTC, MyHTML_NAMESPACE_HTML);
1891             }
1892            
1893 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1894 0 0         if(current_node->tag_id != MyHTML_TAG_RTC && current_node->tag_id != MyHTML_TAG_RUBY) {
1895             // parse error
1896             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1897             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_RTC NEED_NS:MyHTML_NAMESPACE_HTML */
1898             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_RUBY NEED_NS:MyHTML_NAMESPACE_HTML */
1899             }
1900            
1901 0           myhtml_tree_node_insert_html_element(tree, token);
1902 0           break;
1903             }
1904            
1905             case MyHTML_TAG_MATH:
1906             {
1907 0           myhtml_tree_active_formatting_reconstruction(tree);
1908            
1909 0           myhtml_token_node_wait_for_done(tree->token, token);
1910            
1911 0           myhtml_token_adjust_mathml_attributes(token);
1912 0           myhtml_token_adjust_foreign_attributes(token);
1913            
1914 0           myhtml_tree_node_t* current_node = myhtml_tree_node_insert_foreign_element(tree, token);
1915 0           current_node->ns = MyHTML_NAMESPACE_MATHML;
1916            
1917 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE_SELF)
1918 0           myhtml_tree_open_elements_pop(tree);
1919            
1920 0           break;
1921             }
1922            
1923             case MyHTML_TAG_SVG:
1924             {
1925 0           myhtml_tree_active_formatting_reconstruction(tree);
1926            
1927 0           myhtml_token_node_wait_for_done(tree->token, token);
1928            
1929 0           myhtml_token_adjust_svg_attributes(token);
1930 0           myhtml_token_adjust_foreign_attributes(token);
1931            
1932 0           myhtml_tree_node_t* current_node = myhtml_tree_node_insert_foreign_element(tree, token);
1933 0           current_node->ns = MyHTML_NAMESPACE_SVG;
1934            
1935 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE_SELF)
1936 0           myhtml_tree_open_elements_pop(tree);
1937            
1938 0           break;
1939             }
1940            
1941             case MyHTML_TAG_CAPTION:
1942             case MyHTML_TAG_COL:
1943             case MyHTML_TAG_COLGROUP:
1944             case MyHTML_TAG_FRAME:
1945             case MyHTML_TAG_HEAD:
1946             case MyHTML_TAG_TBODY:
1947             case MyHTML_TAG_TD:
1948             case MyHTML_TAG_TFOOT:
1949             case MyHTML_TAG_TH:
1950             case MyHTML_TAG_THEAD:
1951             case MyHTML_TAG_TR:
1952             {
1953             // parse error
1954             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
1955 0           break;
1956             }
1957            
1958             default:
1959             {
1960 18           myhtml_tree_active_formatting_reconstruction(tree);
1961 18           myhtml_tree_node_insert_html_element(tree, token);
1962            
1963 18           break;
1964             }
1965             }
1966             }
1967            
1968 1580           return false;
1969             }
1970              
1971 0           bool myhtml_insertion_mode_text(myhtml_tree_t* tree, myhtml_token_node_t* token)
1972             {
1973 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
1974             {
1975 0 0         switch (token->tag_id) {
1976             case MyHTML_TAG_SCRIPT:
1977             {
1978             // new document.write is not works; set back
1979 0           myhtml_tree_open_elements_pop(tree);
1980 0           tree->insert_mode = tree->orig_insert_mode;
1981 0           break;
1982             }
1983            
1984             default:
1985             {
1986 0           myhtml_tree_open_elements_pop(tree);
1987 0           tree->insert_mode = tree->orig_insert_mode;
1988 0           break;
1989             }
1990             }
1991             }
1992             else {
1993 0 0         if(token->tag_id == MyHTML_TAG__END_OF_FILE)
1994             {
1995             // parse error
1996             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:PREMATURE_TERMINATION LEVEL:ERROR */
1997            
1998 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1999            
2000 0 0         if(current_node->tag_id == MyHTML_TAG_SCRIPT)
2001 0           current_node->flags |= MyHTML_TREE_FLAGS_ALREADY_STARTED;
2002            
2003 0           myhtml_tree_open_elements_pop(tree);
2004            
2005 0           tree->insert_mode = tree->orig_insert_mode;
2006 0           return true;
2007             }
2008            
2009 0           myhtml_tree_node_insert_text(tree, token);
2010             }
2011            
2012 0           return false;
2013             }
2014              
2015 0           bool myhtml_insertion_mode_in_table(myhtml_tree_t* tree, myhtml_token_node_t* token)
2016             {
2017 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2018             {
2019 0           switch (token->tag_id) {
2020             case MyHTML_TAG_TABLE:
2021             {
2022 0           myhtml_tree_node_t* table_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TABLE, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2023            
2024 0 0         if(table_node == NULL) {
2025             // parse error
2026             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2027 0           break;
2028             }
2029            
2030 0           myhtml_tree_open_elements_pop_until_by_node(tree, table_node, false);
2031 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
2032            
2033 0           break;
2034             }
2035            
2036             case MyHTML_TAG_BODY:
2037             case MyHTML_TAG_CAPTION:
2038             case MyHTML_TAG_COL:
2039             case MyHTML_TAG_COLGROUP:
2040             case MyHTML_TAG_HTML:
2041             case MyHTML_TAG_TBODY:
2042             case MyHTML_TAG_TD:
2043             case MyHTML_TAG_TFOOT:
2044             case MyHTML_TAG_TH:
2045             case MyHTML_TAG_THEAD:
2046             case MyHTML_TAG_TR:
2047             {
2048             // parse error
2049             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2050 0           break;
2051             }
2052            
2053             case MyHTML_TAG_TEMPLATE:
2054             {
2055 0           return myhtml_insertion_mode_in_head(tree, token);
2056             }
2057            
2058             default: {
2059             // parse error
2060 0           tree->foster_parenting = true;
2061 0           myhtml_insertion_mode_in_body(tree, token);
2062 0           tree->foster_parenting = false;
2063            
2064 0           break;
2065             }
2066             }
2067             }
2068             else {
2069 0           switch (token->tag_id)
2070             {
2071             case MyHTML_TAG__TEXT:
2072             {
2073 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2074            
2075 0 0         if((current_node->tag_id == MyHTML_TAG_TABLE ||
    0          
2076 0 0         current_node->tag_id == MyHTML_TAG_TBODY ||
2077 0 0         current_node->tag_id == MyHTML_TAG_TFOOT ||
2078 0 0         current_node->tag_id == MyHTML_TAG_THEAD ||
2079 0 0         current_node->tag_id == MyHTML_TAG_TR) &&
2080 0           current_node->ns == MyHTML_NAMESPACE_HTML)
2081             {
2082 0           myhtml_tree_token_list_clean(tree->token_list);
2083            
2084 0           tree->orig_insert_mode = tree->insert_mode;
2085 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_TEXT;
2086            
2087 0           return true;
2088             }
2089             else {
2090 0           tree->foster_parenting = true;
2091 0           myhtml_insertion_mode_in_body(tree, token);
2092 0           tree->foster_parenting = false;
2093            
2094 0           break;
2095             }
2096             }
2097            
2098             case MyHTML_TAG__COMMENT:
2099 0           myhtml_tree_node_insert_comment(tree, token, 0);
2100 0           break;
2101            
2102             case MyHTML_TAG__DOCTYPE: {
2103             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:WARNING */
2104 0           break;
2105             }
2106            
2107             case MyHTML_TAG_CAPTION:
2108             {
2109 0           myhtml_tree_clear_stack_back_table_context(tree);
2110            
2111 0           myhtml_tree_node_insert_html_element(tree, token);
2112 0           myhtml_tree_active_formatting_append(tree, tree->myhtml->marker);
2113            
2114 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_CAPTION;
2115 0           break;
2116             }
2117            
2118             case MyHTML_TAG_COLGROUP:
2119             {
2120 0           myhtml_tree_clear_stack_back_table_context(tree);
2121            
2122 0           myhtml_tree_node_insert_html_element(tree, token);
2123            
2124 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_COLUMN_GROUP;
2125 0           break;
2126             }
2127            
2128             case MyHTML_TAG_COL:
2129             {
2130 0           myhtml_tree_clear_stack_back_table_context(tree);
2131 0           myhtml_tree_node_insert(tree, MyHTML_TAG_COLGROUP, MyHTML_NAMESPACE_HTML);
2132            
2133 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_COLUMN_GROUP;
2134 0           return true;
2135             }
2136            
2137             case MyHTML_TAG_TBODY:
2138             case MyHTML_TAG_TFOOT:
2139             case MyHTML_TAG_THEAD:
2140             {
2141 0           myhtml_tree_clear_stack_back_table_context(tree);
2142            
2143 0           myhtml_tree_node_insert_html_element(tree, token);
2144            
2145 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2146 0           break;
2147             }
2148            
2149             case MyHTML_TAG_TD:
2150             case MyHTML_TAG_TH:
2151             case MyHTML_TAG_TR:
2152             {
2153 0           myhtml_tree_clear_stack_back_table_context(tree);
2154 0           myhtml_tree_node_insert(tree, MyHTML_TAG_TBODY, MyHTML_NAMESPACE_HTML);
2155            
2156 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2157 0           return true;
2158             }
2159            
2160             case MyHTML_TAG_TABLE:
2161             {
2162             // parse error
2163             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2164            
2165 0           myhtml_tree_node_t* table_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TABLE, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2166            
2167 0 0         if(table_node == NULL) {
2168             // parse error
2169             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
2170            
2171 0           break;
2172             }
2173            
2174 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_TABLE, MyHTML_NAMESPACE_HTML, false);
2175 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
2176            
2177 0           return true;
2178             }
2179            
2180             case MyHTML_TAG_STYLE:
2181             case MyHTML_TAG_SCRIPT:
2182             case MyHTML_TAG_TEMPLATE:
2183             {
2184 0           return myhtml_insertion_mode_in_head(tree, token);
2185             }
2186            
2187             case MyHTML_TAG_INPUT:
2188             {
2189 0           myhtml_token_node_wait_for_done(tree->token, token);
2190            
2191 0 0         if(myhtml_token_attr_match_case(tree->token, token, "type", 4, "hidden", 6) == NULL) {
2192 0           tree->foster_parenting = true;
2193 0           myhtml_insertion_mode_in_body(tree, token);
2194 0           tree->foster_parenting = false;
2195            
2196 0           break;
2197             }
2198            
2199             // parse error
2200             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2201            
2202 0           myhtml_tree_node_insert_html_element(tree, token);
2203 0           myhtml_tree_open_elements_pop(tree);
2204            
2205 0           token->type |= MyHTML_TOKEN_TYPE_CLOSE_SELF;
2206 0           break;
2207             }
2208            
2209             case MyHTML_TAG_FORM:
2210             {
2211             // parse error
2212             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2213            
2214 0           myhtml_tree_node_t* template = myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL);
2215 0 0         if(tree->node_form || template)
    0          
2216             break;
2217            
2218 0           tree->node_form = myhtml_tree_node_insert_html_element(tree, token);
2219            
2220 0           myhtml_tree_open_elements_pop(tree);
2221             }
2222            
2223             case MyHTML_TAG__END_OF_FILE:
2224 0           return myhtml_insertion_mode_in_body(tree, token);
2225            
2226             default:
2227             {
2228             // parse error
2229             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2230            
2231 0           tree->foster_parenting = true;
2232 0           myhtml_insertion_mode_in_body(tree, token);
2233 0           tree->foster_parenting = false;
2234            
2235 0           break;
2236             }
2237             }
2238             }
2239            
2240 0           return false;
2241             }
2242              
2243 0           bool myhtml_insertion_mode_in_table_text(myhtml_tree_t* tree, myhtml_token_node_t* token)
2244             {
2245             // skip NULL, we replaced earlier
2246 0 0         if(token->tag_id == MyHTML_TAG__TEXT)
2247             {
2248 0 0         if(token->type & MyHTML_TOKEN_TYPE_NULL) {
2249             // parse error
2250             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:NULL_CHAR ACTION:IGNORE LEVEL:ERROR */
2251            
2252 0           myhtml_insertion_fix_for_null_char_drop_all(tree, token);
2253            
2254 0 0         if(token->str.length)
2255 0           myhtml_tree_token_list_append(tree->token_list, token);
2256             }
2257             else
2258 0           myhtml_tree_token_list_append(tree->token_list, token);
2259             }
2260             else {
2261 0           myhtml_tree_token_list_t* token_list = tree->token_list;
2262 0           bool is_not_ws = false;
2263            
2264 0 0         for(size_t i = 0; i < token_list->length; i++) {
2265 0 0         if((token_list->list[i]->type & MyHTML_TOKEN_TYPE_WHITESPACE) == 0) {
2266 0           is_not_ws = true;
2267 0           break;
2268             }
2269             }
2270            
2271 0 0         if(is_not_ws)
2272             {
2273 0 0         for(size_t i = 0; i < token_list->length; i++) {
2274             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR TOKEN:token_list->list[i] */
2275            
2276 0           tree->foster_parenting = true;
2277 0           myhtml_insertion_mode_in_body(tree, token_list->list[i]);
2278 0           tree->foster_parenting = false;
2279             }
2280             }
2281             else {
2282 0 0         for(size_t i = 0; i < token_list->length; i++) {
2283 0           myhtml_tree_node_insert_text(tree, token_list->list[i]);
2284             }
2285             }
2286            
2287 0           tree->insert_mode = tree->orig_insert_mode;
2288 0           return true;
2289             }
2290            
2291 0           return false;
2292             }
2293              
2294 0           bool myhtml_insertion_mode_in_caption(myhtml_tree_t* tree, myhtml_token_node_t* token)
2295             {
2296 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2297             {
2298 0           switch (token->tag_id) {
2299             case MyHTML_TAG_CAPTION:
2300             {
2301 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE) == NULL) {
2302             // parse error
2303             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2304 0           break;
2305             }
2306            
2307 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
2308            
2309 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2310 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_CAPTION) == false) {
2311             // parse error
2312             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
2313             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_CAPTION NEED_NS:MyHTML_NAMESPACE_HTML */
2314             }
2315            
2316 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, false);
2317 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
2318            
2319 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2320 0           break;
2321             }
2322            
2323             case MyHTML_TAG_TABLE:
2324             {
2325 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE) == NULL) {
2326             // parse error
2327             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2328 0           break;
2329             }
2330            
2331 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
2332            
2333 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2334 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_CAPTION) == false) {
2335             // parse error
2336             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
2337             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_CAPTION NEED_NS:MyHTML_NAMESPACE_HTML */
2338             }
2339            
2340 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, false);
2341 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
2342            
2343 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2344 0           return true;
2345             }
2346            
2347             case MyHTML_TAG_BODY:
2348             case MyHTML_TAG_COL:
2349             case MyHTML_TAG_COLGROUP:
2350             case MyHTML_TAG_HTML:
2351             case MyHTML_TAG_TBODY:
2352             case MyHTML_TAG_TD:
2353             case MyHTML_TAG_TFOOT:
2354             case MyHTML_TAG_TH:
2355             case MyHTML_TAG_THEAD:
2356             case MyHTML_TAG_TR:
2357             {
2358             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2359 0           break;
2360             }
2361            
2362             default:
2363 0           return myhtml_insertion_mode_in_body(tree, token);
2364             }
2365             }
2366             else {
2367 0 0         switch (token->tag_id)
2368             {
2369             case MyHTML_TAG_CAPTION:
2370             case MyHTML_TAG_COL:
2371             case MyHTML_TAG_COLGROUP:
2372             case MyHTML_TAG_TBODY:
2373             case MyHTML_TAG_TD:
2374             case MyHTML_TAG_TFOOT:
2375             case MyHTML_TAG_TH:
2376             case MyHTML_TAG_THEAD:
2377             case MyHTML_TAG_TR:
2378             {
2379 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE) == NULL) {
2380             // parse error
2381             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2382 0           break;
2383             }
2384            
2385 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
2386            
2387 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2388 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_CAPTION) == false) {
2389             // parse error
2390             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
2391             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:MyHTML_TAG_CAPTION NEED_NS:MyHTML_NAMESPACE_HTML */
2392             }
2393            
2394 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, false);
2395 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
2396            
2397 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2398 0           return true;
2399             }
2400            
2401             default:
2402 0           return myhtml_insertion_mode_in_body(tree, token);
2403             }
2404             }
2405            
2406 0           return false;
2407             }
2408              
2409 0           bool myhtml_insertion_mode_in_column_group(myhtml_tree_t* tree, myhtml_token_node_t* token)
2410             {
2411 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2412             {
2413 0           switch (token->tag_id) {
2414             case MyHTML_TAG_COLGROUP:
2415             {
2416 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2417            
2418 0 0         if(current_node && myhtml_is_html_node(current_node, MyHTML_TAG_COLGROUP)) {
    0          
2419 0           myhtml_tree_open_elements_pop(tree);
2420            
2421 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2422 0           return false;
2423             }
2424            
2425             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2426 0           break;
2427             }
2428            
2429             case MyHTML_TAG_COL:
2430             {
2431             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2432            
2433 0           break;
2434             }
2435            
2436             case MyHTML_TAG_TEMPLATE:
2437             {
2438 0           return myhtml_insertion_mode_in_head(tree, token);
2439             }
2440            
2441             default: {
2442 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2443            
2444 0 0         if(current_node && myhtml_is_html_node(current_node, MyHTML_TAG_COLGROUP)) {
    0          
2445 0           myhtml_tree_open_elements_pop(tree);
2446            
2447 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2448 0           return true;
2449             }
2450            
2451             // parse error
2452             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2453 0           break;
2454             }
2455             }
2456             }
2457             else {
2458 0           switch (token->tag_id)
2459             {
2460             case MyHTML_TAG__TEXT:
2461             {
2462 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE) {
2463 0           myhtml_tree_node_insert_text(tree, token);
2464 0           break;
2465             }
2466            
2467 0           myhtml_token_node_t* new_token = myhtml_insertion_fix_split_for_text_begin_ws(tree, token);
2468 0 0         if(new_token)
2469 0           myhtml_tree_node_insert_text(tree, new_token);
2470            
2471             /* default: */
2472 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2473            
2474 0 0         if(current_node && myhtml_is_html_node(current_node, MyHTML_TAG_COLGROUP)) {
    0          
2475 0           myhtml_tree_open_elements_pop(tree);
2476            
2477 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2478 0           return true;
2479             }
2480            
2481             // parse error
2482             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2483 0           break;
2484             }
2485            
2486             case MyHTML_TAG__COMMENT:
2487             {
2488 0           myhtml_tree_node_insert_comment(tree, token, 0);
2489 0           break;
2490             }
2491            
2492             case MyHTML_TAG__DOCTYPE: {
2493             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
2494 0           break;
2495             }
2496             case MyHTML_TAG_HTML:
2497             {
2498 0           return myhtml_insertion_mode_in_body(tree, token);
2499             }
2500            
2501             case MyHTML_TAG_COL:
2502             {
2503 0           myhtml_tree_node_insert_html_element(tree, token);
2504 0           myhtml_tree_open_elements_pop(tree);
2505 0           break;
2506             }
2507            
2508             case MyHTML_TAG_TEMPLATE:
2509             {
2510 0           return myhtml_insertion_mode_in_head(tree, token);
2511             }
2512            
2513             case MyHTML_TAG__END_OF_FILE:
2514 0           return myhtml_insertion_mode_in_body(tree, token);
2515            
2516             default:
2517             {
2518 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2519            
2520 0 0         if(current_node && myhtml_is_html_node(current_node, MyHTML_TAG_COLGROUP)) {
    0          
2521 0           myhtml_tree_open_elements_pop(tree);
2522            
2523 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2524 0           return true;
2525             }
2526            
2527             // parse error
2528             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2529 0           break;
2530             }
2531             }
2532             }
2533            
2534 0           return false;
2535             }
2536              
2537 0           bool myhtml_insertion_mode_in_table_body(myhtml_tree_t* tree, myhtml_token_node_t* token)
2538             {
2539 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2540             {
2541 0           switch (token->tag_id) {
2542             case MyHTML_TAG_TBODY:
2543             case MyHTML_TAG_TFOOT:
2544             case MyHTML_TAG_THEAD:
2545             {
2546 0           myhtml_tree_node_t* node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2547            
2548 0 0         if(node == NULL) {
2549             // parse error
2550             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2551 0           break;
2552             }
2553            
2554 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2555 0           myhtml_tree_open_elements_pop(tree);
2556            
2557 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2558 0           break;
2559             }
2560            
2561             case MyHTML_TAG_TABLE:
2562             {
2563 0           myhtml_tree_node_t* tbody_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TBODY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2564 0           myhtml_tree_node_t* tfoot_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TFOOT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2565 0           myhtml_tree_node_t* thead_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_THEAD, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2566            
2567 0 0         if(tbody_node == NULL && tfoot_node == NULL && thead_node == NULL) {
    0          
    0          
2568             // parse error
2569             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2570             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_THEAD NEED_NS:MyHTML_NAMESPACE_HTML */
2571             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_TBODY NEED_NS:MyHTML_NAMESPACE_HTML */
2572             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_TFOOT NEED_NS:MyHTML_NAMESPACE_HTML */
2573 0           break;
2574             }
2575            
2576 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2577 0           myhtml_tree_open_elements_pop(tree);
2578            
2579 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2580 0           return true;
2581             }
2582            
2583             case MyHTML_TAG_BODY:
2584             case MyHTML_TAG_CAPTION:
2585             case MyHTML_TAG_COL:
2586             case MyHTML_TAG_COLGROUP:
2587             case MyHTML_TAG_HTML:
2588             case MyHTML_TAG_TD:
2589             case MyHTML_TAG_TH:
2590             case MyHTML_TAG_TR:
2591             {
2592             // parse error
2593             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2594 0           break;
2595             }
2596            
2597             default:
2598 0           return myhtml_insertion_mode_in_table(tree, token);
2599             }
2600             }
2601             else {
2602 0           switch (token->tag_id)
2603             {
2604             case MyHTML_TAG_TR:
2605             {
2606 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2607            
2608 0           myhtml_tree_node_insert_html_element(tree, token);
2609            
2610 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_ROW;
2611 0           break;
2612             }
2613            
2614             case MyHTML_TAG_TH:
2615             case MyHTML_TAG_TD:
2616             {
2617             // parse error
2618             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2619            
2620 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2621            
2622 0           myhtml_tree_node_insert(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML);
2623            
2624 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_ROW;
2625 0           return true;
2626             }
2627            
2628             case MyHTML_TAG_CAPTION:
2629             case MyHTML_TAG_COL:
2630             case MyHTML_TAG_COLGROUP:
2631             case MyHTML_TAG_TBODY:
2632             case MyHTML_TAG_TFOOT:
2633             case MyHTML_TAG_THEAD:
2634             {
2635 0           myhtml_tree_node_t* tbody_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TBODY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2636 0           myhtml_tree_node_t* tfoot_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TFOOT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2637 0           myhtml_tree_node_t* thead_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_THEAD, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2638            
2639 0 0         if(tbody_node == NULL && tfoot_node == NULL && thead_node == NULL) {
    0          
    0          
2640             // parse error
2641             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2642             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_THEAD NEED_NS:MyHTML_NAMESPACE_HTML */
2643             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_TBODY NEED_NS:MyHTML_NAMESPACE_HTML */
2644             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_TFOOT NEED_NS:MyHTML_NAMESPACE_HTML */
2645 0           break;
2646             }
2647            
2648 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2649 0           myhtml_tree_open_elements_pop(tree);
2650            
2651 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2652 0           return true;
2653             }
2654            
2655             default:
2656 0           return myhtml_insertion_mode_in_table(tree, token);
2657             }
2658             }
2659            
2660 0           return false;
2661             }
2662              
2663 0           bool myhtml_insertion_mode_in_row(myhtml_tree_t* tree, myhtml_token_node_t* token)
2664             {
2665 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2666             {
2667 0           switch (token->tag_id) {
2668             case MyHTML_TAG_TR:
2669             {
2670 0           myhtml_tree_node_t* tr_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2671            
2672 0 0         if(tr_node == NULL) {
2673             // parse error
2674             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2675 0           break;
2676             }
2677            
2678 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2679            
2680 0           myhtml_tree_open_elements_pop(tree);
2681            
2682 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2683 0           break;
2684             }
2685            
2686             case MyHTML_TAG_TABLE:
2687             {
2688 0           myhtml_tree_node_t* tr_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2689            
2690 0 0         if(tr_node == NULL) {
2691             // parse error
2692             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2693             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_TR NEED_NS:MyHTML_NAMESPACE_HTML */
2694 0           break;
2695             }
2696            
2697 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2698 0           myhtml_tree_open_elements_pop(tree);
2699            
2700 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2701 0           return true;
2702             }
2703            
2704             case MyHTML_TAG_TBODY:
2705             case MyHTML_TAG_TFOOT:
2706             case MyHTML_TAG_THEAD:
2707             {
2708 0           myhtml_tree_node_t* node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2709 0 0         if(node == NULL) {
2710             // parse error
2711             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2712 0           break;
2713             }
2714            
2715 0           myhtml_tree_node_t* tr_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2716 0 0         if(tr_node == NULL)
2717 0           break;
2718            
2719 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2720 0           myhtml_tree_open_elements_pop(tree);
2721            
2722 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2723 0           return true;
2724             }
2725            
2726             case MyHTML_TAG_BODY:
2727             case MyHTML_TAG_CAPTION:
2728             case MyHTML_TAG_COL:
2729             case MyHTML_TAG_COLGROUP:
2730             case MyHTML_TAG_HTML:
2731             case MyHTML_TAG_TD:
2732             case MyHTML_TAG_TH:
2733             {
2734             // parse error
2735             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2736 0           break;
2737             }
2738            
2739             default:
2740 0           return myhtml_insertion_mode_in_table(tree, token);
2741             }
2742             }
2743             else {
2744 0           switch (token->tag_id)
2745             {
2746             case MyHTML_TAG_TH:
2747             case MyHTML_TAG_TD:
2748             {
2749 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2750            
2751 0           myhtml_tree_node_insert_html_element(tree, token);
2752 0           myhtml_tree_active_formatting_append(tree, tree->myhtml->marker);
2753            
2754 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_CELL;
2755 0           break;
2756             }
2757             case MyHTML_TAG_CAPTION:
2758             case MyHTML_TAG_COL:
2759             case MyHTML_TAG_COLGROUP:
2760             case MyHTML_TAG_TBODY:
2761             case MyHTML_TAG_TFOOT:
2762             case MyHTML_TAG_THEAD:
2763             case MyHTML_TAG_TR:
2764             {
2765 0           myhtml_tree_node_t* tr_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2766            
2767 0 0         if(tr_node == NULL) {
2768             // parse error
2769             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2770             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_TR NEED_NS:MyHTML_NAMESPACE_HTML */
2771 0           break;
2772             }
2773            
2774 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2775 0           myhtml_tree_open_elements_pop(tree);
2776            
2777 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2778 0           return true;
2779             }
2780            
2781             default:
2782 0           return myhtml_insertion_mode_in_table(tree, token);
2783             }
2784             }
2785            
2786 0           return false;
2787             }
2788              
2789 0           bool myhtml_insertion_mode_in_cell(myhtml_tree_t* tree, myhtml_token_node_t* token)
2790             {
2791 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2792             {
2793 0           switch (token->tag_id) {
2794             case MyHTML_TAG_TD:
2795             case MyHTML_TAG_TH:
2796             {
2797 0           myhtml_tree_node_t* node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2798            
2799 0 0         if(node == NULL) {
2800             // parse error
2801             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2802 0           break;
2803             }
2804            
2805 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
2806            
2807 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2808            
2809 0           if(myhtml_is_html_node(current_node, token->tag_id) == false)
2810             {
2811             // parse error
2812             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
2813             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:NULL HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:token->tag_id NEED_NS:MyHTML_NAMESPACE_HTML */
2814             }
2815            
2816 0           myhtml_tree_open_elements_pop_until(tree, token->tag_id, MyHTML_NAMESPACE_HTML, false);
2817            
2818 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
2819            
2820 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_ROW;
2821 0           break;
2822             }
2823            
2824             case MyHTML_TAG_BODY:
2825             case MyHTML_TAG_CAPTION:
2826             case MyHTML_TAG_COL:
2827             case MyHTML_TAG_COLGROUP:
2828             case MyHTML_TAG_HTML:
2829             {
2830             // parse error
2831             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2832 0           break;
2833             }
2834            
2835            
2836             case MyHTML_TAG_TABLE:
2837             case MyHTML_TAG_TBODY:
2838             case MyHTML_TAG_TFOOT:
2839             case MyHTML_TAG_THEAD:
2840             case MyHTML_TAG_TR:
2841             {
2842 0           myhtml_tree_node_t* node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2843            
2844 0 0         if(node == NULL) {
2845             // parse error
2846             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2847 0           break;
2848             }
2849            
2850 0           node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TD, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2851 0 0         if(node) {
2852 0           myhtml_tree_close_cell(tree, node, token);
2853             }
2854             else {
2855 0           node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TH, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2856 0 0         if(node)
2857 0           myhtml_tree_close_cell(tree, node, token);
2858             }
2859            
2860 0           return true;
2861             }
2862            
2863             default:
2864 0           return myhtml_insertion_mode_in_table(tree, token);
2865             }
2866             }
2867             else {
2868 0 0         switch (token->tag_id)
2869             {
2870             case MyHTML_TAG_CAPTION:
2871             case MyHTML_TAG_COL:
2872             case MyHTML_TAG_COLGROUP:
2873             case MyHTML_TAG_TBODY:
2874             case MyHTML_TAG_TD:
2875             case MyHTML_TAG_TFOOT:
2876             case MyHTML_TAG_TH:
2877             case MyHTML_TAG_THEAD:
2878             case MyHTML_TAG_TR:
2879             {
2880 0           myhtml_tree_node_t* td_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TD, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2881 0           myhtml_tree_node_t* th_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TH, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2882            
2883 0 0         if(td_node == NULL && th_node == NULL) {
    0          
2884             // parse error
2885             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2886             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_TD NEED_NS:MyHTML_NAMESPACE_HTML */
2887             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:NULL NEED:NULL HAVE_TAG_ID:MyHTML_TAG__UNDEF HAVE_NS:MyHTML_NAMESPACE_UNDEF NEED_TAG_ID:MyHTML_TAG_TH NEED_NS:MyHTML_NAMESPACE_HTML */
2888            
2889 0           break;
2890             }
2891            
2892 0 0         myhtml_tree_close_cell(tree, (td_node == NULL ? th_node : td_node), token);
2893            
2894 0           return true;
2895             }
2896            
2897             default:
2898 0           return myhtml_insertion_mode_in_body(tree, token);
2899             }
2900             }
2901            
2902 0           return false;
2903             }
2904              
2905 0           bool myhtml_insertion_mode_in_select(myhtml_tree_t* tree, myhtml_token_node_t* token)
2906             {
2907 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2908             {
2909 0           switch (token->tag_id) {
2910             case MyHTML_TAG_OPTGROUP:
2911             {
2912 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2913            
2914 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_OPTION))
2915             {
2916 0 0         if(tree->open_elements->length > 1) {
2917 0           myhtml_tree_node_t *optgrp_node = tree->open_elements->list[ tree->open_elements->length - 2 ];
2918            
2919 0 0         if(myhtml_is_html_node(optgrp_node, MyHTML_TAG_OPTGROUP))
2920             {
2921 0           myhtml_tree_open_elements_pop(tree);
2922             }
2923             }
2924             }
2925            
2926 0           current_node = myhtml_tree_current_node(tree);
2927            
2928 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_OPTGROUP))
2929 0           myhtml_tree_open_elements_pop(tree);
2930             else {
2931             // parse error
2932             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED ACTION:IGNORE LEVEL:ERROR */
2933            
2934 0           break;
2935             }
2936            
2937 0           break;
2938             }
2939            
2940             case MyHTML_TAG_OPTION:
2941             {
2942 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2943            
2944 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_OPTION))
2945 0           myhtml_tree_open_elements_pop(tree);
2946             else {
2947             // parse error
2948             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2949            
2950 0           break;
2951             }
2952            
2953 0           break;
2954             }
2955            
2956             case MyHTML_TAG_SELECT:
2957             {
2958 0           myhtml_tree_node_t* select_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_SELECT);
2959            
2960 0 0         if(select_node == NULL) {
2961             // parse error
2962             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2963 0           break;
2964             }
2965            
2966 0           myhtml_tree_open_elements_pop_until_by_node(tree, select_node, false);
2967 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
2968            
2969 0           break;
2970             }
2971            
2972             case MyHTML_TAG_TEMPLATE:
2973 0           return myhtml_insertion_mode_in_head(tree, token);
2974            
2975             default: {
2976             // parse error
2977             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2978            
2979 0           break;
2980             }
2981             }
2982             }
2983             else {
2984 0           switch (token->tag_id)
2985             {
2986             case MyHTML_TAG__TEXT: {
2987 0 0         if(token->type & MyHTML_TOKEN_TYPE_NULL) {
2988             // parse error
2989             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:NULL_CHAR ACTION:IGNORE LEVEL:ERROR */
2990            
2991 0           myhtml_insertion_fix_for_null_char_drop_all(tree, token);
2992            
2993 0 0         if(token->str.length)
2994 0           myhtml_tree_node_insert_text(tree, token);
2995             }
2996             else
2997 0           myhtml_tree_node_insert_text(tree, token);
2998            
2999 0           break;
3000             }
3001            
3002             case MyHTML_TAG__COMMENT:
3003 0           myhtml_tree_node_insert_comment(tree, token, NULL);
3004 0           break;
3005            
3006             case MyHTML_TAG__DOCTYPE: {
3007             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3008            
3009 0           break;
3010             }
3011            
3012             case MyHTML_TAG_HTML:
3013 0           return myhtml_insertion_mode_in_body(tree, token);
3014            
3015             case MyHTML_TAG_OPTION:
3016             {
3017 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3018            
3019 0 0         if(myhtml_is_html_node(current_node, token->tag_id))
3020 0           myhtml_tree_open_elements_pop(tree);
3021            
3022 0           myhtml_tree_node_insert_html_element(tree, token);
3023 0           break;
3024             }
3025            
3026             case MyHTML_TAG_OPTGROUP:
3027             {
3028 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3029            
3030 0 0         if(current_node->tag_id == MyHTML_TAG_OPTION &&
    0          
3031 0           current_node->ns == MyHTML_NAMESPACE_HTML)
3032 0           myhtml_tree_open_elements_pop(tree);
3033            
3034 0           current_node = myhtml_tree_current_node(tree);
3035            
3036 0 0         if(current_node->tag_id == token->tag_id &&
    0          
3037 0           current_node->ns == MyHTML_NAMESPACE_HTML)
3038 0           myhtml_tree_open_elements_pop(tree);
3039            
3040 0           myhtml_tree_node_insert_html_element(tree, token);
3041 0           break;
3042             }
3043            
3044             case MyHTML_TAG_SELECT:
3045             {
3046             // parse error
3047             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
3048            
3049 0           myhtml_tree_node_t* select_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_SELECT);
3050            
3051 0 0         if(select_node == NULL) {
3052             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
3053            
3054 0           break;
3055             }
3056            
3057 0           myhtml_tree_open_elements_pop_until_by_node(tree, select_node, false);
3058 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3059            
3060 0           break;
3061             }
3062            
3063             case MyHTML_TAG_INPUT:
3064             case MyHTML_TAG_KEYGEN:
3065             case MyHTML_TAG_TEXTAREA:
3066             {
3067             // parse error
3068             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
3069            
3070 0           myhtml_tree_node_t* select_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_SELECT);
3071            
3072 0 0         if(select_node == NULL) {
3073             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
3074            
3075 0           break;
3076             }
3077            
3078 0           myhtml_tree_open_elements_pop_until_by_node(tree, select_node, false);
3079 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3080            
3081 0           return true;
3082             }
3083            
3084             case MyHTML_TAG_SCRIPT:
3085             case MyHTML_TAG_TEMPLATE:
3086 0           return myhtml_insertion_mode_in_head(tree, token);
3087            
3088             case MyHTML_TAG__END_OF_FILE:
3089 0           return myhtml_insertion_mode_in_body(tree, token);
3090            
3091             default: {
3092             // parse error
3093             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3094 0           break;
3095             }
3096             }
3097             }
3098            
3099 0           return false;
3100             }
3101              
3102 0           bool myhtml_insertion_mode_in_select_in_table(myhtml_tree_t* tree, myhtml_token_node_t* token)
3103             {
3104 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3105             {
3106 0 0         switch (token->tag_id) {
3107             case MyHTML_TAG_CAPTION:
3108             case MyHTML_TAG_TABLE:
3109             case MyHTML_TAG_TBODY:
3110             case MyHTML_TAG_TFOOT:
3111             case MyHTML_TAG_THEAD:
3112             case MyHTML_TAG_TR:
3113             case MyHTML_TAG_TD:
3114             case MyHTML_TAG_TH:
3115             {
3116             // parse error
3117             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
3118            
3119 0           myhtml_tree_node_t* some_node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
3120            
3121 0 0         if(some_node == NULL) {
3122             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
3123            
3124 0           break;
3125             }
3126            
3127 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, false);
3128 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3129            
3130 0           return true;
3131             }
3132            
3133             default:
3134 0           return myhtml_insertion_mode_in_select(tree, token);
3135             }
3136             }
3137             else {
3138 0 0         switch (token->tag_id)
3139             {
3140             case MyHTML_TAG_CAPTION:
3141             case MyHTML_TAG_TABLE:
3142             case MyHTML_TAG_TBODY:
3143             case MyHTML_TAG_TFOOT:
3144             case MyHTML_TAG_THEAD:
3145             case MyHTML_TAG_TR:
3146             case MyHTML_TAG_TD:
3147             case MyHTML_TAG_TH:
3148             {
3149             // parse error
3150             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
3151            
3152 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, false);
3153 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3154            
3155 0           return true;
3156             }
3157            
3158             default:
3159 0           return myhtml_insertion_mode_in_select(tree, token);
3160             }
3161             }
3162            
3163 0           return false;
3164             }
3165              
3166 0           bool myhtml_insertion_mode_in_template(myhtml_tree_t* tree, myhtml_token_node_t* token)
3167             {
3168 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3169             {
3170 0 0         switch (token->tag_id) {
3171             case MyHTML_TAG_TEMPLATE:
3172 0           return myhtml_insertion_mode_in_body(tree, token);
3173            
3174             default: {
3175             // parse error
3176             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3177            
3178 0           break;
3179             }
3180             }
3181             }
3182             else {
3183 0           switch (token->tag_id)
3184             {
3185             case MyHTML_TAG__TEXT:
3186             case MyHTML_TAG__COMMENT:
3187             case MyHTML_TAG__DOCTYPE:
3188 0           return myhtml_insertion_mode_in_body(tree, token);
3189            
3190             case MyHTML_TAG_BASE:
3191             case MyHTML_TAG_BASEFONT:
3192             case MyHTML_TAG_BGSOUND:
3193             case MyHTML_TAG_LINK:
3194             case MyHTML_TAG_META:
3195             case MyHTML_TAG_NOFRAMES:
3196             case MyHTML_TAG_SCRIPT:
3197             case MyHTML_TAG_STYLE:
3198             case MyHTML_TAG_TEMPLATE:
3199             case MyHTML_TAG_TITLE:
3200 0           return myhtml_insertion_mode_in_head(tree, token);
3201            
3202             case MyHTML_TAG_CAPTION:
3203             case MyHTML_TAG_COLGROUP:
3204             case MyHTML_TAG_TBODY:
3205             case MyHTML_TAG_TFOOT:
3206             case MyHTML_TAG_THEAD:
3207 0           myhtml_tree_template_insertion_pop(tree);
3208 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_TABLE);
3209            
3210 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
3211 0           return true;
3212            
3213             case MyHTML_TAG_COL:
3214 0           myhtml_tree_template_insertion_pop(tree);
3215 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_COLUMN_GROUP);
3216            
3217 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_COLUMN_GROUP;
3218 0           return true;
3219            
3220             case MyHTML_TAG_TR:
3221 0           myhtml_tree_template_insertion_pop(tree);
3222 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_TABLE_BODY);
3223            
3224 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
3225 0           return true;
3226            
3227             case MyHTML_TAG_TD:
3228             case MyHTML_TAG_TH:
3229 0           myhtml_tree_template_insertion_pop(tree);
3230 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_ROW);
3231            
3232 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_ROW;
3233 0           return true;
3234            
3235             case MyHTML_TAG__END_OF_FILE:
3236             {
3237 0           myhtml_tree_node_t* node = myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL);
3238            
3239 0 0         if(node == NULL) {
3240 0           myhtml_rules_stop_parsing(tree);
3241 0           break;
3242             }
3243            
3244             // parse error
3245             /* %EXTERNAL% VALIDATOR:RULES TAG STATUS:ELEMENT_NOT_CLOSED LEVEL:ERROR TAG_ID:MyHTML_TAG_TEMPLATE NS:MyHTML_NAMESPACE_HTML */
3246            
3247 0           myhtml_tree_open_elements_pop_until_by_node(tree, node, false);
3248 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
3249 0           myhtml_tree_template_insertion_pop(tree);
3250 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3251            
3252 0           return true;
3253             }
3254            
3255             default:
3256 0           myhtml_tree_template_insertion_pop(tree);
3257 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_BODY);
3258            
3259 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3260 0           return true;
3261             }
3262             }
3263            
3264 0           return false;
3265             }
3266              
3267 1           bool myhtml_insertion_mode_after_body(myhtml_tree_t* tree, myhtml_token_node_t* token)
3268             {
3269 1 50         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3270             {
3271 0 0         switch (token->tag_id) {
3272             case MyHTML_TAG_HTML:
3273             {
3274 0 0         if(tree->fragment) {
3275             // parse error
3276             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED ACTION:IGNORE LEVEL:ERROR */
3277            
3278 0           break;
3279             }
3280            
3281 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_AFTER_BODY;
3282 0           break;
3283             }
3284            
3285             default: {
3286             // parse error
3287             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3288            
3289 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3290 0           return true;
3291             }
3292             }
3293             }
3294             else {
3295 1           switch (token->tag_id)
3296             {
3297             case MyHTML_TAG__TEXT:
3298             {
3299 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE)
3300 0           return myhtml_insertion_mode_in_body(tree, token);
3301            
3302 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3303 0           return true;
3304             }
3305            
3306             case MyHTML_TAG__COMMENT:
3307             {
3308 0 0         if(tree->open_elements->length == 0) {
3309             MyCORE_DEBUG_ERROR("after body state; open_elements length < 1");
3310 0           break;
3311             }
3312            
3313 0           myhtml_tree_node_t* adjusted_location = tree->open_elements->list[0];
3314            
3315             // state 2
3316 0           myhtml_tree_node_t* node = myhtml_tree_node_create(tree);
3317            
3318 0           node->tag_id = MyHTML_TAG__COMMENT;
3319 0           node->token = token;
3320 0           node->ns = adjusted_location->ns;
3321            
3322 0           myhtml_tree_node_add_child(adjusted_location, node);
3323            
3324 0           break;
3325             }
3326            
3327             case MyHTML_TAG__DOCTYPE: {
3328             // parse error
3329             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3330            
3331 0           break;
3332             }
3333             case MyHTML_TAG_HTML:
3334 0           return myhtml_insertion_mode_in_body(tree, token);
3335            
3336             case MyHTML_TAG__END_OF_FILE:
3337 1           myhtml_rules_stop_parsing(tree);
3338 1           break;
3339            
3340             default: {
3341             // parse error
3342             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3343            
3344 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3345 0           return true;
3346             }
3347             }
3348             }
3349            
3350 1           return false;
3351             }
3352              
3353 0           bool myhtml_insertion_mode_in_frameset(myhtml_tree_t* tree, myhtml_token_node_t* token)
3354             {
3355 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3356             {
3357 0 0         switch (token->tag_id) {
3358             case MyHTML_TAG_FRAMESET:
3359             {
3360 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3361            
3362 0 0         if(current_node == tree->document->child) {
3363             // parse error
3364             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED ACTION:IGNORE LEVEL:ERROR */
3365            
3366 0           break;
3367             }
3368            
3369 0           myhtml_tree_open_elements_pop(tree);
3370            
3371 0           current_node = myhtml_tree_current_node(tree);
3372            
3373 0 0         if(tree->fragment == NULL &&
    0          
3374 0 0         !(current_node->tag_id == MyHTML_TAG_FRAMESET &&
3375 0           current_node->ns == MyHTML_NAMESPACE_HTML))
3376             {
3377 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_FRAMESET;
3378             }
3379            
3380 0           break;
3381             }
3382            
3383             default: {
3384             // parse error
3385             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3386            
3387 0           break;
3388             }
3389             }
3390             }
3391             else {
3392 0           switch (token->tag_id)
3393             {
3394             case MyHTML_TAG__TEXT:
3395             {
3396 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE) {
3397 0           myhtml_tree_node_insert_text(tree, token);
3398 0           break;
3399             }
3400            
3401             // parse error
3402             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3403            
3404 0           myhtml_token_node_wait_for_done(tree->token, token);
3405 0           mycore_string_stay_only_whitespace(&token->str);
3406            
3407 0 0         if(token->str.length)
3408 0           myhtml_tree_node_insert_text(tree, token);
3409            
3410 0           break;
3411             }
3412            
3413             case MyHTML_TAG__COMMENT:
3414             {
3415 0           myhtml_tree_node_insert_comment(tree, token, NULL);
3416 0           break;
3417             }
3418            
3419             case MyHTML_TAG__DOCTYPE: {
3420             // parse error
3421             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3422            
3423 0           break;
3424             }
3425            
3426             case MyHTML_TAG_HTML:
3427 0           return myhtml_insertion_mode_in_body(tree, token);
3428            
3429             case MyHTML_TAG_FRAMESET:
3430 0           myhtml_tree_node_insert_html_element(tree, token);
3431 0           break;
3432            
3433             case MyHTML_TAG_FRAME:
3434 0           myhtml_tree_node_insert_html_element(tree, token);
3435 0           myhtml_tree_open_elements_pop(tree);
3436 0           break;
3437            
3438             case MyHTML_TAG_NOFRAMES:
3439 0           return myhtml_insertion_mode_in_head(tree, token);
3440            
3441             case MyHTML_TAG__END_OF_FILE:
3442             {
3443 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3444            
3445 0           if(current_node == tree->document->child) {
3446             // parse error
3447             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3448             }
3449            
3450 0           myhtml_rules_stop_parsing(tree);
3451 0           break;
3452             }
3453            
3454             default: {
3455             // parse error
3456             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3457            
3458 0           break;
3459             }
3460             }
3461             }
3462            
3463 0           return false;
3464             }
3465              
3466 0           bool myhtml_insertion_mode_after_frameset(myhtml_tree_t* tree, myhtml_token_node_t* token)
3467             {
3468 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3469             {
3470 0 0         switch (token->tag_id) {
3471             case MyHTML_TAG_HTML:
3472 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_AFTER_FRAMESET;
3473 0           break;
3474            
3475             default: {
3476             // parse error
3477             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3478            
3479 0           break;
3480             }
3481             }
3482             }
3483             else {
3484 0           switch (token->tag_id)
3485             {
3486             case MyHTML_TAG__TEXT:
3487             {
3488 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE) {
3489 0           myhtml_tree_node_insert_text(tree, token);
3490 0           break;
3491             }
3492            
3493             // parse error
3494             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3495            
3496 0           myhtml_token_node_wait_for_done(tree->token, token);
3497 0           mycore_string_stay_only_whitespace(&token->str);
3498            
3499 0 0         if(token->str.length)
3500 0           myhtml_tree_node_insert_text(tree, token);
3501            
3502 0           break;
3503             }
3504            
3505             case MyHTML_TAG__COMMENT:
3506             {
3507 0           myhtml_tree_node_insert_comment(tree, token, NULL);
3508 0           break;
3509             }
3510            
3511             case MyHTML_TAG__DOCTYPE: {
3512             // parse error
3513             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3514 0           break;
3515             }
3516            
3517             case MyHTML_TAG_HTML:
3518 0           return myhtml_insertion_mode_in_body(tree, token);
3519            
3520             case MyHTML_TAG_NOFRAMES:
3521 0           return myhtml_insertion_mode_in_head(tree, token);
3522            
3523             case MyHTML_TAG__END_OF_FILE:
3524 0           myhtml_rules_stop_parsing(tree);
3525 0           break;
3526            
3527             default: {
3528             // parse error
3529             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3530            
3531 0           break;
3532             }
3533             }
3534             }
3535            
3536 0           return false;
3537             }
3538              
3539 0           bool myhtml_insertion_mode_after_after_body(myhtml_tree_t* tree, myhtml_token_node_t* token)
3540             {
3541 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3542             {
3543 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3544 0           return true;
3545             }
3546             else {
3547 0           switch (token->tag_id)
3548             {
3549             case MyHTML_TAG__COMMENT:
3550             {
3551 0           myhtml_tree_node_t* adjusted_location = tree->document;
3552 0           myhtml_tree_node_t* node = myhtml_tree_node_create(tree);
3553            
3554 0           node->tag_id = MyHTML_TAG__COMMENT;
3555 0           node->token = token;
3556 0           node->ns = adjusted_location->ns;
3557            
3558 0           myhtml_tree_node_add_child(adjusted_location, node);
3559 0           break;
3560             }
3561            
3562             case MyHTML_TAG__TEXT:
3563             {
3564 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE)
3565 0           return myhtml_insertion_mode_in_body(tree, token);
3566            
3567             // parse error
3568             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3569            
3570 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3571 0           return true;
3572             }
3573            
3574             case MyHTML_TAG_HTML:
3575             case MyHTML_TAG__DOCTYPE:
3576 0           return myhtml_insertion_mode_in_body(tree, token);
3577            
3578             case MyHTML_TAG__END_OF_FILE:
3579 0           myhtml_rules_stop_parsing(tree);
3580 0           break;
3581            
3582             default: {
3583             // parse error
3584             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3585            
3586 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3587 0           return true;
3588             }
3589             }
3590             }
3591            
3592 0           return false;
3593             }
3594              
3595 0           bool myhtml_insertion_mode_after_after_frameset(myhtml_tree_t* tree, myhtml_token_node_t* token)
3596             {
3597 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE) {
3598             // parse error
3599             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3600            
3601 0           return false;
3602             }
3603             else {
3604 0           switch (token->tag_id)
3605             {
3606             case MyHTML_TAG__COMMENT:
3607             {
3608 0           myhtml_tree_node_t* adjusted_location = tree->document;
3609 0           myhtml_tree_node_t* node = myhtml_tree_node_create(tree);
3610            
3611 0           node->tag_id = MyHTML_TAG__COMMENT;
3612 0           node->token = token;
3613 0           node->ns = adjusted_location->ns;
3614            
3615 0           myhtml_tree_node_add_child(adjusted_location, node);
3616 0           break;
3617             }
3618            
3619             case MyHTML_TAG__TEXT:
3620             {
3621 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE)
3622 0           return myhtml_insertion_mode_in_body(tree, token);
3623            
3624 0           myhtml_token_node_t* new_token = myhtml_insertion_fix_split_for_text_begin_ws(tree, token);
3625 0 0         if(new_token)
3626 0           return myhtml_insertion_mode_in_body(tree, new_token);
3627            
3628             // parse error
3629             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3630            
3631 0           break;
3632             }
3633            
3634             case MyHTML_TAG_HTML:
3635             case MyHTML_TAG__DOCTYPE:
3636 0           return myhtml_insertion_mode_in_body(tree, token);
3637            
3638             case MyHTML_TAG__END_OF_FILE:
3639 0           myhtml_rules_stop_parsing(tree);
3640 0           break;
3641            
3642             case MyHTML_TAG_NOFRAMES:
3643 0           return myhtml_insertion_mode_in_head(tree, token);
3644            
3645             default: {
3646             // parse error
3647             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3648 0           break;
3649             }
3650             }
3651             }
3652            
3653 0           return false;
3654             }
3655              
3656 0           bool myhtml_insertion_mode_in_foreign_content_end_other(myhtml_tree_t* tree, myhtml_tree_node_t* current_node, myhtml_token_node_t* token)
3657             {
3658 0           if(current_node->tag_id != token->tag_id) {
3659             // parse error
3660             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3661             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED_ADD HAVE:current_node->token NEED:token HAVE_TAG_ID:current_node->tag_id HAVE_NS:current_node->ns NEED_TAG_ID:token->tag_id NEED_NS:MyHTML_NAMESPACE_HTML */
3662             }
3663            
3664 0 0         if(tree->open_elements->length)
3665             {
3666 0           myhtml_tree_node_t** list = tree->open_elements->list;
3667 0           size_t i = tree->open_elements->length - 1;
3668            
3669 0 0         while (i)
3670             {
3671 0           current_node = list[i];
3672            
3673 0 0         if(current_node->tag_id == token->tag_id) {
3674 0           myhtml_tree_open_elements_pop_until_by_node(tree, current_node, false);
3675 0           return false;
3676             }
3677            
3678 0           i--;
3679            
3680 0 0         if(list[i]->ns == MyHTML_NAMESPACE_HTML)
3681 0           break;
3682             }
3683             }
3684            
3685 0           return tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3686             }
3687              
3688 0           bool myhtml_insertion_mode_in_foreign_content_start_other(myhtml_tree_t* tree, myhtml_token_node_t* token)
3689             {
3690 0           myhtml_tree_node_t* adjusted_node = myhtml_tree_adjusted_current_node(tree);
3691            
3692 0           myhtml_token_node_wait_for_done(tree->token, token);
3693            
3694 0 0         if(adjusted_node->ns == MyHTML_NAMESPACE_MATHML) {
3695 0           myhtml_token_adjust_mathml_attributes(token);
3696             }
3697 0 0         else if(adjusted_node->ns == MyHTML_NAMESPACE_SVG) {
3698 0           myhtml_token_adjust_svg_attributes(token);
3699             }
3700            
3701 0           myhtml_token_adjust_foreign_attributes(token);
3702            
3703 0           myhtml_tree_node_t* node = myhtml_tree_node_insert_foreign_element(tree, token);
3704 0           node->ns = adjusted_node->ns;
3705            
3706 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE_SELF)
3707             {
3708 0 0         if(token->tag_id == MyHTML_TAG_SCRIPT &&
    0          
3709 0           node->ns == MyHTML_NAMESPACE_SVG)
3710             {
3711 0           return myhtml_insertion_mode_in_foreign_content_end_other(tree, myhtml_tree_current_node(tree), token);
3712             }
3713             else {
3714 0           myhtml_tree_open_elements_pop(tree);
3715             }
3716             }
3717            
3718 0           return false;
3719             }
3720              
3721 0           bool myhtml_insertion_mode_in_foreign_content(myhtml_tree_t* tree, myhtml_token_node_t* token)
3722             {
3723 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE) {
3724 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3725            
3726 0 0         if(token->tag_id == MyHTML_TAG_SCRIPT &&
    0          
3727 0 0         current_node->tag_id == MyHTML_TAG_SCRIPT &&
3728 0           current_node->ns == MyHTML_NAMESPACE_SVG)
3729             {
3730 0           myhtml_tree_open_elements_pop(tree);
3731             // TODO: now script is disable, skip this
3732 0           return false;
3733             }
3734            
3735 0           return myhtml_insertion_mode_in_foreign_content_end_other(tree, current_node, token);
3736             }
3737             else {
3738 0           switch (token->tag_id)
3739             {
3740             case MyHTML_TAG__TEXT:
3741             {
3742 0 0         if(token->type & MyHTML_TOKEN_TYPE_NULL) {
3743             // parse error
3744             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:NULL_CHAR LEVEL:ERROR */
3745            
3746 0           myhtml_token_node_wait_for_done(tree->token, token);
3747 0           myhtml_token_set_replacement_character_for_null_token(tree, token);
3748             }
3749            
3750 0           myhtml_tree_node_insert_text(tree, token);
3751            
3752 0 0         if((token->type & MyHTML_TOKEN_TYPE_WHITESPACE) == 0)
3753 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
3754            
3755 0           break;
3756             }
3757            
3758             case MyHTML_TAG__COMMENT:
3759 0           myhtml_tree_node_insert_comment(tree, token, NULL);
3760 0           break;
3761            
3762             case MyHTML_TAG__DOCTYPE: {
3763             // parse error
3764             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3765            
3766 0           break;
3767             }
3768            
3769             case MyHTML_TAG_B:
3770             case MyHTML_TAG_BIG:
3771             case MyHTML_TAG_BLOCKQUOTE:
3772             case MyHTML_TAG_BODY:
3773             case MyHTML_TAG_BR:
3774             case MyHTML_TAG_CENTER:
3775             case MyHTML_TAG_CODE:
3776             case MyHTML_TAG_DD:
3777             case MyHTML_TAG_DIV:
3778             case MyHTML_TAG_DL:
3779             case MyHTML_TAG_DT:
3780             case MyHTML_TAG_EM:
3781             case MyHTML_TAG_EMBED:
3782             case MyHTML_TAG_H1:
3783             case MyHTML_TAG_H2:
3784             case MyHTML_TAG_H3:
3785             case MyHTML_TAG_H4:
3786             case MyHTML_TAG_H5:
3787             case MyHTML_TAG_H6:
3788             case MyHTML_TAG_HEAD:
3789             case MyHTML_TAG_HR:
3790             case MyHTML_TAG_I:
3791             case MyHTML_TAG_IMG:
3792             case MyHTML_TAG_LI:
3793             case MyHTML_TAG_LISTING:
3794             case MyHTML_TAG_MENU:
3795             case MyHTML_TAG_META:
3796             case MyHTML_TAG_NOBR:
3797             case MyHTML_TAG_OL:
3798             case MyHTML_TAG_P:
3799             case MyHTML_TAG_PRE:
3800             case MyHTML_TAG_RUBY:
3801             case MyHTML_TAG_S:
3802             case MyHTML_TAG_SMALL:
3803             case MyHTML_TAG_SPAN:
3804             case MyHTML_TAG_STRONG:
3805             case MyHTML_TAG_STRIKE:
3806             case MyHTML_TAG_SUB:
3807             case MyHTML_TAG_SUP:
3808             case MyHTML_TAG_TABLE:
3809             case MyHTML_TAG_TT:
3810             case MyHTML_TAG_U:
3811             case MyHTML_TAG_UL:
3812             case MyHTML_TAG_VAR:
3813             case MyHTML_TAG_FONT:
3814             {
3815             // parse error
3816             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3817            
3818 0 0         if(token->tag_id == MyHTML_TAG_FONT)
3819             {
3820 0           myhtml_token_node_wait_for_done(tree->token, token);
3821            
3822 0           if(myhtml_token_attr_by_name(token, "color", 5) == NULL &&
3823 0 0         myhtml_token_attr_by_name(token, "face" , 4) == NULL &&
3824 0           myhtml_token_attr_by_name(token, "size" , 4) == NULL)
3825             {
3826 0           return myhtml_insertion_mode_in_foreign_content_start_other(tree, token);
3827             }
3828             }
3829            
3830 0 0         if(tree->fragment == NULL) {
3831             myhtml_tree_node_t* current_node;
3832            
3833             do {
3834 0           myhtml_tree_open_elements_pop(tree);
3835 0           current_node = myhtml_tree_current_node(tree);
3836             }
3837 0 0         while(current_node && !(myhtml_tree_is_mathml_integration_point(tree, current_node) ||
3838 0           myhtml_tree_is_html_integration_point(tree, current_node) ||
3839 0 0         current_node->ns == MyHTML_NAMESPACE_HTML));
3840            
3841 0           return true;
3842             }
3843             }
3844            
3845             default:
3846 0           return myhtml_insertion_mode_in_foreign_content_start_other(tree, token);
3847             }
3848             }
3849            
3850 0           return false;
3851             }
3852              
3853 145           void myhtml_rules_stop_parsing(myhtml_tree_t* tree)
3854             {
3855             // THIS! IS! -(SPARTA!)- STOP PARSING
3856 145           }
3857              
3858 2288           bool myhtml_rules_check_for_first_newline(myhtml_tree_t* tree, myhtml_token_node_t* token)
3859             {
3860 2288 50         if(tree->flags & MyHTML_TREE_FLAGS_PARSE_FLAG) {
3861 0 0         if(tree->flags &MyHTML_TREE_FLAGS_PARSE_FLAG_EMIT_NEWLINE)
3862             {
3863 0 0         if(token->tag_id == MyHTML_TAG__TEXT) {
3864 0           myhtml_token_node_wait_for_done(tree->token, token);
3865            
3866 0 0         if(token->str.length > 0) {
3867 0 0         if(token->str.data[0] == '\n') {
3868 0           token->str.data = mchar_async_crop_first_chars_without_cache(token->str.data, 1);
3869            
3870 0           token->str.length--;
3871            
3872 0 0         if(token->str.length == 0) {
3873 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_PARSE_FLAG);
3874 0           return true;
3875             }
3876             }
3877             }
3878             else
3879 0           return true;
3880             }
3881             }
3882            
3883 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_PARSE_FLAG);
3884             }
3885            
3886 2288           return false;
3887             }
3888              
3889 2288           bool myhtml_rules_tree_dispatcher(myhtml_tree_t* tree, myhtml_token_node_t* token)
3890             {
3891             // for textarea && pre && listen
3892 2288 50         if(myhtml_rules_check_for_first_newline(tree, token)) {
3893 0           tree->token_last_done = token;
3894            
3895 0           return false;
3896             }
3897            
3898 2288 50         if(tree->state_of_builder != MyHTML_TOKENIZER_STATE_DATA)
3899 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_DATA;
3900            
3901 2288           bool reprocess = false;
3902 2288           myhtml_tree_node_t* adjusted_node = myhtml_tree_adjusted_current_node(tree);
3903            
3904 2288 100         if(tree->open_elements->length == 0 || adjusted_node->ns == MyHTML_NAMESPACE_HTML) {
    50          
3905 2288           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3906             }
3907 0 0         else if(myhtml_tree_is_mathml_integration_point(tree, adjusted_node) &&
    0          
3908 0 0         ((token->tag_id == MyHTML_TAG__TEXT ||
3909 0 0         (token->tag_id != MyHTML_TAG_MGLYPH && token->tag_id != MyHTML_TAG_MALIGNMARK)) &&
    0          
3910 0           (token->type & MyHTML_TOKEN_TYPE_CLOSE) == 0))
3911             {
3912 0           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3913             }
3914 0 0         else if(adjusted_node->tag_id == MyHTML_TAG_ANNOTATION_XML &&
    0          
3915 0 0         adjusted_node->ns == MyHTML_NAMESPACE_MATHML &&
3916 0 0         token->tag_id == MyHTML_TAG_SVG && (token->type & MyHTML_TOKEN_TYPE_CLOSE) == 0)
3917             {
3918 0           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3919             }
3920 0 0         else if(myhtml_tree_is_html_integration_point(tree, adjusted_node) &&
    0          
3921 0 0         ((token->type & MyHTML_TOKEN_TYPE_CLOSE) == 0 || token->tag_id == MyHTML_TAG__TEXT))
3922             {
3923 0           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3924             }
3925 0 0         else if(token->tag_id == MyHTML_TAG__END_OF_FILE)
3926 0           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3927             else
3928 0           reprocess = myhtml_insertion_mode_in_foreign_content(tree, token);
3929            
3930 2288 100         if(reprocess == false) {
3931 1685           tree->token_last_done = token;
3932             }
3933            
3934 2288           return reprocess;
3935             }
3936              
3937 115           mystatus_t myhtml_rules_init(myhtml_t* myhtml)
3938             {
3939 115           myhtml->insertion_func = (myhtml_insertion_f*)mycore_malloc(sizeof(myhtml_insertion_f) * MyHTML_INSERTION_MODE_LAST_ENTRY);
3940            
3941 115 50         if(myhtml->insertion_func == NULL)
3942 0           return MyHTML_STATUS_RULES_ERROR_MEMORY_ALLOCATION;
3943            
3944 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_INITIAL] = myhtml_insertion_mode_initial;
3945 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_BEFORE_HTML] = myhtml_insertion_mode_before_html;
3946 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_BEFORE_HEAD] = myhtml_insertion_mode_before_head;
3947 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_HEAD] = myhtml_insertion_mode_in_head;
3948 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_HEAD_NOSCRIPT] = myhtml_insertion_mode_in_head_noscript;
3949 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_HEAD] = myhtml_insertion_mode_after_head;
3950 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_BODY] = myhtml_insertion_mode_in_body;
3951 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_TEXT] = myhtml_insertion_mode_text;
3952 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_TABLE] = myhtml_insertion_mode_in_table;
3953 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_TABLE_TEXT] = myhtml_insertion_mode_in_table_text;
3954 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_CAPTION] = myhtml_insertion_mode_in_caption;
3955 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_COLUMN_GROUP] = myhtml_insertion_mode_in_column_group;
3956 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_TABLE_BODY] = myhtml_insertion_mode_in_table_body;
3957 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_ROW] = myhtml_insertion_mode_in_row;
3958 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_CELL] = myhtml_insertion_mode_in_cell;
3959 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_SELECT] = myhtml_insertion_mode_in_select;
3960 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_SELECT_IN_TABLE] = myhtml_insertion_mode_in_select_in_table;
3961 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_TEMPLATE] = myhtml_insertion_mode_in_template;
3962 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_BODY] = myhtml_insertion_mode_after_body;
3963 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_FRAMESET] = myhtml_insertion_mode_in_frameset;
3964 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_FRAMESET] = myhtml_insertion_mode_after_frameset;
3965 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_AFTER_BODY] = myhtml_insertion_mode_after_after_body;
3966 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_AFTER_FRAMESET] = myhtml_insertion_mode_after_after_frameset;
3967            
3968 115           return MyHTML_STATUS_OK;
3969             }
3970              
3971