source: frontend/node_modules/tailwindcss/src/value-parser/parse.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 7.8 KB
Line 
1var openParentheses = '('.charCodeAt(0)
2var closeParentheses = ')'.charCodeAt(0)
3var singleQuote = "'".charCodeAt(0)
4var doubleQuote = '"'.charCodeAt(0)
5var backslash = '\\'.charCodeAt(0)
6var slash = '/'.charCodeAt(0)
7var comma = ','.charCodeAt(0)
8var colon = ':'.charCodeAt(0)
9var star = '*'.charCodeAt(0)
10var uLower = 'u'.charCodeAt(0)
11var uUpper = 'U'.charCodeAt(0)
12var plus = '+'.charCodeAt(0)
13var isUnicodeRange = /^[a-f0-9?-]+$/i
14
15module.exports = function (input) {
16 var tokens = []
17 var value = input
18
19 var next, quote, prev, token, escape, escapePos, whitespacePos, parenthesesOpenPos
20 var pos = 0
21 var code = value.charCodeAt(pos)
22 var max = value.length
23 var stack = [{ nodes: tokens }]
24 var balanced = 0
25 var parent
26
27 var name = ''
28 var before = ''
29 var after = ''
30
31 while (pos < max) {
32 // Whitespaces
33 if (code <= 32) {
34 next = pos
35 do {
36 next += 1
37 code = value.charCodeAt(next)
38 } while (code <= 32)
39 token = value.slice(pos, next)
40
41 prev = tokens[tokens.length - 1]
42 if (code === closeParentheses && balanced) {
43 after = token
44 } else if (prev && prev.type === 'div') {
45 prev.after = token
46 prev.sourceEndIndex += token.length
47 } else if (
48 code === comma ||
49 code === colon ||
50 (code === slash &&
51 value.charCodeAt(next + 1) !== star &&
52 (!parent || (parent && parent.type === 'function' && false)))
53 ) {
54 before = token
55 } else {
56 tokens.push({
57 type: 'space',
58 sourceIndex: pos,
59 sourceEndIndex: next,
60 value: token,
61 })
62 }
63
64 pos = next
65
66 // Quotes
67 } else if (code === singleQuote || code === doubleQuote) {
68 next = pos
69 quote = code === singleQuote ? "'" : '"'
70 token = {
71 type: 'string',
72 sourceIndex: pos,
73 quote: quote,
74 }
75 do {
76 escape = false
77 next = value.indexOf(quote, next + 1)
78 if (~next) {
79 escapePos = next
80 while (value.charCodeAt(escapePos - 1) === backslash) {
81 escapePos -= 1
82 escape = !escape
83 }
84 } else {
85 value += quote
86 next = value.length - 1
87 token.unclosed = true
88 }
89 } while (escape)
90 token.value = value.slice(pos + 1, next)
91 token.sourceEndIndex = token.unclosed ? next : next + 1
92 tokens.push(token)
93 pos = next + 1
94 code = value.charCodeAt(pos)
95
96 // Comments
97 } else if (code === slash && value.charCodeAt(pos + 1) === star) {
98 next = value.indexOf('*/', pos)
99
100 token = {
101 type: 'comment',
102 sourceIndex: pos,
103 sourceEndIndex: next + 2,
104 }
105
106 if (next === -1) {
107 token.unclosed = true
108 next = value.length
109 token.sourceEndIndex = next
110 }
111
112 token.value = value.slice(pos + 2, next)
113 tokens.push(token)
114
115 pos = next + 2
116 code = value.charCodeAt(pos)
117
118 // Operation within calc
119 } else if ((code === slash || code === star) && parent && parent.type === 'function' && true) {
120 token = value[pos]
121 tokens.push({
122 type: 'word',
123 sourceIndex: pos - before.length,
124 sourceEndIndex: pos + token.length,
125 value: token,
126 })
127 pos += 1
128 code = value.charCodeAt(pos)
129
130 // Dividers
131 } else if (code === slash || code === comma || code === colon) {
132 token = value[pos]
133
134 tokens.push({
135 type: 'div',
136 sourceIndex: pos - before.length,
137 sourceEndIndex: pos + token.length,
138 value: token,
139 before: before,
140 after: '',
141 })
142 before = ''
143
144 pos += 1
145 code = value.charCodeAt(pos)
146
147 // Open parentheses
148 } else if (openParentheses === code) {
149 // Whitespaces after open parentheses
150 next = pos
151 do {
152 next += 1
153 code = value.charCodeAt(next)
154 } while (code <= 32)
155 parenthesesOpenPos = pos
156 token = {
157 type: 'function',
158 sourceIndex: pos - name.length,
159 value: name,
160 before: value.slice(parenthesesOpenPos + 1, next),
161 }
162 pos = next
163
164 if (name === 'url' && code !== singleQuote && code !== doubleQuote) {
165 next -= 1
166 do {
167 escape = false
168 next = value.indexOf(')', next + 1)
169 if (~next) {
170 escapePos = next
171 while (value.charCodeAt(escapePos - 1) === backslash) {
172 escapePos -= 1
173 escape = !escape
174 }
175 } else {
176 value += ')'
177 next = value.length - 1
178 token.unclosed = true
179 }
180 } while (escape)
181 // Whitespaces before closed
182 whitespacePos = next
183 do {
184 whitespacePos -= 1
185 code = value.charCodeAt(whitespacePos)
186 } while (code <= 32)
187 if (parenthesesOpenPos < whitespacePos) {
188 if (pos !== whitespacePos + 1) {
189 token.nodes = [
190 {
191 type: 'word',
192 sourceIndex: pos,
193 sourceEndIndex: whitespacePos + 1,
194 value: value.slice(pos, whitespacePos + 1),
195 },
196 ]
197 } else {
198 token.nodes = []
199 }
200 if (token.unclosed && whitespacePos + 1 !== next) {
201 token.after = ''
202 token.nodes.push({
203 type: 'space',
204 sourceIndex: whitespacePos + 1,
205 sourceEndIndex: next,
206 value: value.slice(whitespacePos + 1, next),
207 })
208 } else {
209 token.after = value.slice(whitespacePos + 1, next)
210 token.sourceEndIndex = next
211 }
212 } else {
213 token.after = ''
214 token.nodes = []
215 }
216 pos = next + 1
217 token.sourceEndIndex = token.unclosed ? next : pos
218 code = value.charCodeAt(pos)
219 tokens.push(token)
220 } else {
221 balanced += 1
222 token.after = ''
223 token.sourceEndIndex = pos + 1
224 tokens.push(token)
225 stack.push(token)
226 tokens = token.nodes = []
227 parent = token
228 }
229 name = ''
230
231 // Close parentheses
232 } else if (closeParentheses === code && balanced) {
233 pos += 1
234 code = value.charCodeAt(pos)
235
236 parent.after = after
237 parent.sourceEndIndex += after.length
238 after = ''
239 balanced -= 1
240 stack[stack.length - 1].sourceEndIndex = pos
241 stack.pop()
242 parent = stack[balanced]
243 tokens = parent.nodes
244
245 // Words
246 } else {
247 next = pos
248 do {
249 if (code === backslash) {
250 next += 1
251 }
252 next += 1
253 code = value.charCodeAt(next)
254 } while (
255 next < max &&
256 !(
257 code <= 32 ||
258 code === singleQuote ||
259 code === doubleQuote ||
260 code === comma ||
261 code === colon ||
262 code === slash ||
263 code === openParentheses ||
264 (code === star && parent && parent.type === 'function' && true) ||
265 (code === slash && parent.type === 'function' && true) ||
266 (code === closeParentheses && balanced)
267 )
268 )
269 token = value.slice(pos, next)
270
271 if (openParentheses === code) {
272 name = token
273 } else if (
274 (uLower === token.charCodeAt(0) || uUpper === token.charCodeAt(0)) &&
275 plus === token.charCodeAt(1) &&
276 isUnicodeRange.test(token.slice(2))
277 ) {
278 tokens.push({
279 type: 'unicode-range',
280 sourceIndex: pos,
281 sourceEndIndex: next,
282 value: token,
283 })
284 } else {
285 tokens.push({
286 type: 'word',
287 sourceIndex: pos,
288 sourceEndIndex: next,
289 value: token,
290 })
291 }
292
293 pos = next
294 }
295 }
296
297 for (pos = stack.length - 1; pos; pos -= 1) {
298 stack[pos].unclosed = true
299 stack[pos].sourceEndIndex = value.length
300 }
301
302 return stack[0].nodes
303}
Note: See TracBrowser for help on using the repository browser.