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