source: frontend/node_modules/postcss/lib/tokenize.js

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

Fix frontend appearance

  • Property mode set to 100644
File size: 6.5 KB
Line 
1'use strict'
2
3const SINGLE_QUOTE = "'".charCodeAt(0)
4const DOUBLE_QUOTE = '"'.charCodeAt(0)
5const BACKSLASH = '\\'.charCodeAt(0)
6const SLASH = '/'.charCodeAt(0)
7const NEWLINE = '\n'.charCodeAt(0)
8const SPACE = ' '.charCodeAt(0)
9const FEED = '\f'.charCodeAt(0)
10const TAB = '\t'.charCodeAt(0)
11const CR = '\r'.charCodeAt(0)
12const OPEN_SQUARE = '['.charCodeAt(0)
13const CLOSE_SQUARE = ']'.charCodeAt(0)
14const OPEN_PARENTHESES = '('.charCodeAt(0)
15const CLOSE_PARENTHESES = ')'.charCodeAt(0)
16const OPEN_CURLY = '{'.charCodeAt(0)
17const CLOSE_CURLY = '}'.charCodeAt(0)
18const SEMICOLON = ';'.charCodeAt(0)
19const ASTERISK = '*'.charCodeAt(0)
20const COLON = ':'.charCodeAt(0)
21const AT = '@'.charCodeAt(0)
22
23const RE_AT_END = /[\t\n\f\r "#'()/;[\\\]{}]/g
24const RE_WORD_END = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g
25const RE_BAD_BRACKET = /.[\r\n"'(/\\]/
26const RE_HEX_ESCAPE = /[\da-f]/i
27
28module.exports = function tokenizer(input, options = {}) {
29 let css = input.css.valueOf()
30 let ignore = options.ignoreErrors
31
32 let code, content, escape, next, quote
33 let currentToken, escaped, escapePos, n, prev
34
35 let length = css.length
36 let pos = 0
37 let buffer = []
38 let returned = []
39 let lastBadParen = -1
40
41 function position() {
42 return pos
43 }
44
45 function unclosed(what) {
46 throw input.error('Unclosed ' + what, pos)
47 }
48
49 function endOfFile() {
50 return returned.length === 0 && pos >= length
51 }
52
53 function nextToken(opts) {
54 if (returned.length) return returned.pop()
55 if (pos >= length) return
56
57 let ignoreUnclosed = opts ? opts.ignoreUnclosed : false
58
59 code = css.charCodeAt(pos)
60
61 switch (code) {
62 case NEWLINE:
63 case SPACE:
64 case TAB:
65 case CR:
66 case FEED: {
67 next = pos
68 do {
69 next += 1
70 code = css.charCodeAt(next)
71 } while (
72 code === SPACE ||
73 code === NEWLINE ||
74 code === TAB ||
75 code === CR ||
76 code === FEED
77 )
78
79 currentToken = ['space', css.slice(pos, next)]
80 pos = next - 1
81 break
82 }
83
84 case OPEN_SQUARE:
85 case CLOSE_SQUARE:
86 case OPEN_CURLY:
87 case CLOSE_CURLY:
88 case COLON:
89 case SEMICOLON:
90 case CLOSE_PARENTHESES: {
91 let controlChar = String.fromCharCode(code)
92 currentToken = [controlChar, controlChar, pos]
93 break
94 }
95
96 case OPEN_PARENTHESES: {
97 prev = buffer.length ? buffer.pop()[1] : ''
98 n = css.charCodeAt(pos + 1)
99 if (
100 prev === 'url' &&
101 n !== SINGLE_QUOTE &&
102 n !== DOUBLE_QUOTE &&
103 n !== SPACE &&
104 n !== NEWLINE &&
105 n !== TAB &&
106 n !== FEED &&
107 n !== CR
108 ) {
109 next = pos
110 do {
111 escaped = false
112 next = css.indexOf(')', next + 1)
113 if (next === -1) {
114 if (ignore || ignoreUnclosed) {
115 next = pos
116 break
117 } else {
118 unclosed('bracket')
119 }
120 }
121 escapePos = next
122 while (css.charCodeAt(escapePos - 1) === BACKSLASH) {
123 escapePos -= 1
124 escaped = !escaped
125 }
126 } while (escaped)
127
128 currentToken = ['brackets', css.slice(pos, next + 1), pos, next]
129
130 pos = next
131 } else if (pos <= lastBadParen) {
132 currentToken = ['(', '(', pos]
133 } else {
134 next = css.indexOf(')', pos + 1)
135 content = css.slice(pos, next + 1)
136
137 if (next === -1 || RE_BAD_BRACKET.test(content)) {
138 lastBadParen = next === -1 ? length : next
139 currentToken = ['(', '(', pos]
140 } else {
141 currentToken = ['brackets', content, pos, next]
142 pos = next
143 }
144 }
145
146 break
147 }
148
149 case SINGLE_QUOTE:
150 case DOUBLE_QUOTE: {
151 quote = code === SINGLE_QUOTE ? "'" : '"'
152 next = pos
153 do {
154 escaped = false
155 next = css.indexOf(quote, next + 1)
156 if (next === -1) {
157 if (ignore || ignoreUnclosed) {
158 next = pos + 1
159 break
160 } else {
161 unclosed('string')
162 }
163 }
164 escapePos = next
165 while (css.charCodeAt(escapePos - 1) === BACKSLASH) {
166 escapePos -= 1
167 escaped = !escaped
168 }
169 } while (escaped)
170
171 currentToken = ['string', css.slice(pos, next + 1), pos, next]
172 pos = next
173 break
174 }
175
176 case AT: {
177 RE_AT_END.lastIndex = pos + 1
178 RE_AT_END.test(css)
179 if (RE_AT_END.lastIndex === 0) {
180 next = css.length - 1
181 } else {
182 next = RE_AT_END.lastIndex - 2
183 }
184
185 currentToken = ['at-word', css.slice(pos, next + 1), pos, next]
186
187 pos = next
188 break
189 }
190
191 case BACKSLASH: {
192 next = pos
193 escape = true
194 while (css.charCodeAt(next + 1) === BACKSLASH) {
195 next += 1
196 escape = !escape
197 }
198 code = css.charCodeAt(next + 1)
199 if (
200 escape &&
201 code !== SLASH &&
202 code !== SPACE &&
203 code !== NEWLINE &&
204 code !== TAB &&
205 code !== CR &&
206 code !== FEED
207 ) {
208 next += 1
209 if (RE_HEX_ESCAPE.test(css.charAt(next))) {
210 while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) {
211 next += 1
212 }
213 if (css.charCodeAt(next + 1) === SPACE) {
214 next += 1
215 }
216 }
217 }
218
219 currentToken = ['word', css.slice(pos, next + 1), pos, next]
220
221 pos = next
222 break
223 }
224
225 default: {
226 if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) {
227 next = css.indexOf('*/', pos + 2) + 1
228 if (next === 0) {
229 if (ignore || ignoreUnclosed) {
230 next = css.length
231 } else {
232 unclosed('comment')
233 }
234 }
235
236 currentToken = ['comment', css.slice(pos, next + 1), pos, next]
237 pos = next
238 } else {
239 RE_WORD_END.lastIndex = pos + 1
240 RE_WORD_END.test(css)
241 if (RE_WORD_END.lastIndex === 0) {
242 next = css.length - 1
243 } else {
244 next = RE_WORD_END.lastIndex - 2
245 }
246
247 currentToken = ['word', css.slice(pos, next + 1), pos, next]
248 buffer.push(currentToken)
249 pos = next
250 }
251
252 break
253 }
254 }
255
256 pos++
257 return currentToken
258 }
259
260 function back(token) {
261 returned.push(token)
262 }
263
264 return {
265 back,
266 endOfFile,
267 nextToken,
268 position
269 }
270}
Note: See TracBrowser for help on using the repository browser.