@xylentis/testgen 0.0.0-stage → 1.1.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.
@@ -0,0 +1,950 @@
1
+ /* eslint-disable notice/notice */
2
+ const between = function (num, first, last) { return num >= first && num <= last; };
3
+ function digit(code) { return between(code, 0x30, 0x39); }
4
+ function hexdigit(code) { return digit(code) || between(code, 0x41, 0x46) || between(code, 0x61, 0x66); }
5
+ function uppercaseletter(code) { return between(code, 0x41, 0x5a); }
6
+ function lowercaseletter(code) { return between(code, 0x61, 0x7a); }
7
+ function letter(code) { return uppercaseletter(code) || lowercaseletter(code); }
8
+ function nonascii(code) { return code >= 0x80; }
9
+ function namestartchar(code) { return letter(code) || nonascii(code) || code === 0x5f; }
10
+ function namechar(code) { return namestartchar(code) || digit(code) || code === 0x2d; }
11
+ function nonprintable(code) { return between(code, 0, 8) || code === 0xb || between(code, 0xe, 0x1f) || code === 0x7f; }
12
+ function newline(code) { return code === 0xa; }
13
+ function whitespace(code) { return newline(code) || code === 9 || code === 0x20; }
14
+ const maximumallowedcodepoint = 0x10ffff;
15
+ export class InvalidCharacterError extends Error {
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = 'InvalidCharacterError';
19
+ }
20
+ }
21
+ function preprocess(str) {
22
+ // Turn a string into an array of code points,
23
+ // following the preprocessing cleanup rules.
24
+ const codepoints = [];
25
+ for (let i = 0; i < str.length; i++) {
26
+ let code = str.charCodeAt(i);
27
+ if (code === 0xd && str.charCodeAt(i + 1) === 0xa) {
28
+ code = 0xa;
29
+ i++;
30
+ }
31
+ if (code === 0xd || code === 0xc)
32
+ code = 0xa;
33
+ if (code === 0x0)
34
+ code = 0xfffd;
35
+ if (between(code, 0xd800, 0xdbff) && between(str.charCodeAt(i + 1), 0xdc00, 0xdfff)) {
36
+ // Decode a surrogate pair into an astral codepoint.
37
+ const lead = code - 0xd800;
38
+ const trail = str.charCodeAt(i + 1) - 0xdc00;
39
+ code = Math.pow(2, 16) + lead * Math.pow(2, 10) + trail;
40
+ i++;
41
+ }
42
+ codepoints.push(code);
43
+ }
44
+ return codepoints;
45
+ }
46
+ function stringFromCode(code) {
47
+ if (code <= 0xffff)
48
+ return String.fromCharCode(code);
49
+ // Otherwise, encode astral char as surrogate pair.
50
+ code -= Math.pow(2, 16);
51
+ const lead = Math.floor(code / Math.pow(2, 10)) + 0xd800;
52
+ const trail = code % Math.pow(2, 10) + 0xdc00;
53
+ return String.fromCharCode(lead) + String.fromCharCode(trail);
54
+ }
55
+ export function tokenize(str1) {
56
+ const str = preprocess(str1);
57
+ let i = -1;
58
+ const tokens = [];
59
+ let code;
60
+ // Line number information.
61
+ let line = 0;
62
+ let column = 0;
63
+ // The only use of lastLineLength is in reconsume().
64
+ let lastLineLength = 0;
65
+ const incrLineno = function () {
66
+ line += 1;
67
+ lastLineLength = column;
68
+ column = 0;
69
+ };
70
+ const locStart = { line: line, column: column };
71
+ const codepoint = function (i) {
72
+ if (i >= str.length)
73
+ return -1;
74
+ return str[i];
75
+ };
76
+ const next = function (num) {
77
+ if (num === undefined)
78
+ num = 1;
79
+ if (num > 3)
80
+ throw 'Spec Error: no more than three codepoints of lookahead.';
81
+ return codepoint(i + num);
82
+ };
83
+ const consume = function (num) {
84
+ if (num === undefined)
85
+ num = 1;
86
+ i += num;
87
+ code = codepoint(i);
88
+ if (newline(code))
89
+ incrLineno();
90
+ else
91
+ column += num;
92
+ // console.log('Consume '+i+' '+String.fromCharCode(code) + ' 0x' + code.toString(16));
93
+ return true;
94
+ };
95
+ const reconsume = function () {
96
+ i -= 1;
97
+ if (newline(code)) {
98
+ line -= 1;
99
+ column = lastLineLength;
100
+ }
101
+ else {
102
+ column -= 1;
103
+ }
104
+ locStart.line = line;
105
+ locStart.column = column;
106
+ return true;
107
+ };
108
+ const eof = function (codepoint) {
109
+ if (codepoint === undefined)
110
+ codepoint = code;
111
+ return codepoint === -1;
112
+ };
113
+ const donothing = function () { };
114
+ const parseerror = function () {
115
+ // Language bindings don't like writing to stdout!
116
+ // console.log('Parse error at index ' + i + ', processing codepoint 0x' + code.toString(16) + '.'); return true;
117
+ };
118
+ const consumeAToken = function () {
119
+ consumeComments();
120
+ consume();
121
+ if (whitespace(code)) {
122
+ while (whitespace(next()))
123
+ consume();
124
+ return new WhitespaceToken();
125
+ }
126
+ else if (code === 0x22) {
127
+ return consumeAStringToken();
128
+ }
129
+ else if (code === 0x23) {
130
+ if (namechar(next()) || areAValidEscape(next(1), next(2))) {
131
+ const token = new HashToken('');
132
+ if (wouldStartAnIdentifier(next(1), next(2), next(3)))
133
+ token.type = 'id';
134
+ token.value = consumeAName();
135
+ return token;
136
+ }
137
+ else {
138
+ return new DelimToken(code);
139
+ }
140
+ }
141
+ else if (code === 0x24) {
142
+ if (next() === 0x3d) {
143
+ consume();
144
+ return new SuffixMatchToken();
145
+ }
146
+ else {
147
+ return new DelimToken(code);
148
+ }
149
+ }
150
+ else if (code === 0x27) {
151
+ return consumeAStringToken();
152
+ }
153
+ else if (code === 0x28) {
154
+ return new OpenParenToken();
155
+ }
156
+ else if (code === 0x29) {
157
+ return new CloseParenToken();
158
+ }
159
+ else if (code === 0x2a) {
160
+ if (next() === 0x3d) {
161
+ consume();
162
+ return new SubstringMatchToken();
163
+ }
164
+ else {
165
+ return new DelimToken(code);
166
+ }
167
+ }
168
+ else if (code === 0x2b) {
169
+ if (startsWithANumber()) {
170
+ reconsume();
171
+ return consumeANumericToken();
172
+ }
173
+ else {
174
+ return new DelimToken(code);
175
+ }
176
+ }
177
+ else if (code === 0x2c) {
178
+ return new CommaToken();
179
+ }
180
+ else if (code === 0x2d) {
181
+ if (startsWithANumber()) {
182
+ reconsume();
183
+ return consumeANumericToken();
184
+ }
185
+ else if (next(1) === 0x2d && next(2) === 0x3e) {
186
+ consume(2);
187
+ return new CDCToken();
188
+ }
189
+ else if (startsWithAnIdentifier()) {
190
+ reconsume();
191
+ return consumeAnIdentlikeToken();
192
+ }
193
+ else {
194
+ return new DelimToken(code);
195
+ }
196
+ }
197
+ else if (code === 0x2e) {
198
+ if (startsWithANumber()) {
199
+ reconsume();
200
+ return consumeANumericToken();
201
+ }
202
+ else {
203
+ return new DelimToken(code);
204
+ }
205
+ }
206
+ else if (code === 0x3a) {
207
+ return new ColonToken();
208
+ }
209
+ else if (code === 0x3b) {
210
+ return new SemicolonToken();
211
+ }
212
+ else if (code === 0x3c) {
213
+ if (next(1) === 0x21 && next(2) === 0x2d && next(3) === 0x2d) {
214
+ consume(3);
215
+ return new CDOToken();
216
+ }
217
+ else {
218
+ return new DelimToken(code);
219
+ }
220
+ }
221
+ else if (code === 0x40) {
222
+ if (wouldStartAnIdentifier(next(1), next(2), next(3)))
223
+ return new AtKeywordToken(consumeAName());
224
+ else
225
+ return new DelimToken(code);
226
+ }
227
+ else if (code === 0x5b) {
228
+ return new OpenSquareToken();
229
+ }
230
+ else if (code === 0x5c) {
231
+ if (startsWithAValidEscape()) {
232
+ reconsume();
233
+ return consumeAnIdentlikeToken();
234
+ }
235
+ else {
236
+ parseerror();
237
+ return new DelimToken(code);
238
+ }
239
+ }
240
+ else if (code === 0x5d) {
241
+ return new CloseSquareToken();
242
+ }
243
+ else if (code === 0x5e) {
244
+ if (next() === 0x3d) {
245
+ consume();
246
+ return new PrefixMatchToken();
247
+ }
248
+ else {
249
+ return new DelimToken(code);
250
+ }
251
+ }
252
+ else if (code === 0x7b) {
253
+ return new OpenCurlyToken();
254
+ }
255
+ else if (code === 0x7c) {
256
+ if (next() === 0x3d) {
257
+ consume();
258
+ return new DashMatchToken();
259
+ }
260
+ else if (next() === 0x7c) {
261
+ consume();
262
+ return new ColumnToken();
263
+ }
264
+ else {
265
+ return new DelimToken(code);
266
+ }
267
+ }
268
+ else if (code === 0x7d) {
269
+ return new CloseCurlyToken();
270
+ }
271
+ else if (code === 0x7e) {
272
+ if (next() === 0x3d) {
273
+ consume();
274
+ return new IncludeMatchToken();
275
+ }
276
+ else {
277
+ return new DelimToken(code);
278
+ }
279
+ }
280
+ else if (digit(code)) {
281
+ reconsume();
282
+ return consumeANumericToken();
283
+ }
284
+ else if (namestartchar(code)) {
285
+ reconsume();
286
+ return consumeAnIdentlikeToken();
287
+ }
288
+ else if (eof()) {
289
+ return new EOFToken();
290
+ }
291
+ else {
292
+ return new DelimToken(code);
293
+ }
294
+ };
295
+ const consumeComments = function () {
296
+ while (next(1) === 0x2f && next(2) === 0x2a) {
297
+ consume(2);
298
+ while (true) {
299
+ consume();
300
+ if (code === 0x2a && next() === 0x2f) {
301
+ consume();
302
+ break;
303
+ }
304
+ else if (eof()) {
305
+ parseerror();
306
+ return;
307
+ }
308
+ }
309
+ }
310
+ };
311
+ const consumeANumericToken = function () {
312
+ const num = consumeANumber();
313
+ if (wouldStartAnIdentifier(next(1), next(2), next(3))) {
314
+ const token = new DimensionToken();
315
+ token.value = num.value;
316
+ token.repr = num.repr;
317
+ token.type = num.type;
318
+ token.unit = consumeAName();
319
+ return token;
320
+ }
321
+ else if (next() === 0x25) {
322
+ consume();
323
+ const token = new PercentageToken();
324
+ token.value = num.value;
325
+ token.repr = num.repr;
326
+ return token;
327
+ }
328
+ else {
329
+ const token = new NumberToken();
330
+ token.value = num.value;
331
+ token.repr = num.repr;
332
+ token.type = num.type;
333
+ return token;
334
+ }
335
+ };
336
+ const consumeAnIdentlikeToken = function () {
337
+ const str = consumeAName();
338
+ if (str.toLowerCase() === 'url' && next() === 0x28) {
339
+ consume();
340
+ while (whitespace(next(1)) && whitespace(next(2)))
341
+ consume();
342
+ if (next() === 0x22 || next() === 0x27)
343
+ return new FunctionToken(str);
344
+ else if (whitespace(next()) && (next(2) === 0x22 || next(2) === 0x27))
345
+ return new FunctionToken(str);
346
+ else
347
+ return consumeAURLToken();
348
+ }
349
+ else if (next() === 0x28) {
350
+ consume();
351
+ return new FunctionToken(str);
352
+ }
353
+ else {
354
+ return new IdentToken(str);
355
+ }
356
+ };
357
+ const consumeAStringToken = function (endingCodePoint) {
358
+ if (endingCodePoint === undefined)
359
+ endingCodePoint = code;
360
+ let string = '';
361
+ while (consume()) {
362
+ if (code === endingCodePoint || eof()) {
363
+ return new StringToken(string);
364
+ }
365
+ else if (newline(code)) {
366
+ parseerror();
367
+ reconsume();
368
+ return new BadStringToken();
369
+ }
370
+ else if (code === 0x5c) {
371
+ if (eof(next()))
372
+ donothing();
373
+ else if (newline(next()))
374
+ consume();
375
+ else
376
+ string += stringFromCode(consumeEscape());
377
+ }
378
+ else {
379
+ string += stringFromCode(code);
380
+ }
381
+ }
382
+ throw new Error('Internal error');
383
+ };
384
+ const consumeAURLToken = function () {
385
+ const token = new URLToken('');
386
+ while (whitespace(next()))
387
+ consume();
388
+ if (eof(next()))
389
+ return token;
390
+ while (consume()) {
391
+ if (code === 0x29 || eof()) {
392
+ return token;
393
+ }
394
+ else if (whitespace(code)) {
395
+ while (whitespace(next()))
396
+ consume();
397
+ if (next() === 0x29 || eof(next())) {
398
+ consume();
399
+ return token;
400
+ }
401
+ else {
402
+ consumeTheRemnantsOfABadURL();
403
+ return new BadURLToken();
404
+ }
405
+ }
406
+ else if (code === 0x22 || code === 0x27 || code === 0x28 || nonprintable(code)) {
407
+ parseerror();
408
+ consumeTheRemnantsOfABadURL();
409
+ return new BadURLToken();
410
+ }
411
+ else if (code === 0x5c) {
412
+ if (startsWithAValidEscape()) {
413
+ token.value += stringFromCode(consumeEscape());
414
+ }
415
+ else {
416
+ parseerror();
417
+ consumeTheRemnantsOfABadURL();
418
+ return new BadURLToken();
419
+ }
420
+ }
421
+ else {
422
+ token.value += stringFromCode(code);
423
+ }
424
+ }
425
+ throw new Error('Internal error');
426
+ };
427
+ const consumeEscape = function () {
428
+ // Assume the current character is the \
429
+ // and the next code point is not a newline.
430
+ consume();
431
+ if (hexdigit(code)) {
432
+ // Consume 1-6 hex digits
433
+ const digits = [code];
434
+ for (let total = 0; total < 5; total++) {
435
+ if (hexdigit(next())) {
436
+ consume();
437
+ digits.push(code);
438
+ }
439
+ else {
440
+ break;
441
+ }
442
+ }
443
+ if (whitespace(next()))
444
+ consume();
445
+ let value = parseInt(digits.map(function (x) { return String.fromCharCode(x); }).join(''), 16);
446
+ if (value > maximumallowedcodepoint)
447
+ value = 0xfffd;
448
+ return value;
449
+ }
450
+ else if (eof()) {
451
+ return 0xfffd;
452
+ }
453
+ else {
454
+ return code;
455
+ }
456
+ };
457
+ const areAValidEscape = function (c1, c2) {
458
+ if (c1 !== 0x5c)
459
+ return false;
460
+ if (newline(c2))
461
+ return false;
462
+ return true;
463
+ };
464
+ const startsWithAValidEscape = function () {
465
+ return areAValidEscape(code, next());
466
+ };
467
+ const wouldStartAnIdentifier = function (c1, c2, c3) {
468
+ if (c1 === 0x2d)
469
+ return namestartchar(c2) || c2 === 0x2d || areAValidEscape(c2, c3);
470
+ else if (namestartchar(c1))
471
+ return true;
472
+ else if (c1 === 0x5c)
473
+ return areAValidEscape(c1, c2);
474
+ else
475
+ return false;
476
+ };
477
+ const startsWithAnIdentifier = function () {
478
+ return wouldStartAnIdentifier(code, next(1), next(2));
479
+ };
480
+ const wouldStartANumber = function (c1, c2, c3) {
481
+ if (c1 === 0x2b || c1 === 0x2d) {
482
+ if (digit(c2))
483
+ return true;
484
+ if (c2 === 0x2e && digit(c3))
485
+ return true;
486
+ return false;
487
+ }
488
+ else if (c1 === 0x2e) {
489
+ if (digit(c2))
490
+ return true;
491
+ return false;
492
+ }
493
+ else if (digit(c1)) {
494
+ return true;
495
+ }
496
+ else {
497
+ return false;
498
+ }
499
+ };
500
+ const startsWithANumber = function () {
501
+ return wouldStartANumber(code, next(1), next(2));
502
+ };
503
+ const consumeAName = function () {
504
+ let result = '';
505
+ while (consume()) {
506
+ if (namechar(code)) {
507
+ result += stringFromCode(code);
508
+ }
509
+ else if (startsWithAValidEscape()) {
510
+ result += stringFromCode(consumeEscape());
511
+ }
512
+ else {
513
+ reconsume();
514
+ return result;
515
+ }
516
+ }
517
+ throw new Error('Internal parse error');
518
+ };
519
+ const consumeANumber = function () {
520
+ let repr = '';
521
+ let type = 'integer';
522
+ if (next() === 0x2b || next() === 0x2d) {
523
+ consume();
524
+ repr += stringFromCode(code);
525
+ }
526
+ while (digit(next())) {
527
+ consume();
528
+ repr += stringFromCode(code);
529
+ }
530
+ if (next(1) === 0x2e && digit(next(2))) {
531
+ consume();
532
+ repr += stringFromCode(code);
533
+ consume();
534
+ repr += stringFromCode(code);
535
+ type = 'number';
536
+ while (digit(next())) {
537
+ consume();
538
+ repr += stringFromCode(code);
539
+ }
540
+ }
541
+ const c1 = next(1);
542
+ const c2 = next(2);
543
+ const c3 = next(3);
544
+ if ((c1 === 0x45 || c1 === 0x65) && digit(c2)) {
545
+ consume();
546
+ repr += stringFromCode(code);
547
+ consume();
548
+ repr += stringFromCode(code);
549
+ type = 'number';
550
+ while (digit(next())) {
551
+ consume();
552
+ repr += stringFromCode(code);
553
+ }
554
+ }
555
+ else if ((c1 === 0x45 || c1 === 0x65) && (c2 === 0x2b || c2 === 0x2d) && digit(c3)) {
556
+ consume();
557
+ repr += stringFromCode(code);
558
+ consume();
559
+ repr += stringFromCode(code);
560
+ consume();
561
+ repr += stringFromCode(code);
562
+ type = 'number';
563
+ while (digit(next())) {
564
+ consume();
565
+ repr += stringFromCode(code);
566
+ }
567
+ }
568
+ const value = convertAStringToANumber(repr);
569
+ return { type: type, value: value, repr: repr };
570
+ };
571
+ const convertAStringToANumber = function (string) {
572
+ // CSS's number rules are identical to JS, afaik.
573
+ return +string;
574
+ };
575
+ const consumeTheRemnantsOfABadURL = function () {
576
+ while (consume()) {
577
+ if (code === 0x29 || eof()) {
578
+ return;
579
+ }
580
+ else if (startsWithAValidEscape()) {
581
+ consumeEscape();
582
+ donothing();
583
+ }
584
+ else {
585
+ donothing();
586
+ }
587
+ }
588
+ };
589
+ let iterationCount = 0;
590
+ while (!eof(next())) {
591
+ tokens.push(consumeAToken());
592
+ iterationCount++;
593
+ if (iterationCount > str.length * 2)
594
+ throw new Error("I'm infinite-looping!");
595
+ }
596
+ return tokens;
597
+ }
598
+ export class CSSParserToken {
599
+ tokenType = '';
600
+ value;
601
+ toJSON() {
602
+ return { token: this.tokenType };
603
+ }
604
+ toString() { return this.tokenType; }
605
+ toSource() { return '' + this; }
606
+ }
607
+ export class BadStringToken extends CSSParserToken {
608
+ tokenType = 'BADSTRING';
609
+ }
610
+ export class BadURLToken extends CSSParserToken {
611
+ tokenType = 'BADURL';
612
+ }
613
+ export class WhitespaceToken extends CSSParserToken {
614
+ tokenType = 'WHITESPACE';
615
+ toString() { return 'WS'; }
616
+ toSource() { return ' '; }
617
+ }
618
+ export class CDOToken extends CSSParserToken {
619
+ tokenType = 'CDO';
620
+ toSource() { return '<!--'; }
621
+ }
622
+ export class CDCToken extends CSSParserToken {
623
+ tokenType = 'CDC';
624
+ toSource() { return '-->'; }
625
+ }
626
+ export class ColonToken extends CSSParserToken {
627
+ tokenType = ':';
628
+ }
629
+ export class SemicolonToken extends CSSParserToken {
630
+ tokenType = ';';
631
+ }
632
+ export class CommaToken extends CSSParserToken {
633
+ tokenType = ',';
634
+ }
635
+ export class GroupingToken extends CSSParserToken {
636
+ value = '';
637
+ mirror = '';
638
+ }
639
+ export class OpenCurlyToken extends GroupingToken {
640
+ tokenType = '{';
641
+ constructor() {
642
+ super();
643
+ this.value = '{';
644
+ this.mirror = '}';
645
+ }
646
+ }
647
+ export class CloseCurlyToken extends GroupingToken {
648
+ tokenType = '}';
649
+ constructor() {
650
+ super();
651
+ this.value = '}';
652
+ this.mirror = '{';
653
+ }
654
+ }
655
+ export class OpenSquareToken extends GroupingToken {
656
+ tokenType = '[';
657
+ constructor() {
658
+ super();
659
+ this.value = '[';
660
+ this.mirror = ']';
661
+ }
662
+ }
663
+ export class CloseSquareToken extends GroupingToken {
664
+ tokenType = ']';
665
+ constructor() {
666
+ super();
667
+ this.value = ']';
668
+ this.mirror = '[';
669
+ }
670
+ }
671
+ export class OpenParenToken extends GroupingToken {
672
+ tokenType = '(';
673
+ constructor() {
674
+ super();
675
+ this.value = '(';
676
+ this.mirror = ')';
677
+ }
678
+ }
679
+ export class CloseParenToken extends GroupingToken {
680
+ tokenType = ')';
681
+ constructor() {
682
+ super();
683
+ this.value = ')';
684
+ this.mirror = '(';
685
+ }
686
+ }
687
+ export class IncludeMatchToken extends CSSParserToken {
688
+ tokenType = '~=';
689
+ }
690
+ export class DashMatchToken extends CSSParserToken {
691
+ tokenType = '|=';
692
+ }
693
+ export class PrefixMatchToken extends CSSParserToken {
694
+ tokenType = '^=';
695
+ }
696
+ export class SuffixMatchToken extends CSSParserToken {
697
+ tokenType = '$=';
698
+ }
699
+ export class SubstringMatchToken extends CSSParserToken {
700
+ tokenType = '*=';
701
+ }
702
+ export class ColumnToken extends CSSParserToken {
703
+ tokenType = '||';
704
+ }
705
+ export class EOFToken extends CSSParserToken {
706
+ tokenType = 'EOF';
707
+ toSource() { return ''; }
708
+ }
709
+ export class DelimToken extends CSSParserToken {
710
+ tokenType = 'DELIM';
711
+ value = '';
712
+ constructor(code) {
713
+ super();
714
+ this.value = stringFromCode(code);
715
+ }
716
+ toString() { return 'DELIM(' + this.value + ')'; }
717
+ toJSON() {
718
+ const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
719
+ json.value = this.value;
720
+ return json;
721
+ }
722
+ toSource() {
723
+ if (this.value === '\\')
724
+ return '\\\n';
725
+ else
726
+ return this.value;
727
+ }
728
+ }
729
+ export class StringValuedToken extends CSSParserToken {
730
+ value = '';
731
+ ASCIIMatch(str) {
732
+ return this.value.toLowerCase() === str.toLowerCase();
733
+ }
734
+ toJSON() {
735
+ const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
736
+ json.value = this.value;
737
+ return json;
738
+ }
739
+ }
740
+ export class IdentToken extends StringValuedToken {
741
+ constructor(val) {
742
+ super();
743
+ this.value = val;
744
+ }
745
+ tokenType = 'IDENT';
746
+ toString() { return 'IDENT(' + this.value + ')'; }
747
+ toSource() {
748
+ return escapeIdent(this.value);
749
+ }
750
+ }
751
+ export class FunctionToken extends StringValuedToken {
752
+ tokenType = 'FUNCTION';
753
+ mirror;
754
+ constructor(val) {
755
+ super();
756
+ this.value = val;
757
+ this.mirror = ')';
758
+ }
759
+ toString() { return 'FUNCTION(' + this.value + ')'; }
760
+ toSource() {
761
+ return escapeIdent(this.value) + '(';
762
+ }
763
+ }
764
+ export class AtKeywordToken extends StringValuedToken {
765
+ tokenType = 'AT-KEYWORD';
766
+ constructor(val) {
767
+ super();
768
+ this.value = val;
769
+ }
770
+ toString() { return 'AT(' + this.value + ')'; }
771
+ toSource() {
772
+ return '@' + escapeIdent(this.value);
773
+ }
774
+ }
775
+ export class HashToken extends StringValuedToken {
776
+ tokenType = 'HASH';
777
+ type;
778
+ constructor(val) {
779
+ super();
780
+ this.value = val;
781
+ this.type = 'unrestricted';
782
+ }
783
+ toString() { return 'HASH(' + this.value + ')'; }
784
+ toJSON() {
785
+ const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
786
+ json.value = this.value;
787
+ json.type = this.type;
788
+ return json;
789
+ }
790
+ toSource() {
791
+ if (this.type === 'id')
792
+ return '#' + escapeIdent(this.value);
793
+ else
794
+ return '#' + escapeHash(this.value);
795
+ }
796
+ }
797
+ export class StringToken extends StringValuedToken {
798
+ tokenType = 'STRING';
799
+ constructor(val) {
800
+ super();
801
+ this.value = val;
802
+ }
803
+ toString() {
804
+ return '"' + escapeString(this.value) + '"';
805
+ }
806
+ }
807
+ export class URLToken extends StringValuedToken {
808
+ tokenType = 'URL';
809
+ constructor(val) {
810
+ super();
811
+ this.value = val;
812
+ }
813
+ toString() { return 'URL(' + this.value + ')'; }
814
+ toSource() {
815
+ return 'url("' + escapeString(this.value) + '")';
816
+ }
817
+ }
818
+ export class NumberToken extends CSSParserToken {
819
+ tokenType = 'NUMBER';
820
+ type;
821
+ repr;
822
+ constructor() {
823
+ super();
824
+ this.type = 'integer';
825
+ this.repr = '';
826
+ }
827
+ toString() {
828
+ if (this.type === 'integer')
829
+ return 'INT(' + this.value + ')';
830
+ return 'NUMBER(' + this.value + ')';
831
+ }
832
+ toJSON() {
833
+ const json = super.toJSON();
834
+ json.value = this.value;
835
+ json.type = this.type;
836
+ json.repr = this.repr;
837
+ return json;
838
+ }
839
+ toSource() { return this.repr; }
840
+ }
841
+ export class PercentageToken extends CSSParserToken {
842
+ tokenType = 'PERCENTAGE';
843
+ repr;
844
+ constructor() {
845
+ super();
846
+ this.repr = '';
847
+ }
848
+ toString() { return 'PERCENTAGE(' + this.value + ')'; }
849
+ toJSON() {
850
+ const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
851
+ json.value = this.value;
852
+ json.repr = this.repr;
853
+ return json;
854
+ }
855
+ toSource() { return this.repr + '%'; }
856
+ }
857
+ export class DimensionToken extends CSSParserToken {
858
+ tokenType = 'DIMENSION';
859
+ type;
860
+ repr;
861
+ unit;
862
+ constructor() {
863
+ super();
864
+ this.type = 'integer';
865
+ this.repr = '';
866
+ this.unit = '';
867
+ }
868
+ toString() { return 'DIM(' + this.value + ',' + this.unit + ')'; }
869
+ toJSON() {
870
+ const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
871
+ json.value = this.value;
872
+ json.type = this.type;
873
+ json.repr = this.repr;
874
+ json.unit = this.unit;
875
+ return json;
876
+ }
877
+ toSource() {
878
+ const source = this.repr;
879
+ let unit = escapeIdent(this.unit);
880
+ if (unit[0].toLowerCase() === 'e' && (unit[1] === '-' || between(unit.charCodeAt(1), 0x30, 0x39))) {
881
+ // Unit is ambiguous with scinot
882
+ // Remove the leading "e", replace with escape.
883
+ unit = '\\65 ' + unit.slice(1, unit.length);
884
+ }
885
+ return source + unit;
886
+ }
887
+ }
888
+ function escapeIdent(string) {
889
+ string = '' + string;
890
+ let result = '';
891
+ const firstcode = string.charCodeAt(0);
892
+ for (let i = 0; i < string.length; i++) {
893
+ const code = string.charCodeAt(i);
894
+ if (code === 0x0)
895
+ throw new InvalidCharacterError('Invalid character: the input contains U+0000.');
896
+ if (between(code, 0x1, 0x1f) || code === 0x7f ||
897
+ (i === 0 && between(code, 0x30, 0x39)) ||
898
+ (i === 1 && between(code, 0x30, 0x39) && firstcode === 0x2d))
899
+ result += '\\' + code.toString(16) + ' ';
900
+ else if (code >= 0x80 ||
901
+ code === 0x2d ||
902
+ code === 0x5f ||
903
+ between(code, 0x30, 0x39) ||
904
+ between(code, 0x41, 0x5a) ||
905
+ between(code, 0x61, 0x7a))
906
+ result += string[i];
907
+ else
908
+ result += '\\' + string[i];
909
+ }
910
+ return result;
911
+ }
912
+ function escapeHash(string) {
913
+ // Escapes the contents of "unrestricted"-type hash tokens.
914
+ // Won't preserve the ID-ness of "id"-type hash tokens;
915
+ // use escapeIdent() for that.
916
+ string = '' + string;
917
+ let result = '';
918
+ for (let i = 0; i < string.length; i++) {
919
+ const code = string.charCodeAt(i);
920
+ if (code === 0x0)
921
+ throw new InvalidCharacterError('Invalid character: the input contains U+0000.');
922
+ if (code >= 0x80 ||
923
+ code === 0x2d ||
924
+ code === 0x5f ||
925
+ between(code, 0x30, 0x39) ||
926
+ between(code, 0x41, 0x5a) ||
927
+ between(code, 0x61, 0x7a))
928
+ result += string[i];
929
+ else
930
+ result += '\\' + code.toString(16) + ' ';
931
+ }
932
+ return result;
933
+ }
934
+ function escapeString(string) {
935
+ string = '' + string;
936
+ let result = '';
937
+ for (let i = 0; i < string.length; i++) {
938
+ const code = string.charCodeAt(i);
939
+ if (code === 0x0)
940
+ throw new InvalidCharacterError('Invalid character: the input contains U+0000.');
941
+ if (between(code, 0x1, 0x1f) || code === 0x7f)
942
+ result += '\\' + code.toString(16) + ' ';
943
+ else if (code === 0x22 || code === 0x5c)
944
+ result += '\\' + string[i];
945
+ else
946
+ result += string[i];
947
+ }
948
+ return result;
949
+ }
950
+ //# sourceMappingURL=cssTokenizer.js.map