Serenity Operating System
1/*
2 * Copyright (c) 2020-2021, the SerenityOS developers.
3 * Copyright (c) 2022-2023, Sam Atkins <atkinssj@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <LibWeb/CSS/Parser/Token.h>
9#include <LibWeb/CSS/Serialize.h>
10
11namespace Web::CSS::Parser {
12
13ErrorOr<String> Token::to_string() const
14{
15 StringBuilder builder;
16
17 switch (m_type) {
18 case Type::EndOfFile:
19 return String {};
20 case Type::Ident:
21 return serialize_an_identifier(ident());
22 case Type::Function:
23 return String::formatted("{}(", TRY(serialize_an_identifier(function())));
24 case Type::AtKeyword:
25 return String::formatted("@{}", TRY(serialize_an_identifier(at_keyword())));
26 case Type::Hash: {
27 switch (m_hash_type) {
28 case HashType::Id:
29 return String::formatted("#{}", TRY(serialize_an_identifier(hash_value())));
30 case HashType::Unrestricted:
31 return String::formatted("#{}", hash_value());
32 }
33 VERIFY_NOT_REACHED();
34 }
35 case Type::String:
36 return serialize_a_string(string());
37 case Type::BadString:
38 return String {};
39 case Type::Url:
40 return serialize_a_url(url());
41 case Type::BadUrl:
42 return "url()"_string;
43 case Type::Delim:
44 return String { m_value };
45 case Type::Number:
46 return String::number(m_number_value.value());
47 case Type::Percentage:
48 return String::formatted("{}%", m_number_value.value());
49 case Type::Dimension:
50 return String::formatted("{}{}", m_number_value.value(), dimension_unit());
51 case Type::Whitespace:
52 return " "_short_string;
53 case Type::CDO:
54 return "<!--"_string;
55 case Type::CDC:
56 return "-->"_short_string;
57 case Type::Colon:
58 return ":"_short_string;
59 case Type::Semicolon:
60 return ";"_short_string;
61 case Type::Comma:
62 return ","_short_string;
63 case Type::OpenSquare:
64 return "["_short_string;
65 case Type::CloseSquare:
66 return "]"_short_string;
67 case Type::OpenParen:
68 return "("_short_string;
69 case Type::CloseParen:
70 return ")"_short_string;
71 case Type::OpenCurly:
72 return "{"_short_string;
73 case Type::CloseCurly:
74 return "}"_short_string;
75 case Type::Invalid:
76 default:
77 VERIFY_NOT_REACHED();
78 }
79}
80
81ErrorOr<String> Token::to_debug_string() const
82{
83 switch (m_type) {
84 case Type::Invalid:
85 VERIFY_NOT_REACHED();
86
87 case Type::EndOfFile:
88 return "__EOF__"_string;
89 case Type::Ident:
90 return String::formatted("Ident: {}", ident());
91 case Type::Function:
92 return String::formatted("Function: {}", function());
93 case Type::AtKeyword:
94 return String::formatted("AtKeyword: {}", at_keyword());
95 case Type::Hash:
96 return String::formatted("Hash: {} (hash_type: {})", hash_value(), m_hash_type == HashType::Unrestricted ? "Unrestricted" : "Id");
97 case Type::String:
98 return String::formatted("String: {}", string());
99 case Type::BadString:
100 return "BadString"_string;
101 case Type::Url:
102 return String::formatted("Url: {}", url());
103 case Type::BadUrl:
104 return "BadUrl"_string;
105 case Type::Delim:
106 return String::formatted("Delim: {}", m_value);
107 case Type::Number:
108 return String::formatted("Number: {}{} (number_type: {})", m_number_value.value() > 0 && m_number_value.is_integer_with_explicit_sign() ? "+" : "", m_number_value.value(), m_number_value.is_integer() ? "Integer" : "Number");
109 case Type::Percentage:
110 return String::formatted("Percentage: {}% (number_type: {})", percentage(), m_number_value.is_integer() ? "Integer" : "Number");
111 case Type::Dimension:
112 return String::formatted("Dimension: {}{} (number_type: {})", dimension_value(), dimension_unit(), m_number_value.is_integer() ? "Integer" : "Number");
113 case Type::Whitespace:
114 return "Whitespace"_string;
115 case Type::CDO:
116 return "CDO"_string;
117 case Type::CDC:
118 return "CDC"_string;
119 case Type::Colon:
120 return "Colon"_string;
121 case Type::Semicolon:
122 return "Semicolon"_string;
123 case Type::Comma:
124 return "Comma"_string;
125 case Type::OpenSquare:
126 return "OpenSquare"_string;
127 case Type::CloseSquare:
128 return "CloseSquare"_string;
129 case Type::OpenParen:
130 return "OpenParen"_string;
131 case Type::CloseParen:
132 return "CloseParen"_string;
133 case Type::OpenCurly:
134 return "OpenCurly"_string;
135 case Type::CloseCurly:
136 return "CloseCurly"_string;
137 }
138 VERIFY_NOT_REACHED();
139}
140
141Token::Type Token::mirror_variant() const
142{
143 if (is(Token::Type::OpenCurly)) {
144 return Type::CloseCurly;
145 }
146
147 if (is(Token::Type::OpenSquare)) {
148 return Type::CloseSquare;
149 }
150
151 if (is(Token::Type::OpenParen)) {
152 return Type::CloseParen;
153 }
154
155 return Type::Invalid;
156}
157
158StringView Token::bracket_string() const
159{
160 if (is(Token::Type::OpenCurly)) {
161 return "{"sv;
162 }
163
164 if (is(Token::Type::CloseCurly)) {
165 return "}"sv;
166 }
167
168 if (is(Token::Type::OpenSquare)) {
169 return "["sv;
170 }
171
172 if (is(Token::Type::CloseSquare)) {
173 return "]"sv;
174 }
175
176 if (is(Token::Type::OpenParen)) {
177 return "("sv;
178 }
179
180 if (is(Token::Type::CloseParen)) {
181 return ")"sv;
182 }
183
184 return ""sv;
185}
186
187StringView Token::bracket_mirror_string() const
188{
189 if (is(Token::Type::OpenCurly)) {
190 return "}"sv;
191 }
192
193 if (is(Token::Type::CloseCurly)) {
194 return "{"sv;
195 }
196
197 if (is(Token::Type::OpenSquare)) {
198 return "]"sv;
199 }
200
201 if (is(Token::Type::CloseSquare)) {
202 return "["sv;
203 }
204
205 if (is(Token::Type::OpenParen)) {
206 return ")"sv;
207 }
208
209 if (is(Token::Type::CloseParen)) {
210 return "("sv;
211 }
212
213 return ""sv;
214}
215
216}