php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
tree.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018-2022 Alexander Borisov
3 *
4 * Author: Alexander Borisov <borisov@lexbor.com>
5 */
6
11
12#include "lexbor/html/tree.h"
24
25
28 const lxb_char_t *name, size_t length);
29
32 size_t length);
33
34const lxb_tag_data_t *
36 const lxb_char_t *name, size_t length);
37
38static lxb_html_token_t *
39lxb_html_tree_token_callback(lxb_html_tokenizer_t *tkz,
40 lxb_html_token_t *token, void *ctx);
41
42static lxb_status_t
43lxb_html_tree_insertion_mode(lxb_html_tree_t *tree, lxb_html_token_t *token);
44
45
48{
49 return lexbor_calloc(1, sizeof(lxb_html_tree_t));
50}
51
54{
55 if (tree == NULL) {
57 }
58
59 if (tkz == NULL) {
61 }
62
64
65 /* Stack of open elements */
68 if (status != LXB_STATUS_OK) {
69 return status;
70 }
71
72 /* Stack of active formatting */
75 if (status != LXB_STATUS_OK) {
76 return status;
77 }
78
79 /* Stack of template insertion modes */
83 if (status != LXB_STATUS_OK) {
84 return status;
85 }
86
87 /* Stack of pending table character tokens */
90 sizeof(lexbor_str_t));
91 if (status != LXB_STATUS_OK) {
92 return status;
93 }
94
95 /* Parse errors */
98 sizeof(lxb_html_tree_error_t));
99 if (status != LXB_STATUS_OK) {
100 return status;
101 }
102
103 tree->tkz_ref = lxb_html_tokenizer_ref(tkz);
104
105 tree->document = NULL;
106 tree->fragment = NULL;
107
108 tree->form = NULL;
109
110 tree->foster_parenting = false;
111 tree->frameset_ok = true;
112
114 tree->before_append_attr = NULL;
115
116 tree->status = LXB_STATUS_OK;
117
118 tree->ref_count = 1;
119
121 lxb_html_tree_token_callback,
122 tree);
123
124 return LXB_STATUS_OK;
125}
126
129{
130 if (tree == NULL) {
131 return NULL;
132 }
133
134 tree->ref_count++;
135
136 return tree;
137}
138
141{
142 if (tree == NULL || tree->ref_count == 0) {
143 return NULL;
144 }
145
146 tree->ref_count--;
147
148 if (tree->ref_count == 0) {
150 }
151
152 return NULL;
153}
154
155void
177
180{
181 if (tree == NULL) {
182 return NULL;
183 }
184
187 true);
189 true);
191 true);
192
195
196 return lexbor_free(tree);
197}
198
199static lxb_html_token_t *
200lxb_html_tree_token_callback(lxb_html_tokenizer_t *tkz,
201 lxb_html_token_t *token, void *ctx)
202{
204
205 status = lxb_html_tree_insertion_mode(ctx, token);
206 if (status != LXB_STATUS_OK) {
207 tkz->status = status;
208 return NULL;
209 }
210
211 return token;
212}
213
214/* TODO: not complete!!! */
222
223bool
225{
226 if (tree->status == LXB_STATUS_OK) {
228 }
229
230 tree->open_elements->length = 0;
232
233 return true;
234}
235
236void
242
243bool
245 lxb_html_token_t *token)
246{
247 lxb_dom_node_t *adjusted;
248
250
251 if (adjusted == NULL || adjusted->ns == LXB_NS_HTML) {
252 return tree->mode(tree, token);
253 }
254
256 {
257 if ((token->type & LXB_HTML_TOKEN_TYPE_CLOSE) == 0
258 && token->tag_id != LXB_TAG_MGLYPH
259 && token->tag_id != LXB_TAG_MALIGNMARK)
260 {
261 return tree->mode(tree, token);
262 }
263
264 if (token->tag_id == LXB_TAG__TEXT) {
265 return tree->mode(tree, token);
266 }
267 }
268
269 if (adjusted->local_name == LXB_TAG_ANNOTATION_XML
270 && adjusted->ns == LXB_NS_MATH
271 && (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) == 0
272 && token->tag_id == LXB_TAG_SVG)
273 {
274 return tree->mode(tree, token);
275 }
276
278 if ((token->type & LXB_HTML_TOKEN_TYPE_CLOSE) == 0
279 || token->tag_id == LXB_TAG__TEXT)
280 {
281 return tree->mode(tree, token);
282 }
283 }
284
285 if (token->tag_id == LXB_TAG__END_OF_FILE) {
286 return tree->mode(tree, token);
287 }
288
290}
291
292static lxb_status_t
293lxb_html_tree_insertion_mode(lxb_html_tree_t *tree, lxb_html_token_t *token)
294{
295 while (lxb_html_tree_construction_dispatcher(tree, token) == false) {}
296
297 return tree->status;
298}
299
300/*
301 * Action
302 */
305 lxb_dom_node_t *override_target,
307{
308 lxb_dom_node_t *target, *adjusted_location = NULL;
309
311
312 if (override_target != NULL) {
313 target = override_target;
314 }
315 else {
316 target = lxb_html_tree_current_node(tree);
317 }
318
319 if (tree->foster_parenting && target->ns == LXB_NS_HTML
320 && (target->local_name == LXB_TAG_TABLE
321 || target->local_name == LXB_TAG_TBODY
322 || target->local_name == LXB_TAG_TFOOT
323 || target->local_name == LXB_TAG_THEAD
324 || target->local_name == LXB_TAG_TR))
325 {
326 lxb_dom_node_t *last_temp, *last_table;
327 size_t last_temp_idx, last_table_idx;
328
332 &last_temp_idx);
333
337 &last_table_idx);
338
339 if(last_temp != NULL && (last_table == NULL
340 || last_temp_idx > last_table_idx))
341 {
342 lxb_dom_document_fragment_t *doc_fragment;
343
344 doc_fragment = lxb_html_interface_template(last_temp)->content;
345
346 return lxb_dom_interface_node(doc_fragment);
347 }
348 else if (last_table == NULL) {
349 adjusted_location = lxb_html_tree_open_elements_first(tree);
350
351 lexbor_assert(adjusted_location != NULL);
352 lexbor_assert(adjusted_location->local_name == LXB_TAG_HTML);
353 }
354 else if (last_table->parent != NULL) {
355 adjusted_location = last_table;
356
358 }
359 else {
360 lexbor_assert(last_table_idx != 0);
361
362 adjusted_location = lxb_html_tree_open_elements_get(tree,
363 last_table_idx - 1);
364 }
365 }
366 else {
367 adjusted_location = target;
368 }
369
370 if (adjusted_location == NULL) {
371 return NULL;
372 }
373
374 /*
375 * In Spec it is not entirely clear what is meant:
376 *
377 * If the adjusted insertion location is inside a template element,
378 * let it instead be inside the template element's template contents,
379 * after its last child (if any).
380 */
381 if (lxb_html_tree_node_is(adjusted_location, LXB_TAG_TEMPLATE)) {
383
384 df = lxb_html_interface_template(adjusted_location)->content;
385 adjusted_location = lxb_dom_interface_node(df);
386 }
387
388 return adjusted_location;
389}
390
393 lxb_html_token_t *token, lxb_ns_id_t ns)
394{
397 lxb_html_element_t *element;
399
401 if (pos == NULL) {
402 return NULL;
403 }
404
405 element = lxb_html_tree_create_element_for_token(tree, token, ns);
406 if (element == NULL) {
407 return NULL;
408 }
409
411
413 lxb_dom_interface_node(element));
414 if (status != LXB_HTML_STATUS_OK) {
415 return lxb_html_interface_destroy(element);
416 }
417
418 return element;
419}
420
423 lxb_html_token_t *token, lxb_ns_id_t ns)
424{
425 lxb_dom_node_t *node = lxb_html_tree_create_node(tree, token->tag_id, ns);
426 if (node == NULL) {
427 return NULL;
428 }
429
430 node->line = token->line;
431 /* We only expose line number in PHP DOM */
432
435
436 if (token->base_element == NULL) {
437 status = lxb_html_tree_append_attributes(tree, element, token, ns);
438 }
439 else {
441 token->base_element, ns);
442 }
443
444 if (status != LXB_HTML_STATUS_OK) {
445 return lxb_html_interface_destroy(element);
446 }
447
448 return lxb_html_interface_element(node);
449}
450
453 lxb_dom_element_t *element,
454 lxb_html_token_t *token, lxb_ns_id_t ns)
455{
459 lxb_html_token_attr_t *token_attr = token->attr_first;
460
462
463 while (token_attr != NULL) {
465 token_attr->name);
466 if (attr != NULL) {
467 token_attr = token_attr->next;
468 continue;
469 }
470
472 if (attr == NULL) {
474 }
475
476 if (token_attr->value_begin != NULL) {
478 token_attr->value_size);
479 if (status != LXB_HTML_STATUS_OK) {
480 return status;
481 }
482 }
483
484 attr->node.local_name = token_attr->name->attr_id;
485 attr->node.ns = ns;
486
487 /* Fix for adjust MathML/SVG attributes */
488 if (tree->before_append_attr != NULL) {
489 status = tree->before_append_attr(tree, attr, NULL);
490 if (status != LXB_STATUS_OK) {
491 return status;
492 }
493 }
494
496
497 token_attr = token_attr->next;
498 }
499
500 return LXB_HTML_STATUS_OK;
501}
502
505 lxb_dom_element_t *element,
506 lxb_dom_element_t *from,
507 lxb_ns_id_t ns)
508{
511 lxb_dom_attr_t *new_attr;
512
513 while (attr != NULL) {
515 if (new_attr == NULL) {
517 }
518
520 if (status != LXB_HTML_STATUS_OK) {
521 return status;
522 }
523
524 new_attr->node.ns = attr->node.ns;
525
526 /* Fix for adjust MathML/SVG attributes */
527 if (tree->before_append_attr != NULL) {
528 status = tree->before_append_attr(tree, new_attr, NULL);
529 if (status != LXB_STATUS_OK) {
530 return status;
531 }
532 }
533
535
536 attr = attr->next;
537 }
538
539 return LXB_HTML_STATUS_OK;
540}
541
544 lxb_dom_attr_t *attr, void *ctx)
545{
546 lexbor_hash_t *attrs;
548
549 attrs = attr->node.owner_document->attrs;
550 data = lxb_dom_attr_data_by_id(attrs, attr->node.local_name);
551
552 if (data->entry.length == 13
554 (const lxb_char_t *) "definitionurl"))
555 {
557 (const lxb_char_t *) "definitionURL", 13);
558 if (data == NULL) {
559 return LXB_STATUS_ERROR;
560 }
561
562 attr->qualified_name = data->attr_id;
563 }
564
565 return LXB_STATUS_OK;
566}
567
570 lxb_dom_attr_t *attr, void *ctx)
571{
572 lexbor_hash_t *attrs;
575
576 size_t len = sizeof(lxb_html_tree_res_attr_adjust_svg_map)
578
579 attrs = attr->node.owner_document->attrs;
580
581 data = lxb_dom_attr_data_by_id(attrs, attr->node.local_name);
582
583 for (size_t i = 0; i < len; i++) {
584 adjust = &lxb_html_tree_res_attr_adjust_svg_map[i];
585
586 if (data->entry.length == adjust->len
588 (const lxb_char_t *) adjust->from))
589 {
591 (const lxb_char_t *) adjust->to, adjust->len);
592 if (data == NULL) {
593 return LXB_STATUS_ERROR;
594 }
595
596 attr->qualified_name = data->attr_id;
597
598 return LXB_STATUS_OK;
599 }
600 }
601
602 return LXB_STATUS_OK;
603}
604
607 lxb_dom_attr_t *attr, void *ctx)
608{
609 size_t lname_length;
610 lexbor_hash_t *attrs, *prefix;
611 const lxb_dom_attr_data_t *attr_data;
612 const lxb_ns_prefix_data_t *prefix_data;
615
616 size_t len = sizeof(lxb_html_tree_res_attr_adjust_foreign_map)
618
619 attrs = attr->node.owner_document->attrs;
620 prefix = attr->node.owner_document->prefix;
621
622 data = lxb_dom_attr_data_by_id(attrs, attr->node.local_name);
623
624 for (size_t i = 0; i < len; i++) {
625 adjust = &lxb_html_tree_res_attr_adjust_foreign_map[i];
626
627 if (data->entry.length == adjust->name_len
629 (const lxb_char_t *) adjust->name))
630 {
631 if (adjust->prefix_len != 0) {
633 (const lxb_char_t *) adjust->name, adjust->name_len);
634 if (data == NULL) {
635 return LXB_STATUS_ERROR;
636 }
637
638 attr->qualified_name = data->attr_id;
639
640 lname_length = adjust->name_len - adjust->prefix_len - 1;
641
642 attr_data = lxb_dom_attr_local_name_append(attrs,
643 (const lxb_char_t *) adjust->local_name, lname_length);
644 if (attr_data == NULL) {
645 return LXB_STATUS_ERROR;
646 }
647
648 attr->node.local_name = attr_data->attr_id;
649
650 prefix_data = lxb_ns_prefix_append(prefix,
651 (const lxb_char_t *) adjust->prefix, adjust->prefix_len);
652 if (prefix_data == NULL) {
653 return LXB_STATUS_ERROR;
654 }
655
656 attr->node.prefix = prefix_data->prefix_id;
657 }
658
659 attr->node.ns = adjust->ns;
660
661 return LXB_STATUS_OK;
662 }
663 }
664
665 return LXB_STATUS_OK;
666}
667
670 lxb_dom_node_t **ret_node)
671{
672 size_t size;
674 lexbor_str_t str = {0};
675
676 size = token->text_end - token->text_start;
677
678 lexbor_str_init(&str, tree->document->dom_document.text, size + 1);
679 if (str.data == NULL) {
681 }
682
683 memcpy(str.data, token->text_start, size);
684
685 str.data[size] = 0x00;
686 str.length = size;
687
688 status = lxb_html_tree_insert_character_for_data(tree, &str, ret_node);
689 if (status != LXB_STATUS_OK) {
690 return status;
691 }
692
693 return LXB_STATUS_OK;
694}
695
698 lexbor_str_t *str,
699 lxb_dom_node_t **ret_node)
700{
701 const lxb_char_t *data;
705
706 if (ret_node != NULL) {
707 *ret_node = NULL;
708 }
709
711 if (pos == NULL) {
712 return LXB_STATUS_ERROR;
713 }
714
716 goto destroy_str;
717 }
718
720 /* No need check namespace */
721 if (pos->prev != NULL && pos->prev->local_name == LXB_TAG__TEXT) {
723
724 if (ret_node != NULL) {
725 *ret_node = pos->prev;
726 }
727 }
728 }
729 else {
730 /* No need check namespace */
731 if (pos->last_child != NULL
732 && pos->last_child->local_name == LXB_TAG__TEXT)
733 {
734 chrs = lxb_dom_interface_character_data(pos->last_child);
735
736 if (ret_node != NULL) {
737 *ret_node = pos->last_child;
738 }
739 }
740 }
741
742 if (chrs != NULL) {
743 /* This is error. This can not happen, but... */
744 if (chrs->data.data == NULL) {
746 str->length);
747 if (data == NULL) {
749 }
750 }
751
753 str->data, str->length);
754 if (data == NULL) {
756 }
757
758 goto destroy_str;
759 }
760
763 if (text == NULL) {
765 }
766
767 lxb_dom_interface_text(text)->char_data.data = *str;
768
769 if (tree->tkz_ref) {
770 text->line = tree->tkz_ref->token->line;
771 /* We only expose line number in PHP DOM */
772 }
773
774 if (ret_node != NULL) {
775 *ret_node = text;
776 }
777
779
780 return LXB_STATUS_OK;
781
782destroy_str:
783
784 lexbor_str_destroy(str, tree->document->dom_document.text, false);
785
786 return LXB_STATUS_OK;
787}
788
792{
793 lxb_dom_node_t *node;
794 lxb_dom_comment_t *comment;
796
797 if (pos == NULL) {
799 }
800 else {
802 }
803
805
806 node = lxb_html_tree_create_node(tree, token->tag_id, pos->ns);
807 comment = lxb_dom_interface_comment(node);
808
809 if (comment == NULL) {
810 return NULL;
811 }
812
813 node->line = token->line;
814 /* We only expose line number in PHP DOM */
815
816 tree->status = lxb_html_token_make_text(token, &comment->char_data.data,
817 tree->document->dom_document.text);
818 if (tree->status != LXB_STATUS_OK) {
819 return NULL;
820 }
821
822 lxb_html_tree_insert_node(pos, node, ipos);
823
824 return comment;
825}
826
829 lxb_html_token_t *token)
830{
832 lxb_dom_node_t *doctype_node;
833 lxb_dom_document_type_t *doc_type;
834
835 /* Create */
836 doctype_node = lxb_html_tree_create_node(tree, token->tag_id, LXB_NS_HTML);
837 if (doctype_node == NULL) {
838 return NULL;
839 }
840
841 doc_type = lxb_dom_interface_document_type(doctype_node);
842
843 /* Parse */
844 status = lxb_html_token_doctype_parse(token, doc_type);
845 if (status != LXB_STATUS_OK) {
847 }
848
849 return doc_type;
850}
851
852/*
853 * TODO: need use ref and unref for nodes (ref counter)
854 * Not implemented until the end. It is necessary to finish it.
855 */
856void
861
864 lxb_html_token_t *token)
865{
866 lxb_html_element_t *element;
867
868 element = lxb_html_tree_insert_html_element(tree, token);
869 if (element == NULL) {
870 return NULL;
871 }
872
873 /*
874 * Need for tokenizer state RAWTEXT
875 * See description for 'lxb_html_tokenizer_state_rawtext_before' function
876 */
880
881 tree->original_mode = tree->mode;
883
884 return element;
885}
886
887/* Magic of CopyPast power! */
890 lxb_html_token_t *token)
891{
892 lxb_html_element_t *element;
893
894 element = lxb_html_tree_insert_html_element(tree, token);
895 if (element == NULL) {
896 return NULL;
897 }
898
899 /*
900 * Need for tokenizer state RCDATA
901 * See description for 'lxb_html_tokenizer_state_rcdata_before' function
902 */
906
907 tree->original_mode = tree->mode;
909
910 return element;
911}
912
913void
915 lxb_tag_id_t ex_tag, lxb_ns_id_t ex_ns)
916{
917 lxb_dom_node_t *node;
918
919 lexbor_assert(tree->open_elements != 0);
920
921 while (lexbor_array_length(tree->open_elements) != 0) {
922 node = lxb_html_tree_current_node(tree);
923
924 lexbor_assert(node != NULL);
925
926 switch (node->local_name) {
927 case LXB_TAG_DD:
928 case LXB_TAG_DT:
929 case LXB_TAG_LI:
930 case LXB_TAG_OPTGROUP:
931 case LXB_TAG_OPTION:
932 case LXB_TAG_P:
933 case LXB_TAG_RB:
934 case LXB_TAG_RP:
935 case LXB_TAG_RT:
936 case LXB_TAG_RTC:
937 if(node->local_name == ex_tag && node->ns == ex_ns) {
938 return;
939 }
940
942
943 break;
944
945 default:
946 return;
947 }
948 }
949}
950
951void
953 lxb_tag_id_t ex_tag,
954 lxb_ns_id_t ex_ns)
955{
956 lxb_dom_node_t *node;
957
958 lexbor_assert(tree->open_elements != 0);
959
960 while (lexbor_array_length(tree->open_elements) != 0) {
961 node = lxb_html_tree_current_node(tree);
962
963 lexbor_assert(node != NULL);
964
965 switch (node->local_name) {
966 case LXB_TAG_CAPTION:
967 case LXB_TAG_COLGROUP:
968 case LXB_TAG_DD:
969 case LXB_TAG_DT:
970 case LXB_TAG_LI:
971 case LXB_TAG_OPTGROUP:
972 case LXB_TAG_OPTION:
973 case LXB_TAG_P:
974 case LXB_TAG_RB:
975 case LXB_TAG_RP:
976 case LXB_TAG_RT:
977 case LXB_TAG_RTC:
978 case LXB_TAG_TBODY:
979 case LXB_TAG_TD:
980 case LXB_TAG_TFOOT:
981 case LXB_TAG_TH:
982 case LXB_TAG_THEAD:
983 case LXB_TAG_TR:
984 if(node->local_name == ex_tag && node->ns == ex_ns) {
985 return;
986 }
987
989
990 break;
991
992 default:
993 return;
994 }
995 }
996}
997
998void
1000{
1001 lxb_dom_node_t *node;
1002 size_t idx = tree->open_elements->length;
1003
1004 /* Step 1 */
1005 bool last = false;
1006 void **list = tree->open_elements->list;
1007
1008 /* Step 3 */
1009 while (idx != 0) {
1010 idx--;
1011
1012 /* Step 2 */
1013 node = list[idx];
1014
1015 /* Step 3 */
1016 if (idx == 0) {
1017 last = true;
1018
1019 if (tree->fragment != NULL) {
1020 node = tree->fragment;
1021 }
1022 }
1023
1024 lexbor_assert(node != NULL);
1025
1026 /* Step 16 */
1027 if (node->ns != LXB_NS_HTML) {
1028 if (last) {
1030 return;
1031 }
1032
1033 continue;
1034 }
1035
1036 /* Step 4 */
1037 if (node->local_name == LXB_TAG_SELECT) {
1038 /* Step 4.1 */
1039 if (last) {
1041 return;
1042 }
1043
1044 /* Step 4.2 */
1045 size_t ancestor = idx;
1046
1047 for (;;) {
1048 /* Step 4.3 */
1049 if (ancestor == 0) {
1051 return;
1052 }
1053
1054 /* Step 4.4 */
1055 ancestor--;
1056
1057 /* Step 4.5 */
1058 lxb_dom_node_t *ancestor_node = list[ancestor];
1059
1060 if(lxb_html_tree_node_is(ancestor_node, LXB_TAG_TEMPLATE)) {
1062 return;
1063 }
1064
1065 /* Step 4.6 */
1066 else if(lxb_html_tree_node_is(ancestor_node, LXB_TAG_TABLE)) {
1068 return;
1069 }
1070 }
1071 }
1072
1073 /* Step 5-15 */
1074 switch (node->local_name) {
1075 case LXB_TAG_TD:
1076 case LXB_TAG_TH:
1077 if (last == false) {
1079 return;
1080 }
1081
1082 break;
1083
1084 case LXB_TAG_TR:
1086 return;
1087
1088 case LXB_TAG_TBODY:
1089 case LXB_TAG_TFOOT:
1090 case LXB_TAG_THEAD:
1092 return;
1093
1094 case LXB_TAG_CAPTION:
1096 return;
1097
1098 case LXB_TAG_COLGROUP:
1100 return;
1101
1102 case LXB_TAG_TABLE:
1104 return;
1105
1106 case LXB_TAG_TEMPLATE:
1108
1109 lexbor_assert(tree->mode != NULL);
1110
1111 return;
1112
1113 case LXB_TAG_HEAD:
1114 if (last == false) {
1116 return;
1117 }
1118
1119 break;
1120
1121 case LXB_TAG_BODY:
1123 return;
1124
1125 case LXB_TAG_FRAMESET:
1127 return;
1128
1129 case LXB_TAG_HTML: {
1130 if (tree->document->head == NULL) {
1132 return;
1133 }
1134
1136 return;
1137 }
1138
1139 default:
1140 break;
1141 }
1142
1143 /* Step 16 */
1144 if (last) {
1146 return;
1147 }
1148 }
1149}
1150
1154{
1155 lxb_dom_node_t *node;
1156
1157 size_t idx = tree->open_elements->length;
1158 void **list = tree->open_elements->list;
1159
1160 while (idx != 0) {
1161 idx--;
1162 node = list[idx];
1163
1164 if (node->local_name == tag_id && node->ns == ns) {
1165 return node;
1166 }
1167
1168 if (lxb_html_tag_is_category(node->local_name, node->ns, ct)) {
1169 return NULL;
1170 }
1171 }
1172
1173 return NULL;
1174}
1175
1178 lxb_dom_node_t *by_node,
1180{
1181 lxb_dom_node_t *node;
1182
1183 size_t idx = tree->open_elements->length;
1184 void **list = tree->open_elements->list;
1185
1186 while (idx != 0) {
1187 idx--;
1188 node = list[idx];
1189
1190 if (node == by_node) {
1191 return node;
1192 }
1193
1194 if (lxb_html_tag_is_category(node->local_name, node->ns, ct)) {
1195 return NULL;
1196 }
1197 }
1198
1199 return NULL;
1200}
1201
1204{
1205 lxb_dom_node_t *node;
1206
1207 size_t idx = tree->open_elements->length;
1208 void **list = tree->open_elements->list;
1209
1210 while (idx != 0) {
1211 idx--;
1212 node = list[idx];
1213
1214 switch (node->local_name) {
1215 case LXB_TAG_H1:
1216 case LXB_TAG_H2:
1217 case LXB_TAG_H3:
1218 case LXB_TAG_H4:
1219 case LXB_TAG_H5:
1220 case LXB_TAG_H6:
1221 if (node->ns == LXB_NS_HTML) {
1222 return node;
1223 }
1224
1225 break;
1226
1227 default:
1228 break;
1229 }
1230
1233 {
1234 return NULL;
1235 }
1236 }
1237
1238 return NULL;
1239}
1240
1243{
1244 lxb_dom_node_t *node;
1245
1246 size_t idx = tree->open_elements->length;
1247 void **list = tree->open_elements->list;
1248
1249 while (idx != 0) {
1250 idx--;
1251 node = list[idx];
1252
1253 switch (node->local_name) {
1254 case LXB_TAG_TBODY:
1255 case LXB_TAG_THEAD:
1256 case LXB_TAG_TFOOT:
1257 if (node->ns == LXB_NS_HTML) {
1258 return node;
1259 }
1260
1261 break;
1262
1263 default:
1264 break;
1265 }
1266
1269 {
1270 return NULL;
1271 }
1272 }
1273
1274 return NULL;
1275}
1276
1279{
1280 lxb_dom_node_t *node;
1281
1282 size_t idx = tree->open_elements->length;
1283 void **list = tree->open_elements->list;
1284
1285 while (idx != 0) {
1286 idx--;
1287 node = list[idx];
1288
1289 switch (node->local_name) {
1290 case LXB_TAG_TD:
1291 case LXB_TAG_TH:
1292 if (node->ns == LXB_NS_HTML) {
1293 return node;
1294 }
1295
1296 break;
1297
1298 default:
1299 break;
1300 }
1301
1304 {
1305 return NULL;
1306 }
1307 }
1308
1309 return NULL;
1310}
1311
1312bool
1314{
1315 lxb_dom_node_t *node;
1316
1317 for (size_t i = 0; i < tree->open_elements->length; i++) {
1318 node = tree->open_elements->list[i];
1319
1320 switch (node->local_name) {
1321 case LXB_TAG_DD:
1322 case LXB_TAG_DT:
1323 case LXB_TAG_LI:
1324 case LXB_TAG_OPTGROUP:
1325 case LXB_TAG_OPTION:
1326 case LXB_TAG_P:
1327 case LXB_TAG_RB:
1328 case LXB_TAG_RP:
1329 case LXB_TAG_RT:
1330 case LXB_TAG_RTC:
1331 case LXB_TAG_TBODY:
1332 case LXB_TAG_TD:
1333 case LXB_TAG_TFOOT:
1334 case LXB_TAG_TH:
1335 case LXB_TAG_THEAD:
1336 case LXB_TAG_TR:
1337 case LXB_TAG_BODY:
1338 case LXB_TAG_HTML:
1339 return true;
1340
1341 default:
1342 break;
1343 }
1344 }
1345
1346 return false;
1347}
1348
1349void
1364
1365#include "lexbor/html/serialize.h"
1366
1367bool
1369 lxb_html_token_t *token,
1371{
1372 lexbor_assert(tree->open_elements->length != 0);
1373
1374 /* State 1 */
1375 bool is;
1376 short outer_loop;
1377 lxb_html_element_t *element;
1378 lxb_dom_node_t *node, *marker, **oel_list, **afe_list;
1379
1380 lxb_tag_id_t subject = token->tag_id;
1381
1382 oel_list = (lxb_dom_node_t **) tree->open_elements->list;
1383 afe_list = (lxb_dom_node_t **) tree->active_formatting->list;
1385
1387
1388 /* State 2 */
1389 node = lxb_html_tree_current_node(tree);
1390 lexbor_assert(node != NULL);
1391
1392 if (lxb_html_tree_node_is(node, subject)) {
1394 NULL);
1395 if (is == false) {
1397
1398 return false;
1399 }
1400 }
1401
1402 /* State 3 */
1403 outer_loop = 0;
1404
1405 /* State 4 */
1406 while (outer_loop < 8) {
1407 /* State 5 */
1408 outer_loop++;
1409
1410 /* State 6 */
1411 size_t formatting_index = 0;
1412 size_t idx = tree->active_formatting->length;
1413 lxb_dom_node_t *formatting_element = NULL;
1414
1415 while (idx) {
1416 idx--;
1417
1418 if (afe_list[idx] == marker) {
1419 return true;
1420 }
1421 else if (afe_list[idx]->local_name == subject) {
1422 formatting_index = idx;
1423 formatting_element = afe_list[idx];
1424
1425 break;
1426 }
1427 }
1428
1429 if (formatting_element == NULL) {
1430 return true;
1431 }
1432
1433 /* State 7 */
1434 size_t oel_formatting_idx;
1436 formatting_element,
1437 &oel_formatting_idx);
1438 if (is == false) {
1439 lxb_html_tree_parse_error(tree, token,
1441
1443 formatting_element);
1444
1445 return false;
1446 }
1447
1448 /* State 8 */
1449 node = lxb_html_tree_element_in_scope_by_node(tree, formatting_element,
1451 if (node == NULL) {
1452 lxb_html_tree_parse_error(tree, token,
1454 return false;
1455 }
1456
1457 /* State 9 */
1458 node = lxb_html_tree_current_node(tree);
1459
1460 if (formatting_element != node) {
1461 lxb_html_tree_parse_error(tree, token,
1463 }
1464
1465 /* State 10 */
1466 lxb_dom_node_t *furthest_block = NULL;
1467 size_t furthest_block_idx = 0;
1468 size_t oel_idx = tree->open_elements->length;
1469
1470 for (furthest_block_idx = oel_formatting_idx;
1471 furthest_block_idx < oel_idx;
1472 furthest_block_idx++)
1473 {
1474 is = lxb_html_tag_is_category(oel_list[furthest_block_idx]->local_name,
1475 oel_list[furthest_block_idx]->ns,
1477 if (is) {
1478 furthest_block = oel_list[furthest_block_idx];
1479
1480 break;
1481 }
1482 }
1483
1484 /* State 11 */
1485 if (furthest_block == NULL) {
1486 lxb_html_tree_open_elements_pop_until_node(tree, formatting_element,
1487 true);
1488
1490 formatting_element);
1491
1492 return false;
1493 }
1494
1495 lexbor_assert(oel_formatting_idx != 0);
1496
1497 /* State 12 */
1498 lxb_dom_node_t *common_ancestor = oel_list[oel_formatting_idx - 1];
1499
1500 /* State 13 */
1501 size_t bookmark = formatting_index;
1502
1503 /* State 14 */
1504 lxb_dom_node_t *node;
1505 lxb_dom_node_t *last = furthest_block;
1506 size_t node_idx = furthest_block_idx;
1507
1508 /* State 14.1 */
1509 size_t inner_loop_counter = 0;
1510
1511 /* State 14.2 */
1512 while (1) {
1513 inner_loop_counter++;
1514
1515 /* State 14.3 */
1516 lexbor_assert(node_idx != 0);
1517
1518 if (node_idx == 0) {
1519 return false;
1520 }
1521
1522 node_idx--;
1523 node = oel_list[node_idx];
1524
1525 /* State 14.4 */
1526 if (node == formatting_element) {
1527 break;
1528 }
1529
1530 /* State 14.5 */
1531 size_t afe_node_idx;
1533 node,
1534 &afe_node_idx);
1535 /* State 14.5 */
1536 if (inner_loop_counter > 3 && is) {
1538
1539 continue;
1540 }
1541
1542 /* State 14.6 */
1543 if (is == false) {
1545
1546 continue;
1547 }
1548
1549 /* State 14.7 */
1550 lxb_html_token_t fake_token = {0};
1551
1552 fake_token.tag_id = node->local_name;
1553 fake_token.base_element = node;
1554
1555 element = lxb_html_tree_create_element_for_token(tree, &fake_token,
1556 LXB_NS_HTML);
1557 if (element == NULL) {
1559
1560 return false;
1561 }
1562
1563 node = lxb_dom_interface_node(element);
1564
1565 afe_list[afe_node_idx] = node;
1566 oel_list[node_idx] = node;
1567
1568 /* State 14.8 */
1569 if (last == furthest_block) {
1570 bookmark = afe_node_idx + 1;
1571
1572 lexbor_assert(bookmark < tree->active_formatting->length);
1573 }
1574
1575 /* State 14.9 */
1576 if (last->parent != NULL) {
1578 }
1579
1581
1582 /* State 14.10 */
1583 last = node;
1584 }
1585
1586 if (last->parent != NULL) {
1588 }
1589
1590 /* State 15 */
1593
1595 common_ancestor,
1596 &ipos);
1597 if (pos == NULL) {
1598 return false;
1599 }
1600
1602
1603 /* State 16 */
1604 lxb_html_token_t fake_token = {0};
1605
1606 fake_token.tag_id = formatting_element->local_name;
1607 fake_token.base_element = formatting_element;
1608
1609 element = lxb_html_tree_create_element_for_token(tree, &fake_token,
1610 LXB_NS_HTML);
1611 if (element == NULL) {
1613
1614 return false;
1615 }
1616
1617 /* State 17 */
1619 node = furthest_block->first_child;
1620
1621 while (node != NULL) {
1622 next = node->next;
1623
1626 node);
1627 node = next;
1628 }
1629
1630 node = lxb_dom_interface_node(element);
1631
1632 /* State 18 */
1633 lxb_dom_node_insert_child_wo_events(furthest_block, node);
1634
1635 /* State 19 */
1636 lxb_html_tree_active_formatting_remove(tree, formatting_index);
1637
1638 if (bookmark > tree->active_formatting->length) {
1639 bookmark = tree->active_formatting->length;
1640 }
1641
1642 *status = lxb_html_tree_active_formatting_insert(tree, node, bookmark);
1643 if (*status != LXB_STATUS_OK) {
1644 return false;
1645 }
1646
1647 /* State 20 */
1648 lxb_html_tree_open_elements_remove_by_node(tree, formatting_element);
1649
1650 lxb_html_tree_open_elements_find_by_node(tree, furthest_block,
1651 &furthest_block_idx);
1652
1654 furthest_block_idx);
1655 if (*status != LXB_STATUS_OK) {
1656 return false;
1657 }
1658 }
1659
1660 return false;
1661}
1662
1663bool
1665{
1666 if (node->ns == LXB_NS_MATH
1668 {
1671 (const lxb_char_t *) "encoding",
1672 8);
1673 if (attr == NULL || attr->value == NULL) {
1674 return false;
1675 }
1676
1677 if (attr->value->length == 9
1678 && lexbor_str_data_casecmp(attr->value->data,
1679 (const lxb_char_t *) "text/html"))
1680 {
1681 return true;
1682 }
1683
1684 if (attr->value->length == 21
1685 && lexbor_str_data_casecmp(attr->value->data,
1686 (const lxb_char_t *) "application/xhtml+xml"))
1687 {
1688 return true;
1689 }
1690
1691 return false;
1692 }
1693
1694 if (node->ns == LXB_NS_SVG
1696 || node->local_name == LXB_TAG_DESC
1697 || node->local_name == LXB_TAG_TITLE))
1698 {
1699 return true;
1700 }
1701
1702 return false;
1703}
1704
1707 lxb_dom_attr_t *attr, void *ctx)
1708{
1710
1712 if (status !=LXB_STATUS_OK) {
1713 return status;
1714 }
1715
1717}
1718
1721 lxb_dom_attr_t *attr, void *ctx)
1722{
1724
1726 if (status !=LXB_STATUS_OK) {
1727 return status;
1728 }
1729
1731}
bool lxb_html_tree_active_formatting_find_by_node_reverse(lxb_html_tree_t *tree, lxb_dom_node_t *node, size_t *return_pos)
void lxb_html_tree_active_formatting_remove_by_node(lxb_html_tree_t *tree, lxb_dom_node_t *node)
lxb_html_element_t * lxb_html_tree_active_formatting_marker(void)
lxb_inline lxb_status_t lxb_html_tree_active_formatting_insert(lxb_html_tree_t *tree, lxb_dom_node_t *node, size_t idx)
lxb_inline void lxb_html_tree_active_formatting_remove(lxb_html_tree_t *tree, size_t idx)
size_t len
Definition apprentice.c:174
lxb_inline size_t lexbor_array_length(lexbor_array_t *array)
Definition array.h:72
void lexbor_array_obj_clean(lexbor_array_obj_t *array)
Definition array_obj.c:42
lexbor_array_obj_t * lexbor_array_obj_create(void)
Definition array_obj.c:11
lxb_status_t lexbor_array_obj_init(lexbor_array_obj_t *array, size_t size, size_t struct_size)
Definition array_obj.c:17
lexbor_array_obj_t * lexbor_array_obj_destroy(lexbor_array_obj_t *array, bool self_destroy)
Definition array_obj.c:50
@ LXB_STATUS_ERROR_MEMORY_ALLOCATION
Definition base.h:51
@ LXB_STATUS_ERROR_OBJECT_IS_NULL
Definition base.h:52
@ LXB_STATUS_ABORTED
Definition base.h:65
@ LXB_STATUS_ERROR_WRONG_ARGS
Definition base.h:58
@ LXB_STATUS_OK
Definition base.h:49
@ LXB_STATUS_ERROR
Definition base.h:50
#define lexbor_assert(val)
Definition base.h:37
DNS_STATUS status
Definition dns_win32.c:49
lxb_dom_document_type_t * lxb_dom_document_type_interface_destroy(lxb_dom_document_type_t *document_type)
struct lxb_dom_document_fragment lxb_dom_document_fragment_t
Definition interface.h:43
struct lxb_dom_document_type lxb_dom_document_type_t
Definition interface.h:42
#define lxb_dom_interface_element(obj)
Definition interface.h:28
#define lxb_dom_interface_node(obj)
Definition interface.h:31
struct lxb_dom_comment lxb_dom_comment_t
Definition interface.h:49
#define lxb_dom_interface_document(obj)
Definition interface.h:25
struct lxb_dom_node lxb_dom_node_t
Definition interface.h:38
struct lxb_dom_character_data lxb_dom_character_data_t
Definition interface.h:45
#define lxb_dom_interface_comment(obj)
Definition interface.h:24
#define lxb_dom_interface_document_type(obj)
Definition interface.h:27
struct lxb_dom_attr lxb_dom_attr_t
Definition interface.h:40
#define lxb_dom_interface_character_data(obj)
Definition interface.h:23
struct lxb_dom_element lxb_dom_element_t
Definition interface.h:39
#define lxb_dom_interface_text(obj)
Definition interface.h:34
lexbor_array_t * lexbor_array_create(void)
Definition array.c:11
lexbor_array_t * lexbor_array_destroy(lexbor_array_t *array, bool self_destroy)
Definition array.c:47
void lexbor_array_clean(lexbor_array_t *array)
Definition array.c:39
lxb_status_t lexbor_array_init(lexbor_array_t *array, size_t size)
Definition array.c:17
lxb_dom_interface_t * lxb_html_interface_destroy(lxb_dom_interface_t *intrfc)
Definition interface.c:120
lxb_html_tokenizer_t * lxb_html_tokenizer_ref(lxb_html_tokenizer_t *tkz)
Definition tokenizer.c:163
lxb_html_tokenizer_t * lxb_html_tokenizer_unref(lxb_html_tokenizer_t *tkz)
Definition tokenizer.c:179
new_type size
Definition ffi.c:4365
memcpy(ptr1, ptr2, size)
new_type attr
Definition ffi.c:4364
#define NULL
Definition gdcache.h:45
#define prefix
lxb_inline lxb_char_t * lexbor_hash_entry_str(const lexbor_hash_entry_t *entry)
Definition hash.h:161
struct lexbor_hash lexbor_hash_t
Definition hash.h:41
hash(string $algo, string $data, bool $binary=false, array $options=[])
Definition hash.stub.php:12
struct lxb_html_tokenizer lxb_html_tokenizer_t
Definition base.h:26
struct lxb_html_tree lxb_html_tree_t
Definition base.h:28
@ LXB_HTML_STATUS_OK
Definition base.h:34
#define lxb_html_interface_element(obj)
Definition interface.h:36
#define lxb_html_interface_document(obj)
Definition interface.h:20
struct lxb_html_element lxb_html_element_t
Definition interface.h:111
#define lxb_html_interface_template(obj)
Definition interface.h:84
struct lxb_html_document lxb_html_document_t
Definition interface.h:95
@ LXB_HTML_DOCUMENT_READY_STATE_COMPLETE
Definition document.h:34
@ LXB_HTML_TAG_CATEGORY_SCOPE_TABLE
Definition tag.h:31
@ LXB_HTML_TAG_CATEGORY_SPECIAL
Definition tag.h:26
@ LXB_HTML_TAG_CATEGORY_SCOPE
Definition tag.h:28
lxb_inline bool lxb_html_tag_is_category(lxb_tag_id_t tag_id, lxb_ns_id_t ns, lxb_html_tag_category_t cat)
Definition tag.h:51
int lxb_html_tag_category_t
Definition tag.h:21
lxb_status_t lxb_html_token_make_text(lxb_html_token_t *token, lexbor_str_t *str, lexbor_mraw_t *mraw)
Definition token.c:91
lxb_status_t lxb_html_token_doctype_parse(lxb_html_token_t *token, lxb_dom_document_type_t *doc_type)
Definition token.c:259
@ LXB_HTML_TOKEN_TYPE_CLOSE
Definition token.h:27
lxb_inline void lxb_html_tokenizer_state_set(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_f state)
Definition tokenizer.h:222
lxb_inline void lxb_html_tokenizer_tmp_tag_id_set(lxb_html_tokenizer_t *tkz, lxb_tag_id_t tag_id)
Definition tokenizer.h:229
lxb_inline void lxb_html_tokenizer_callback_token_done_set(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_token_f call_func, void *ctx)
Definition tokenizer.h:207
lxb_html_tree_error_t * lxb_html_tree_error_add(lexbor_array_obj_t *parse_errors, lxb_html_token_t *token, lxb_html_tree_error_id_t id)
Definition error.c:11
lxb_html_tree_error_id_t
Definition error.h:20
@ LXB_HTML_RULES_ERROR_UNELINOPELST
Definition error.h:66
@ LXB_HTML_RULES_ERROR_MIELINOPELST
Definition error.h:68
@ LXB_HTML_RULES_ERROR_MIELINSC
Definition error.h:72
LXB_API bool lxb_html_tree_insertion_mode_initial(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition initial.c:134
LXB_API bool lxb_html_tree_insertion_mode_in_head(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition in_head.c:41
LXB_API bool lxb_html_tree_insertion_mode_in_caption(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition in_caption.c:113
LXB_API bool lxb_html_tree_insertion_mode_in_table_body(lxb_html_tree_t *tree, lxb_html_token_t *token)
LXB_API bool lxb_html_tree_insertion_mode_in_select(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition in_select.c:311
LXB_API bool lxb_html_tree_insertion_mode_after_head(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition after_head.c:27
LXB_API bool lxb_html_tree_insertion_mode_in_cell(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition in_cell.c:142
LXB_API bool lxb_html_tree_insertion_mode_text(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition text.c:14
LXB_API bool lxb_html_tree_insertion_mode_before_head(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition before_head.c:27
LXB_API bool lxb_html_tree_insertion_mode_in_table(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition in_table.c:371
LXB_API bool lxb_html_tree_insertion_mode_foreign_content(lxb_html_tree_t *tree, lxb_html_token_t *token)
LXB_API bool lxb_html_tree_insertion_mode_in_select_in_table(lxb_html_tree_t *tree, lxb_html_token_t *token)
LXB_API bool lxb_html_tree_insertion_mode_in_row(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition in_row.c:162
LXB_API bool lxb_html_tree_insertion_mode_in_column_group(lxb_html_tree_t *tree, lxb_html_token_t *token)
LXB_API bool lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition in_body.c:1685
LXB_API bool lxb_html_tree_insertion_mode_in_frameset(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition in_frameset.c:12
lxb_dom_attr_t * lxb_dom_attr_interface_create(lxb_dom_document_t *document)
Definition attr.c:26
lxb_status_t lxb_dom_attr_set_value_wo_copy(lxb_dom_attr_t *attr, lxb_char_t *value, size_t value_len)
Definition attr.c:259
const lxb_dom_attr_data_t * lxb_dom_attr_data_by_id(lexbor_hash_t *hash, lxb_dom_attr_id_t attr_id)
Definition attr.c:411
lxb_status_t lxb_dom_attr_clone_name_value(lxb_dom_attr_t *attr_from, lxb_dom_attr_t *attr_to)
Definition attr.c:285
lxb_status_t lxb_dom_element_attr_append(lxb_dom_element_t *element, lxb_dom_attr_t *attr)
Definition element.c:346
lxb_dom_attr_t * lxb_dom_element_attr_is_exist(lxb_dom_element_t *element, const lxb_char_t *qualified_name, size_t length)
Definition element.c:524
lxb_dom_attr_t * lxb_dom_element_attr_by_local_name_data(lxb_dom_element_t *element, const lxb_dom_attr_data_t *data)
Definition element.c:441
void lxb_dom_node_remove_wo_events(lxb_dom_node_t *node)
Definition node.c:452
void lxb_dom_node_remove(lxb_dom_node_t *node)
Definition node.c:478
void lxb_dom_node_insert_child_wo_events(lxb_dom_node_t *to, lxb_dom_node_t *node)
Definition node.c:368
lxb_dom_node_t * lxb_html_tree_element_in_scope_by_node(lxb_html_tree_t *tree, lxb_dom_node_t *by_node, lxb_html_tag_category_t ct)
Definition tree.c:1177
lxb_status_t lxb_html_tree_adjust_mathml_attributes(lxb_html_tree_t *tree, lxb_dom_attr_t *attr, void *ctx)
Definition tree.c:543
lxb_status_t lxb_html_tree_adjust_attributes_mathml(lxb_html_tree_t *tree, lxb_dom_attr_t *attr, void *ctx)
Definition tree.c:1706
lxb_html_element_t * lxb_html_tree_insert_foreign_element(lxb_html_tree_t *tree, lxb_html_token_t *token, lxb_ns_id_t ns)
Definition tree.c:392
void lxb_html_tree_node_delete_deep(lxb_html_tree_t *tree, lxb_dom_node_t *node)
Definition tree.c:857
bool lxb_html_tree_process_abort(lxb_html_tree_t *tree)
Definition tree.c:224
void lxb_html_tree_close_p_element(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition tree.c:1350
void lxb_html_tree_generate_all_implied_end_tags_thoroughly(lxb_html_tree_t *tree, lxb_tag_id_t ex_tag, lxb_ns_id_t ex_ns)
Definition tree.c:952
lxb_dom_node_t * lxb_html_tree_element_in_scope_td_th(lxb_html_tree_t *tree)
Definition tree.c:1278
bool lxb_html_tree_html_integration_point(lxb_dom_node_t *node)
Definition tree.c:1664
void lxb_html_tree_clean(lxb_html_tree_t *tree)
Definition tree.c:156
lxb_status_t lxb_html_tree_append_attributes_from_element(lxb_html_tree_t *tree, lxb_dom_element_t *element, lxb_dom_element_t *from, lxb_ns_id_t ns)
Definition tree.c:504
lxb_dom_comment_t * lxb_html_tree_insert_comment(lxb_html_tree_t *tree, lxb_html_token_t *token, lxb_dom_node_t *pos)
Definition tree.c:790
lxb_html_element_t * lxb_html_tree_generic_rawtext_parsing(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition tree.c:863
lxb_dom_attr_data_t * lxb_dom_attr_qualified_name_append(lexbor_hash_t *hash, const lxb_char_t *name, size_t length)
Definition attr.c:385
lxb_html_tree_t * lxb_html_tree_create(void)
Definition tree.c:47
lxb_status_t lxb_html_tree_stop_parsing(lxb_html_tree_t *tree)
Definition tree.c:216
lxb_html_tree_t * lxb_html_tree_destroy(lxb_html_tree_t *tree)
Definition tree.c:179
void lxb_html_tree_generate_implied_end_tags(lxb_html_tree_t *tree, lxb_tag_id_t ex_tag, lxb_ns_id_t ex_ns)
Definition tree.c:914
lxb_html_tree_t * lxb_html_tree_ref(lxb_html_tree_t *tree)
Definition tree.c:128
lxb_html_tree_t * lxb_html_tree_unref(lxb_html_tree_t *tree)
Definition tree.c:140
lxb_status_t lxb_html_tree_init(lxb_html_tree_t *tree, lxb_html_tokenizer_t *tkz)
Definition tree.c:53
lxb_status_t lxb_html_tree_insert_character_for_data(lxb_html_tree_t *tree, lexbor_str_t *str, lxb_dom_node_t **ret_node)
Definition tree.c:697
lxb_dom_node_t * lxb_html_tree_element_in_scope_tbody_thead_tfoot(lxb_html_tree_t *tree)
Definition tree.c:1242
bool lxb_html_tree_check_scope_element(lxb_html_tree_t *tree)
Definition tree.c:1313
lxb_dom_attr_data_t * lxb_dom_attr_local_name_append(lexbor_hash_t *hash, const lxb_char_t *name, size_t length)
Definition attr.c:358
lxb_status_t lxb_html_tree_adjust_svg_attributes(lxb_html_tree_t *tree, lxb_dom_attr_t *attr, void *ctx)
Definition tree.c:569
lxb_dom_node_t * lxb_html_tree_element_in_scope(lxb_html_tree_t *tree, lxb_tag_id_t tag_id, lxb_ns_id_t ns, lxb_html_tag_category_t ct)
Definition tree.c:1152
bool lxb_html_tree_construction_dispatcher(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition tree.c:244
lxb_dom_node_t * lxb_html_tree_appropriate_place_inserting_node(lxb_html_tree_t *tree, lxb_dom_node_t *override_target, lxb_html_tree_insertion_position_t *ipos)
Definition tree.c:304
lxb_status_t lxb_html_tree_adjust_foreign_attributes(lxb_html_tree_t *tree, lxb_dom_attr_t *attr, void *ctx)
Definition tree.c:606
lxb_status_t lxb_html_tree_insert_character(lxb_html_tree_t *tree, lxb_html_token_t *token, lxb_dom_node_t **ret_node)
Definition tree.c:669
lxb_html_element_t * lxb_html_tree_create_element_for_token(lxb_html_tree_t *tree, lxb_html_token_t *token, lxb_ns_id_t ns)
Definition tree.c:422
lxb_html_element_t * lxb_html_tree_generic_rcdata_parsing(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition tree.c:889
lxb_status_t lxb_html_tree_adjust_attributes_svg(lxb_html_tree_t *tree, lxb_dom_attr_t *attr, void *ctx)
Definition tree.c:1720
lxb_status_t lxb_html_tree_append_attributes(lxb_html_tree_t *tree, lxb_dom_element_t *element, lxb_html_token_t *token, lxb_ns_id_t ns)
Definition tree.c:452
void lxb_html_tree_parse_error(lxb_html_tree_t *tree, lxb_html_token_t *token, lxb_html_tree_error_id_t id)
Definition tree.c:237
lxb_dom_node_t * lxb_html_tree_element_in_scope_h123456(lxb_html_tree_t *tree)
Definition tree.c:1203
bool lxb_html_tree_adoption_agency_algorithm(lxb_html_tree_t *tree, lxb_html_token_t *token, lxb_status_t *status)
Definition tree.c:1368
const lxb_tag_data_t * lxb_tag_append_lower(lexbor_hash_t *hash, const lxb_char_t *name, size_t length)
Definition tag.c:41
lxb_dom_document_type_t * lxb_html_tree_create_document_type_from_token(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition tree.c:828
void lxb_html_tree_reset_insertion_mode_appropriately(lxb_html_tree_t *tree)
Definition tree.c:999
LXB_API void * lexbor_free(void *dst)
Definition memory.c:33
LXB_API void * lexbor_calloc(size_t num, size_t size)
Definition memory.c:27
#define next(ls)
Definition minilua.c:2661
uintptr_t lxb_ns_id_t
Definition const.h:20
@ LXB_NS_MATH
Definition const.h:27
@ LXB_NS_SVG
Definition const.h:28
@ LXB_NS_HTML
Definition const.h:26
const lxb_ns_prefix_data_t * lxb_ns_prefix_append(lexbor_hash_t *hash, const lxb_char_t *prefix, size_t length)
Definition ns.c:97
LXB_API void lxb_html_tree_open_elements_remove_by_node(lxb_html_tree_t *tree, lxb_dom_node_t *node)
lxb_dom_node_t * lxb_html_tree_open_elements_find_reverse(lxb_html_tree_t *tree, lxb_tag_id_t tag_id, lxb_ns_id_t ns, size_t *return_index)
bool lxb_html_tree_open_elements_find_by_node_reverse(lxb_html_tree_t *tree, lxb_dom_node_t *node, size_t *return_pos)
void lxb_html_tree_open_elements_pop_until_node(lxb_html_tree_t *tree, lxb_dom_node_t *node, bool exclude)
void lxb_html_tree_open_elements_pop_until_tag_id(lxb_html_tree_t *tree, lxb_tag_id_t tag_id, lxb_ns_id_t ns, bool exclude)
bool lxb_html_tree_open_elements_find_by_node(lxb_html_tree_t *tree, lxb_dom_node_t *node, size_t *return_pos)
lxb_inline lxb_status_t lxb_html_tree_open_elements_push(lxb_html_tree_t *tree, lxb_dom_node_t *node)
lxb_inline lxb_status_t lxb_html_tree_open_elements_insert_after(lxb_html_tree_t *tree, lxb_dom_node_t *node, size_t idx)
lxb_inline lxb_dom_node_t * lxb_html_tree_open_elements_first(lxb_html_tree_t *tree)
lxb_inline lxb_dom_node_t * lxb_html_tree_open_elements_get(lxb_html_tree_t *tree, size_t idx)
lxb_inline lxb_dom_node_t * lxb_html_tree_open_elements_pop(lxb_html_tree_t *tree)
unsigned const char * pos
Definition php_ffi.h:52
unsigned const char * text
Definition php_ffi.h:53
zend_constant * data
const lxb_char_t * lxb_html_tokenizer_state_rawtext_before(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end)
const lxb_char_t * lxb_html_tokenizer_state_rcdata_before(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end)
lxb_char_t * lexbor_str_append(lexbor_str_t *str, lexbor_mraw_t *mraw, const lxb_char_t *buff, size_t length)
Definition str.c:131
bool lexbor_str_data_cmp(const lxb_char_t *first, const lxb_char_t *sec)
Definition str.c:530
lxb_char_t * lexbor_str_init(lexbor_str_t *str, lexbor_mraw_t *mraw, size_t size)
Definition str.c:22
bool lexbor_str_data_casecmp(const lxb_char_t *first, const lxb_char_t *sec)
Definition str.c:476
lexbor_str_t * lexbor_str_destroy(lexbor_str_t *str, lexbor_mraw_t *mraw, bool destroy_obj)
Definition str.c:76
size_t length
Definition array.h:20
void ** list
Definition array.h:18
lxb_char_t * data
Definition str.h:47
size_t length
Definition str.h:48
lxb_dom_attr_id_t attr_id
Definition attr.h:27
lxb_dom_node_t node
Definition attr.h:35
lxb_dom_character_data_t char_data
Definition comment.h:19
lexbor_mraw_t * text
Definition document.h:54
lxb_dom_node_t node
Definition element.h:33
lxb_dom_attr_t * first_attr
Definition element.h:45
uintptr_t ns
Definition node.h:48
lxb_dom_node_t * first_child
Definition node.h:55
lxb_dom_document_t * owner_document
Definition node.h:50
size_t line
Definition node.h:61
uintptr_t local_name
Definition node.h:46
lxb_dom_node_t * parent
Definition node.h:54
lxb_dom_node_t * next
Definition node.h:52
lxb_html_head_element_t * head
Definition document.h:62
lxb_html_document_ready_state_t ready_state
Definition document.h:69
lxb_dom_document_t dom_document
Definition document.h:58
lxb_char_t * value
Definition token_attr.h:39
const lxb_char_t * value_begin
Definition token_attr.h:35
lxb_html_token_attr_t * next
Definition token_attr.h:42
const lxb_dom_attr_data_t * name
Definition token_attr.h:38
lxb_html_token_type_t type
Definition token.h:49
const lxb_char_t * text_end
Definition token.h:40
lxb_tag_id_t tag_id
Definition token.h:48
const lxb_char_t * text_start
Definition token.h:39
lxb_html_token_attr_t * attr_first
Definition token.h:42
void * base_element
Definition token.h:45
size_t line
Definition token.h:36
lxb_html_token_t * token
Definition tokenizer.h:49
lxb_status_t status
Definition tokenizer.h:90
lexbor_array_obj_t * text_list
Definition tree.h:34
lxb_html_tree_append_attr_f before_append_attr
Definition tree.h:64
lxb_html_tree_pending_table_t pending_table
Definition tree.h:51
size_t ref_count
Definition tree.h:68
bool frameset_ok
Definition tree.h:56
lxb_html_tree_insertion_mode_f original_mode
Definition tree.h:63
lexbor_array_obj_t * template_insertion_modes
Definition tree.h:49
lxb_html_tokenizer_t * tkz_ref
Definition tree.h:40
lxb_html_form_element_t * form
Definition tree.h:45
lxb_status_t status
Definition tree.h:66
lexbor_array_t * active_formatting
Definition tree.h:48
lexbor_array_obj_t * parse_errors
Definition tree.h:53
lxb_html_tree_insertion_mode_f mode
Definition tree.h:62
lexbor_array_t * open_elements
Definition tree.h:47
bool foster_parenting
Definition tree.h:55
lxb_html_document_t * document
Definition tree.h:42
lxb_dom_node_t * fragment
Definition tree.h:43
lxb_ns_prefix_id_t prefix_id
Definition ns.h:32
@ LXB_TAG_OPTION
Definition const.h:167
@ LXB_TAG_DD
Definition const.h:68
@ LXB_TAG_TEMPLATE
Definition const.h:203
@ LXB_TAG_TITLE
Definition const.h:210
@ LXB_TAG_H4
Definition const.h:118
@ LXB_TAG__END_OF_FILE
Definition const.h:25
@ LXB_TAG_H5
Definition const.h:119
@ LXB_TAG_OPTGROUP
Definition const.h:166
@ LXB_TAG_TD
Definition const.h:202
@ LXB_TAG__DOCUMENT
Definition const.h:27
@ LXB_TAG_H1
Definition const.h:115
@ LXB_TAG_HEAD
Definition const.h:121
@ LXB_TAG_HTML
Definition const.h:125
@ LXB_TAG_THEAD
Definition const.h:208
@ LXB_TAG_LI
Definition const.h:137
@ LXB_TAG_FOREIGNOBJECT
Definition const.h:110
@ LXB_TAG_CAPTION
Definition const.h:59
@ LXB_TAG_BODY
Definition const.h:55
@ LXB_TAG_TBODY
Definition const.h:201
@ LXB_TAG_COLGROUP
Definition const.h:65
@ LXB_TAG_H2
Definition const.h:116
@ LXB_TAG_ANNOTATION_XML
Definition const.h:40
@ LXB_TAG_MALIGNMARK
Definition const.h:142
@ LXB_TAG_TABLE
Definition const.h:200
@ LXB_TAG_RTC
Definition const.h:181
@ LXB_TAG_H6
Definition const.h:120
@ LXB_TAG_DT
Definition const.h:77
@ LXB_TAG_P
Definition const.h:169
@ LXB_TAG_TFOOT
Definition const.h:206
@ LXB_TAG_RT
Definition const.h:180
@ LXB_TAG_TH
Definition const.h:207
@ LXB_TAG_TR
Definition const.h:211
@ LXB_TAG_MGLYPH
Definition const.h:151
@ LXB_TAG_RB
Definition const.h:178
@ LXB_TAG_FRAMESET
Definition const.h:113
@ LXB_TAG_RP
Definition const.h:179
@ LXB_TAG__TEXT
Definition const.h:26
@ LXB_TAG_DESC
Definition const.h:70
@ LXB_TAG_H3
Definition const.h:117
@ LXB_TAG_SVG
Definition const.h:199
@ LXB_TAG_SELECT
Definition const.h:187
uintptr_t lxb_tag_id_t
Definition const.h:21
lxb_inline lxb_html_tree_insertion_mode_f lxb_html_tree_template_insertion_current(lxb_html_tree_t *tree)
struct lxb_html_token_attr lxb_html_token_attr_t
Definition token_attr.h:22
lxb_html_tree_insertion_position_t
Definition tree.h:71
@ LXB_HTML_TREE_INSERTION_POSITION_BEFORE
Definition tree.h:73
@ LXB_HTML_TREE_INSERTION_POSITION_CHILD
Definition tree.h:72
lxb_inline bool lxb_html_tree_mathml_text_integration_point(lxb_dom_node_t *node)
Definition tree.h:343
lxb_inline void lxb_html_tree_insert_node(lxb_dom_node_t *to, lxb_dom_node_t *node, lxb_html_tree_insertion_position_t ipos)
Definition tree.h:314
lxb_inline lxb_dom_node_t * lxb_html_tree_current_node(lxb_html_tree_t *tree)
Definition tree.h:286
lxb_inline lxb_dom_node_t * lxb_html_tree_adjusted_current_node(lxb_html_tree_t *tree)
Definition tree.h:297
lxb_inline lxb_dom_node_t * lxb_html_tree_create_node(lxb_html_tree_t *tree, lxb_tag_id_t tag_id, lxb_ns_id_t ns)
Definition tree.h:272
lxb_inline bool lxb_html_tree_node_is(lxb_dom_node_t *node, lxb_tag_id_t tag_id)
Definition tree.h:280
lxb_inline lxb_html_element_t * lxb_html_tree_insert_html_element(lxb_html_tree_t *tree, lxb_html_token_t *token)
Definition tree.h:307
unsigned int lxb_status_t
Definition types.h:28
unsigned char lxb_char_t
Definition types.h:27
int last
zend_string * name