@tbela99/css-parser 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,11 @@
1
1
  import { isWhiteSpace, isNewLine, isDigit, isNonPrintable } from './utils/syntax.js';
2
+ import { EnumToken } from '../ast/types.js';
3
+ import '../ast/minify.js';
4
+ import './parse.js';
5
+ import '../renderer/utils/color.js';
6
+ import '../renderer/sourcemap/lib/encode.js';
2
7
 
3
- function* tokenize(iterator) {
8
+ function* tokenize(stream) {
4
9
  let ind = -1;
5
10
  let lin = 1;
6
11
  let col = 0;
@@ -13,14 +18,14 @@ function* tokenize(iterator) {
13
18
  let buffer = '';
14
19
  function consumeWhiteSpace() {
15
20
  let count = 0;
16
- while (isWhiteSpace(iterator.charAt(count + ind + 1).charCodeAt(0))) {
21
+ while (isWhiteSpace(stream.charAt(count + ind + 1).charCodeAt(0))) {
17
22
  count++;
18
23
  }
19
24
  next(count);
20
25
  return count;
21
26
  }
22
27
  function pushToken(token, hint) {
23
- const result = { token, hint, position: { ...position }, bytesIn: ind };
28
+ const result = { token, hint, position: { ...position }, bytesIn: ind + 1 };
24
29
  position.ind = ind;
25
30
  position.lin = lin;
26
31
  position.col = col == 0 ? 1 : col;
@@ -80,7 +85,7 @@ function* tokenize(iterator) {
80
85
  }
81
86
  if (value == quote) {
82
87
  buffer += value;
83
- yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'String');
88
+ yield pushToken(buffer, hasNewLine ? EnumToken.BadStringTokenType : EnumToken.StringTokenType);
84
89
  next();
85
90
  // i += value.length;
86
91
  buffer = '';
@@ -90,7 +95,7 @@ function* tokenize(iterator) {
90
95
  hasNewLine = true;
91
96
  }
92
97
  if (hasNewLine && value == ';') {
93
- yield pushToken(buffer + value, 'Bad-string');
98
+ yield pushToken(buffer + value, EnumToken.BadStringTokenType);
94
99
  buffer = '';
95
100
  next();
96
101
  break;
@@ -99,25 +104,25 @@ function* tokenize(iterator) {
99
104
  next();
100
105
  }
101
106
  if (hasNewLine) {
102
- yield pushToken(buffer, 'Bad-string');
107
+ yield pushToken(buffer, EnumToken.BadStringTokenType);
103
108
  }
104
109
  else {
105
110
  // EOF - 'Unclosed-string' fixed
106
- yield pushToken(buffer + quote, 'String');
111
+ yield pushToken(buffer + quote, EnumToken.StringTokenType);
107
112
  }
108
113
  buffer = '';
109
114
  }
110
115
  function peek(count = 1) {
111
116
  if (count == 1) {
112
- return iterator.charAt(ind + 1);
117
+ return stream.charAt(ind + 1);
113
118
  }
114
- return iterator.slice(ind + 1, ind + count + 1);
119
+ return stream.slice(ind + 1, ind + count + 1);
115
120
  }
116
121
  function prev(count = 1) {
117
122
  if (count == 1) {
118
- return ind == 0 ? '' : iterator.charAt(ind - 1);
123
+ return ind == 0 ? '' : stream.charAt(ind - 1);
119
124
  }
120
- return iterator.slice(ind - 1 - count, ind - 1);
125
+ return stream.slice(ind - 1 - count, ind - 1);
121
126
  }
122
127
  function next(count = 1) {
123
128
  let char = '';
@@ -125,9 +130,9 @@ function* tokenize(iterator) {
125
130
  if (count < 0) {
126
131
  return '';
127
132
  }
128
- while (count-- && (chr = iterator.charAt(ind + 1))) {
133
+ while (count-- && (chr = stream.charAt(ind + 1))) {
129
134
  char += chr;
130
- const codepoint = iterator.charCodeAt(++ind);
135
+ const codepoint = stream.charCodeAt(++ind);
131
136
  if (isNaN(codepoint)) {
132
137
  return char;
133
138
  }
@@ -152,7 +157,7 @@ function* tokenize(iterator) {
152
157
  break;
153
158
  }
154
159
  }
155
- yield pushToken('', 'Whitespace');
160
+ yield pushToken('', EnumToken.WhitespaceTokenType);
156
161
  buffer = '';
157
162
  }
158
163
  switch (value) {
@@ -172,7 +177,7 @@ function* tokenize(iterator) {
172
177
  if (value == '*') {
173
178
  buffer += value;
174
179
  if (peek() == '/') {
175
- yield pushToken(buffer + next(), 'Comment');
180
+ yield pushToken(buffer + next(), EnumToken.CommentTokenType);
176
181
  buffer = '';
177
182
  break;
178
183
  }
@@ -181,7 +186,7 @@ function* tokenize(iterator) {
181
186
  buffer += value;
182
187
  }
183
188
  }
184
- yield pushToken(buffer, 'Bad-comment');
189
+ yield pushToken(buffer, EnumToken.BadCommentTokenType);
185
190
  buffer = '';
186
191
  }
187
192
  break;
@@ -191,7 +196,7 @@ function* tokenize(iterator) {
191
196
  buffer = '';
192
197
  }
193
198
  if (peek() == '=') {
194
- yield pushToken('', 'Lte');
199
+ yield pushToken('', EnumToken.LteTokenType);
195
200
  next();
196
201
  break;
197
202
  }
@@ -205,10 +210,10 @@ function* tokenize(iterator) {
205
210
  }
206
211
  }
207
212
  if (value === '') {
208
- yield pushToken(buffer, 'Bad-cdo');
213
+ yield pushToken(buffer, EnumToken.BadCdoTokenType);
209
214
  }
210
215
  else {
211
- yield pushToken(buffer + next(2), 'CDOCOMM');
216
+ yield pushToken(buffer + next(2), EnumToken.CDOCOMMTokenType);
212
217
  }
213
218
  buffer = '';
214
219
  }
@@ -217,8 +222,10 @@ function* tokenize(iterator) {
217
222
  // EOF
218
223
  if (!(value = next())) {
219
224
  // end of stream ignore \\
220
- yield pushToken(buffer);
221
- buffer = '';
225
+ if (buffer.length > 0) {
226
+ yield pushToken(buffer);
227
+ buffer = '';
228
+ }
222
229
  break;
223
230
  }
224
231
  buffer += prev() + value;
@@ -227,29 +234,51 @@ function* tokenize(iterator) {
227
234
  case "'":
228
235
  yield* consumeString(value);
229
236
  break;
237
+ case '^':
230
238
  case '~':
231
239
  case '|':
240
+ case '$':
241
+ if (value == '|' && peek() == '|') {
242
+ next();
243
+ yield pushToken('', EnumToken.ColumnCombinatorTokenType);
244
+ buffer = '';
245
+ break;
246
+ }
232
247
  if (buffer.length > 0) {
233
248
  yield pushToken(buffer);
234
249
  buffer = '';
235
250
  }
236
251
  buffer += value;
237
- if (!(value = next())) {
252
+ if (!(value = peek())) {
238
253
  yield pushToken(buffer);
239
254
  buffer = '';
240
255
  break;
241
256
  }
242
- if (value == '=') {
243
- buffer += value;
244
- yield pushToken(buffer, buffer[0] == '~' ? 'Includes' : 'Dash-matches');
257
+ // ~=
258
+ // ^=
259
+ // $=
260
+ // |=
261
+ if (peek() == '=') {
262
+ next();
263
+ switch (buffer.charAt(0)) {
264
+ case '~':
265
+ yield pushToken(buffer, EnumToken.IncludeMatchTokenType);
266
+ break;
267
+ case '^':
268
+ yield pushToken(buffer, EnumToken.StartMatchTokenType);
269
+ break;
270
+ case '$':
271
+ yield pushToken(buffer, EnumToken.EndMatchTokenType);
272
+ break;
273
+ case '|':
274
+ yield pushToken(buffer, EnumToken.DashMatchTokenType);
275
+ break;
276
+ }
245
277
  buffer = '';
246
278
  break;
247
279
  }
248
280
  yield pushToken(buffer);
249
- while (isWhiteSpace(value.charCodeAt(0))) {
250
- value = next();
251
- }
252
- buffer = value;
281
+ buffer = '';
253
282
  break;
254
283
  case '>':
255
284
  if (buffer !== '') {
@@ -257,11 +286,11 @@ function* tokenize(iterator) {
257
286
  buffer = '';
258
287
  }
259
288
  if (peek() == '=') {
260
- yield pushToken('', 'Gte');
289
+ yield pushToken('', EnumToken.GteTokenType);
261
290
  next();
262
291
  }
263
292
  else {
264
- yield pushToken('', 'Gt');
293
+ yield pushToken('', EnumToken.GtTokenType);
265
294
  }
266
295
  consumeWhiteSpace();
267
296
  break;
@@ -275,6 +304,7 @@ function* tokenize(iterator) {
275
304
  buffer += value;
276
305
  break;
277
306
  case '+':
307
+ case '*':
278
308
  case ':':
279
309
  case ',':
280
310
  case '=':
@@ -282,13 +312,19 @@ function* tokenize(iterator) {
282
312
  yield pushToken(buffer);
283
313
  buffer = '';
284
314
  }
285
- if (value == ':' && ':' == peek()) {
315
+ const val = peek();
316
+ if (val == '=') {
317
+ next();
318
+ yield pushToken(value + val, EnumToken.ContainMatchTokenType);
319
+ break;
320
+ }
321
+ if (value == ':' && ':' == val) {
286
322
  buffer += value + next();
287
323
  break;
288
324
  }
289
325
  yield pushToken(value);
290
326
  buffer = '';
291
- if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
327
+ if (['+', '*', '/'].includes(value) && isWhiteSpace(peek().charCodeAt(0))) {
292
328
  yield pushToken(next());
293
329
  }
294
330
  while (isWhiteSpace(peek().charCodeAt(0))) {
@@ -300,7 +336,7 @@ function* tokenize(iterator) {
300
336
  yield pushToken(buffer);
301
337
  buffer = '';
302
338
  }
303
- yield pushToken('', 'End-parens');
339
+ yield pushToken('', EnumToken.EndParensTokenType);
304
340
  break;
305
341
  case '(':
306
342
  if (buffer.length == 0) {
@@ -338,7 +374,7 @@ function* tokenize(iterator) {
338
374
  }
339
375
  }
340
376
  if (value === '') {
341
- yield pushToken(buffer, 'Bad-string');
377
+ yield pushToken(buffer, EnumToken.BadUrlTokenType);
342
378
  buffer = '';
343
379
  break;
344
380
  }
@@ -365,7 +401,7 @@ function* tokenize(iterator) {
365
401
  break;
366
402
  }
367
403
  if (!(value = next())) {
368
- yield pushToken(buffer, hasNewLine ? 'Bad-url-token' : 'Url-token');
404
+ yield pushToken(buffer, hasNewLine ? EnumToken.BadUrlTokenType : EnumToken.UrlTokenTokenType);
369
405
  buffer = '';
370
406
  break;
371
407
  }
@@ -373,8 +409,8 @@ function* tokenize(iterator) {
373
409
  cp = value.charCodeAt(0);
374
410
  // ')'
375
411
  if (cp == 0x29) {
376
- yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'String');
377
- yield pushToken('', 'End-parens');
412
+ yield pushToken(buffer, hasNewLine ? EnumToken.BadStringTokenType : EnumToken.StringTokenType);
413
+ yield pushToken('', EnumToken.EndParensTokenType);
378
414
  buffer = '';
379
415
  break;
380
416
  }
@@ -385,15 +421,15 @@ function* tokenize(iterator) {
385
421
  continue;
386
422
  }
387
423
  if (cp == 0x29) {
388
- yield pushToken(buffer, 'Bad-string');
389
- yield pushToken('', 'End-parens');
424
+ yield pushToken(buffer, EnumToken.BadStringTokenType);
425
+ yield pushToken('', EnumToken.EndParensTokenType);
390
426
  buffer = '';
391
427
  break;
392
428
  }
393
429
  buffer += value;
394
430
  }
395
431
  if (hasNewLine) {
396
- yield pushToken(buffer, 'Bad-string');
432
+ yield pushToken(buffer, EnumToken.BadStringTokenType);
397
433
  buffer = '';
398
434
  }
399
435
  break;
@@ -408,8 +444,8 @@ function* tokenize(iterator) {
408
444
  cp = value.charCodeAt(0);
409
445
  // ')'
410
446
  if (cp == 0x29) {
411
- yield pushToken(buffer, 'Url-token');
412
- yield pushToken('', 'End-parens');
447
+ yield pushToken(buffer, EnumToken.UrlTokenTokenType);
448
+ yield pushToken('', EnumToken.EndParensTokenType);
413
449
  buffer = '';
414
450
  break;
415
451
  }
@@ -445,7 +481,7 @@ function* tokenize(iterator) {
445
481
  }
446
482
  buffer += next();
447
483
  }
448
- yield pushToken(buffer, 'Bad-url-token');
484
+ yield pushToken(buffer, EnumToken.BadUrlTokenType);
449
485
  buffer = '';
450
486
  break;
451
487
  }
@@ -453,7 +489,7 @@ function* tokenize(iterator) {
453
489
  }
454
490
  }
455
491
  if (buffer !== '') {
456
- yield pushToken(buffer, 'Url-token');
492
+ yield pushToken(buffer, EnumToken.UrlTokenTokenType);
457
493
  buffer = '';
458
494
  break;
459
495
  }
@@ -479,7 +515,7 @@ function* tokenize(iterator) {
479
515
  buffer = '';
480
516
  }
481
517
  if (peek(9) == 'important') {
482
- yield pushToken('', 'Important');
518
+ yield pushToken('', EnumToken.ImportantTokenType);
483
519
  next(9);
484
520
  buffer = '';
485
521
  break;
@@ -1,5 +1,8 @@
1
1
  import { colorsFunc } from '../../renderer/render.js';
2
2
  import { COLORS_NAMES } from '../../renderer/utils/color.js';
3
+ import { EnumToken } from '../../ast/types.js';
4
+ import '../../ast/minify.js';
5
+ import '../parse.js';
3
6
 
4
7
  // https://www.w3.org/TR/CSS21/syndata.html#syntax
5
8
  // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
@@ -27,17 +30,17 @@ function isFrequency(dimension) {
27
30
  return 'unit' in dimension && ['hz', 'khz'].includes(dimension.unit.toLowerCase());
28
31
  }
29
32
  function isColor(token) {
30
- if (token.typ == 'Color') {
33
+ if (token.typ == EnumToken.ColorTokenType) {
31
34
  return true;
32
35
  }
33
- if (token.typ == 'Iden') {
36
+ if (token.typ == EnumToken.IdenTokenType) {
34
37
  // named color
35
38
  return token.val.toLowerCase() in COLORS_NAMES;
36
39
  }
37
- if (token.typ == 'Func' && token.chi.length > 0 && colorsFunc.includes(token.val)) {
40
+ if (token.typ == EnumToken.FunctionTokenType && token.chi.length > 0 && colorsFunc.includes(token.val)) {
38
41
  // @ts-ignore
39
42
  for (const v of token.chi) {
40
- if (!['Number', 'Angle', 'Perc', 'Comma', 'Whitespace', 'Literal'].includes(v.typ)) {
43
+ if (![EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
41
44
  return false;
42
45
  }
43
46
  }
@@ -206,29 +209,29 @@ function parseDimension(name) {
206
209
  index++;
207
210
  break;
208
211
  }
209
- const dimension = { typ: 'Dimension', val: name.slice(0, index), unit: name.slice(index) };
212
+ const dimension = { typ: EnumToken.DimensionTokenType, val: name.slice(0, index), unit: name.slice(index) };
210
213
  if (isAngle(dimension)) {
211
214
  // @ts-ignore
212
- dimension.typ = 'Angle';
215
+ dimension.typ = EnumToken.AngleTokenType;
213
216
  }
214
217
  else if (isLength(dimension)) {
215
218
  // @ts-ignore
216
- dimension.typ = 'Length';
219
+ dimension.typ = EnumToken.LengthTokenType;
217
220
  }
218
221
  else if (isTime(dimension)) {
219
222
  // @ts-ignore
220
- dimension.typ = 'Time';
223
+ dimension.typ = EnumToken.TimeTokenType;
221
224
  }
222
225
  else if (isResolution(dimension)) {
223
226
  // @ts-ignore
224
- dimension.typ = 'Resolution';
227
+ dimension.typ = EnumToken.ResolutionTokenType;
225
228
  if (dimension.unit == 'dppx') {
226
229
  dimension.unit = 'x';
227
230
  }
228
231
  }
229
232
  else if (isFrequency(dimension)) {
230
233
  // @ts-ignore
231
- dimension.typ = 'Frequency';
234
+ dimension.typ = EnumToken.FrequencyTokenType;
232
235
  }
233
236
  return dimension;
234
237
  }
@@ -1,14 +1,31 @@
1
+ import { EnumToken } from '../../ast/types.js';
2
+ import '../../ast/minify.js';
3
+ import '../parse.js';
4
+ import '../../renderer/utils/color.js';
5
+ import '../../renderer/sourcemap/lib/encode.js';
6
+
7
+ // https://www.w3.org/TR/css-values-4/#math-function
1
8
  const funcList = ['clamp', 'calc'];
2
9
  function matchType(val, properties) {
3
- if (val.typ == 'Iden' && properties.keywords.includes(val.val) ||
4
- (properties.types.includes(val.typ))) {
10
+ if (val.typ == EnumToken.IdenTokenType && properties.keywords.includes(val.val) ||
11
+ // @ts-ignore
12
+ (properties.types.some((t) => EnumToken[t] == val.typ))) {
5
13
  return true;
6
14
  }
7
- if (val.typ == 'Number' && val.val == '0') {
8
- return properties.types.some(type => type == 'Length' || type == 'Angle');
15
+ if (val.typ == EnumToken.NumberTokenType && val.val == '0') {
16
+ // @ts-ignore
17
+ return properties.types.some((type) => {
18
+ // @ts-ignore
19
+ const typ = EnumToken[type];
20
+ return typ == EnumToken.LengthTokenType || typ == EnumToken.AngleTokenType;
21
+ });
9
22
  }
10
- if (val.typ == 'Func' && funcList.includes(val.val)) {
11
- return val.chi.every((t => ['Literal', 'Comma', 'Whitespace', 'Start-parens', 'End-parens'].includes(t.typ) || matchType(t, properties)));
23
+ if (val.typ == EnumToken.FunctionTokenType) {
24
+ if (funcList.includes(val.val)) {
25
+ return val.chi.every((t => [EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.StartParensTokenType, EnumToken.EndParensTokenType].includes(t.typ) || matchType(t, properties)));
26
+ }
27
+ // match type defined like function 'symbols()', 'url()', 'attr()' etc.
28
+ // return properties.types.includes((<FunctionToken>val).val + '()')
12
29
  }
13
30
  return false;
14
31
  }