UNPKG

6.99 kBJavaScriptView Raw
1'use strict';
2
3exports.__esModule = true;
4exports.default = tokenize;
5var singleQuote = 39,
6 doubleQuote = 34,
7 backslash = 92,
8 slash = 47,
9 newline = 10,
10 space = 32,
11 feed = 12,
12 tab = 9,
13 cr = 13,
14 plus = 43,
15 gt = 62,
16 tilde = 126,
17 pipe = 124,
18 comma = 44,
19 openBracket = 40,
20 closeBracket = 41,
21 openSq = 91,
22 closeSq = 93,
23 semicolon = 59,
24 asterisk = 42,
25 colon = 58,
26 ampersand = 38,
27 at = 64,
28 atEnd = /[ \n\t\r\{\(\)'"\\;/]/g,
29 wordEnd = /[ \n\t\r\(\)\*:;@!&'"\+\|~>,\[\]\\]|\/(?=\*)/g;
30
31function tokenize(input) {
32 var tokens = [];
33 var css = input.css.valueOf();
34
35 var code = void 0,
36 next = void 0,
37 quote = void 0,
38 lines = void 0,
39 last = void 0,
40 content = void 0,
41 escape = void 0,
42 nextLine = void 0,
43 nextOffset = void 0,
44 escaped = void 0,
45 escapePos = void 0;
46
47 var length = css.length;
48 var offset = -1;
49 var line = 1;
50 var pos = 0;
51
52 var unclosed = function unclosed(what, end) {
53 if (input.safe) {
54 css += end;
55 next = css.length - 1;
56 } else {
57 throw input.error('Unclosed ' + what, line, pos - offset, pos);
58 }
59 };
60
61 while (pos < length) {
62 code = css.charCodeAt(pos);
63
64 if (code === newline) {
65 offset = pos;
66 line += 1;
67 }
68
69 switch (code) {
70 case newline:
71 case space:
72 case tab:
73 case cr:
74 case feed:
75 next = pos;
76 do {
77 next += 1;
78 code = css.charCodeAt(next);
79 if (code === newline) {
80 offset = next;
81 line += 1;
82 }
83 } while (code === space || code === newline || code === tab || code === cr || code === feed);
84
85 tokens.push(['space', css.slice(pos, next), line, pos - offset, pos]);
86 pos = next - 1;
87 break;
88
89 case plus:
90 case gt:
91 case tilde:
92 case pipe:
93 next = pos;
94 do {
95 next += 1;
96 code = css.charCodeAt(next);
97 } while (code === plus || code === gt || code === tilde || code === pipe);
98 tokens.push(['combinator', css.slice(pos, next), line, pos - offset, pos]);
99 pos = next - 1;
100 break;
101
102 case asterisk:
103 tokens.push(['*', '*', line, pos - offset, pos]);
104 break;
105
106 case ampersand:
107 tokens.push(['&', '&', line, pos - offset, pos]);
108 break;
109
110 case comma:
111 tokens.push([',', ',', line, pos - offset, pos]);
112 break;
113
114 case openSq:
115 tokens.push(['[', '[', line, pos - offset, pos]);
116 break;
117
118 case closeSq:
119 tokens.push([']', ']', line, pos - offset, pos]);
120 break;
121
122 case colon:
123 tokens.push([':', ':', line, pos - offset, pos]);
124 break;
125
126 case semicolon:
127 tokens.push([';', ';', line, pos - offset, pos]);
128 break;
129
130 case openBracket:
131 tokens.push(['(', '(', line, pos - offset, pos]);
132 break;
133
134 case closeBracket:
135 tokens.push([')', ')', line, pos - offset, pos]);
136 break;
137
138 case singleQuote:
139 case doubleQuote:
140 quote = code === singleQuote ? "'" : '"';
141 next = pos;
142 do {
143 escaped = false;
144 next = css.indexOf(quote, next + 1);
145 if (next === -1) {
146 unclosed('quote', quote);
147 }
148 escapePos = next;
149 while (css.charCodeAt(escapePos - 1) === backslash) {
150 escapePos -= 1;
151 escaped = !escaped;
152 }
153 } while (escaped);
154
155 tokens.push(['string', css.slice(pos, next + 1), line, pos - offset, line, next - offset, pos]);
156 pos = next;
157 break;
158
159 case at:
160 atEnd.lastIndex = pos + 1;
161 atEnd.test(css);
162 if (atEnd.lastIndex === 0) {
163 next = css.length - 1;
164 } else {
165 next = atEnd.lastIndex - 2;
166 }
167 tokens.push(['at-word', css.slice(pos, next + 1), line, pos - offset, line, next - offset, pos]);
168 pos = next;
169 break;
170
171 case backslash:
172 next = pos;
173 escape = true;
174 while (css.charCodeAt(next + 1) === backslash) {
175 next += 1;
176 escape = !escape;
177 }
178 code = css.charCodeAt(next + 1);
179 if (escape && code !== slash && code !== space && code !== newline && code !== tab && code !== cr && code !== feed) {
180 next += 1;
181 }
182 tokens.push(['word', css.slice(pos, next + 1), line, pos - offset, line, next - offset, pos]);
183 pos = next;
184 break;
185
186 default:
187 if (code === slash && css.charCodeAt(pos + 1) === asterisk) {
188 next = css.indexOf('*/', pos + 2) + 1;
189 if (next === 0) {
190 unclosed('comment', '*/');
191 }
192
193 content = css.slice(pos, next + 1);
194 lines = content.split('\n');
195 last = lines.length - 1;
196
197 if (last > 0) {
198 nextLine = line + last;
199 nextOffset = next - lines[last].length;
200 } else {
201 nextLine = line;
202 nextOffset = offset;
203 }
204
205 tokens.push(['comment', content, line, pos - offset, nextLine, next - nextOffset, pos]);
206
207 offset = nextOffset;
208 line = nextLine;
209 pos = next;
210 } else {
211 wordEnd.lastIndex = pos + 1;
212 wordEnd.test(css);
213 if (wordEnd.lastIndex === 0) {
214 next = css.length - 1;
215 } else {
216 next = wordEnd.lastIndex - 2;
217 }
218
219 tokens.push(['word', css.slice(pos, next + 1), line, pos - offset, line, next - offset, pos]);
220 pos = next;
221 }
222
223 break;
224 }
225
226 pos++;
227 }
228
229 return tokens;
230}
231module.exports = exports['default'];
\No newline at end of file