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 static bool
12 lxb_html_tree_insertion_mode_in_head_noscript_open(lxb_html_tree_t *tree,
13                                                    lxb_html_token_t *token);
14 
15 static bool
16 lxb_html_tree_insertion_mode_in_head_noscript_closed(lxb_html_tree_t *tree,
17                                                      lxb_html_token_t *token);
18 
19 
20 bool
lxb_html_tree_insertion_mode_in_head_noscript(lxb_html_tree_t * tree,lxb_html_token_t * token)21 lxb_html_tree_insertion_mode_in_head_noscript(lxb_html_tree_t *tree,
22                                               lxb_html_token_t *token)
23 {
24     if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) {
25        return lxb_html_tree_insertion_mode_in_head_noscript_closed(tree, token);
26     }
27 
28     return lxb_html_tree_insertion_mode_in_head_noscript_open(tree, token);
29 }
30 
31 lxb_inline bool
32 lxb_html_tree_insertion_mode_in_head_noscript_anything_else(lxb_html_tree_t *tree,
33                                                             lxb_html_token_t *token);
34 
35 
36 static bool
lxb_html_tree_insertion_mode_in_head_noscript_open(lxb_html_tree_t * tree,lxb_html_token_t * token)37 lxb_html_tree_insertion_mode_in_head_noscript_open(lxb_html_tree_t *tree,
38                                                    lxb_html_token_t *token)
39 {
40     switch (token->tag_id) {
41         case LXB_TAG__EM_DOCTYPE:
42             lxb_html_tree_parse_error(tree, token,
43                                       LXB_HTML_RULES_ERROR_DOTOINHENOMO);
44             break;
45 
46         case LXB_TAG_HTML:
47             return lxb_html_tree_insertion_mode_in_body(tree, token);
48 
49         case LXB_TAG__EM_COMMENT:
50         case LXB_TAG_BASEFONT:
51         case LXB_TAG_BGSOUND:
52         case LXB_TAG_LINK:
53         case LXB_TAG_META:
54         case LXB_TAG_NOFRAMES:
55         case LXB_TAG_STYLE:
56             return lxb_html_tree_insertion_mode_in_head(tree, token);
57 
58         case LXB_TAG_HEAD:
59         case LXB_TAG_NOSCRIPT:
60             lxb_html_tree_parse_error(tree, token,
61                                       LXB_HTML_RULES_ERROR_UNTO);
62             break;
63 
64         /* CopyPast from "in head" insertion mode */
65         case LXB_TAG__TEXT: {
66             lxb_html_token_t ws_token = {0};
67 
68             tree->status = lxb_html_token_data_split_ws_begin(token, &ws_token);
69             if (tree->status != LXB_STATUS_OK) {
70                 return lxb_html_tree_process_abort(tree);
71             }
72 
73             if (ws_token.text_start != ws_token.text_end) {
74                 tree->status = lxb_html_tree_insert_character(tree, &ws_token,
75                                                               NULL);
76                 if (tree->status != LXB_STATUS_OK) {
77                     return lxb_html_tree_process_abort(tree);
78                 }
79             }
80 
81             if (token->text_start == token->text_end) {
82                 return true;
83             }
84         }
85         /* fall through */
86 
87         default:
88             return lxb_html_tree_insertion_mode_in_head_noscript_anything_else(tree,
89                                                                                token);
90     }
91 
92     return true;
93 }
94 
95 static bool
lxb_html_tree_insertion_mode_in_head_noscript_closed(lxb_html_tree_t * tree,lxb_html_token_t * token)96 lxb_html_tree_insertion_mode_in_head_noscript_closed(lxb_html_tree_t *tree,
97                                                      lxb_html_token_t *token)
98 {
99     if(token->tag_id == LXB_TAG_BR) {
100         return lxb_html_tree_insertion_mode_in_head_noscript_anything_else(tree,
101                                                                             token);
102     }
103 
104     lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO);
105 
106     return true;
107 }
108 
109 lxb_inline bool
lxb_html_tree_insertion_mode_in_head_noscript_anything_else(lxb_html_tree_t * tree,lxb_html_token_t * token)110 lxb_html_tree_insertion_mode_in_head_noscript_anything_else(lxb_html_tree_t *tree,
111                                                             lxb_html_token_t *token)
112 {
113     lxb_html_tree_parse_error(tree, token,
114                               LXB_HTML_RULES_ERROR_UNTO);
115 
116     lxb_html_tree_open_elements_pop(tree);
117 
118     tree->mode = lxb_html_tree_insertion_mode_in_head;
119 
120     return false;
121 }
122