1 /*
2 * Copyright (C) 2018-2020 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
10
11 bool
lxb_html_tree_insertion_mode_in_frameset(lxb_html_tree_t * tree,lxb_html_token_t * token)12 lxb_html_tree_insertion_mode_in_frameset(lxb_html_tree_t *tree,
13 lxb_html_token_t *token)
14 {
15 if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) {
16 if (token->tag_id == LXB_TAG_FRAMESET)
17 {
18 lxb_dom_node_t *node;
19 node = lxb_html_tree_current_node(tree);
20
21 if (node == lxb_html_tree_open_elements_first(tree)) {
22 lxb_html_tree_parse_error(tree, token,
23 LXB_HTML_RULES_ERROR_UNELINOPELST);
24 return true;
25 }
26
27 lxb_html_tree_open_elements_pop(tree);
28
29 node = lxb_html_tree_current_node(tree);
30
31 if (tree->fragment == NULL
32 && lxb_html_tree_node_is(node, LXB_TAG_FRAMESET) == false)
33 {
34 tree->mode = lxb_html_tree_insertion_mode_after_frameset;
35 }
36
37 return true;
38 }
39
40 lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO);
41
42 return true;
43 }
44
45 switch (token->tag_id) {
46 case LXB_TAG__EM_COMMENT: {
47 lxb_dom_comment_t *comment;
48
49 comment = lxb_html_tree_insert_comment(tree, token, NULL);
50 if (comment == NULL) {
51 return lxb_html_tree_process_abort(tree);
52 }
53
54 break;
55 }
56
57 case LXB_TAG__EM_DOCTYPE:
58 lxb_html_tree_parse_error(tree, token,
59 LXB_HTML_RULES_ERROR_DOTOINFRMO);
60 break;
61
62 case LXB_TAG_HTML:
63 return lxb_html_tree_insertion_mode_in_body(tree, token);
64
65 case LXB_TAG_FRAMESET: {
66 lxb_html_element_t *element;
67
68 element = lxb_html_tree_insert_html_element(tree, token);
69 if (element == NULL) {
70 tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
71
72 return lxb_html_tree_process_abort(tree);
73 }
74
75 break;
76 }
77
78 case LXB_TAG_FRAME: {
79 lxb_html_element_t *element;
80
81 element = lxb_html_tree_insert_html_element(tree, token);
82 if (element == NULL) {
83 tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION;
84
85 return lxb_html_tree_process_abort(tree);
86 }
87
88 lxb_html_tree_open_elements_pop(tree);
89 lxb_html_tree_acknowledge_token_self_closing(tree, token);
90
91 break;
92 }
93
94 case LXB_TAG_NOFRAMES:
95 return lxb_html_tree_insertion_mode_in_head(tree, token);
96
97 case LXB_TAG__END_OF_FILE: {
98 lxb_dom_node_t *node = lxb_html_tree_current_node(tree);
99
100 if (node != lxb_html_tree_open_elements_first(tree)) {
101 lxb_html_tree_parse_error(tree, token,
102 LXB_HTML_RULES_ERROR_UNELINOPELST);
103 }
104
105 tree->status = lxb_html_tree_stop_parsing(tree);
106 if (tree->status != LXB_STATUS_OK) {
107 return lxb_html_tree_process_abort(tree);
108 }
109
110 break;
111 }
112
113 case LXB_TAG__TEXT: {
114 size_t cur_len;
115 lexbor_str_t str;
116
117 tree->status = lxb_html_token_make_text(token, &str,
118 tree->document->dom_document.text);
119 if (tree->status != LXB_STATUS_OK) {
120 return lxb_html_tree_process_abort(tree);
121 }
122
123 cur_len = str.length;
124
125 lexbor_str_stay_only_whitespace(&str);
126
127 if (str.length != 0) {
128 tree->status = lxb_html_tree_insert_character_for_data(tree,
129 &str,
130 NULL);
131 if (tree->status != LXB_STATUS_OK) {
132 return lxb_html_tree_process_abort(tree);
133 }
134 }
135
136 if (str.length == cur_len) {
137 return true;
138 }
139 }
140 /* fall through */
141
142 default:
143 lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO);
144
145 break;
146 }
147
148 return true;
149 }
150