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 
11 
12 lxb_inline bool
lxb_html_tree_insertion_mode_in_caption_caption_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)13 lxb_html_tree_insertion_mode_in_caption_caption_closed(lxb_html_tree_t *tree,
14                                                        lxb_html_token_t *token)
15 {
16     lxb_dom_node_t *node;
17 
18     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_CAPTION, LXB_NS_HTML,
19                                           LXB_HTML_TAG_CATEGORY_SCOPE_TABLE);
20     if (node == NULL) {
21         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_MIELINSC);
22 
23         return true;
24     }
25 
26     lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF,
27                                             LXB_NS__UNDEF);
28 
29     node = lxb_html_tree_current_node(tree);
30 
31     if (lxb_html_tree_node_is(node, LXB_TAG_CAPTION) == false) {
32         lxb_html_tree_parse_error(tree, token,
33                                   LXB_HTML_RULES_ERROR_UNELINOPELST);
34     }
35 
36     lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_CAPTION,
37                                                  LXB_NS_HTML, true);
38 
39     lxb_html_tree_active_formatting_up_to_last_marker(tree);
40 
41     tree->mode = lxb_html_tree_insertion_mode_in_table;
42 
43     return true;
44 }
45 
46 /*
47  * A start tag whose tag name is one of: "caption", "col", "colgroup", "tbody",
48  * "td", "tfoot", "th", "thead", "tr"
49  * An end tag whose tag name is "table"
50  */
51 lxb_inline bool
lxb_html_tree_insertion_mode_in_caption_ct_open_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)52 lxb_html_tree_insertion_mode_in_caption_ct_open_closed(lxb_html_tree_t *tree,
53                                                        lxb_html_token_t *token)
54 {
55     lxb_dom_node_t *node;
56 
57     node = lxb_html_tree_element_in_scope(tree, LXB_TAG_CAPTION, LXB_NS_HTML,
58                                           LXB_HTML_TAG_CATEGORY_SCOPE_TABLE);
59     if (node == NULL) {
60         lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_MIELINSC);
61 
62         return true;
63     }
64 
65     lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF,
66                                             LXB_NS__UNDEF);
67 
68     node = lxb_html_tree_current_node(tree);
69 
70     if (lxb_html_tree_node_is(node, LXB_TAG_CAPTION) == false) {
71         lxb_html_tree_parse_error(tree, token,
72                                   LXB_HTML_RULES_ERROR_UNELINOPELST);
73     }
74 
75     lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_CAPTION,
76                                                  LXB_NS_HTML, true);
77 
78     lxb_html_tree_active_formatting_up_to_last_marker(tree);
79 
80     tree->mode = lxb_html_tree_insertion_mode_in_table;
81 
82     return false;
83 }
84 
85 /*
86  * "body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead",
87  * "tr"
88  */
89 lxb_inline bool
lxb_html_tree_insertion_mode_in_caption_bcht_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)90 lxb_html_tree_insertion_mode_in_caption_bcht_closed(lxb_html_tree_t *tree,
91                                                     lxb_html_token_t *token)
92 {
93     lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO);
94 
95     return true;
96 }
97 
98 lxb_inline bool
lxb_html_tree_insertion_mode_in_caption_anything_else(lxb_html_tree_t * tree,lxb_html_token_t * token)99 lxb_html_tree_insertion_mode_in_caption_anything_else(lxb_html_tree_t *tree,
100                                                       lxb_html_token_t *token)
101 {
102     return lxb_html_tree_insertion_mode_in_body(tree, token);
103 }
104 
105 lxb_inline bool
lxb_html_tree_insertion_mode_in_caption_anything_else_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)106 lxb_html_tree_insertion_mode_in_caption_anything_else_closed(lxb_html_tree_t *tree,
107                                                              lxb_html_token_t *token)
108 {
109     return lxb_html_tree_insertion_mode_in_caption_anything_else(tree, token);
110 }
111 
112 bool
lxb_html_tree_insertion_mode_in_caption(lxb_html_tree_t * tree,lxb_html_token_t * token)113 lxb_html_tree_insertion_mode_in_caption(lxb_html_tree_t *tree,
114                                         lxb_html_token_t *token)
115 {
116     if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) {
117         switch (token->tag_id) {
118             case LXB_TAG_CAPTION:
119                 return lxb_html_tree_insertion_mode_in_caption_caption_closed(tree,
120                                                                               token);
121             case LXB_TAG_TABLE:
122                 return lxb_html_tree_insertion_mode_in_caption_ct_open_closed(tree,
123                                                                               token);
124             case LXB_TAG_BODY:
125             case LXB_TAG_COL:
126             case LXB_TAG_COLGROUP:
127             case LXB_TAG_HTML:
128             case LXB_TAG_TBODY:
129             case LXB_TAG_TD:
130             case LXB_TAG_TFOOT:
131             case LXB_TAG_TH:
132             case LXB_TAG_THEAD:
133             case LXB_TAG_TR:
134                 return lxb_html_tree_insertion_mode_in_caption_bcht_closed(tree,
135                                                                            token);
136             default:
137                 return lxb_html_tree_insertion_mode_in_caption_anything_else_closed(tree,
138                                                                                     token);
139         }
140     }
141 
142     switch (token->tag_id) {
143         case LXB_TAG_CAPTION:
144         case LXB_TAG_COL:
145         case LXB_TAG_COLGROUP:
146         case LXB_TAG_TBODY:
147         case LXB_TAG_TD:
148         case LXB_TAG_TFOOT:
149         case LXB_TAG_TH:
150         case LXB_TAG_THEAD:
151         case LXB_TAG_TR:
152             return lxb_html_tree_insertion_mode_in_caption_ct_open_closed(tree,
153                                                                           token);
154         default:
155             return lxb_html_tree_insertion_mode_in_caption_anything_else(tree,
156                                                                          token);
157     }
158 }
159