1 /*
2 * Copyright (C) 2018-2019 Alexander Borisov
3 *
4 * Author: Alexander Borisov <borisov@lexbor.com>
5 */
6
7 #include "lexbor/html/tree/insertion_mode.h"
8 #include "lexbor/html/tree/open_elements.h"
9 #include "lexbor/html/tree/active_formatting.h"
10 #include "lexbor/html/tree/template_insertion.h"
11
12
13 /*
14 * "caption", "colgroup", "tbody", "tfoot", "thead"
15 */
16 lxb_inline bool
lxb_html_tree_insertion_mode_in_template_ct(lxb_html_tree_t * tree,lxb_html_token_t * token)17 lxb_html_tree_insertion_mode_in_template_ct(lxb_html_tree_t *tree,
18 lxb_html_token_t *token)
19 {
20 lxb_html_tree_template_insertion_pop(tree);
21
22 tree->status = lxb_html_tree_template_insertion_push(tree,
23 lxb_html_tree_insertion_mode_in_table);
24 if (tree->status != LXB_STATUS_OK) {
25 return lxb_html_tree_process_abort(tree);
26 }
27
28 tree->mode = lxb_html_tree_insertion_mode_in_table;
29
30 return false;
31 }
32
33 lxb_inline bool
lxb_html_tree_insertion_mode_in_template_col(lxb_html_tree_t * tree,lxb_html_token_t * token)34 lxb_html_tree_insertion_mode_in_template_col(lxb_html_tree_t *tree,
35 lxb_html_token_t *token)
36 {
37 lxb_html_tree_template_insertion_pop(tree);
38
39 tree->status = lxb_html_tree_template_insertion_push(tree,
40 lxb_html_tree_insertion_mode_in_column_group);
41 if (tree->status != LXB_STATUS_OK) {
42 return lxb_html_tree_process_abort(tree);
43 }
44
45 tree->mode = lxb_html_tree_insertion_mode_in_column_group;
46
47 return false;
48 }
49
50 lxb_inline bool
lxb_html_tree_insertion_mode_in_template_tr(lxb_html_tree_t * tree,lxb_html_token_t * token)51 lxb_html_tree_insertion_mode_in_template_tr(lxb_html_tree_t *tree,
52 lxb_html_token_t *token)
53 {
54 lxb_html_tree_template_insertion_pop(tree);
55
56 tree->status = lxb_html_tree_template_insertion_push(tree,
57 lxb_html_tree_insertion_mode_in_table_body);
58 if (tree->status != LXB_STATUS_OK) {
59 return lxb_html_tree_process_abort(tree);
60 }
61
62 tree->mode = lxb_html_tree_insertion_mode_in_table_body;
63
64 return false;
65 }
66
67 /*
68 * "td", "th"
69 */
70 lxb_inline bool
lxb_html_tree_insertion_mode_in_template_tdth(lxb_html_tree_t * tree,lxb_html_token_t * token)71 lxb_html_tree_insertion_mode_in_template_tdth(lxb_html_tree_t *tree,
72 lxb_html_token_t *token)
73 {
74 lxb_html_tree_template_insertion_pop(tree);
75
76 tree->status = lxb_html_tree_template_insertion_push(tree,
77 lxb_html_tree_insertion_mode_in_row);
78 if (tree->status != LXB_STATUS_OK) {
79 return lxb_html_tree_process_abort(tree);
80 }
81
82 tree->mode = lxb_html_tree_insertion_mode_in_row;
83
84 return false;
85 }
86
87 lxb_inline bool
lxb_html_tree_insertion_mode_in_template_end_of_file(lxb_html_tree_t * tree,lxb_html_token_t * token)88 lxb_html_tree_insertion_mode_in_template_end_of_file(lxb_html_tree_t *tree,
89 lxb_html_token_t *token)
90 {
91 lxb_dom_node_t *node;
92
93 node = lxb_html_tree_open_elements_find(tree, LXB_TAG_TEMPLATE, LXB_NS_HTML,
94 NULL);
95 if (node == NULL) {
96 tree->status = lxb_html_tree_stop_parsing(tree);
97 if (tree->status != LXB_STATUS_OK) {
98 return lxb_html_tree_process_abort(tree);
99 }
100
101 return true;
102 }
103
104 lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNENOFFI);
105
106 lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_TEMPLATE,
107 LXB_NS_HTML, true);
108
109 lxb_html_tree_active_formatting_up_to_last_marker(tree);
110 lxb_html_tree_template_insertion_pop(tree);
111 lxb_html_tree_reset_insertion_mode_appropriately(tree);
112
113 return false;
114 }
115
116 lxb_inline bool
lxb_html_tree_insertion_mode_in_template_anything_else(lxb_html_tree_t * tree,lxb_html_token_t * token)117 lxb_html_tree_insertion_mode_in_template_anything_else(lxb_html_tree_t *tree,
118 lxb_html_token_t *token)
119 {
120 lxb_html_tree_template_insertion_pop(tree);
121
122 tree->status = lxb_html_tree_template_insertion_push(tree,
123 lxb_html_tree_insertion_mode_in_body);
124 if (tree->status != LXB_STATUS_OK) {
125 return lxb_html_tree_process_abort(tree);
126 }
127
128 tree->mode = lxb_html_tree_insertion_mode_in_body;
129
130 return false;
131 }
132
133 bool
lxb_html_tree_insertion_mode_in_template(lxb_html_tree_t * tree,lxb_html_token_t * token)134 lxb_html_tree_insertion_mode_in_template(lxb_html_tree_t *tree,
135 lxb_html_token_t *token)
136 {
137 if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) {
138 if (token->tag_id == LXB_TAG_TEMPLATE) {
139 return lxb_html_tree_insertion_mode_in_head(tree, token);
140 }
141
142 lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO);
143
144 return true;
145 }
146
147 switch (token->tag_id) {
148 case LXB_TAG__TEXT:
149 case LXB_TAG__EM_COMMENT:
150 case LXB_TAG__EM_DOCTYPE:
151 return lxb_html_tree_insertion_mode_in_body(tree, token);
152
153 case LXB_TAG_BASE:
154 case LXB_TAG_BASEFONT:
155 case LXB_TAG_BGSOUND:
156 case LXB_TAG_LINK:
157 case LXB_TAG_META:
158 case LXB_TAG_NOFRAMES:
159 case LXB_TAG_SCRIPT:
160 case LXB_TAG_STYLE:
161 case LXB_TAG_TEMPLATE:
162 case LXB_TAG_TITLE:
163 return lxb_html_tree_insertion_mode_in_head(tree, token);
164
165 case LXB_TAG_CAPTION:
166 case LXB_TAG_COLGROUP:
167 case LXB_TAG_TBODY:
168 case LXB_TAG_TFOOT:
169 case LXB_TAG_THEAD:
170 return lxb_html_tree_insertion_mode_in_template_ct(tree, token);
171
172 case LXB_TAG_COL:
173 return lxb_html_tree_insertion_mode_in_template_col(tree, token);
174
175 case LXB_TAG_TR:
176 return lxb_html_tree_insertion_mode_in_template_tr(tree, token);
177
178 case LXB_TAG_TD:
179 case LXB_TAG_TH:
180 return lxb_html_tree_insertion_mode_in_template_tdth(tree, token);
181
182 case LXB_TAG__END_OF_FILE:
183 return lxb_html_tree_insertion_mode_in_template_end_of_file(tree,
184 token);
185 default:
186 return lxb_html_tree_insertion_mode_in_template_anything_else(tree,
187 token);
188 }
189 }
190