File Coverage

third_party/modest/source/myhtml/rules.c
Criterion Covered Total %
statement 243 1649 14.7
branch 57 580 9.8
condition n/a
subroutine n/a
pod n/a
total 300 2229 13.4


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 59           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 0           case MyHTML_TAG__COMMENT:
105             {
106 0           myhtml_tree_node_insert_comment(tree, token, tree->document);
107 0           return false;
108             }
109            
110 36           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 &&
121 5 100         (tree->doctype.attr_public == NULL ||
122 1 50         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 77           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 0           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 0           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 0           case MyHTML_TAG__DOCTYPE: {
169             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:WARNING */
170 0           break;
171             }
172            
173 0           case MyHTML_TAG__COMMENT:
174             {
175 0           myhtml_tree_node_insert_comment(tree, token, tree->document);
176 0           break;
177             }
178            
179 17           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 0           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 113           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 0           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 0           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 15           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 0           case MyHTML_TAG__COMMENT:
258             {
259 0           myhtml_tree_node_insert_comment(tree, token, 0);
260 0           break;
261             }
262            
263 0           case MyHTML_TAG__DOCTYPE: {
264             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
265 0           break;
266             }
267            
268 0           case MyHTML_TAG_HTML:
269             {
270 0           return myhtml_insertion_mode_in_body(tree, token);
271             }
272            
273 0           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 113           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 0           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 0           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 0           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 0           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 15           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 0           case MyHTML_TAG__COMMENT:
371             {
372 0           myhtml_tree_node_insert_comment(tree, token, 0);
373 0           break;
374             }
375            
376 0           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 0           case MyHTML_TAG_HTML:
383             {
384 0           return myhtml_insertion_mode_in_body(tree, token);
385             }
386            
387 0           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 2           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 0           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 0           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 0           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 0           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 0           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 0           case MyHTML_TAG_HEAD: {
484             // parse error
485             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:WARNING */
486 0           break;
487             }
488            
489 113           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 0           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 0           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 0           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 0           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 0           case MyHTML_TAG_HTML:
538             {
539 0           return myhtml_insertion_mode_in_body(tree, token);
540             }
541            
542 0           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 0           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 0           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 0           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 0           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 0           case MyHTML_TAG_TEMPLATE:
601             {
602 0           return myhtml_insertion_mode_in_head(tree, token);
603             }
604            
605 0           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 15           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 0           case MyHTML_TAG__COMMENT:
634 0           myhtml_tree_node_insert_comment(tree, token, 0);
635 0           break;
636            
637 0           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 0           case MyHTML_TAG_HTML:
644 0           return myhtml_insertion_mode_in_body(tree, token);
645            
646 1           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 0           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 0           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 0           case MyHTML_TAG_HEAD: {
680             // parse error
681             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:WARNING */
682 0           break;
683             }
684            
685 112           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 0           case MyHTML_TAG_TEMPLATE:
741             {
742 0           return myhtml_insertion_mode_in_head(tree, token);
743             }
744            
745 1           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 2           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 0           default:
780 0           break;
781             }
782             }
783            
784 1           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_BODY;
785 1           break;
786             }
787            
788 0           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 0           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 0           default:
823 0           break;
824             }
825             }
826 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_BODY;
827            
828 0           return true;
829             }
830            
831 129           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 129           break;
879             }
880            
881 0           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 0           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 186           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 0           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 0           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 ||
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 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 ||
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 0         list[tree->open_elements->length]->ns == MyHTML_NAMESPACE_HTML)
1064             {
1065 0           break;
1066             }
1067             }
1068            
1069 0           break;
1070             }
1071            
1072 40           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 0           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 0           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           token->type = MyHTML_TOKEN_TYPE_OPEN;
1139            
1140 0           myhtml_tree_node_insert_html_element(tree, token);
1141 0           myhtml_tree_open_elements_pop(tree);
1142            
1143 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1144            
1145 0           break;
1146             }
1147            
1148 19           default:
1149             {
1150 19           return myhtml_insertion_mode_in_body_other_end_tag(tree, token);
1151             }
1152             }
1153             }
1154             // open elements
1155             else {
1156 1226           switch (token->tag_id)
1157             {
1158 646           case MyHTML_TAG__TEXT:
1159             {
1160 646 50         if(token->type & MyHTML_TOKEN_TYPE_NULL) {
1161             // parse error
1162             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:NULL_CHAR ACTION:IGNORE LEVEL:ERROR */
1163            
1164 0           myhtml_insertion_fix_for_null_char_drop_all(tree, token);
1165            
1166 0 0         if(token->str.length) {
1167 0           myhtml_tree_active_formatting_reconstruction(tree);
1168 0           myhtml_tree_node_insert_text(tree, token);
1169            
1170 0 0         if((token->type & MyHTML_TOKEN_TYPE_WHITESPACE) == 0)
1171 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1172             }
1173             }
1174             else {
1175 646           myhtml_tree_active_formatting_reconstruction(tree);
1176 646           myhtml_tree_node_insert_text(tree, token);
1177            
1178 646 100         if((token->type & MyHTML_TOKEN_TYPE_WHITESPACE) == 0)
1179 290           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1180             }
1181            
1182 646           break;
1183             }
1184            
1185 61           case MyHTML_TAG__COMMENT:
1186 61           myhtml_tree_node_insert_comment(tree, token, 0);
1187 61           break;
1188            
1189 0           case MyHTML_TAG__DOCTYPE: {
1190             // parse error
1191             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:WARNING */
1192 0           break;
1193             }
1194            
1195 0           case MyHTML_TAG_HTML:
1196             {
1197 0 0         if(myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL)) {
1198             // parse error
1199             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:WARNING */
1200 0           break;
1201             }
1202            
1203             // parse error
1204             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:WARNING */
1205            
1206 0 0         if(tree->open_elements->length > 0) {
1207 0           myhtml_tree_node_t* top_node = tree->open_elements->list[0];
1208            
1209 0 0         if(top_node->token) {
1210 0           myhtml_token_node_wait_for_done(tree->token, token);
1211 0           myhtml_token_node_wait_for_done(tree->token, top_node->token);
1212 0           myhtml_token_node_attr_copy_with_check(tree->token, token, top_node->token, tree->mcasync_rules_attr_id);
1213             }
1214             else {
1215 0           top_node->token = token;
1216             }
1217             }
1218            
1219 0           break;
1220             }
1221            
1222 2           case MyHTML_TAG_BASE:
1223             case MyHTML_TAG_BASEFONT:
1224             case MyHTML_TAG_BGSOUND:
1225             case MyHTML_TAG_LINK:
1226             case MyHTML_TAG_META:
1227             case MyHTML_TAG_NOFRAMES:
1228             case MyHTML_TAG_SCRIPT:
1229             case MyHTML_TAG_STYLE:
1230             case MyHTML_TAG_TEMPLATE:
1231             case MyHTML_TAG_TITLE:
1232             {
1233 2           return myhtml_insertion_mode_in_head(tree, token);
1234             }
1235            
1236 0           case MyHTML_TAG_BODY:
1237             {
1238             // parse error
1239             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:WARNING */
1240            
1241 0 0         if(tree->open_elements->length > 1)
1242             {
1243 0 0         if(!(tree->open_elements->list[1]->tag_id == MyHTML_TAG_BODY &&
1244 0           tree->open_elements->list[1]->ns == MyHTML_NAMESPACE_HTML) ||
1245 0           myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL))
1246             {
1247             // parse error
1248             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:WARNING */
1249            
1250             break;
1251             }
1252             }
1253             else
1254 0           break;
1255            
1256 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1257            
1258 0 0         if(tree->open_elements->length > 1) {
1259 0           myhtml_tree_node_t* top_node = tree->open_elements->list[1];
1260            
1261 0 0         if(top_node->token) {
1262 0           myhtml_token_node_wait_for_done(tree->token, token);
1263 0           myhtml_token_node_wait_for_done(tree->token, top_node->token);
1264 0           myhtml_token_node_attr_copy_with_check(tree->token, token, top_node->token, tree->mcasync_rules_attr_id);
1265             }
1266             else {
1267 0           top_node->token = token;
1268             }
1269             }
1270            
1271 0           break;
1272             }
1273            
1274 0           case MyHTML_TAG_FRAMESET:
1275             {
1276             // parse error
1277             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
1278            
1279 0 0         if(tree->open_elements->length > 1)
1280             {
1281 0 0         if(!(tree->open_elements->list[1]->tag_id == MyHTML_TAG_BODY &&
1282 0 0         tree->open_elements->list[1]->ns == MyHTML_NAMESPACE_HTML))
1283             {
1284             // parse error
1285             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
1286            
1287             break;
1288             }
1289             }
1290             else
1291 0           break;
1292            
1293 0 0         if((tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK) == 0) {
1294             // parse error
1295             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
1296            
1297 0           break;
1298             }
1299            
1300 0           myhtml_tree_node_t* node = tree->open_elements->list[1];
1301            
1302 0           myhtml_tree_node_remove(node);
1303 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_HTML, MyHTML_NAMESPACE_HTML, true);
1304            
1305 0           myhtml_tree_node_insert_html_element(tree, token);
1306            
1307 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_FRAMESET;
1308 0           break;
1309             }
1310            
1311 144           case MyHTML_TAG__END_OF_FILE:
1312             {
1313 144 50         if(tree->template_insertion->length)
1314 0           return myhtml_insertion_mode_in_template(tree, token);
1315            
1316 144           myhtml_tree_node_t** list = tree->open_elements->list;
1317 415 100         for(size_t i = 0; i < tree->open_elements->length; i++) {
1318             if(list[i]->tag_id != MyHTML_TAG_DD && list[i]->tag_id != MyHTML_TAG_DT &&
1319             list[i]->tag_id != MyHTML_TAG_LI && list[i]->tag_id != MyHTML_TAG_MENUITEM &&
1320             list[i]->tag_id != MyHTML_TAG_OPTGROUP && list[i]->tag_id != MyHTML_TAG_OPTION &&
1321             list[i]->tag_id != MyHTML_TAG_P && list[i]->tag_id != MyHTML_TAG_RB &&
1322             list[i]->tag_id != MyHTML_TAG_RP && list[i]->tag_id != MyHTML_TAG_RT &&
1323             list[i]->tag_id != MyHTML_TAG_RTC && list[i]->tag_id != MyHTML_TAG_TBODY &&
1324             list[i]->tag_id != MyHTML_TAG_TD && list[i]->tag_id != MyHTML_TAG_TFOOT &&
1325             list[i]->tag_id != MyHTML_TAG_TH && list[i]->tag_id != MyHTML_TAG_THEAD &&
1326             list[i]->tag_id != MyHTML_TAG_TR && list[i]->tag_id != MyHTML_TAG_BODY &&
1327             list[i]->tag_id != MyHTML_TAG_HTML && list[i]->ns != MyHTML_NAMESPACE_HTML)
1328             {
1329             // parse error
1330             }
1331             }
1332            
1333 144           myhtml_rules_stop_parsing(tree);
1334 144           break;
1335             }
1336            
1337 129           case MyHTML_TAG_ADDRESS:
1338             case MyHTML_TAG_ARTICLE:
1339             case MyHTML_TAG_ASIDE:
1340             case MyHTML_TAG_BLOCKQUOTE:
1341             case MyHTML_TAG_CENTER:
1342             case MyHTML_TAG_DETAILS:
1343             case MyHTML_TAG_DIALOG:
1344             case MyHTML_TAG_DIR:
1345             case MyHTML_TAG_DIV:
1346             case MyHTML_TAG_DL:
1347             case MyHTML_TAG_FIELDSET:
1348             case MyHTML_TAG_FIGCAPTION:
1349             case MyHTML_TAG_FIGURE:
1350             case MyHTML_TAG_FOOTER:
1351             case MyHTML_TAG_HEADER:
1352             case MyHTML_TAG_HGROUP:
1353             case MyHTML_TAG_MAIN:
1354             case MyHTML_TAG_NAV:
1355             case MyHTML_TAG_OL:
1356             case MyHTML_TAG_P:
1357             case MyHTML_TAG_SECTION:
1358             case MyHTML_TAG_SUMMARY:
1359             case MyHTML_TAG_UL:
1360             {
1361 129 50         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1362 0           myhtml_tree_tags_close_p(tree, token);
1363             }
1364            
1365 129           myhtml_tree_node_insert_html_element(tree, token);
1366 129           break;
1367             }
1368            
1369 0           case MyHTML_TAG_MENU:
1370             {
1371 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1372 0           myhtml_tree_tags_close_p(tree, token);
1373             }
1374            
1375 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1376            
1377 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_MENUITEM))
1378 0           myhtml_tree_open_elements_pop(tree);
1379            
1380 0           myhtml_tree_node_insert_html_element(tree, token);
1381 0           break;
1382             }
1383            
1384 0           case MyHTML_TAG_H1:
1385             case MyHTML_TAG_H2:
1386             case MyHTML_TAG_H3:
1387             case MyHTML_TAG_H4:
1388             case MyHTML_TAG_H5:
1389             case MyHTML_TAG_H6:
1390             {
1391 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1392 0           myhtml_tree_tags_close_p(tree, token);
1393             }
1394            
1395 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1396            
1397 0 0         switch (current_node->tag_id) {
1398 0           case MyHTML_TAG_H1:
1399             case MyHTML_TAG_H2:
1400             case MyHTML_TAG_H3:
1401             case MyHTML_TAG_H4:
1402             case MyHTML_TAG_H5:
1403             case MyHTML_TAG_H6:
1404            
1405 0 0         if(current_node->ns == MyHTML_NAMESPACE_HTML) {
1406             // parse error
1407             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:WARNING */
1408 0           myhtml_tree_open_elements_pop(tree);
1409             }
1410            
1411 0           break;
1412            
1413 0           default:
1414 0           break;
1415             }
1416            
1417 0           myhtml_tree_node_insert_html_element(tree, token);
1418 0           break;
1419             }
1420            
1421 0           case MyHTML_TAG_PRE:
1422             case MyHTML_TAG_LISTING:
1423             {
1424 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1425 0           myhtml_tree_tags_close_p(tree, token);
1426             }
1427            
1428 0           myhtml_tree_node_insert_html_element(tree, token);
1429            
1430             // If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move on to the next one.
1431             // (Newlines at the start of pre blocks are ignored as an authoring convenience.)
1432             // !!! see dispatcher (myhtml_rules_tree_dispatcher) for this
1433 0           tree->flags |= MyHTML_TREE_FLAGS_PARSE_FLAG|MyHTML_TREE_FLAGS_PARSE_FLAG_EMIT_NEWLINE;
1434            
1435 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1436 0           break;
1437             }
1438            
1439 0           case MyHTML_TAG_FORM:
1440             {
1441 0           myhtml_tree_node_t* is_in_node = myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL);
1442 0 0         if(tree->node_form && is_in_node == NULL) {
    0          
1443             // parse error
1444             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
1445 0           break;
1446             }
1447            
1448 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1449 0           myhtml_tree_tags_close_p(tree, token);
1450             }
1451            
1452 0           myhtml_tree_node_t* current = myhtml_tree_node_insert_html_element(tree, token);
1453            
1454 0 0         if(is_in_node == NULL)
1455 0           tree->node_form = current;
1456            
1457 0           break;
1458             }
1459            
1460 186           case MyHTML_TAG_LI:
1461             {
1462 186           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1463            
1464 186           size_t oel_index = tree->open_elements->length;
1465            
1466 186 50         while (oel_index) {
1467 186           oel_index--;
1468            
1469 186           myhtml_tree_node_t* node = tree->open_elements->list[oel_index];
1470 186           const myhtml_tag_context_t *tag_ctx = myhtml_tag_get_by_id(tree->tags, node->tag_id);
1471            
1472             /* 3 */
1473 186 50         if(myhtml_is_html_node(node, MyHTML_TAG_LI)) {
1474             /* 3.1 */
1475 0           myhtml_tree_generate_implied_end_tags(tree, MyHTML_TAG_LI, MyHTML_NAMESPACE_HTML);
1476            
1477             /* 3.2 */
1478 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1479 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_LI) == false) {
1480             // parse error
1481             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1482             /* %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 */
1483             }
1484            
1485             /* 3.3 */
1486 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_LI, MyHTML_NAMESPACE_HTML, false);
1487 0           break;
1488             }
1489 186 50         else if(tag_ctx->cats[node->ns] & MyHTML_TAG_CATEGORIES_SPECIAL)
1490             {
1491 186 50         if(!((node->tag_id == MyHTML_TAG_ADDRESS || node->tag_id == MyHTML_TAG_DIV ||
    50          
1492 186 50         node->tag_id == MyHTML_TAG_P) && node->ns == MyHTML_NAMESPACE_HTML))
    0          
1493             break;
1494             }
1495             }
1496            
1497 186 50         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1498 0           myhtml_tree_tags_close_p(tree, token);
1499             }
1500            
1501 186           myhtml_tree_node_insert_html_element(tree, token);
1502 186           break;
1503             }
1504            
1505 0           case MyHTML_TAG_DT:
1506             case MyHTML_TAG_DD:
1507             {
1508             // this is copy/past
1509 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1510            
1511 0           size_t oel_index = tree->open_elements->length;
1512            
1513 0 0         while (oel_index) {
1514 0           oel_index--;
1515            
1516 0           myhtml_tree_node_t* node = tree->open_elements->list[oel_index];
1517 0           const myhtml_tag_context_t *tag_ctx = myhtml_tag_get_by_id(tree->tags, node->tag_id);
1518            
1519 0 0         if(myhtml_is_html_node(node, MyHTML_TAG_DD)) {
1520 0           myhtml_tree_generate_implied_end_tags(tree, MyHTML_TAG_DD, MyHTML_NAMESPACE_HTML);
1521            
1522             /* 3.2 */
1523 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1524 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_DD)) {
1525             // parse error
1526             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1527             /* %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 */
1528             }
1529            
1530 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_DD, MyHTML_NAMESPACE_HTML, false);
1531 0           break;
1532             }
1533 0 0         else if(myhtml_is_html_node(node, MyHTML_TAG_DT)) {
1534 0           myhtml_tree_generate_implied_end_tags(tree, MyHTML_TAG_DT, MyHTML_NAMESPACE_HTML);
1535            
1536             /* 3.2 */
1537 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1538 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_DT)) {
1539             // parse error
1540             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1541             /* %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 */
1542             }
1543            
1544 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_DT, MyHTML_NAMESPACE_HTML, false);
1545 0           break;
1546             }
1547 0 0         else if(tag_ctx->cats[node->ns] & MyHTML_TAG_CATEGORIES_SPECIAL)
1548             {
1549 0 0         if(!((node->tag_id == MyHTML_TAG_ADDRESS || node->tag_id == MyHTML_TAG_DIV ||
    0          
1550 0 0         node->tag_id == MyHTML_TAG_P) && node->ns == MyHTML_NAMESPACE_HTML))
    0          
1551             break;
1552             }
1553             }
1554            
1555 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1556 0           myhtml_tree_tags_close_p(tree, token);
1557             }
1558            
1559 0           myhtml_tree_node_insert_html_element(tree, token);
1560 0           break;
1561             }
1562            
1563 0           case MyHTML_TAG_PLAINTEXT:
1564             {
1565 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1566 0           myhtml_tree_tags_close_p(tree, token);
1567             }
1568            
1569 0           myhtml_tree_node_insert_html_element(tree, token);
1570            
1571 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_PLAINTEXT;
1572 0           break;
1573             }
1574            
1575 0           case MyHTML_TAG_BUTTON:
1576             {
1577 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_BUTTON, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE)) {
1578             // parse error
1579             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
1580            
1581 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
1582 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_BUTTON, MyHTML_NAMESPACE_HTML, false);
1583             }
1584            
1585 0           myhtml_tree_active_formatting_reconstruction(tree);
1586 0           myhtml_tree_node_insert_html_element(tree, token);
1587            
1588 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1589 0           break;
1590             }
1591            
1592 0           case MyHTML_TAG_A:
1593             {
1594 0           myhtml_tree_node_t* node = myhtml_tree_active_formatting_between_last_marker(tree, MyHTML_TAG_A, NULL);
1595            
1596 0 0         if(node) {
1597             // parse error
1598             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
1599            
1600 0           myhtml_tree_adoption_agency_algorithm(tree, token, MyHTML_TAG_A);
1601 0           node = myhtml_tree_active_formatting_between_last_marker(tree, MyHTML_TAG_A, NULL);
1602            
1603 0 0         if(node) {
1604 0           myhtml_tree_open_elements_remove(tree, node);
1605 0           myhtml_tree_active_formatting_remove(tree, node);
1606             }
1607             }
1608            
1609 0           myhtml_tree_active_formatting_reconstruction(tree);
1610            
1611 0           myhtml_tree_node_t* current = myhtml_tree_node_insert_html_element(tree, token);
1612 0           myhtml_tree_active_formatting_append_with_check(tree, current);
1613 0           break;
1614             }
1615            
1616 40           case MyHTML_TAG_B:
1617             case MyHTML_TAG_BIG:
1618             case MyHTML_TAG_CODE:
1619             case MyHTML_TAG_EM:
1620             case MyHTML_TAG_FONT:
1621             case MyHTML_TAG_I:
1622             case MyHTML_TAG_S:
1623             case MyHTML_TAG_SMALL:
1624             case MyHTML_TAG_STRIKE:
1625             case MyHTML_TAG_STRONG:
1626             case MyHTML_TAG_TT:
1627             case MyHTML_TAG_U:
1628             {
1629 40           myhtml_tree_active_formatting_reconstruction(tree);
1630            
1631 40           myhtml_tree_node_t* current = myhtml_tree_node_insert_html_element(tree, token);
1632 40           myhtml_tree_active_formatting_append_with_check(tree, current);
1633 40           break;
1634             }
1635              
1636 0           case MyHTML_TAG_NOBR:
1637             {
1638 0           myhtml_tree_active_formatting_reconstruction(tree);
1639            
1640 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_NOBR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE)) {
1641             // parse error
1642             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
1643            
1644 0           myhtml_tree_adoption_agency_algorithm(tree, token, MyHTML_TAG_NOBR);
1645 0           myhtml_tree_active_formatting_reconstruction(tree);
1646             }
1647            
1648 0           myhtml_tree_node_t* current = myhtml_tree_node_insert_html_element(tree, token);
1649 0           myhtml_tree_active_formatting_append_with_check(tree, current);
1650 0           break;
1651             }
1652              
1653 0           case MyHTML_TAG_APPLET:
1654             case MyHTML_TAG_MARQUEE:
1655             case MyHTML_TAG_OBJECT:
1656             {
1657 0           myhtml_tree_active_formatting_reconstruction(tree);
1658            
1659 0           myhtml_tree_node_insert_html_element(tree, token);
1660 0           myhtml_tree_active_formatting_append(tree, tree->myhtml->marker); // marker
1661            
1662 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1663 0           break;
1664             }
1665            
1666 0           case MyHTML_TAG_TABLE:
1667             {
1668 0           if((tree->compat_mode & MyHTML_TREE_COMPAT_MODE_QUIRKS) == 0 &&
1669 0           myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON))
1670             {
1671 0           myhtml_tree_tags_close_p(tree, token);
1672             }
1673            
1674 0           myhtml_tree_node_insert_html_element(tree, token);
1675 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1676            
1677 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
1678 0           break;
1679             }
1680            
1681 0           case MyHTML_TAG_AREA:
1682             case MyHTML_TAG_BR:
1683             case MyHTML_TAG_EMBED:
1684             case MyHTML_TAG_IMG:
1685             case MyHTML_TAG_KEYGEN:
1686             case MyHTML_TAG_WBR:
1687             {
1688 0           myhtml_tree_active_formatting_reconstruction(tree);
1689            
1690 0           myhtml_tree_node_insert_html_element(tree, token);
1691 0           myhtml_tree_open_elements_pop(tree);
1692            
1693 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1694 0           break;
1695             }
1696            
1697 0           case MyHTML_TAG_INPUT:
1698             {
1699 0           myhtml_tree_active_formatting_reconstruction(tree);
1700            
1701 0           myhtml_tree_node_insert_html_element(tree, token);
1702 0           myhtml_tree_open_elements_pop(tree);
1703            
1704 0           myhtml_token_node_wait_for_done(tree->token, token);
1705 0 0         if(myhtml_token_attr_match_case(tree->token, token, "type", 4, "hidden", 6) == NULL) {
1706 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1707             }
1708            
1709 0           break;
1710             }
1711            
1712 0           case MyHTML_TAG_PARAM:
1713             case MyHTML_TAG_SOURCE:
1714             case MyHTML_TAG_TRACK:
1715             {
1716 0           myhtml_tree_node_insert_html_element(tree, token);
1717 0           myhtml_tree_open_elements_pop(tree);
1718 0           break;
1719             }
1720            
1721 0           case MyHTML_TAG_HR:
1722             {
1723 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1724 0           myhtml_tree_tags_close_p(tree, token);
1725             }
1726            
1727 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1728            
1729 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_MENUITEM))
1730 0           myhtml_tree_open_elements_pop(tree);
1731            
1732 0           myhtml_tree_node_insert_html_element(tree, token);
1733 0           myhtml_tree_open_elements_pop(tree);
1734            
1735 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1736 0           break;
1737             }
1738            
1739 0           case MyHTML_TAG_IMAGE:
1740             {
1741             // parse error
1742             /* %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 */
1743            
1744 0           token->tag_id = MyHTML_TAG_IMG;
1745 0           return true;
1746             }
1747            
1748 0           case MyHTML_TAG_TEXTAREA:
1749             {
1750 0           myhtml_tree_node_insert_html_element(tree, token);
1751            
1752             // If the next token is a U+000A LINE FEED (LF) character token,
1753             // then ignore that token and move on to the next one.
1754             // (Newlines at the start of textarea elements are ignored as an authoring convenience.)
1755             // !!! see dispatcher (myhtml_rules_tree_dispatcher) for this
1756 0           tree->flags |= MyHTML_TREE_FLAGS_PARSE_FLAG|MyHTML_TREE_FLAGS_PARSE_FLAG_EMIT_NEWLINE;
1757            
1758 0           tree->orig_insert_mode = tree->insert_mode;
1759 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1760 0           tree->insert_mode = MyHTML_INSERTION_MODE_TEXT;
1761 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RCDATA;
1762            
1763 0           break;
1764             }
1765              
1766 0           case MyHTML_TAG_XMP:
1767             {
1768 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_P, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_BUTTON)) {
1769 0           myhtml_tree_tags_close_p(tree, token);
1770             }
1771            
1772 0           myhtml_tree_active_formatting_reconstruction(tree);
1773            
1774 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1775 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
1776            
1777 0           myhtml_tree_generic_raw_text_element_parsing_algorithm(tree, token);
1778 0           break;
1779             }
1780              
1781 0           case MyHTML_TAG_IFRAME:
1782             {
1783 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1784 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
1785            
1786 0           myhtml_tree_generic_raw_text_element_parsing_algorithm(tree, token);
1787 0           break;
1788             }
1789            
1790 0           case MyHTML_TAG_NOEMBED:
1791             {
1792 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
1793 0           myhtml_tree_generic_raw_text_element_parsing_algorithm(tree, token);
1794 0           break;
1795             }
1796            
1797 0           case MyHTML_TAG_NOSCRIPT:
1798             {
1799 0 0         if(tree->flags & MyHTML_TREE_FLAGS_SCRIPT) {
1800 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_RAWTEXT;
1801 0           myhtml_tree_generic_raw_text_element_parsing_algorithm(tree, token);
1802             }
1803             else {
1804 0           myhtml_tree_active_formatting_reconstruction(tree);
1805 0           myhtml_tree_node_insert_html_element(tree, token);
1806             }
1807             // else {
1808             // myhtml_tree_node_insert_html_element(tree, token);
1809             // tree->insert_mode = MyHTML_INSERTION_MODE_IN_HEAD_NOSCRIPT;
1810             // }
1811            
1812 0           break;
1813             }
1814            
1815 0           case MyHTML_TAG_SELECT:
1816             {
1817 0           myhtml_tree_active_formatting_reconstruction(tree);
1818            
1819 0           myhtml_tree_node_insert_html_element(tree, token);
1820            
1821 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
1822            
1823 0 0         if(tree->insert_mode == MyHTML_INSERTION_MODE_IN_TABLE ||
1824 0 0         tree->insert_mode == MyHTML_INSERTION_MODE_IN_CAPTION ||
1825 0 0         tree->insert_mode == MyHTML_INSERTION_MODE_IN_TABLE_BODY ||
1826 0 0         tree->insert_mode == MyHTML_INSERTION_MODE_IN_ROW ||
1827 0 0         tree->insert_mode == MyHTML_INSERTION_MODE_IN_CELL)
1828             {
1829 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_SELECT_IN_TABLE;
1830             }
1831             else
1832 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_SELECT;
1833            
1834 0           break;
1835             }
1836            
1837 0           case MyHTML_TAG_OPTGROUP:
1838             case MyHTML_TAG_OPTION:
1839             {
1840 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1841            
1842 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_OPTION))
1843 0           myhtml_tree_open_elements_pop(tree);
1844            
1845 0           myhtml_tree_active_formatting_reconstruction(tree);
1846            
1847 0           myhtml_tree_node_insert_html_element(tree, token);
1848 0           break;
1849             }
1850            
1851 0           case MyHTML_TAG_MENUITEM:
1852             {
1853 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1854            
1855 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_MENUITEM))
1856 0           myhtml_tree_open_elements_pop(tree);
1857            
1858 0           myhtml_tree_active_formatting_reconstruction(tree);
1859            
1860 0           myhtml_tree_node_insert_html_element(tree, token);
1861 0           break;
1862             }
1863            
1864 0           case MyHTML_TAG_RB:
1865             case MyHTML_TAG_RTC:
1866             {
1867 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_RUBY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE)) {
1868 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
1869             }
1870            
1871 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1872 0           if(current_node->tag_id != MyHTML_TAG_RUBY) {
1873             // parse error
1874             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1875             /* %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 */
1876             }
1877            
1878 0           myhtml_tree_node_insert_html_element(tree, token);
1879 0           break;
1880             }
1881            
1882 0           case MyHTML_TAG_RP:
1883             case MyHTML_TAG_RT:
1884             {
1885 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_RUBY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE)) {
1886 0           myhtml_tree_generate_implied_end_tags(tree, MyHTML_TAG_RTC, MyHTML_NAMESPACE_HTML);
1887             }
1888            
1889 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1890 0 0         if(current_node->tag_id != MyHTML_TAG_RTC && current_node->tag_id != MyHTML_TAG_RUBY) {
1891             // parse error
1892             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
1893             /* %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 */
1894             /* %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 */
1895             }
1896            
1897 0           myhtml_tree_node_insert_html_element(tree, token);
1898 0           break;
1899             }
1900            
1901 0           case MyHTML_TAG_MATH:
1902             {
1903 0           myhtml_tree_active_formatting_reconstruction(tree);
1904            
1905 0           myhtml_token_node_wait_for_done(tree->token, token);
1906            
1907 0           myhtml_token_adjust_mathml_attributes(token);
1908 0           myhtml_token_adjust_foreign_attributes(token);
1909            
1910 0           myhtml_tree_node_t* current_node = myhtml_tree_node_insert_foreign_element(tree, token);
1911 0           current_node->ns = MyHTML_NAMESPACE_MATHML;
1912            
1913 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE_SELF)
1914 0           myhtml_tree_open_elements_pop(tree);
1915            
1916 0           break;
1917             }
1918            
1919 0           case MyHTML_TAG_SVG:
1920             {
1921 0           myhtml_tree_active_formatting_reconstruction(tree);
1922            
1923 0           myhtml_token_node_wait_for_done(tree->token, token);
1924            
1925 0           myhtml_token_adjust_svg_attributes(token);
1926 0           myhtml_token_adjust_foreign_attributes(token);
1927            
1928 0           myhtml_tree_node_t* current_node = myhtml_tree_node_insert_foreign_element(tree, token);
1929 0           current_node->ns = MyHTML_NAMESPACE_SVG;
1930            
1931 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE_SELF)
1932 0           myhtml_tree_open_elements_pop(tree);
1933            
1934 0           break;
1935             }
1936            
1937 0           case MyHTML_TAG_CAPTION:
1938             case MyHTML_TAG_COL:
1939             case MyHTML_TAG_COLGROUP:
1940             case MyHTML_TAG_FRAME:
1941             case MyHTML_TAG_HEAD:
1942             case MyHTML_TAG_TBODY:
1943             case MyHTML_TAG_TD:
1944             case MyHTML_TAG_TFOOT:
1945             case MyHTML_TAG_TH:
1946             case MyHTML_TAG_THEAD:
1947             case MyHTML_TAG_TR:
1948             {
1949             // parse error
1950             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
1951 0           break;
1952             }
1953            
1954 18           default:
1955             {
1956 18           myhtml_tree_active_formatting_reconstruction(tree);
1957 18           myhtml_tree_node_insert_html_element(tree, token);
1958            
1959 18           break;
1960             }
1961             }
1962             }
1963            
1964 1580           return false;
1965             }
1966              
1967 0           bool myhtml_insertion_mode_text(myhtml_tree_t* tree, myhtml_token_node_t* token)
1968             {
1969 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
1970             {
1971 0 0         switch (token->tag_id) {
1972 0           case MyHTML_TAG_SCRIPT:
1973             {
1974             // new document.write is not works; set back
1975 0           myhtml_tree_open_elements_pop(tree);
1976 0           tree->insert_mode = tree->orig_insert_mode;
1977 0           break;
1978             }
1979            
1980 0           default:
1981             {
1982 0           myhtml_tree_open_elements_pop(tree);
1983 0           tree->insert_mode = tree->orig_insert_mode;
1984 0           break;
1985             }
1986             }
1987             }
1988             else {
1989 0 0         if(token->tag_id == MyHTML_TAG__END_OF_FILE)
1990             {
1991             // parse error
1992             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:PREMATURE_TERMINATION LEVEL:ERROR */
1993            
1994 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
1995            
1996 0 0         if(current_node->tag_id == MyHTML_TAG_SCRIPT)
1997 0           current_node->flags |= MyHTML_TREE_FLAGS_ALREADY_STARTED;
1998            
1999 0           myhtml_tree_open_elements_pop(tree);
2000            
2001 0           tree->insert_mode = tree->orig_insert_mode;
2002 0           return true;
2003             }
2004            
2005 0           myhtml_tree_node_insert_text(tree, token);
2006             }
2007            
2008 0           return false;
2009             }
2010              
2011 0           bool myhtml_insertion_mode_in_table(myhtml_tree_t* tree, myhtml_token_node_t* token)
2012             {
2013 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2014             {
2015 0           switch (token->tag_id) {
2016 0           case MyHTML_TAG_TABLE:
2017             {
2018 0           myhtml_tree_node_t* table_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TABLE, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2019            
2020 0 0         if(table_node == NULL) {
2021             // parse error
2022             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2023 0           break;
2024             }
2025            
2026 0           myhtml_tree_open_elements_pop_until_by_node(tree, table_node, false);
2027 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
2028            
2029 0           break;
2030             }
2031            
2032 0           case MyHTML_TAG_BODY:
2033             case MyHTML_TAG_CAPTION:
2034             case MyHTML_TAG_COL:
2035             case MyHTML_TAG_COLGROUP:
2036             case MyHTML_TAG_HTML:
2037             case MyHTML_TAG_TBODY:
2038             case MyHTML_TAG_TD:
2039             case MyHTML_TAG_TFOOT:
2040             case MyHTML_TAG_TH:
2041             case MyHTML_TAG_THEAD:
2042             case MyHTML_TAG_TR:
2043             {
2044             // parse error
2045             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2046 0           break;
2047             }
2048            
2049 0           case MyHTML_TAG_TEMPLATE:
2050             {
2051 0           return myhtml_insertion_mode_in_head(tree, token);
2052             }
2053            
2054 0           default: {
2055             // parse error
2056 0           tree->foster_parenting = true;
2057 0           myhtml_insertion_mode_in_body(tree, token);
2058 0           tree->foster_parenting = false;
2059            
2060 0           break;
2061             }
2062             }
2063             }
2064             else {
2065 0           switch (token->tag_id)
2066             {
2067 0           case MyHTML_TAG__TEXT:
2068             {
2069 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2070            
2071 0 0         if((current_node->tag_id == MyHTML_TAG_TABLE ||
2072 0 0         current_node->tag_id == MyHTML_TAG_TBODY ||
2073 0 0         current_node->tag_id == MyHTML_TAG_TFOOT ||
2074 0 0         current_node->tag_id == MyHTML_TAG_THEAD ||
2075 0 0         current_node->tag_id == MyHTML_TAG_TR) &&
2076 0 0         current_node->ns == MyHTML_NAMESPACE_HTML)
2077             {
2078 0           myhtml_tree_token_list_clean(tree->token_list);
2079            
2080 0           tree->orig_insert_mode = tree->insert_mode;
2081 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_TEXT;
2082            
2083 0           return true;
2084             }
2085             else {
2086 0           tree->foster_parenting = true;
2087 0           myhtml_insertion_mode_in_body(tree, token);
2088 0           tree->foster_parenting = false;
2089            
2090 0           break;
2091             }
2092             }
2093            
2094 0           case MyHTML_TAG__COMMENT:
2095 0           myhtml_tree_node_insert_comment(tree, token, 0);
2096 0           break;
2097            
2098 0           case MyHTML_TAG__DOCTYPE: {
2099             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:WARNING */
2100 0           break;
2101             }
2102            
2103 0           case MyHTML_TAG_CAPTION:
2104             {
2105 0           myhtml_tree_clear_stack_back_table_context(tree);
2106            
2107 0           myhtml_tree_node_insert_html_element(tree, token);
2108 0           myhtml_tree_active_formatting_append(tree, tree->myhtml->marker);
2109            
2110 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_CAPTION;
2111 0           break;
2112             }
2113            
2114 0           case MyHTML_TAG_COLGROUP:
2115             {
2116 0           myhtml_tree_clear_stack_back_table_context(tree);
2117            
2118 0           myhtml_tree_node_insert_html_element(tree, token);
2119            
2120 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_COLUMN_GROUP;
2121 0           break;
2122             }
2123            
2124 0           case MyHTML_TAG_COL:
2125             {
2126 0           myhtml_tree_clear_stack_back_table_context(tree);
2127 0           myhtml_tree_node_insert(tree, MyHTML_TAG_COLGROUP, MyHTML_NAMESPACE_HTML);
2128            
2129 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_COLUMN_GROUP;
2130 0           return true;
2131             }
2132            
2133 0           case MyHTML_TAG_TBODY:
2134             case MyHTML_TAG_TFOOT:
2135             case MyHTML_TAG_THEAD:
2136             {
2137 0           myhtml_tree_clear_stack_back_table_context(tree);
2138            
2139 0           myhtml_tree_node_insert_html_element(tree, token);
2140            
2141 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2142 0           break;
2143             }
2144            
2145 0           case MyHTML_TAG_TD:
2146             case MyHTML_TAG_TH:
2147             case MyHTML_TAG_TR:
2148             {
2149 0           myhtml_tree_clear_stack_back_table_context(tree);
2150 0           myhtml_tree_node_insert(tree, MyHTML_TAG_TBODY, MyHTML_NAMESPACE_HTML);
2151            
2152 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2153 0           return true;
2154             }
2155            
2156 0           case MyHTML_TAG_TABLE:
2157             {
2158             // parse error
2159             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2160            
2161 0           myhtml_tree_node_t* table_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TABLE, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2162            
2163 0 0         if(table_node == NULL) {
2164             // parse error
2165             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
2166            
2167 0           break;
2168             }
2169            
2170 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_TABLE, MyHTML_NAMESPACE_HTML, false);
2171 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
2172            
2173 0           return true;
2174             }
2175            
2176 0           case MyHTML_TAG_STYLE:
2177             case MyHTML_TAG_SCRIPT:
2178             case MyHTML_TAG_TEMPLATE:
2179             {
2180 0           return myhtml_insertion_mode_in_head(tree, token);
2181             }
2182            
2183 0           case MyHTML_TAG_INPUT:
2184             {
2185 0           myhtml_token_node_wait_for_done(tree->token, token);
2186            
2187 0 0         if(myhtml_token_attr_match_case(tree->token, token, "type", 4, "hidden", 6) == NULL) {
2188 0           tree->foster_parenting = true;
2189 0           myhtml_insertion_mode_in_body(tree, token);
2190 0           tree->foster_parenting = false;
2191            
2192 0           break;
2193             }
2194            
2195             // parse error
2196             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2197            
2198 0           myhtml_tree_node_insert_html_element(tree, token);
2199 0           myhtml_tree_open_elements_pop(tree);
2200            
2201 0           token->type |= MyHTML_TOKEN_TYPE_CLOSE_SELF;
2202 0           break;
2203             }
2204            
2205 0           case MyHTML_TAG_FORM:
2206             {
2207             // parse error
2208             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2209            
2210 0           myhtml_tree_node_t* template = myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL);
2211 0 0         if(tree->node_form || template)
    0          
2212             break;
2213            
2214 0           tree->node_form = myhtml_tree_node_insert_html_element(tree, token);
2215            
2216 0           myhtml_tree_open_elements_pop(tree);
2217             }
2218            
2219 0           case MyHTML_TAG__END_OF_FILE:
2220 0           return myhtml_insertion_mode_in_body(tree, token);
2221            
2222 0           default:
2223             {
2224             // parse error
2225             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2226            
2227 0           tree->foster_parenting = true;
2228 0           myhtml_insertion_mode_in_body(tree, token);
2229 0           tree->foster_parenting = false;
2230            
2231 0           break;
2232             }
2233             }
2234             }
2235            
2236 0           return false;
2237             }
2238              
2239 0           bool myhtml_insertion_mode_in_table_text(myhtml_tree_t* tree, myhtml_token_node_t* token)
2240             {
2241             // skip NULL, we replaced earlier
2242 0 0         if(token->tag_id == MyHTML_TAG__TEXT)
2243             {
2244 0 0         if(token->type & MyHTML_TOKEN_TYPE_NULL) {
2245             // parse error
2246             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:NULL_CHAR ACTION:IGNORE LEVEL:ERROR */
2247            
2248 0           myhtml_insertion_fix_for_null_char_drop_all(tree, token);
2249            
2250 0 0         if(token->str.length)
2251 0           myhtml_tree_token_list_append(tree->token_list, token);
2252             }
2253             else
2254 0           myhtml_tree_token_list_append(tree->token_list, token);
2255             }
2256             else {
2257 0           myhtml_tree_token_list_t* token_list = tree->token_list;
2258 0           bool is_not_ws = false;
2259            
2260 0 0         for(size_t i = 0; i < token_list->length; i++) {
2261 0 0         if((token_list->list[i]->type & MyHTML_TOKEN_TYPE_WHITESPACE) == 0) {
2262 0           is_not_ws = true;
2263 0           break;
2264             }
2265             }
2266            
2267 0 0         if(is_not_ws)
2268             {
2269 0 0         for(size_t i = 0; i < token_list->length; i++) {
2270             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR TOKEN:token_list->list[i] */
2271            
2272 0           tree->foster_parenting = true;
2273 0           myhtml_insertion_mode_in_body(tree, token_list->list[i]);
2274 0           tree->foster_parenting = false;
2275             }
2276             }
2277             else {
2278 0 0         for(size_t i = 0; i < token_list->length; i++) {
2279 0           myhtml_tree_node_insert_text(tree, token_list->list[i]);
2280             }
2281             }
2282            
2283 0           tree->insert_mode = tree->orig_insert_mode;
2284 0           return true;
2285             }
2286            
2287 0           return false;
2288             }
2289              
2290 0           bool myhtml_insertion_mode_in_caption(myhtml_tree_t* tree, myhtml_token_node_t* token)
2291             {
2292 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2293             {
2294 0           switch (token->tag_id) {
2295 0           case MyHTML_TAG_CAPTION:
2296             {
2297 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE) == NULL) {
2298             // parse error
2299             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2300 0           break;
2301             }
2302            
2303 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
2304            
2305 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2306 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_CAPTION) == false) {
2307             // parse error
2308             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
2309             /* %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 */
2310             }
2311            
2312 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, false);
2313 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
2314            
2315 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2316 0           break;
2317             }
2318            
2319 0           case MyHTML_TAG_TABLE:
2320             {
2321 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE) == NULL) {
2322             // parse error
2323             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2324 0           break;
2325             }
2326            
2327 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
2328            
2329 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2330 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_CAPTION) == false) {
2331             // parse error
2332             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
2333             /* %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 */
2334             }
2335            
2336 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, false);
2337 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
2338            
2339 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2340 0           return true;
2341             }
2342            
2343 0           case MyHTML_TAG_BODY:
2344             case MyHTML_TAG_COL:
2345             case MyHTML_TAG_COLGROUP:
2346             case MyHTML_TAG_HTML:
2347             case MyHTML_TAG_TBODY:
2348             case MyHTML_TAG_TD:
2349             case MyHTML_TAG_TFOOT:
2350             case MyHTML_TAG_TH:
2351             case MyHTML_TAG_THEAD:
2352             case MyHTML_TAG_TR:
2353             {
2354             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2355 0           break;
2356             }
2357            
2358 0           default:
2359 0           return myhtml_insertion_mode_in_body(tree, token);
2360             }
2361             }
2362             else {
2363 0 0         switch (token->tag_id)
2364             {
2365 0           case MyHTML_TAG_CAPTION:
2366             case MyHTML_TAG_COL:
2367             case MyHTML_TAG_COLGROUP:
2368             case MyHTML_TAG_TBODY:
2369             case MyHTML_TAG_TD:
2370             case MyHTML_TAG_TFOOT:
2371             case MyHTML_TAG_TH:
2372             case MyHTML_TAG_THEAD:
2373             case MyHTML_TAG_TR:
2374             {
2375 0 0         if(myhtml_tree_element_in_scope(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE) == NULL) {
2376             // parse error
2377             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2378 0           break;
2379             }
2380            
2381 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
2382            
2383 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2384 0           if(myhtml_is_html_node(current_node, MyHTML_TAG_CAPTION) == false) {
2385             // parse error
2386             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
2387             /* %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 */
2388             }
2389            
2390 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_CAPTION, MyHTML_NAMESPACE_HTML, false);
2391 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
2392            
2393 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2394 0           return true;
2395             }
2396            
2397 0           default:
2398 0           return myhtml_insertion_mode_in_body(tree, token);
2399             }
2400             }
2401            
2402 0           return false;
2403             }
2404              
2405 0           bool myhtml_insertion_mode_in_column_group(myhtml_tree_t* tree, myhtml_token_node_t* token)
2406             {
2407 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2408             {
2409 0           switch (token->tag_id) {
2410 0           case MyHTML_TAG_COLGROUP:
2411             {
2412 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2413            
2414 0 0         if(current_node && myhtml_is_html_node(current_node, MyHTML_TAG_COLGROUP)) {
    0          
2415 0           myhtml_tree_open_elements_pop(tree);
2416            
2417 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2418 0           return false;
2419             }
2420            
2421             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2422 0           break;
2423             }
2424            
2425 0           case MyHTML_TAG_COL:
2426             {
2427             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2428            
2429 0           break;
2430             }
2431            
2432 0           case MyHTML_TAG_TEMPLATE:
2433             {
2434 0           return myhtml_insertion_mode_in_head(tree, token);
2435             }
2436            
2437 0           default: {
2438 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2439            
2440 0 0         if(current_node && myhtml_is_html_node(current_node, MyHTML_TAG_COLGROUP)) {
    0          
2441 0           myhtml_tree_open_elements_pop(tree);
2442            
2443 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2444 0           return true;
2445             }
2446            
2447             // parse error
2448             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2449 0           break;
2450             }
2451             }
2452             }
2453             else {
2454 0           switch (token->tag_id)
2455             {
2456 0           case MyHTML_TAG__TEXT:
2457             {
2458 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE) {
2459 0           myhtml_tree_node_insert_text(tree, token);
2460 0           break;
2461             }
2462            
2463 0           myhtml_token_node_t* new_token = myhtml_insertion_fix_split_for_text_begin_ws(tree, token);
2464 0 0         if(new_token)
2465 0           myhtml_tree_node_insert_text(tree, new_token);
2466            
2467             /* default: */
2468 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2469            
2470 0 0         if(current_node && myhtml_is_html_node(current_node, MyHTML_TAG_COLGROUP)) {
    0          
2471 0           myhtml_tree_open_elements_pop(tree);
2472            
2473 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2474 0           return true;
2475             }
2476            
2477             // parse error
2478             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2479 0           break;
2480             }
2481            
2482 0           case MyHTML_TAG__COMMENT:
2483             {
2484 0           myhtml_tree_node_insert_comment(tree, token, 0);
2485 0           break;
2486             }
2487            
2488 0           case MyHTML_TAG__DOCTYPE: {
2489             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
2490 0           break;
2491             }
2492 0           case MyHTML_TAG_HTML:
2493             {
2494 0           return myhtml_insertion_mode_in_body(tree, token);
2495             }
2496            
2497 0           case MyHTML_TAG_COL:
2498             {
2499 0           myhtml_tree_node_insert_html_element(tree, token);
2500 0           myhtml_tree_open_elements_pop(tree);
2501 0           break;
2502             }
2503            
2504 0           case MyHTML_TAG_TEMPLATE:
2505             {
2506 0           return myhtml_insertion_mode_in_head(tree, token);
2507             }
2508            
2509 0           case MyHTML_TAG__END_OF_FILE:
2510 0           return myhtml_insertion_mode_in_body(tree, token);
2511            
2512 0           default:
2513             {
2514 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2515            
2516 0 0         if(current_node && myhtml_is_html_node(current_node, MyHTML_TAG_COLGROUP)) {
    0          
2517 0           myhtml_tree_open_elements_pop(tree);
2518            
2519 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2520 0           return true;
2521             }
2522            
2523             // parse error
2524             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2525 0           break;
2526             }
2527             }
2528             }
2529            
2530 0           return false;
2531             }
2532              
2533 0           bool myhtml_insertion_mode_in_table_body(myhtml_tree_t* tree, myhtml_token_node_t* token)
2534             {
2535 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2536             {
2537 0           switch (token->tag_id) {
2538 0           case MyHTML_TAG_TBODY:
2539             case MyHTML_TAG_TFOOT:
2540             case MyHTML_TAG_THEAD:
2541             {
2542 0           myhtml_tree_node_t* node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2543            
2544 0 0         if(node == NULL) {
2545             // parse error
2546             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2547 0           break;
2548             }
2549            
2550 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2551 0           myhtml_tree_open_elements_pop(tree);
2552            
2553 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2554 0           break;
2555             }
2556            
2557 0           case MyHTML_TAG_TABLE:
2558             {
2559 0           myhtml_tree_node_t* tbody_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TBODY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2560 0           myhtml_tree_node_t* tfoot_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TFOOT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2561 0           myhtml_tree_node_t* thead_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_THEAD, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2562            
2563 0 0         if(tbody_node == NULL && tfoot_node == NULL && thead_node == NULL) {
    0          
    0          
2564             // parse error
2565             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2566             /* %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 */
2567             /* %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 */
2568             /* %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 */
2569 0           break;
2570             }
2571            
2572 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2573 0           myhtml_tree_open_elements_pop(tree);
2574            
2575 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2576 0           return true;
2577             }
2578            
2579 0           case MyHTML_TAG_BODY:
2580             case MyHTML_TAG_CAPTION:
2581             case MyHTML_TAG_COL:
2582             case MyHTML_TAG_COLGROUP:
2583             case MyHTML_TAG_HTML:
2584             case MyHTML_TAG_TD:
2585             case MyHTML_TAG_TH:
2586             case MyHTML_TAG_TR:
2587             {
2588             // parse error
2589             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2590 0           break;
2591             }
2592            
2593 0           default:
2594 0           return myhtml_insertion_mode_in_table(tree, token);
2595             }
2596             }
2597             else {
2598 0           switch (token->tag_id)
2599             {
2600 0           case MyHTML_TAG_TR:
2601             {
2602 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2603            
2604 0           myhtml_tree_node_insert_html_element(tree, token);
2605            
2606 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_ROW;
2607 0           break;
2608             }
2609            
2610 0           case MyHTML_TAG_TH:
2611             case MyHTML_TAG_TD:
2612             {
2613             // parse error
2614             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
2615            
2616 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2617            
2618 0           myhtml_tree_node_insert(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML);
2619            
2620 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_ROW;
2621 0           return true;
2622             }
2623            
2624 0           case MyHTML_TAG_CAPTION:
2625             case MyHTML_TAG_COL:
2626             case MyHTML_TAG_COLGROUP:
2627             case MyHTML_TAG_TBODY:
2628             case MyHTML_TAG_TFOOT:
2629             case MyHTML_TAG_THEAD:
2630             {
2631 0           myhtml_tree_node_t* tbody_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TBODY, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2632 0           myhtml_tree_node_t* tfoot_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TFOOT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2633 0           myhtml_tree_node_t* thead_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_THEAD, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2634            
2635 0 0         if(tbody_node == NULL && tfoot_node == NULL && thead_node == NULL) {
    0          
    0          
2636             // parse error
2637             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2638             /* %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 */
2639             /* %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 */
2640             /* %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 */
2641 0           break;
2642             }
2643            
2644 0           myhtml_tree_clear_stack_back_table_body_context(tree);
2645 0           myhtml_tree_open_elements_pop(tree);
2646            
2647 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
2648 0           return true;
2649             }
2650            
2651 0           default:
2652 0           return myhtml_insertion_mode_in_table(tree, token);
2653             }
2654             }
2655            
2656 0           return false;
2657             }
2658              
2659 0           bool myhtml_insertion_mode_in_row(myhtml_tree_t* tree, myhtml_token_node_t* token)
2660             {
2661 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2662             {
2663 0           switch (token->tag_id) {
2664 0           case MyHTML_TAG_TR:
2665             {
2666 0           myhtml_tree_node_t* tr_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2667            
2668 0 0         if(tr_node == NULL) {
2669             // parse error
2670             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2671 0           break;
2672             }
2673            
2674 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2675            
2676 0           myhtml_tree_open_elements_pop(tree);
2677            
2678 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2679 0           break;
2680             }
2681            
2682 0           case MyHTML_TAG_TABLE:
2683             {
2684 0           myhtml_tree_node_t* tr_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2685            
2686 0 0         if(tr_node == NULL) {
2687             // parse error
2688             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2689             /* %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 */
2690 0           break;
2691             }
2692            
2693 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2694 0           myhtml_tree_open_elements_pop(tree);
2695            
2696 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2697 0           return true;
2698             }
2699            
2700 0           case MyHTML_TAG_TBODY:
2701             case MyHTML_TAG_TFOOT:
2702             case MyHTML_TAG_THEAD:
2703             {
2704 0           myhtml_tree_node_t* node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2705 0 0         if(node == NULL) {
2706             // parse error
2707             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2708 0           break;
2709             }
2710            
2711 0           myhtml_tree_node_t* tr_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2712 0 0         if(tr_node == NULL)
2713 0           break;
2714            
2715 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2716 0           myhtml_tree_open_elements_pop(tree);
2717            
2718 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2719 0           return true;
2720             }
2721            
2722 0           case MyHTML_TAG_BODY:
2723             case MyHTML_TAG_CAPTION:
2724             case MyHTML_TAG_COL:
2725             case MyHTML_TAG_COLGROUP:
2726             case MyHTML_TAG_HTML:
2727             case MyHTML_TAG_TD:
2728             case MyHTML_TAG_TH:
2729             {
2730             // parse error
2731             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2732 0           break;
2733             }
2734            
2735 0           default:
2736 0           return myhtml_insertion_mode_in_table(tree, token);
2737             }
2738             }
2739             else {
2740 0           switch (token->tag_id)
2741             {
2742 0           case MyHTML_TAG_TH:
2743             case MyHTML_TAG_TD:
2744             {
2745 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2746            
2747 0           myhtml_tree_node_insert_html_element(tree, token);
2748 0           myhtml_tree_active_formatting_append(tree, tree->myhtml->marker);
2749            
2750 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_CELL;
2751 0           break;
2752             }
2753 0           case MyHTML_TAG_CAPTION:
2754             case MyHTML_TAG_COL:
2755             case MyHTML_TAG_COLGROUP:
2756             case MyHTML_TAG_TBODY:
2757             case MyHTML_TAG_TFOOT:
2758             case MyHTML_TAG_THEAD:
2759             case MyHTML_TAG_TR:
2760             {
2761 0           myhtml_tree_node_t* tr_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TR, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2762            
2763 0 0         if(tr_node == NULL) {
2764             // parse error
2765             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2766             /* %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 */
2767 0           break;
2768             }
2769            
2770 0           myhtml_tree_clear_stack_back_table_row_context(tree);
2771 0           myhtml_tree_open_elements_pop(tree);
2772            
2773 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
2774 0           return true;
2775             }
2776            
2777 0           default:
2778 0           return myhtml_insertion_mode_in_table(tree, token);
2779             }
2780             }
2781            
2782 0           return false;
2783             }
2784              
2785 0           bool myhtml_insertion_mode_in_cell(myhtml_tree_t* tree, myhtml_token_node_t* token)
2786             {
2787 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2788             {
2789 0           switch (token->tag_id) {
2790 0           case MyHTML_TAG_TD:
2791             case MyHTML_TAG_TH:
2792             {
2793 0           myhtml_tree_node_t* node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2794            
2795 0 0         if(node == NULL) {
2796             // parse error
2797             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2798 0           break;
2799             }
2800            
2801 0           myhtml_tree_generate_implied_end_tags(tree, 0, MyHTML_NAMESPACE_UNDEF);
2802            
2803 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2804            
2805 0           if(myhtml_is_html_node(current_node, token->tag_id) == false)
2806             {
2807             // parse error
2808             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
2809             /* %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 */
2810             }
2811            
2812 0           myhtml_tree_open_elements_pop_until(tree, token->tag_id, MyHTML_NAMESPACE_HTML, false);
2813            
2814 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
2815            
2816 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_ROW;
2817 0           break;
2818             }
2819            
2820 0           case MyHTML_TAG_BODY:
2821             case MyHTML_TAG_CAPTION:
2822             case MyHTML_TAG_COL:
2823             case MyHTML_TAG_COLGROUP:
2824             case MyHTML_TAG_HTML:
2825             {
2826             // parse error
2827             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2828 0           break;
2829             }
2830            
2831            
2832 0           case MyHTML_TAG_TABLE:
2833             case MyHTML_TAG_TBODY:
2834             case MyHTML_TAG_TFOOT:
2835             case MyHTML_TAG_THEAD:
2836             case MyHTML_TAG_TR:
2837             {
2838 0           myhtml_tree_node_t* node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2839            
2840 0 0         if(node == NULL) {
2841             // parse error
2842             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2843 0           break;
2844             }
2845            
2846 0           node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TD, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2847 0 0         if(node) {
2848 0           myhtml_tree_close_cell(tree, node, token);
2849             }
2850             else {
2851 0           node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TH, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2852 0 0         if(node)
2853 0           myhtml_tree_close_cell(tree, node, token);
2854             }
2855            
2856 0           return true;
2857             }
2858            
2859 0           default:
2860 0           return myhtml_insertion_mode_in_table(tree, token);
2861             }
2862             }
2863             else {
2864 0 0         switch (token->tag_id)
2865             {
2866 0           case MyHTML_TAG_CAPTION:
2867             case MyHTML_TAG_COL:
2868             case MyHTML_TAG_COLGROUP:
2869             case MyHTML_TAG_TBODY:
2870             case MyHTML_TAG_TD:
2871             case MyHTML_TAG_TFOOT:
2872             case MyHTML_TAG_TH:
2873             case MyHTML_TAG_THEAD:
2874             case MyHTML_TAG_TR:
2875             {
2876 0           myhtml_tree_node_t* td_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TD, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2877 0           myhtml_tree_node_t* th_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_TH, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
2878            
2879 0 0         if(td_node == NULL && th_node == NULL) {
    0          
2880             // parse error
2881             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2882             /* %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 */
2883             /* %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 */
2884            
2885 0           break;
2886             }
2887            
2888 0 0         myhtml_tree_close_cell(tree, (td_node == NULL ? th_node : td_node), token);
2889            
2890 0           return true;
2891             }
2892            
2893 0           default:
2894 0           return myhtml_insertion_mode_in_body(tree, token);
2895             }
2896             }
2897            
2898 0           return false;
2899             }
2900              
2901 0           bool myhtml_insertion_mode_in_select(myhtml_tree_t* tree, myhtml_token_node_t* token)
2902             {
2903 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
2904             {
2905 0           switch (token->tag_id) {
2906 0           case MyHTML_TAG_OPTGROUP:
2907             {
2908 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2909            
2910 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_OPTION))
2911             {
2912 0 0         if(tree->open_elements->length > 1) {
2913 0           myhtml_tree_node_t *optgrp_node = tree->open_elements->list[ tree->open_elements->length - 2 ];
2914            
2915 0 0         if(myhtml_is_html_node(optgrp_node, MyHTML_TAG_OPTGROUP))
2916             {
2917 0           myhtml_tree_open_elements_pop(tree);
2918             }
2919             }
2920             }
2921            
2922 0           current_node = myhtml_tree_current_node(tree);
2923            
2924 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_OPTGROUP))
2925 0           myhtml_tree_open_elements_pop(tree);
2926             else {
2927             // parse error
2928             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED ACTION:IGNORE LEVEL:ERROR */
2929            
2930 0           break;
2931             }
2932            
2933 0           break;
2934             }
2935            
2936 0           case MyHTML_TAG_OPTION:
2937             {
2938 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
2939            
2940 0 0         if(myhtml_is_html_node(current_node, MyHTML_TAG_OPTION))
2941 0           myhtml_tree_open_elements_pop(tree);
2942             else {
2943             // parse error
2944             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2945            
2946 0           break;
2947             }
2948            
2949 0           break;
2950             }
2951            
2952 0           case MyHTML_TAG_SELECT:
2953             {
2954 0           myhtml_tree_node_t* select_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_SELECT);
2955            
2956 0 0         if(select_node == NULL) {
2957             // parse error
2958             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
2959 0           break;
2960             }
2961            
2962 0           myhtml_tree_open_elements_pop_until_by_node(tree, select_node, false);
2963 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
2964            
2965 0           break;
2966             }
2967            
2968 0           case MyHTML_TAG_TEMPLATE:
2969 0           return myhtml_insertion_mode_in_head(tree, token);
2970            
2971 0           default: {
2972             // parse error
2973             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
2974            
2975 0           break;
2976             }
2977             }
2978             }
2979             else {
2980 0           switch (token->tag_id)
2981             {
2982 0           case MyHTML_TAG__TEXT: {
2983 0 0         if(token->type & MyHTML_TOKEN_TYPE_NULL) {
2984             // parse error
2985             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:NULL_CHAR ACTION:IGNORE LEVEL:ERROR */
2986            
2987 0           myhtml_insertion_fix_for_null_char_drop_all(tree, token);
2988            
2989 0 0         if(token->str.length)
2990 0           myhtml_tree_node_insert_text(tree, token);
2991             }
2992             else
2993 0           myhtml_tree_node_insert_text(tree, token);
2994            
2995 0           break;
2996             }
2997            
2998 0           case MyHTML_TAG__COMMENT:
2999 0           myhtml_tree_node_insert_comment(tree, token, NULL);
3000 0           break;
3001            
3002 0           case MyHTML_TAG__DOCTYPE: {
3003             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3004            
3005 0           break;
3006             }
3007            
3008 0           case MyHTML_TAG_HTML:
3009 0           return myhtml_insertion_mode_in_body(tree, token);
3010            
3011 0           case MyHTML_TAG_OPTION:
3012             {
3013 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3014            
3015 0 0         if(myhtml_is_html_node(current_node, token->tag_id))
3016 0           myhtml_tree_open_elements_pop(tree);
3017            
3018 0           myhtml_tree_node_insert_html_element(tree, token);
3019 0           break;
3020             }
3021            
3022 0           case MyHTML_TAG_OPTGROUP:
3023             {
3024 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3025            
3026 0 0         if(current_node->tag_id == MyHTML_TAG_OPTION &&
3027 0 0         current_node->ns == MyHTML_NAMESPACE_HTML)
3028 0           myhtml_tree_open_elements_pop(tree);
3029            
3030 0           current_node = myhtml_tree_current_node(tree);
3031            
3032 0 0         if(current_node->tag_id == token->tag_id &&
3033 0 0         current_node->ns == MyHTML_NAMESPACE_HTML)
3034 0           myhtml_tree_open_elements_pop(tree);
3035            
3036 0           myhtml_tree_node_insert_html_element(tree, token);
3037 0           break;
3038             }
3039            
3040 0           case MyHTML_TAG_SELECT:
3041             {
3042             // parse error
3043             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
3044            
3045 0           myhtml_tree_node_t* select_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_SELECT);
3046            
3047 0 0         if(select_node == NULL) {
3048             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
3049            
3050 0           break;
3051             }
3052            
3053 0           myhtml_tree_open_elements_pop_until_by_node(tree, select_node, false);
3054 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3055            
3056 0           break;
3057             }
3058            
3059 0           case MyHTML_TAG_INPUT:
3060             case MyHTML_TAG_KEYGEN:
3061             case MyHTML_TAG_TEXTAREA:
3062             {
3063             // parse error
3064             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
3065            
3066 0           myhtml_tree_node_t* select_node = myhtml_tree_element_in_scope(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_SELECT);
3067            
3068 0 0         if(select_node == NULL) {
3069             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
3070            
3071 0           break;
3072             }
3073            
3074 0           myhtml_tree_open_elements_pop_until_by_node(tree, select_node, false);
3075 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3076            
3077 0           return true;
3078             }
3079            
3080 0           case MyHTML_TAG_SCRIPT:
3081             case MyHTML_TAG_TEMPLATE:
3082 0           return myhtml_insertion_mode_in_head(tree, token);
3083            
3084 0           case MyHTML_TAG__END_OF_FILE:
3085 0           return myhtml_insertion_mode_in_body(tree, token);
3086            
3087 0           default: {
3088             // parse error
3089             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3090 0           break;
3091             }
3092             }
3093             }
3094            
3095 0           return false;
3096             }
3097              
3098 0           bool myhtml_insertion_mode_in_select_in_table(myhtml_tree_t* tree, myhtml_token_node_t* token)
3099             {
3100 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3101             {
3102 0 0         switch (token->tag_id) {
3103 0           case MyHTML_TAG_CAPTION:
3104             case MyHTML_TAG_TABLE:
3105             case MyHTML_TAG_TBODY:
3106             case MyHTML_TAG_TFOOT:
3107             case MyHTML_TAG_THEAD:
3108             case MyHTML_TAG_TR:
3109             case MyHTML_TAG_TD:
3110             case MyHTML_TAG_TH:
3111             {
3112             // parse error
3113             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
3114            
3115 0           myhtml_tree_node_t* some_node = myhtml_tree_element_in_scope(tree, token->tag_id, MyHTML_NAMESPACE_HTML, MyHTML_TAG_CATEGORIES_SCOPE_TABLE);
3116            
3117 0 0         if(some_node == NULL) {
3118             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_OPEN_NOT_FOUND ACTION:IGNORE LEVEL:ERROR */
3119            
3120 0           break;
3121             }
3122            
3123 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, false);
3124 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3125            
3126 0           return true;
3127             }
3128            
3129 0           default:
3130 0           return myhtml_insertion_mode_in_select(tree, token);
3131             }
3132             }
3133             else {
3134 0 0         switch (token->tag_id)
3135             {
3136 0           case MyHTML_TAG_CAPTION:
3137             case MyHTML_TAG_TABLE:
3138             case MyHTML_TAG_TBODY:
3139             case MyHTML_TAG_TFOOT:
3140             case MyHTML_TAG_THEAD:
3141             case MyHTML_TAG_TR:
3142             case MyHTML_TAG_TD:
3143             case MyHTML_TAG_TH:
3144             {
3145             // parse error
3146             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION LEVEL:ERROR */
3147            
3148 0           myhtml_tree_open_elements_pop_until(tree, MyHTML_TAG_SELECT, MyHTML_NAMESPACE_HTML, false);
3149 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3150            
3151 0           return true;
3152             }
3153            
3154 0           default:
3155 0           return myhtml_insertion_mode_in_select(tree, token);
3156             }
3157             }
3158            
3159 0           return false;
3160             }
3161              
3162 0           bool myhtml_insertion_mode_in_template(myhtml_tree_t* tree, myhtml_token_node_t* token)
3163             {
3164 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3165             {
3166 0 0         switch (token->tag_id) {
3167 0           case MyHTML_TAG_TEMPLATE:
3168 0           return myhtml_insertion_mode_in_body(tree, token);
3169            
3170 0           default: {
3171             // parse error
3172             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3173            
3174 0           break;
3175             }
3176             }
3177             }
3178             else {
3179 0           switch (token->tag_id)
3180             {
3181 0           case MyHTML_TAG__TEXT:
3182             case MyHTML_TAG__COMMENT:
3183             case MyHTML_TAG__DOCTYPE:
3184 0           return myhtml_insertion_mode_in_body(tree, token);
3185            
3186 0           case MyHTML_TAG_BASE:
3187             case MyHTML_TAG_BASEFONT:
3188             case MyHTML_TAG_BGSOUND:
3189             case MyHTML_TAG_LINK:
3190             case MyHTML_TAG_META:
3191             case MyHTML_TAG_NOFRAMES:
3192             case MyHTML_TAG_SCRIPT:
3193             case MyHTML_TAG_STYLE:
3194             case MyHTML_TAG_TEMPLATE:
3195             case MyHTML_TAG_TITLE:
3196 0           return myhtml_insertion_mode_in_head(tree, token);
3197            
3198 0           case MyHTML_TAG_CAPTION:
3199             case MyHTML_TAG_COLGROUP:
3200             case MyHTML_TAG_TBODY:
3201             case MyHTML_TAG_TFOOT:
3202             case MyHTML_TAG_THEAD:
3203 0           myhtml_tree_template_insertion_pop(tree);
3204 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_TABLE);
3205            
3206 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE;
3207 0           return true;
3208            
3209 0           case MyHTML_TAG_COL:
3210 0           myhtml_tree_template_insertion_pop(tree);
3211 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_COLUMN_GROUP);
3212            
3213 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_COLUMN_GROUP;
3214 0           return true;
3215            
3216 0           case MyHTML_TAG_TR:
3217 0           myhtml_tree_template_insertion_pop(tree);
3218 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_TABLE_BODY);
3219            
3220 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_TABLE_BODY;
3221 0           return true;
3222            
3223 0           case MyHTML_TAG_TD:
3224             case MyHTML_TAG_TH:
3225 0           myhtml_tree_template_insertion_pop(tree);
3226 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_ROW);
3227            
3228 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_ROW;
3229 0           return true;
3230            
3231 0           case MyHTML_TAG__END_OF_FILE:
3232             {
3233 0           myhtml_tree_node_t* node = myhtml_tree_open_elements_find_by_tag_idx(tree, MyHTML_TAG_TEMPLATE, MyHTML_NAMESPACE_HTML, NULL);
3234            
3235 0 0         if(node == NULL) {
3236 0           myhtml_rules_stop_parsing(tree);
3237 0           break;
3238             }
3239            
3240             // parse error
3241             /* %EXTERNAL% VALIDATOR:RULES TAG STATUS:ELEMENT_NOT_CLOSED LEVEL:ERROR TAG_ID:MyHTML_TAG_TEMPLATE NS:MyHTML_NAMESPACE_HTML */
3242            
3243 0           myhtml_tree_open_elements_pop_until_by_node(tree, node, false);
3244 0           myhtml_tree_active_formatting_up_to_last_marker(tree);
3245 0           myhtml_tree_template_insertion_pop(tree);
3246 0           myhtml_tree_reset_insertion_mode_appropriately(tree);
3247            
3248 0           return true;
3249             }
3250            
3251 0           default:
3252 0           myhtml_tree_template_insertion_pop(tree);
3253 0           myhtml_tree_template_insertion_append(tree, MyHTML_INSERTION_MODE_IN_BODY);
3254            
3255 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3256 0           return true;
3257             }
3258             }
3259            
3260 0           return false;
3261             }
3262              
3263 1           bool myhtml_insertion_mode_after_body(myhtml_tree_t* tree, myhtml_token_node_t* token)
3264             {
3265 1 50         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3266             {
3267 0 0         switch (token->tag_id) {
3268 0           case MyHTML_TAG_HTML:
3269             {
3270 0 0         if(tree->fragment) {
3271             // parse error
3272             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED ACTION:IGNORE LEVEL:ERROR */
3273            
3274 0           break;
3275             }
3276            
3277 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_AFTER_BODY;
3278 0           break;
3279             }
3280            
3281 0           default: {
3282             // parse error
3283             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3284            
3285 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3286 0           return true;
3287             }
3288             }
3289             }
3290             else {
3291 1           switch (token->tag_id)
3292             {
3293 0           case MyHTML_TAG__TEXT:
3294             {
3295 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE)
3296 0           return myhtml_insertion_mode_in_body(tree, token);
3297            
3298 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3299 0           return true;
3300             }
3301            
3302 0           case MyHTML_TAG__COMMENT:
3303             {
3304 0 0         if(tree->open_elements->length == 0) {
3305             MyCORE_DEBUG_ERROR("after body state; open_elements length < 1");
3306 0           break;
3307             }
3308            
3309 0           myhtml_tree_node_t* adjusted_location = tree->open_elements->list[0];
3310            
3311             // state 2
3312 0           myhtml_tree_node_t* node = myhtml_tree_node_create(tree);
3313            
3314 0           node->tag_id = MyHTML_TAG__COMMENT;
3315 0           node->token = token;
3316 0           node->ns = adjusted_location->ns;
3317            
3318 0           myhtml_tree_node_add_child(adjusted_location, node);
3319            
3320 0           break;
3321             }
3322            
3323 0           case MyHTML_TAG__DOCTYPE: {
3324             // parse error
3325             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3326            
3327 0           break;
3328             }
3329 0           case MyHTML_TAG_HTML:
3330 0           return myhtml_insertion_mode_in_body(tree, token);
3331            
3332 1           case MyHTML_TAG__END_OF_FILE:
3333 1           myhtml_rules_stop_parsing(tree);
3334 1           break;
3335            
3336 0           default: {
3337             // parse error
3338             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3339            
3340 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3341 0           return true;
3342             }
3343             }
3344             }
3345            
3346 1           return false;
3347             }
3348              
3349 0           bool myhtml_insertion_mode_in_frameset(myhtml_tree_t* tree, myhtml_token_node_t* token)
3350             {
3351 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3352             {
3353 0 0         switch (token->tag_id) {
3354 0           case MyHTML_TAG_FRAMESET:
3355             {
3356 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3357            
3358 0 0         if(current_node == tree->document->child) {
3359             // parse error
3360             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED ACTION:IGNORE LEVEL:ERROR */
3361            
3362 0           break;
3363             }
3364            
3365 0           myhtml_tree_open_elements_pop(tree);
3366            
3367 0           current_node = myhtml_tree_current_node(tree);
3368            
3369 0 0         if(tree->fragment == NULL &&
3370 0 0         !(current_node->tag_id == MyHTML_TAG_FRAMESET &&
3371 0 0         current_node->ns == MyHTML_NAMESPACE_HTML))
3372             {
3373 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_FRAMESET;
3374             }
3375            
3376 0           break;
3377             }
3378            
3379 0           default: {
3380             // parse error
3381             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3382            
3383 0           break;
3384             }
3385             }
3386             }
3387             else {
3388 0           switch (token->tag_id)
3389             {
3390 0           case MyHTML_TAG__TEXT:
3391             {
3392 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE) {
3393 0           myhtml_tree_node_insert_text(tree, token);
3394 0           break;
3395             }
3396            
3397             // parse error
3398             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3399            
3400 0           myhtml_token_node_wait_for_done(tree->token, token);
3401 0           mycore_string_stay_only_whitespace(&token->str);
3402            
3403 0 0         if(token->str.length)
3404 0           myhtml_tree_node_insert_text(tree, token);
3405            
3406 0           break;
3407             }
3408            
3409 0           case MyHTML_TAG__COMMENT:
3410             {
3411 0           myhtml_tree_node_insert_comment(tree, token, NULL);
3412 0           break;
3413             }
3414            
3415 0           case MyHTML_TAG__DOCTYPE: {
3416             // parse error
3417             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3418            
3419 0           break;
3420             }
3421            
3422 0           case MyHTML_TAG_HTML:
3423 0           return myhtml_insertion_mode_in_body(tree, token);
3424            
3425 0           case MyHTML_TAG_FRAMESET:
3426 0           myhtml_tree_node_insert_html_element(tree, token);
3427 0           break;
3428            
3429 0           case MyHTML_TAG_FRAME:
3430 0           myhtml_tree_node_insert_html_element(tree, token);
3431 0           myhtml_tree_open_elements_pop(tree);
3432 0           break;
3433            
3434 0           case MyHTML_TAG_NOFRAMES:
3435 0           return myhtml_insertion_mode_in_head(tree, token);
3436            
3437 0           case MyHTML_TAG__END_OF_FILE:
3438             {
3439 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3440            
3441 0           if(current_node == tree->document->child) {
3442             // parse error
3443             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3444             }
3445            
3446 0           myhtml_rules_stop_parsing(tree);
3447 0           break;
3448             }
3449            
3450 0           default: {
3451             // parse error
3452             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3453            
3454 0           break;
3455             }
3456             }
3457             }
3458            
3459 0           return false;
3460             }
3461              
3462 0           bool myhtml_insertion_mode_after_frameset(myhtml_tree_t* tree, myhtml_token_node_t* token)
3463             {
3464 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3465             {
3466 0 0         switch (token->tag_id) {
3467 0           case MyHTML_TAG_HTML:
3468 0           tree->insert_mode = MyHTML_INSERTION_MODE_AFTER_AFTER_FRAMESET;
3469 0           break;
3470            
3471 0           default: {
3472             // parse error
3473             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3474            
3475 0           break;
3476             }
3477             }
3478             }
3479             else {
3480 0           switch (token->tag_id)
3481             {
3482 0           case MyHTML_TAG__TEXT:
3483             {
3484 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE) {
3485 0           myhtml_tree_node_insert_text(tree, token);
3486 0           break;
3487             }
3488            
3489             // parse error
3490             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3491            
3492 0           myhtml_token_node_wait_for_done(tree->token, token);
3493 0           mycore_string_stay_only_whitespace(&token->str);
3494            
3495 0 0         if(token->str.length)
3496 0           myhtml_tree_node_insert_text(tree, token);
3497            
3498 0           break;
3499             }
3500            
3501 0           case MyHTML_TAG__COMMENT:
3502             {
3503 0           myhtml_tree_node_insert_comment(tree, token, NULL);
3504 0           break;
3505             }
3506            
3507 0           case MyHTML_TAG__DOCTYPE: {
3508             // parse error
3509             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3510 0           break;
3511             }
3512            
3513 0           case MyHTML_TAG_HTML:
3514 0           return myhtml_insertion_mode_in_body(tree, token);
3515            
3516 0           case MyHTML_TAG_NOFRAMES:
3517 0           return myhtml_insertion_mode_in_head(tree, token);
3518            
3519 0           case MyHTML_TAG__END_OF_FILE:
3520 0           myhtml_rules_stop_parsing(tree);
3521 0           break;
3522            
3523 0           default: {
3524             // parse error
3525             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY ACTION:IGNORE LEVEL:ERROR */
3526            
3527 0           break;
3528             }
3529             }
3530             }
3531            
3532 0           return false;
3533             }
3534              
3535 0           bool myhtml_insertion_mode_after_after_body(myhtml_tree_t* tree, myhtml_token_node_t* token)
3536             {
3537 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE)
3538             {
3539 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3540 0           return true;
3541             }
3542             else {
3543 0           switch (token->tag_id)
3544             {
3545 0           case MyHTML_TAG__COMMENT:
3546             {
3547 0           myhtml_tree_node_t* adjusted_location = tree->document;
3548 0           myhtml_tree_node_t* node = myhtml_tree_node_create(tree);
3549            
3550 0           node->tag_id = MyHTML_TAG__COMMENT;
3551 0           node->token = token;
3552 0           node->ns = adjusted_location->ns;
3553            
3554 0           myhtml_tree_node_add_child(adjusted_location, node);
3555 0           break;
3556             }
3557            
3558 0           case MyHTML_TAG__TEXT:
3559             {
3560 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE)
3561 0           return myhtml_insertion_mode_in_body(tree, token);
3562            
3563             // parse error
3564             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3565            
3566 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3567 0           return true;
3568             }
3569            
3570 0           case MyHTML_TAG_HTML:
3571             case MyHTML_TAG__DOCTYPE:
3572 0           return myhtml_insertion_mode_in_body(tree, token);
3573            
3574 0           case MyHTML_TAG__END_OF_FILE:
3575 0           myhtml_rules_stop_parsing(tree);
3576 0           break;
3577            
3578 0           default: {
3579             // parse error
3580             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3581            
3582 0           tree->insert_mode = MyHTML_INSERTION_MODE_IN_BODY;
3583 0           return true;
3584             }
3585             }
3586             }
3587            
3588 0           return false;
3589             }
3590              
3591 0           bool myhtml_insertion_mode_after_after_frameset(myhtml_tree_t* tree, myhtml_token_node_t* token)
3592             {
3593 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE) {
3594             // parse error
3595             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3596            
3597 0           return false;
3598             }
3599             else {
3600 0           switch (token->tag_id)
3601             {
3602 0           case MyHTML_TAG__COMMENT:
3603             {
3604 0           myhtml_tree_node_t* adjusted_location = tree->document;
3605 0           myhtml_tree_node_t* node = myhtml_tree_node_create(tree);
3606            
3607 0           node->tag_id = MyHTML_TAG__COMMENT;
3608 0           node->token = token;
3609 0           node->ns = adjusted_location->ns;
3610            
3611 0           myhtml_tree_node_add_child(adjusted_location, node);
3612 0           break;
3613             }
3614            
3615 0           case MyHTML_TAG__TEXT:
3616             {
3617 0 0         if(token->type & MyHTML_TOKEN_TYPE_WHITESPACE)
3618 0           return myhtml_insertion_mode_in_body(tree, token);
3619            
3620 0           myhtml_token_node_t* new_token = myhtml_insertion_fix_split_for_text_begin_ws(tree, token);
3621 0 0         if(new_token)
3622 0           return myhtml_insertion_mode_in_body(tree, new_token);
3623            
3624             // parse error
3625             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3626            
3627 0           break;
3628             }
3629            
3630 0           case MyHTML_TAG_HTML:
3631             case MyHTML_TAG__DOCTYPE:
3632 0           return myhtml_insertion_mode_in_body(tree, token);
3633            
3634 0           case MyHTML_TAG__END_OF_FILE:
3635 0           myhtml_rules_stop_parsing(tree);
3636 0           break;
3637            
3638 0           case MyHTML_TAG_NOFRAMES:
3639 0           return myhtml_insertion_mode_in_head(tree, token);
3640            
3641 0           default: {
3642             // parse error
3643             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_UNNECESSARY LEVEL:ERROR */
3644 0           break;
3645             }
3646             }
3647             }
3648            
3649 0           return false;
3650             }
3651              
3652 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)
3653             {
3654 0           if(current_node->tag_id != token->tag_id) {
3655             // parse error
3656             /* %EXTERNAL% VALIDATOR:RULES HAVE_NEED STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3657             /* %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 */
3658             }
3659            
3660 0 0         if(tree->open_elements->length)
3661             {
3662 0           myhtml_tree_node_t** list = tree->open_elements->list;
3663 0           size_t i = tree->open_elements->length - 1;
3664            
3665 0 0         while (i)
3666             {
3667 0           current_node = list[i];
3668            
3669 0 0         if(current_node->tag_id == token->tag_id) {
3670 0           myhtml_tree_open_elements_pop_until_by_node(tree, current_node, false);
3671 0           return false;
3672             }
3673            
3674 0           i--;
3675            
3676 0 0         if(list[i]->ns == MyHTML_NAMESPACE_HTML)
3677 0           break;
3678             }
3679             }
3680            
3681 0           return tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3682             }
3683              
3684 0           bool myhtml_insertion_mode_in_foreign_content_start_other(myhtml_tree_t* tree, myhtml_token_node_t* token)
3685             {
3686 0           myhtml_tree_node_t* adjusted_node = myhtml_tree_adjusted_current_node(tree);
3687            
3688 0           myhtml_token_node_wait_for_done(tree->token, token);
3689            
3690 0 0         if(adjusted_node->ns == MyHTML_NAMESPACE_MATHML) {
3691 0           myhtml_token_adjust_mathml_attributes(token);
3692             }
3693 0 0         else if(adjusted_node->ns == MyHTML_NAMESPACE_SVG) {
3694 0           myhtml_token_adjust_svg_attributes(token);
3695             }
3696            
3697 0           myhtml_token_adjust_foreign_attributes(token);
3698            
3699 0           myhtml_tree_node_t* node = myhtml_tree_node_insert_foreign_element(tree, token);
3700 0           node->ns = adjusted_node->ns;
3701            
3702 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE_SELF)
3703             {
3704 0 0         if(token->tag_id == MyHTML_TAG_SCRIPT &&
3705 0 0         node->ns == MyHTML_NAMESPACE_SVG)
3706             {
3707 0           return myhtml_insertion_mode_in_foreign_content_end_other(tree, myhtml_tree_current_node(tree), token);
3708             }
3709             else {
3710 0           myhtml_tree_open_elements_pop(tree);
3711             }
3712             }
3713            
3714 0           return false;
3715             }
3716              
3717 0           bool myhtml_insertion_mode_in_foreign_content(myhtml_tree_t* tree, myhtml_token_node_t* token)
3718             {
3719 0 0         if(token->type & MyHTML_TOKEN_TYPE_CLOSE) {
3720 0           myhtml_tree_node_t* current_node = myhtml_tree_current_node(tree);
3721            
3722 0 0         if(token->tag_id == MyHTML_TAG_SCRIPT &&
3723 0 0         current_node->tag_id == MyHTML_TAG_SCRIPT &&
3724 0 0         current_node->ns == MyHTML_NAMESPACE_SVG)
3725             {
3726 0           myhtml_tree_open_elements_pop(tree);
3727             // TODO: now script is disable, skip this
3728 0           return false;
3729             }
3730            
3731 0           return myhtml_insertion_mode_in_foreign_content_end_other(tree, current_node, token);
3732             }
3733             else {
3734 0           switch (token->tag_id)
3735             {
3736 0           case MyHTML_TAG__TEXT:
3737             {
3738 0 0         if(token->type & MyHTML_TOKEN_TYPE_NULL) {
3739             // parse error
3740             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:NULL_CHAR LEVEL:ERROR */
3741            
3742 0           myhtml_token_node_wait_for_done(tree->token, token);
3743 0           myhtml_token_set_replacement_character_for_null_token(tree, token);
3744             }
3745            
3746 0           myhtml_tree_node_insert_text(tree, token);
3747            
3748 0 0         if((token->type & MyHTML_TOKEN_TYPE_WHITESPACE) == 0)
3749 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_FRAMESET_OK);
3750            
3751 0           break;
3752             }
3753            
3754 0           case MyHTML_TAG__COMMENT:
3755 0           myhtml_tree_node_insert_comment(tree, token, NULL);
3756 0           break;
3757            
3758 0           case MyHTML_TAG__DOCTYPE: {
3759             // parse error
3760             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_WRONG_LOCATION ACTION:IGNORE LEVEL:ERROR */
3761            
3762 0           break;
3763             }
3764            
3765 0           case MyHTML_TAG_B:
3766             case MyHTML_TAG_BIG:
3767             case MyHTML_TAG_BLOCKQUOTE:
3768             case MyHTML_TAG_BODY:
3769             case MyHTML_TAG_BR:
3770             case MyHTML_TAG_CENTER:
3771             case MyHTML_TAG_CODE:
3772             case MyHTML_TAG_DD:
3773             case MyHTML_TAG_DIV:
3774             case MyHTML_TAG_DL:
3775             case MyHTML_TAG_DT:
3776             case MyHTML_TAG_EM:
3777             case MyHTML_TAG_EMBED:
3778             case MyHTML_TAG_H1:
3779             case MyHTML_TAG_H2:
3780             case MyHTML_TAG_H3:
3781             case MyHTML_TAG_H4:
3782             case MyHTML_TAG_H5:
3783             case MyHTML_TAG_H6:
3784             case MyHTML_TAG_HEAD:
3785             case MyHTML_TAG_HR:
3786             case MyHTML_TAG_I:
3787             case MyHTML_TAG_IMG:
3788             case MyHTML_TAG_LI:
3789             case MyHTML_TAG_LISTING:
3790             case MyHTML_TAG_MENU:
3791             case MyHTML_TAG_META:
3792             case MyHTML_TAG_NOBR:
3793             case MyHTML_TAG_OL:
3794             case MyHTML_TAG_P:
3795             case MyHTML_TAG_PRE:
3796             case MyHTML_TAG_RUBY:
3797             case MyHTML_TAG_S:
3798             case MyHTML_TAG_SMALL:
3799             case MyHTML_TAG_SPAN:
3800             case MyHTML_TAG_STRONG:
3801             case MyHTML_TAG_STRIKE:
3802             case MyHTML_TAG_SUB:
3803             case MyHTML_TAG_SUP:
3804             case MyHTML_TAG_TABLE:
3805             case MyHTML_TAG_TT:
3806             case MyHTML_TAG_U:
3807             case MyHTML_TAG_UL:
3808             case MyHTML_TAG_VAR:
3809             case MyHTML_TAG_FONT:
3810             {
3811             // parse error
3812             /* %EXTERNAL% VALIDATOR:RULES TOKEN STATUS:ELEMENT_NO_EXPECTED LEVEL:ERROR */
3813            
3814 0 0         if(token->tag_id == MyHTML_TAG_FONT)
3815             {
3816 0           myhtml_token_node_wait_for_done(tree->token, token);
3817            
3818 0           if(myhtml_token_attr_by_name(token, "color", 5) == NULL &&
3819 0 0         myhtml_token_attr_by_name(token, "face" , 4) == NULL &&
3820 0           myhtml_token_attr_by_name(token, "size" , 4) == NULL)
3821             {
3822 0           return myhtml_insertion_mode_in_foreign_content_start_other(tree, token);
3823             }
3824             }
3825            
3826 0 0         if(tree->fragment == NULL) {
3827             myhtml_tree_node_t* current_node;
3828            
3829             do {
3830 0           myhtml_tree_open_elements_pop(tree);
3831 0           current_node = myhtml_tree_current_node(tree);
3832             }
3833 0 0         while(current_node && !(myhtml_tree_is_mathml_integration_point(tree, current_node) ||
3834 0           myhtml_tree_is_html_integration_point(tree, current_node) ||
3835 0 0         current_node->ns == MyHTML_NAMESPACE_HTML));
3836            
3837 0           return true;
3838             }
3839             }
3840            
3841             default:
3842 0           return myhtml_insertion_mode_in_foreign_content_start_other(tree, token);
3843             }
3844             }
3845            
3846 0           return false;
3847             }
3848              
3849 145           void myhtml_rules_stop_parsing(myhtml_tree_t* tree)
3850             {
3851             // THIS! IS! -(SPARTA!)- STOP PARSING
3852 145           }
3853              
3854 2288           bool myhtml_rules_check_for_first_newline(myhtml_tree_t* tree, myhtml_token_node_t* token)
3855             {
3856 2288 50         if(tree->flags & MyHTML_TREE_FLAGS_PARSE_FLAG) {
3857 0 0         if(tree->flags &MyHTML_TREE_FLAGS_PARSE_FLAG_EMIT_NEWLINE)
3858             {
3859 0 0         if(token->tag_id == MyHTML_TAG__TEXT) {
3860 0           myhtml_token_node_wait_for_done(tree->token, token);
3861            
3862 0 0         if(token->str.length > 0) {
3863 0 0         if(token->str.data[0] == '\n') {
3864 0           token->str.data = mchar_async_crop_first_chars_without_cache(token->str.data, 1);
3865            
3866 0           token->str.length--;
3867            
3868 0 0         if(token->str.length == 0) {
3869 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_PARSE_FLAG);
3870 0           return true;
3871             }
3872             }
3873             }
3874             else
3875 0           return true;
3876             }
3877             }
3878            
3879 0           tree->flags ^= (tree->flags & MyHTML_TREE_FLAGS_PARSE_FLAG);
3880             }
3881            
3882 2288           return false;
3883             }
3884              
3885 2288           bool myhtml_rules_tree_dispatcher(myhtml_tree_t* tree, myhtml_token_node_t* token)
3886             {
3887             // for textarea && pre && listen
3888 2288 50         if(myhtml_rules_check_for_first_newline(tree, token)) {
3889 0           tree->token_last_done = token;
3890            
3891 0           return false;
3892             }
3893            
3894 2288 50         if(tree->state_of_builder != MyHTML_TOKENIZER_STATE_DATA)
3895 0           tree->state_of_builder = MyHTML_TOKENIZER_STATE_DATA;
3896            
3897 2288           bool reprocess = false;
3898 2288           myhtml_tree_node_t* adjusted_node = myhtml_tree_adjusted_current_node(tree);
3899            
3900 2288 100         if(tree->open_elements->length == 0 || adjusted_node->ns == MyHTML_NAMESPACE_HTML) {
    50          
3901 2288           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3902             }
3903 0 0         else if(myhtml_tree_is_mathml_integration_point(tree, adjusted_node) &&
3904 0 0         ((token->tag_id == MyHTML_TAG__TEXT ||
3905 0 0         (token->tag_id != MyHTML_TAG_MGLYPH && token->tag_id != MyHTML_TAG_MALIGNMARK)) &&
    0          
3906 0 0         (token->type & MyHTML_TOKEN_TYPE_CLOSE) == 0))
3907             {
3908 0           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3909             }
3910 0 0         else if(adjusted_node->tag_id == MyHTML_TAG_ANNOTATION_XML &&
3911 0 0         adjusted_node->ns == MyHTML_NAMESPACE_MATHML &&
3912 0 0         token->tag_id == MyHTML_TAG_SVG && (token->type & MyHTML_TOKEN_TYPE_CLOSE) == 0)
    0          
3913             {
3914 0           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3915             }
3916 0 0         else if(myhtml_tree_is_html_integration_point(tree, adjusted_node) &&
3917 0 0         ((token->type & MyHTML_TOKEN_TYPE_CLOSE) == 0 || token->tag_id == MyHTML_TAG__TEXT))
    0          
3918             {
3919 0           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3920             }
3921 0 0         else if(token->tag_id == MyHTML_TAG__END_OF_FILE)
3922 0           reprocess = tree->myhtml->insertion_func[tree->insert_mode](tree, token);
3923             else
3924 0           reprocess = myhtml_insertion_mode_in_foreign_content(tree, token);
3925            
3926 2288 100         if(reprocess == false) {
3927 1685           tree->token_last_done = token;
3928             }
3929            
3930 2288           return reprocess;
3931             }
3932              
3933 115           mystatus_t myhtml_rules_init(myhtml_t* myhtml)
3934             {
3935 115           myhtml->insertion_func = (myhtml_insertion_f*)mycore_malloc(sizeof(myhtml_insertion_f) * MyHTML_INSERTION_MODE_LAST_ENTRY);
3936            
3937 115 50         if(myhtml->insertion_func == NULL)
3938 0           return MyHTML_STATUS_RULES_ERROR_MEMORY_ALLOCATION;
3939            
3940 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_INITIAL] = myhtml_insertion_mode_initial;
3941 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_BEFORE_HTML] = myhtml_insertion_mode_before_html;
3942 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_BEFORE_HEAD] = myhtml_insertion_mode_before_head;
3943 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_HEAD] = myhtml_insertion_mode_in_head;
3944 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_HEAD_NOSCRIPT] = myhtml_insertion_mode_in_head_noscript;
3945 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_HEAD] = myhtml_insertion_mode_after_head;
3946 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_BODY] = myhtml_insertion_mode_in_body;
3947 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_TEXT] = myhtml_insertion_mode_text;
3948 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_TABLE] = myhtml_insertion_mode_in_table;
3949 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_TABLE_TEXT] = myhtml_insertion_mode_in_table_text;
3950 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_CAPTION] = myhtml_insertion_mode_in_caption;
3951 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_COLUMN_GROUP] = myhtml_insertion_mode_in_column_group;
3952 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_TABLE_BODY] = myhtml_insertion_mode_in_table_body;
3953 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_ROW] = myhtml_insertion_mode_in_row;
3954 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_CELL] = myhtml_insertion_mode_in_cell;
3955 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_SELECT] = myhtml_insertion_mode_in_select;
3956 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_SELECT_IN_TABLE] = myhtml_insertion_mode_in_select_in_table;
3957 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_TEMPLATE] = myhtml_insertion_mode_in_template;
3958 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_BODY] = myhtml_insertion_mode_after_body;
3959 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_IN_FRAMESET] = myhtml_insertion_mode_in_frameset;
3960 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_FRAMESET] = myhtml_insertion_mode_after_frameset;
3961 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_AFTER_BODY] = myhtml_insertion_mode_after_after_body;
3962 115           myhtml->insertion_func[MyHTML_INSERTION_MODE_AFTER_AFTER_FRAMESET] = myhtml_insertion_mode_after_after_frameset;
3963            
3964 115           return MyHTML_STATUS_OK;
3965             }
3966              
3967