vscode-css-languageservice 6.0.1 → 6.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.
- package/CHANGELOG.md +3 -1
- package/SECURITY.md +41 -0
- package/lib/esm/beautify/beautify-css.js +11 -4
- package/lib/esm/cssLanguageService.d.ts +38 -37
- package/lib/esm/cssLanguageService.js +73 -72
- package/lib/esm/cssLanguageTypes.d.ts +238 -238
- package/lib/esm/cssLanguageTypes.js +42 -42
- package/lib/esm/data/webCustomData.js +22089 -21959
- package/lib/esm/languageFacts/builtinData.js +142 -142
- package/lib/esm/languageFacts/colors.js +469 -469
- package/lib/esm/languageFacts/dataManager.js +88 -88
- package/lib/esm/languageFacts/dataProvider.js +73 -73
- package/lib/esm/languageFacts/entry.js +137 -137
- package/lib/esm/languageFacts/facts.js +8 -8
- package/lib/esm/parser/cssErrors.js +48 -48
- package/lib/esm/parser/cssNodes.js +1511 -1502
- package/lib/esm/parser/cssParser.js +1606 -1534
- package/lib/esm/parser/cssScanner.js +592 -592
- package/lib/esm/parser/cssSymbolScope.js +311 -311
- package/lib/esm/parser/lessParser.js +715 -714
- package/lib/esm/parser/lessScanner.js +57 -57
- package/lib/esm/parser/scssErrors.js +18 -18
- package/lib/esm/parser/scssParser.js +806 -796
- package/lib/esm/parser/scssScanner.js +95 -95
- package/lib/esm/services/cssCodeActions.js +77 -77
- package/lib/esm/services/cssCompletion.js +1054 -1054
- package/lib/esm/services/cssFolding.js +190 -190
- package/lib/esm/services/cssFormatter.js +136 -136
- package/lib/esm/services/cssHover.js +148 -148
- package/lib/esm/services/cssNavigation.js +441 -378
- package/lib/esm/services/cssSelectionRange.js +47 -47
- package/lib/esm/services/cssValidation.js +41 -41
- package/lib/esm/services/lessCompletion.js +378 -378
- package/lib/esm/services/lint.js +518 -518
- package/lib/esm/services/lintRules.js +76 -76
- package/lib/esm/services/lintUtil.js +196 -196
- package/lib/esm/services/pathCompletion.js +157 -157
- package/lib/esm/services/scssCompletion.js +354 -354
- package/lib/esm/services/scssNavigation.js +82 -82
- package/lib/esm/services/selectorPrinting.js +492 -492
- package/lib/esm/utils/arrays.js +40 -40
- package/lib/esm/utils/objects.js +11 -11
- package/lib/esm/utils/resources.js +11 -11
- package/lib/esm/utils/strings.js +102 -102
- package/lib/umd/beautify/beautify-css.js +11 -4
- package/lib/umd/cssLanguageService.d.ts +38 -37
- package/lib/umd/cssLanguageService.js +104 -99
- package/lib/umd/cssLanguageTypes.d.ts +238 -238
- package/lib/umd/cssLanguageTypes.js +89 -89
- package/lib/umd/data/webCustomData.js +22102 -21972
- package/lib/umd/languageFacts/builtinData.js +154 -154
- package/lib/umd/languageFacts/colors.js +492 -492
- package/lib/umd/languageFacts/dataManager.js +101 -101
- package/lib/umd/languageFacts/dataProvider.js +86 -86
- package/lib/umd/languageFacts/entry.js +152 -152
- package/lib/umd/languageFacts/facts.js +33 -29
- package/lib/umd/parser/cssErrors.js +61 -61
- package/lib/umd/parser/cssNodes.js +1597 -1587
- package/lib/umd/parser/cssParser.js +1619 -1547
- package/lib/umd/parser/cssScanner.js +606 -606
- package/lib/umd/parser/cssSymbolScope.js +328 -328
- package/lib/umd/parser/lessParser.js +728 -727
- package/lib/umd/parser/lessScanner.js +70 -70
- package/lib/umd/parser/scssErrors.js +31 -31
- package/lib/umd/parser/scssParser.js +819 -809
- package/lib/umd/parser/scssScanner.js +108 -108
- package/lib/umd/services/cssCodeActions.js +90 -90
- package/lib/umd/services/cssCompletion.js +1067 -1067
- package/lib/umd/services/cssFolding.js +203 -203
- package/lib/umd/services/cssFormatter.js +150 -150
- package/lib/umd/services/cssHover.js +161 -161
- package/lib/umd/services/cssNavigation.js +454 -391
- package/lib/umd/services/cssSelectionRange.js +60 -60
- package/lib/umd/services/cssValidation.js +54 -54
- package/lib/umd/services/lessCompletion.js +391 -391
- package/lib/umd/services/lint.js +531 -531
- package/lib/umd/services/lintRules.js +91 -91
- package/lib/umd/services/lintUtil.js +210 -210
- package/lib/umd/services/pathCompletion.js +171 -171
- package/lib/umd/services/scssCompletion.js +367 -367
- package/lib/umd/services/scssNavigation.js +95 -95
- package/lib/umd/services/selectorPrinting.js +510 -510
- package/lib/umd/utils/arrays.js +55 -55
- package/lib/umd/utils/objects.js +25 -25
- package/lib/umd/utils/resources.js +26 -26
- package/lib/umd/utils/strings.js +120 -120
- package/package.json +13 -12
|
@@ -1,606 +1,606 @@
|
|
|
1
|
-
(function (factory) {
|
|
2
|
-
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
-
var v = factory(require, exports);
|
|
4
|
-
if (v !== undefined) module.exports = v;
|
|
5
|
-
}
|
|
6
|
-
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports"], factory);
|
|
8
|
-
}
|
|
9
|
-
})(function (require, exports) {
|
|
10
|
-
/*---------------------------------------------------------------------------------------------
|
|
11
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
12
|
-
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
13
|
-
*--------------------------------------------------------------------------------------------*/
|
|
14
|
-
'use strict';
|
|
15
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.Scanner = exports.MultiLineStream = exports.TokenType = void 0;
|
|
17
|
-
var TokenType;
|
|
18
|
-
(function (TokenType) {
|
|
19
|
-
TokenType[TokenType["Ident"] = 0] = "Ident";
|
|
20
|
-
TokenType[TokenType["AtKeyword"] = 1] = "AtKeyword";
|
|
21
|
-
TokenType[TokenType["String"] = 2] = "String";
|
|
22
|
-
TokenType[TokenType["BadString"] = 3] = "BadString";
|
|
23
|
-
TokenType[TokenType["UnquotedString"] = 4] = "UnquotedString";
|
|
24
|
-
TokenType[TokenType["Hash"] = 5] = "Hash";
|
|
25
|
-
TokenType[TokenType["Num"] = 6] = "Num";
|
|
26
|
-
TokenType[TokenType["Percentage"] = 7] = "Percentage";
|
|
27
|
-
TokenType[TokenType["Dimension"] = 8] = "Dimension";
|
|
28
|
-
TokenType[TokenType["UnicodeRange"] = 9] = "UnicodeRange";
|
|
29
|
-
TokenType[TokenType["CDO"] = 10] = "CDO";
|
|
30
|
-
TokenType[TokenType["CDC"] = 11] = "CDC";
|
|
31
|
-
TokenType[TokenType["Colon"] = 12] = "Colon";
|
|
32
|
-
TokenType[TokenType["SemiColon"] = 13] = "SemiColon";
|
|
33
|
-
TokenType[TokenType["CurlyL"] = 14] = "CurlyL";
|
|
34
|
-
TokenType[TokenType["CurlyR"] = 15] = "CurlyR";
|
|
35
|
-
TokenType[TokenType["ParenthesisL"] = 16] = "ParenthesisL";
|
|
36
|
-
TokenType[TokenType["ParenthesisR"] = 17] = "ParenthesisR";
|
|
37
|
-
TokenType[TokenType["BracketL"] = 18] = "BracketL";
|
|
38
|
-
TokenType[TokenType["BracketR"] = 19] = "BracketR";
|
|
39
|
-
TokenType[TokenType["Whitespace"] = 20] = "Whitespace";
|
|
40
|
-
TokenType[TokenType["Includes"] = 21] = "Includes";
|
|
41
|
-
TokenType[TokenType["Dashmatch"] = 22] = "Dashmatch";
|
|
42
|
-
TokenType[TokenType["SubstringOperator"] = 23] = "SubstringOperator";
|
|
43
|
-
TokenType[TokenType["PrefixOperator"] = 24] = "PrefixOperator";
|
|
44
|
-
TokenType[TokenType["SuffixOperator"] = 25] = "SuffixOperator";
|
|
45
|
-
TokenType[TokenType["Delim"] = 26] = "Delim";
|
|
46
|
-
TokenType[TokenType["EMS"] = 27] = "EMS";
|
|
47
|
-
TokenType[TokenType["EXS"] = 28] = "EXS";
|
|
48
|
-
TokenType[TokenType["Length"] = 29] = "Length";
|
|
49
|
-
TokenType[TokenType["Angle"] = 30] = "Angle";
|
|
50
|
-
TokenType[TokenType["Time"] = 31] = "Time";
|
|
51
|
-
TokenType[TokenType["Freq"] = 32] = "Freq";
|
|
52
|
-
TokenType[TokenType["Exclamation"] = 33] = "Exclamation";
|
|
53
|
-
TokenType[TokenType["Resolution"] = 34] = "Resolution";
|
|
54
|
-
TokenType[TokenType["Comma"] = 35] = "Comma";
|
|
55
|
-
TokenType[TokenType["Charset"] = 36] = "Charset";
|
|
56
|
-
TokenType[TokenType["EscapedJavaScript"] = 37] = "EscapedJavaScript";
|
|
57
|
-
TokenType[TokenType["BadEscapedJavaScript"] = 38] = "BadEscapedJavaScript";
|
|
58
|
-
TokenType[TokenType["Comment"] = 39] = "Comment";
|
|
59
|
-
TokenType[TokenType["SingleLineComment"] = 40] = "SingleLineComment";
|
|
60
|
-
TokenType[TokenType["EOF"] = 41] = "EOF";
|
|
61
|
-
TokenType[TokenType["CustomToken"] = 42] = "CustomToken";
|
|
62
|
-
})(TokenType = exports.TokenType || (exports.TokenType = {}));
|
|
63
|
-
class MultiLineStream {
|
|
64
|
-
constructor(source) {
|
|
65
|
-
this.source = source;
|
|
66
|
-
this.len = source.length;
|
|
67
|
-
this.position = 0;
|
|
68
|
-
}
|
|
69
|
-
substring(from, to = this.position) {
|
|
70
|
-
return this.source.substring(from, to);
|
|
71
|
-
}
|
|
72
|
-
eos() {
|
|
73
|
-
return this.len <= this.position;
|
|
74
|
-
}
|
|
75
|
-
pos() {
|
|
76
|
-
return this.position;
|
|
77
|
-
}
|
|
78
|
-
goBackTo(pos) {
|
|
79
|
-
this.position = pos;
|
|
80
|
-
}
|
|
81
|
-
goBack(n) {
|
|
82
|
-
this.position -= n;
|
|
83
|
-
}
|
|
84
|
-
advance(n) {
|
|
85
|
-
this.position += n;
|
|
86
|
-
}
|
|
87
|
-
nextChar() {
|
|
88
|
-
return this.source.charCodeAt(this.position++) || 0;
|
|
89
|
-
}
|
|
90
|
-
peekChar(n = 0) {
|
|
91
|
-
return this.source.charCodeAt(this.position + n) || 0;
|
|
92
|
-
}
|
|
93
|
-
lookbackChar(n = 0) {
|
|
94
|
-
return this.source.charCodeAt(this.position - n) || 0;
|
|
95
|
-
}
|
|
96
|
-
advanceIfChar(ch) {
|
|
97
|
-
if (ch === this.source.charCodeAt(this.position)) {
|
|
98
|
-
this.position++;
|
|
99
|
-
return true;
|
|
100
|
-
}
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
advanceIfChars(ch) {
|
|
104
|
-
if (this.position + ch.length > this.source.length) {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
let i = 0;
|
|
108
|
-
for (; i < ch.length; i++) {
|
|
109
|
-
if (this.source.charCodeAt(this.position + i) !== ch[i]) {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
this.advance(i);
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
advanceWhileChar(condition) {
|
|
117
|
-
const posNow = this.position;
|
|
118
|
-
while (this.position < this.len && condition(this.source.charCodeAt(this.position))) {
|
|
119
|
-
this.position++;
|
|
120
|
-
}
|
|
121
|
-
return this.position - posNow;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
exports.MultiLineStream = MultiLineStream;
|
|
125
|
-
const _a = 'a'.charCodeAt(0);
|
|
126
|
-
const _f = 'f'.charCodeAt(0);
|
|
127
|
-
const _z = 'z'.charCodeAt(0);
|
|
128
|
-
const _u = 'u'.charCodeAt(0);
|
|
129
|
-
const _A = 'A'.charCodeAt(0);
|
|
130
|
-
const _F = 'F'.charCodeAt(0);
|
|
131
|
-
const _Z = 'Z'.charCodeAt(0);
|
|
132
|
-
const _0 = '0'.charCodeAt(0);
|
|
133
|
-
const _9 = '9'.charCodeAt(0);
|
|
134
|
-
const _TLD = '~'.charCodeAt(0);
|
|
135
|
-
const _HAT = '^'.charCodeAt(0);
|
|
136
|
-
const _EQS = '='.charCodeAt(0);
|
|
137
|
-
const _PIP = '|'.charCodeAt(0);
|
|
138
|
-
const _MIN = '-'.charCodeAt(0);
|
|
139
|
-
const _USC = '_'.charCodeAt(0);
|
|
140
|
-
const _PRC = '%'.charCodeAt(0);
|
|
141
|
-
const _MUL = '*'.charCodeAt(0);
|
|
142
|
-
const _LPA = '('.charCodeAt(0);
|
|
143
|
-
const _RPA = ')'.charCodeAt(0);
|
|
144
|
-
const _LAN = '<'.charCodeAt(0);
|
|
145
|
-
const _RAN = '>'.charCodeAt(0);
|
|
146
|
-
const _ATS = '@'.charCodeAt(0);
|
|
147
|
-
const _HSH = '#'.charCodeAt(0);
|
|
148
|
-
const _DLR = '$'.charCodeAt(0);
|
|
149
|
-
const _BSL = '\\'.charCodeAt(0);
|
|
150
|
-
const _FSL = '/'.charCodeAt(0);
|
|
151
|
-
const _NWL = '\n'.charCodeAt(0);
|
|
152
|
-
const _CAR = '\r'.charCodeAt(0);
|
|
153
|
-
const _LFD = '\f'.charCodeAt(0);
|
|
154
|
-
const _DQO = '"'.charCodeAt(0);
|
|
155
|
-
const _SQO = '\''.charCodeAt(0);
|
|
156
|
-
const _WSP = ' '.charCodeAt(0);
|
|
157
|
-
const _TAB = '\t'.charCodeAt(0);
|
|
158
|
-
const _SEM = ';'.charCodeAt(0);
|
|
159
|
-
const _COL = ':'.charCodeAt(0);
|
|
160
|
-
const _CUL = '{'.charCodeAt(0);
|
|
161
|
-
const _CUR = '}'.charCodeAt(0);
|
|
162
|
-
const _BRL = '['.charCodeAt(0);
|
|
163
|
-
const _BRR = ']'.charCodeAt(0);
|
|
164
|
-
const _CMA = ','.charCodeAt(0);
|
|
165
|
-
const _DOT = '.'.charCodeAt(0);
|
|
166
|
-
const _BNG = '!'.charCodeAt(0);
|
|
167
|
-
const _QSM = '?'.charCodeAt(0);
|
|
168
|
-
const _PLS = '+'.charCodeAt(0);
|
|
169
|
-
const staticTokenTable = {};
|
|
170
|
-
staticTokenTable[_SEM] = TokenType.SemiColon;
|
|
171
|
-
staticTokenTable[_COL] = TokenType.Colon;
|
|
172
|
-
staticTokenTable[_CUL] = TokenType.CurlyL;
|
|
173
|
-
staticTokenTable[_CUR] = TokenType.CurlyR;
|
|
174
|
-
staticTokenTable[_BRR] = TokenType.BracketR;
|
|
175
|
-
staticTokenTable[_BRL] = TokenType.BracketL;
|
|
176
|
-
staticTokenTable[_LPA] = TokenType.ParenthesisL;
|
|
177
|
-
staticTokenTable[_RPA] = TokenType.ParenthesisR;
|
|
178
|
-
staticTokenTable[_CMA] = TokenType.Comma;
|
|
179
|
-
const staticUnitTable = {};
|
|
180
|
-
staticUnitTable['em'] = TokenType.EMS;
|
|
181
|
-
staticUnitTable['ex'] = TokenType.EXS;
|
|
182
|
-
staticUnitTable['px'] = TokenType.Length;
|
|
183
|
-
staticUnitTable['cm'] = TokenType.Length;
|
|
184
|
-
staticUnitTable['mm'] = TokenType.Length;
|
|
185
|
-
staticUnitTable['in'] = TokenType.Length;
|
|
186
|
-
staticUnitTable['pt'] = TokenType.Length;
|
|
187
|
-
staticUnitTable['pc'] = TokenType.Length;
|
|
188
|
-
staticUnitTable['deg'] = TokenType.Angle;
|
|
189
|
-
staticUnitTable['rad'] = TokenType.Angle;
|
|
190
|
-
staticUnitTable['grad'] = TokenType.Angle;
|
|
191
|
-
staticUnitTable['ms'] = TokenType.Time;
|
|
192
|
-
staticUnitTable['s'] = TokenType.Time;
|
|
193
|
-
staticUnitTable['hz'] = TokenType.Freq;
|
|
194
|
-
staticUnitTable['khz'] = TokenType.Freq;
|
|
195
|
-
staticUnitTable['%'] = TokenType.Percentage;
|
|
196
|
-
staticUnitTable['fr'] = TokenType.Percentage;
|
|
197
|
-
staticUnitTable['dpi'] = TokenType.Resolution;
|
|
198
|
-
staticUnitTable['dpcm'] = TokenType.Resolution;
|
|
199
|
-
class Scanner {
|
|
200
|
-
constructor() {
|
|
201
|
-
this.stream = new MultiLineStream('');
|
|
202
|
-
this.ignoreComment = true;
|
|
203
|
-
this.ignoreWhitespace = true;
|
|
204
|
-
this.inURL = false;
|
|
205
|
-
}
|
|
206
|
-
setSource(input) {
|
|
207
|
-
this.stream = new MultiLineStream(input);
|
|
208
|
-
}
|
|
209
|
-
finishToken(offset, type, text) {
|
|
210
|
-
return {
|
|
211
|
-
offset: offset,
|
|
212
|
-
len: this.stream.pos() - offset,
|
|
213
|
-
type: type,
|
|
214
|
-
text: text || this.stream.substring(offset)
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
substring(offset, len) {
|
|
218
|
-
return this.stream.substring(offset, offset + len);
|
|
219
|
-
}
|
|
220
|
-
pos() {
|
|
221
|
-
return this.stream.pos();
|
|
222
|
-
}
|
|
223
|
-
goBackTo(pos) {
|
|
224
|
-
this.stream.goBackTo(pos);
|
|
225
|
-
}
|
|
226
|
-
scanUnquotedString() {
|
|
227
|
-
const offset = this.stream.pos();
|
|
228
|
-
const content = [];
|
|
229
|
-
if (this._unquotedString(content)) {
|
|
230
|
-
return this.finishToken(offset, TokenType.UnquotedString, content.join(''));
|
|
231
|
-
}
|
|
232
|
-
return null;
|
|
233
|
-
}
|
|
234
|
-
scan() {
|
|
235
|
-
// processes all whitespaces and comments
|
|
236
|
-
const triviaToken = this.trivia();
|
|
237
|
-
if (triviaToken !== null) {
|
|
238
|
-
return triviaToken;
|
|
239
|
-
}
|
|
240
|
-
const offset = this.stream.pos();
|
|
241
|
-
// End of file/input
|
|
242
|
-
if (this.stream.eos()) {
|
|
243
|
-
return this.finishToken(offset, TokenType.EOF);
|
|
244
|
-
}
|
|
245
|
-
return this.scanNext(offset);
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Read the range as described in https://www.w3.org/TR/CSS21/syndata.html#tokenization
|
|
249
|
-
* Assume the `u` has aleady been consumed
|
|
250
|
-
* @returns if reading the unicode was successful
|
|
251
|
-
*/
|
|
252
|
-
tryScanUnicode() {
|
|
253
|
-
const offset = this.stream.pos();
|
|
254
|
-
if (!this.stream.eos() && this._unicodeRange()) {
|
|
255
|
-
return this.finishToken(offset, TokenType.UnicodeRange);
|
|
256
|
-
}
|
|
257
|
-
this.stream.goBackTo(offset);
|
|
258
|
-
return undefined;
|
|
259
|
-
}
|
|
260
|
-
scanNext(offset) {
|
|
261
|
-
// CDO <!--
|
|
262
|
-
if (this.stream.advanceIfChars([_LAN, _BNG, _MIN, _MIN])) {
|
|
263
|
-
return this.finishToken(offset, TokenType.CDO);
|
|
264
|
-
}
|
|
265
|
-
// CDC -->
|
|
266
|
-
if (this.stream.advanceIfChars([_MIN, _MIN, _RAN])) {
|
|
267
|
-
return this.finishToken(offset, TokenType.CDC);
|
|
268
|
-
}
|
|
269
|
-
let content = [];
|
|
270
|
-
if (this.ident(content)) {
|
|
271
|
-
return this.finishToken(offset, TokenType.Ident, content.join(''));
|
|
272
|
-
}
|
|
273
|
-
// at-keyword
|
|
274
|
-
if (this.stream.advanceIfChar(_ATS)) {
|
|
275
|
-
content = ['@'];
|
|
276
|
-
if (this._name(content)) {
|
|
277
|
-
const keywordText = content.join('');
|
|
278
|
-
if (keywordText === '@charset') {
|
|
279
|
-
return this.finishToken(offset, TokenType.Charset, keywordText);
|
|
280
|
-
}
|
|
281
|
-
return this.finishToken(offset, TokenType.AtKeyword, keywordText);
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
return this.finishToken(offset, TokenType.Delim);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
// hash
|
|
288
|
-
if (this.stream.advanceIfChar(_HSH)) {
|
|
289
|
-
content = ['#'];
|
|
290
|
-
if (this._name(content)) {
|
|
291
|
-
return this.finishToken(offset, TokenType.Hash, content.join(''));
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
return this.finishToken(offset, TokenType.Delim);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
// Important
|
|
298
|
-
if (this.stream.advanceIfChar(_BNG)) {
|
|
299
|
-
return this.finishToken(offset, TokenType.Exclamation);
|
|
300
|
-
}
|
|
301
|
-
// Numbers
|
|
302
|
-
if (this._number()) {
|
|
303
|
-
const pos = this.stream.pos();
|
|
304
|
-
content = [this.stream.substring(offset, pos)];
|
|
305
|
-
if (this.stream.advanceIfChar(_PRC)) {
|
|
306
|
-
// Percentage 43%
|
|
307
|
-
return this.finishToken(offset, TokenType.Percentage);
|
|
308
|
-
}
|
|
309
|
-
else if (this.ident(content)) {
|
|
310
|
-
const dim = this.stream.substring(pos).toLowerCase();
|
|
311
|
-
const tokenType = staticUnitTable[dim];
|
|
312
|
-
if (typeof tokenType !== 'undefined') {
|
|
313
|
-
// Known dimension 43px
|
|
314
|
-
return this.finishToken(offset, tokenType, content.join(''));
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
// Unknown dimension 43ft
|
|
318
|
-
return this.finishToken(offset, TokenType.Dimension, content.join(''));
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
return this.finishToken(offset, TokenType.Num);
|
|
322
|
-
}
|
|
323
|
-
// String, BadString
|
|
324
|
-
content = [];
|
|
325
|
-
let tokenType = this._string(content);
|
|
326
|
-
if (tokenType !== null) {
|
|
327
|
-
return this.finishToken(offset, tokenType, content.join(''));
|
|
328
|
-
}
|
|
329
|
-
// single character tokens
|
|
330
|
-
tokenType = staticTokenTable[this.stream.peekChar()];
|
|
331
|
-
if (typeof tokenType !== 'undefined') {
|
|
332
|
-
this.stream.advance(1);
|
|
333
|
-
return this.finishToken(offset, tokenType);
|
|
334
|
-
}
|
|
335
|
-
// includes ~=
|
|
336
|
-
if (this.stream.peekChar(0) === _TLD && this.stream.peekChar(1) === _EQS) {
|
|
337
|
-
this.stream.advance(2);
|
|
338
|
-
return this.finishToken(offset, TokenType.Includes);
|
|
339
|
-
}
|
|
340
|
-
// DashMatch |=
|
|
341
|
-
if (this.stream.peekChar(0) === _PIP && this.stream.peekChar(1) === _EQS) {
|
|
342
|
-
this.stream.advance(2);
|
|
343
|
-
return this.finishToken(offset, TokenType.Dashmatch);
|
|
344
|
-
}
|
|
345
|
-
// Substring operator *=
|
|
346
|
-
if (this.stream.peekChar(0) === _MUL && this.stream.peekChar(1) === _EQS) {
|
|
347
|
-
this.stream.advance(2);
|
|
348
|
-
return this.finishToken(offset, TokenType.SubstringOperator);
|
|
349
|
-
}
|
|
350
|
-
// Substring operator ^=
|
|
351
|
-
if (this.stream.peekChar(0) === _HAT && this.stream.peekChar(1) === _EQS) {
|
|
352
|
-
this.stream.advance(2);
|
|
353
|
-
return this.finishToken(offset, TokenType.PrefixOperator);
|
|
354
|
-
}
|
|
355
|
-
// Substring operator $=
|
|
356
|
-
if (this.stream.peekChar(0) === _DLR && this.stream.peekChar(1) === _EQS) {
|
|
357
|
-
this.stream.advance(2);
|
|
358
|
-
return this.finishToken(offset, TokenType.SuffixOperator);
|
|
359
|
-
}
|
|
360
|
-
// Delim
|
|
361
|
-
this.stream.nextChar();
|
|
362
|
-
return this.finishToken(offset, TokenType.Delim);
|
|
363
|
-
}
|
|
364
|
-
trivia() {
|
|
365
|
-
while (true) {
|
|
366
|
-
const offset = this.stream.pos();
|
|
367
|
-
if (this._whitespace()) {
|
|
368
|
-
if (!this.ignoreWhitespace) {
|
|
369
|
-
return this.finishToken(offset, TokenType.Whitespace);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
else if (this.comment()) {
|
|
373
|
-
if (!this.ignoreComment) {
|
|
374
|
-
return this.finishToken(offset, TokenType.Comment);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
return null;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
comment() {
|
|
383
|
-
if (this.stream.advanceIfChars([_FSL, _MUL])) {
|
|
384
|
-
let success = false, hot = false;
|
|
385
|
-
this.stream.advanceWhileChar((ch) => {
|
|
386
|
-
if (hot && ch === _FSL) {
|
|
387
|
-
success = true;
|
|
388
|
-
return false;
|
|
389
|
-
}
|
|
390
|
-
hot = ch === _MUL;
|
|
391
|
-
return true;
|
|
392
|
-
});
|
|
393
|
-
if (success) {
|
|
394
|
-
this.stream.advance(1);
|
|
395
|
-
}
|
|
396
|
-
return true;
|
|
397
|
-
}
|
|
398
|
-
return false;
|
|
399
|
-
}
|
|
400
|
-
_number() {
|
|
401
|
-
let npeek = 0, ch;
|
|
402
|
-
if (this.stream.peekChar() === _DOT) {
|
|
403
|
-
npeek = 1;
|
|
404
|
-
}
|
|
405
|
-
ch = this.stream.peekChar(npeek);
|
|
406
|
-
if (ch >= _0 && ch <= _9) {
|
|
407
|
-
this.stream.advance(npeek + 1);
|
|
408
|
-
this.stream.advanceWhileChar((ch) => {
|
|
409
|
-
return ch >= _0 && ch <= _9 || npeek === 0 && ch === _DOT;
|
|
410
|
-
});
|
|
411
|
-
return true;
|
|
412
|
-
}
|
|
413
|
-
return false;
|
|
414
|
-
}
|
|
415
|
-
_newline(result) {
|
|
416
|
-
const ch = this.stream.peekChar();
|
|
417
|
-
switch (ch) {
|
|
418
|
-
case _CAR:
|
|
419
|
-
case _LFD:
|
|
420
|
-
case _NWL:
|
|
421
|
-
this.stream.advance(1);
|
|
422
|
-
result.push(String.fromCharCode(ch));
|
|
423
|
-
if (ch === _CAR && this.stream.advanceIfChar(_NWL)) {
|
|
424
|
-
result.push('\n');
|
|
425
|
-
}
|
|
426
|
-
return true;
|
|
427
|
-
}
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
_escape(result, includeNewLines) {
|
|
431
|
-
let ch = this.stream.peekChar();
|
|
432
|
-
if (ch === _BSL) {
|
|
433
|
-
this.stream.advance(1);
|
|
434
|
-
ch = this.stream.peekChar();
|
|
435
|
-
let hexNumCount = 0;
|
|
436
|
-
while (hexNumCount < 6 && (ch >= _0 && ch <= _9 || ch >= _a && ch <= _f || ch >= _A && ch <= _F)) {
|
|
437
|
-
this.stream.advance(1);
|
|
438
|
-
ch = this.stream.peekChar();
|
|
439
|
-
hexNumCount++;
|
|
440
|
-
}
|
|
441
|
-
if (hexNumCount > 0) {
|
|
442
|
-
try {
|
|
443
|
-
const hexVal = parseInt(this.stream.substring(this.stream.pos() - hexNumCount), 16);
|
|
444
|
-
if (hexVal) {
|
|
445
|
-
result.push(String.fromCharCode(hexVal));
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
catch (e) {
|
|
449
|
-
// ignore
|
|
450
|
-
}
|
|
451
|
-
// optional whitespace or new line, not part of result text
|
|
452
|
-
if (ch === _WSP || ch === _TAB) {
|
|
453
|
-
this.stream.advance(1);
|
|
454
|
-
}
|
|
455
|
-
else {
|
|
456
|
-
this._newline([]);
|
|
457
|
-
}
|
|
458
|
-
return true;
|
|
459
|
-
}
|
|
460
|
-
if (ch !== _CAR && ch !== _LFD && ch !== _NWL) {
|
|
461
|
-
this.stream.advance(1);
|
|
462
|
-
result.push(String.fromCharCode(ch));
|
|
463
|
-
return true;
|
|
464
|
-
}
|
|
465
|
-
else if (includeNewLines) {
|
|
466
|
-
return this._newline(result);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
return false;
|
|
470
|
-
}
|
|
471
|
-
_stringChar(closeQuote, result) {
|
|
472
|
-
// not closeQuote, not backslash, not newline
|
|
473
|
-
const ch = this.stream.peekChar();
|
|
474
|
-
if (ch !== 0 && ch !== closeQuote && ch !== _BSL && ch !== _CAR && ch !== _LFD && ch !== _NWL) {
|
|
475
|
-
this.stream.advance(1);
|
|
476
|
-
result.push(String.fromCharCode(ch));
|
|
477
|
-
return true;
|
|
478
|
-
}
|
|
479
|
-
return false;
|
|
480
|
-
}
|
|
481
|
-
_string(result) {
|
|
482
|
-
if (this.stream.peekChar() === _SQO || this.stream.peekChar() === _DQO) {
|
|
483
|
-
const closeQuote = this.stream.nextChar();
|
|
484
|
-
result.push(String.fromCharCode(closeQuote));
|
|
485
|
-
while (this._stringChar(closeQuote, result) || this._escape(result, true)) {
|
|
486
|
-
// loop
|
|
487
|
-
}
|
|
488
|
-
if (this.stream.peekChar() === closeQuote) {
|
|
489
|
-
this.stream.nextChar();
|
|
490
|
-
result.push(String.fromCharCode(closeQuote));
|
|
491
|
-
return TokenType.String;
|
|
492
|
-
}
|
|
493
|
-
else {
|
|
494
|
-
return TokenType.BadString;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
return null;
|
|
498
|
-
}
|
|
499
|
-
_unquotedChar(result) {
|
|
500
|
-
// not closeQuote, not backslash, not newline
|
|
501
|
-
const ch = this.stream.peekChar();
|
|
502
|
-
if (ch !== 0 && ch !== _BSL && ch !== _SQO && ch !== _DQO && ch !== _LPA && ch !== _RPA && ch !== _WSP && ch !== _TAB && ch !== _NWL && ch !== _LFD && ch !== _CAR) {
|
|
503
|
-
this.stream.advance(1);
|
|
504
|
-
result.push(String.fromCharCode(ch));
|
|
505
|
-
return true;
|
|
506
|
-
}
|
|
507
|
-
return false;
|
|
508
|
-
}
|
|
509
|
-
_unquotedString(result) {
|
|
510
|
-
let hasContent = false;
|
|
511
|
-
while (this._unquotedChar(result) || this._escape(result)) {
|
|
512
|
-
hasContent = true;
|
|
513
|
-
}
|
|
514
|
-
return hasContent;
|
|
515
|
-
}
|
|
516
|
-
_whitespace() {
|
|
517
|
-
const n = this.stream.advanceWhileChar((ch) => {
|
|
518
|
-
return ch === _WSP || ch === _TAB || ch === _NWL || ch === _LFD || ch === _CAR;
|
|
519
|
-
});
|
|
520
|
-
return n > 0;
|
|
521
|
-
}
|
|
522
|
-
_name(result) {
|
|
523
|
-
let matched = false;
|
|
524
|
-
while (this._identChar(result) || this._escape(result)) {
|
|
525
|
-
matched = true;
|
|
526
|
-
}
|
|
527
|
-
return matched;
|
|
528
|
-
}
|
|
529
|
-
ident(result) {
|
|
530
|
-
const pos = this.stream.pos();
|
|
531
|
-
const hasMinus = this._minus(result);
|
|
532
|
-
if (hasMinus) {
|
|
533
|
-
if (this._minus(result) /* -- */ || this._identFirstChar(result) || this._escape(result)) {
|
|
534
|
-
while (this._identChar(result) || this._escape(result)) {
|
|
535
|
-
// loop
|
|
536
|
-
}
|
|
537
|
-
return true;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
else if (this._identFirstChar(result) || this._escape(result)) {
|
|
541
|
-
while (this._identChar(result) || this._escape(result)) {
|
|
542
|
-
// loop
|
|
543
|
-
}
|
|
544
|
-
return true;
|
|
545
|
-
}
|
|
546
|
-
this.stream.goBackTo(pos);
|
|
547
|
-
return false;
|
|
548
|
-
}
|
|
549
|
-
_identFirstChar(result) {
|
|
550
|
-
const ch = this.stream.peekChar();
|
|
551
|
-
if (ch === _USC || // _
|
|
552
|
-
ch >= _a && ch <= _z || // a-z
|
|
553
|
-
ch >= _A && ch <= _Z || // A-Z
|
|
554
|
-
ch >= 0x80 && ch <= 0xFFFF) { // nonascii
|
|
555
|
-
this.stream.advance(1);
|
|
556
|
-
result.push(String.fromCharCode(ch));
|
|
557
|
-
return true;
|
|
558
|
-
}
|
|
559
|
-
return false;
|
|
560
|
-
}
|
|
561
|
-
_minus(result) {
|
|
562
|
-
const ch = this.stream.peekChar();
|
|
563
|
-
if (ch === _MIN) {
|
|
564
|
-
this.stream.advance(1);
|
|
565
|
-
result.push(String.fromCharCode(ch));
|
|
566
|
-
return true;
|
|
567
|
-
}
|
|
568
|
-
return false;
|
|
569
|
-
}
|
|
570
|
-
_identChar(result) {
|
|
571
|
-
const ch = this.stream.peekChar();
|
|
572
|
-
if (ch === _USC || // _
|
|
573
|
-
ch === _MIN || // -
|
|
574
|
-
ch >= _a && ch <= _z || // a-z
|
|
575
|
-
ch >= _A && ch <= _Z || // A-Z
|
|
576
|
-
ch >= _0 && ch <= _9 || // 0/9
|
|
577
|
-
ch >= 0x80 && ch <= 0xFFFF) { // nonascii
|
|
578
|
-
this.stream.advance(1);
|
|
579
|
-
result.push(String.fromCharCode(ch));
|
|
580
|
-
return true;
|
|
581
|
-
}
|
|
582
|
-
return false;
|
|
583
|
-
}
|
|
584
|
-
_unicodeRange() {
|
|
585
|
-
// follow https://www.w3.org/TR/CSS21/syndata.html#tokenization and https://www.w3.org/TR/css-syntax-3/#urange-syntax
|
|
586
|
-
// assume u has already been parsed
|
|
587
|
-
if (this.stream.advanceIfChar(_PLS)) {
|
|
588
|
-
const isHexDigit = (ch) => (ch >= _0 && ch <= _9 || ch >= _a && ch <= _f || ch >= _A && ch <= _F);
|
|
589
|
-
const codePoints = this.stream.advanceWhileChar(isHexDigit) + this.stream.advanceWhileChar(ch => ch === _QSM);
|
|
590
|
-
if (codePoints >= 1 && codePoints <= 6) {
|
|
591
|
-
if (this.stream.advanceIfChar(_MIN)) {
|
|
592
|
-
const digits = this.stream.advanceWhileChar(isHexDigit);
|
|
593
|
-
if (digits >= 1 && digits <= 6) {
|
|
594
|
-
return true;
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
else {
|
|
598
|
-
return true;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
return false;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
exports.Scanner = Scanner;
|
|
606
|
-
});
|
|
1
|
+
(function (factory) {
|
|
2
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
+
var v = factory(require, exports);
|
|
4
|
+
if (v !== undefined) module.exports = v;
|
|
5
|
+
}
|
|
6
|
+
else if (typeof define === "function" && define.amd) {
|
|
7
|
+
define(["require", "exports"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
/*---------------------------------------------------------------------------------------------
|
|
11
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
12
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
13
|
+
*--------------------------------------------------------------------------------------------*/
|
|
14
|
+
'use strict';
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.Scanner = exports.MultiLineStream = exports.TokenType = void 0;
|
|
17
|
+
var TokenType;
|
|
18
|
+
(function (TokenType) {
|
|
19
|
+
TokenType[TokenType["Ident"] = 0] = "Ident";
|
|
20
|
+
TokenType[TokenType["AtKeyword"] = 1] = "AtKeyword";
|
|
21
|
+
TokenType[TokenType["String"] = 2] = "String";
|
|
22
|
+
TokenType[TokenType["BadString"] = 3] = "BadString";
|
|
23
|
+
TokenType[TokenType["UnquotedString"] = 4] = "UnquotedString";
|
|
24
|
+
TokenType[TokenType["Hash"] = 5] = "Hash";
|
|
25
|
+
TokenType[TokenType["Num"] = 6] = "Num";
|
|
26
|
+
TokenType[TokenType["Percentage"] = 7] = "Percentage";
|
|
27
|
+
TokenType[TokenType["Dimension"] = 8] = "Dimension";
|
|
28
|
+
TokenType[TokenType["UnicodeRange"] = 9] = "UnicodeRange";
|
|
29
|
+
TokenType[TokenType["CDO"] = 10] = "CDO";
|
|
30
|
+
TokenType[TokenType["CDC"] = 11] = "CDC";
|
|
31
|
+
TokenType[TokenType["Colon"] = 12] = "Colon";
|
|
32
|
+
TokenType[TokenType["SemiColon"] = 13] = "SemiColon";
|
|
33
|
+
TokenType[TokenType["CurlyL"] = 14] = "CurlyL";
|
|
34
|
+
TokenType[TokenType["CurlyR"] = 15] = "CurlyR";
|
|
35
|
+
TokenType[TokenType["ParenthesisL"] = 16] = "ParenthesisL";
|
|
36
|
+
TokenType[TokenType["ParenthesisR"] = 17] = "ParenthesisR";
|
|
37
|
+
TokenType[TokenType["BracketL"] = 18] = "BracketL";
|
|
38
|
+
TokenType[TokenType["BracketR"] = 19] = "BracketR";
|
|
39
|
+
TokenType[TokenType["Whitespace"] = 20] = "Whitespace";
|
|
40
|
+
TokenType[TokenType["Includes"] = 21] = "Includes";
|
|
41
|
+
TokenType[TokenType["Dashmatch"] = 22] = "Dashmatch";
|
|
42
|
+
TokenType[TokenType["SubstringOperator"] = 23] = "SubstringOperator";
|
|
43
|
+
TokenType[TokenType["PrefixOperator"] = 24] = "PrefixOperator";
|
|
44
|
+
TokenType[TokenType["SuffixOperator"] = 25] = "SuffixOperator";
|
|
45
|
+
TokenType[TokenType["Delim"] = 26] = "Delim";
|
|
46
|
+
TokenType[TokenType["EMS"] = 27] = "EMS";
|
|
47
|
+
TokenType[TokenType["EXS"] = 28] = "EXS";
|
|
48
|
+
TokenType[TokenType["Length"] = 29] = "Length";
|
|
49
|
+
TokenType[TokenType["Angle"] = 30] = "Angle";
|
|
50
|
+
TokenType[TokenType["Time"] = 31] = "Time";
|
|
51
|
+
TokenType[TokenType["Freq"] = 32] = "Freq";
|
|
52
|
+
TokenType[TokenType["Exclamation"] = 33] = "Exclamation";
|
|
53
|
+
TokenType[TokenType["Resolution"] = 34] = "Resolution";
|
|
54
|
+
TokenType[TokenType["Comma"] = 35] = "Comma";
|
|
55
|
+
TokenType[TokenType["Charset"] = 36] = "Charset";
|
|
56
|
+
TokenType[TokenType["EscapedJavaScript"] = 37] = "EscapedJavaScript";
|
|
57
|
+
TokenType[TokenType["BadEscapedJavaScript"] = 38] = "BadEscapedJavaScript";
|
|
58
|
+
TokenType[TokenType["Comment"] = 39] = "Comment";
|
|
59
|
+
TokenType[TokenType["SingleLineComment"] = 40] = "SingleLineComment";
|
|
60
|
+
TokenType[TokenType["EOF"] = 41] = "EOF";
|
|
61
|
+
TokenType[TokenType["CustomToken"] = 42] = "CustomToken";
|
|
62
|
+
})(TokenType = exports.TokenType || (exports.TokenType = {}));
|
|
63
|
+
class MultiLineStream {
|
|
64
|
+
constructor(source) {
|
|
65
|
+
this.source = source;
|
|
66
|
+
this.len = source.length;
|
|
67
|
+
this.position = 0;
|
|
68
|
+
}
|
|
69
|
+
substring(from, to = this.position) {
|
|
70
|
+
return this.source.substring(from, to);
|
|
71
|
+
}
|
|
72
|
+
eos() {
|
|
73
|
+
return this.len <= this.position;
|
|
74
|
+
}
|
|
75
|
+
pos() {
|
|
76
|
+
return this.position;
|
|
77
|
+
}
|
|
78
|
+
goBackTo(pos) {
|
|
79
|
+
this.position = pos;
|
|
80
|
+
}
|
|
81
|
+
goBack(n) {
|
|
82
|
+
this.position -= n;
|
|
83
|
+
}
|
|
84
|
+
advance(n) {
|
|
85
|
+
this.position += n;
|
|
86
|
+
}
|
|
87
|
+
nextChar() {
|
|
88
|
+
return this.source.charCodeAt(this.position++) || 0;
|
|
89
|
+
}
|
|
90
|
+
peekChar(n = 0) {
|
|
91
|
+
return this.source.charCodeAt(this.position + n) || 0;
|
|
92
|
+
}
|
|
93
|
+
lookbackChar(n = 0) {
|
|
94
|
+
return this.source.charCodeAt(this.position - n) || 0;
|
|
95
|
+
}
|
|
96
|
+
advanceIfChar(ch) {
|
|
97
|
+
if (ch === this.source.charCodeAt(this.position)) {
|
|
98
|
+
this.position++;
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
advanceIfChars(ch) {
|
|
104
|
+
if (this.position + ch.length > this.source.length) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
let i = 0;
|
|
108
|
+
for (; i < ch.length; i++) {
|
|
109
|
+
if (this.source.charCodeAt(this.position + i) !== ch[i]) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
this.advance(i);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
advanceWhileChar(condition) {
|
|
117
|
+
const posNow = this.position;
|
|
118
|
+
while (this.position < this.len && condition(this.source.charCodeAt(this.position))) {
|
|
119
|
+
this.position++;
|
|
120
|
+
}
|
|
121
|
+
return this.position - posNow;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.MultiLineStream = MultiLineStream;
|
|
125
|
+
const _a = 'a'.charCodeAt(0);
|
|
126
|
+
const _f = 'f'.charCodeAt(0);
|
|
127
|
+
const _z = 'z'.charCodeAt(0);
|
|
128
|
+
const _u = 'u'.charCodeAt(0);
|
|
129
|
+
const _A = 'A'.charCodeAt(0);
|
|
130
|
+
const _F = 'F'.charCodeAt(0);
|
|
131
|
+
const _Z = 'Z'.charCodeAt(0);
|
|
132
|
+
const _0 = '0'.charCodeAt(0);
|
|
133
|
+
const _9 = '9'.charCodeAt(0);
|
|
134
|
+
const _TLD = '~'.charCodeAt(0);
|
|
135
|
+
const _HAT = '^'.charCodeAt(0);
|
|
136
|
+
const _EQS = '='.charCodeAt(0);
|
|
137
|
+
const _PIP = '|'.charCodeAt(0);
|
|
138
|
+
const _MIN = '-'.charCodeAt(0);
|
|
139
|
+
const _USC = '_'.charCodeAt(0);
|
|
140
|
+
const _PRC = '%'.charCodeAt(0);
|
|
141
|
+
const _MUL = '*'.charCodeAt(0);
|
|
142
|
+
const _LPA = '('.charCodeAt(0);
|
|
143
|
+
const _RPA = ')'.charCodeAt(0);
|
|
144
|
+
const _LAN = '<'.charCodeAt(0);
|
|
145
|
+
const _RAN = '>'.charCodeAt(0);
|
|
146
|
+
const _ATS = '@'.charCodeAt(0);
|
|
147
|
+
const _HSH = '#'.charCodeAt(0);
|
|
148
|
+
const _DLR = '$'.charCodeAt(0);
|
|
149
|
+
const _BSL = '\\'.charCodeAt(0);
|
|
150
|
+
const _FSL = '/'.charCodeAt(0);
|
|
151
|
+
const _NWL = '\n'.charCodeAt(0);
|
|
152
|
+
const _CAR = '\r'.charCodeAt(0);
|
|
153
|
+
const _LFD = '\f'.charCodeAt(0);
|
|
154
|
+
const _DQO = '"'.charCodeAt(0);
|
|
155
|
+
const _SQO = '\''.charCodeAt(0);
|
|
156
|
+
const _WSP = ' '.charCodeAt(0);
|
|
157
|
+
const _TAB = '\t'.charCodeAt(0);
|
|
158
|
+
const _SEM = ';'.charCodeAt(0);
|
|
159
|
+
const _COL = ':'.charCodeAt(0);
|
|
160
|
+
const _CUL = '{'.charCodeAt(0);
|
|
161
|
+
const _CUR = '}'.charCodeAt(0);
|
|
162
|
+
const _BRL = '['.charCodeAt(0);
|
|
163
|
+
const _BRR = ']'.charCodeAt(0);
|
|
164
|
+
const _CMA = ','.charCodeAt(0);
|
|
165
|
+
const _DOT = '.'.charCodeAt(0);
|
|
166
|
+
const _BNG = '!'.charCodeAt(0);
|
|
167
|
+
const _QSM = '?'.charCodeAt(0);
|
|
168
|
+
const _PLS = '+'.charCodeAt(0);
|
|
169
|
+
const staticTokenTable = {};
|
|
170
|
+
staticTokenTable[_SEM] = TokenType.SemiColon;
|
|
171
|
+
staticTokenTable[_COL] = TokenType.Colon;
|
|
172
|
+
staticTokenTable[_CUL] = TokenType.CurlyL;
|
|
173
|
+
staticTokenTable[_CUR] = TokenType.CurlyR;
|
|
174
|
+
staticTokenTable[_BRR] = TokenType.BracketR;
|
|
175
|
+
staticTokenTable[_BRL] = TokenType.BracketL;
|
|
176
|
+
staticTokenTable[_LPA] = TokenType.ParenthesisL;
|
|
177
|
+
staticTokenTable[_RPA] = TokenType.ParenthesisR;
|
|
178
|
+
staticTokenTable[_CMA] = TokenType.Comma;
|
|
179
|
+
const staticUnitTable = {};
|
|
180
|
+
staticUnitTable['em'] = TokenType.EMS;
|
|
181
|
+
staticUnitTable['ex'] = TokenType.EXS;
|
|
182
|
+
staticUnitTable['px'] = TokenType.Length;
|
|
183
|
+
staticUnitTable['cm'] = TokenType.Length;
|
|
184
|
+
staticUnitTable['mm'] = TokenType.Length;
|
|
185
|
+
staticUnitTable['in'] = TokenType.Length;
|
|
186
|
+
staticUnitTable['pt'] = TokenType.Length;
|
|
187
|
+
staticUnitTable['pc'] = TokenType.Length;
|
|
188
|
+
staticUnitTable['deg'] = TokenType.Angle;
|
|
189
|
+
staticUnitTable['rad'] = TokenType.Angle;
|
|
190
|
+
staticUnitTable['grad'] = TokenType.Angle;
|
|
191
|
+
staticUnitTable['ms'] = TokenType.Time;
|
|
192
|
+
staticUnitTable['s'] = TokenType.Time;
|
|
193
|
+
staticUnitTable['hz'] = TokenType.Freq;
|
|
194
|
+
staticUnitTable['khz'] = TokenType.Freq;
|
|
195
|
+
staticUnitTable['%'] = TokenType.Percentage;
|
|
196
|
+
staticUnitTable['fr'] = TokenType.Percentage;
|
|
197
|
+
staticUnitTable['dpi'] = TokenType.Resolution;
|
|
198
|
+
staticUnitTable['dpcm'] = TokenType.Resolution;
|
|
199
|
+
class Scanner {
|
|
200
|
+
constructor() {
|
|
201
|
+
this.stream = new MultiLineStream('');
|
|
202
|
+
this.ignoreComment = true;
|
|
203
|
+
this.ignoreWhitespace = true;
|
|
204
|
+
this.inURL = false;
|
|
205
|
+
}
|
|
206
|
+
setSource(input) {
|
|
207
|
+
this.stream = new MultiLineStream(input);
|
|
208
|
+
}
|
|
209
|
+
finishToken(offset, type, text) {
|
|
210
|
+
return {
|
|
211
|
+
offset: offset,
|
|
212
|
+
len: this.stream.pos() - offset,
|
|
213
|
+
type: type,
|
|
214
|
+
text: text || this.stream.substring(offset)
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
substring(offset, len) {
|
|
218
|
+
return this.stream.substring(offset, offset + len);
|
|
219
|
+
}
|
|
220
|
+
pos() {
|
|
221
|
+
return this.stream.pos();
|
|
222
|
+
}
|
|
223
|
+
goBackTo(pos) {
|
|
224
|
+
this.stream.goBackTo(pos);
|
|
225
|
+
}
|
|
226
|
+
scanUnquotedString() {
|
|
227
|
+
const offset = this.stream.pos();
|
|
228
|
+
const content = [];
|
|
229
|
+
if (this._unquotedString(content)) {
|
|
230
|
+
return this.finishToken(offset, TokenType.UnquotedString, content.join(''));
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
scan() {
|
|
235
|
+
// processes all whitespaces and comments
|
|
236
|
+
const triviaToken = this.trivia();
|
|
237
|
+
if (triviaToken !== null) {
|
|
238
|
+
return triviaToken;
|
|
239
|
+
}
|
|
240
|
+
const offset = this.stream.pos();
|
|
241
|
+
// End of file/input
|
|
242
|
+
if (this.stream.eos()) {
|
|
243
|
+
return this.finishToken(offset, TokenType.EOF);
|
|
244
|
+
}
|
|
245
|
+
return this.scanNext(offset);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Read the range as described in https://www.w3.org/TR/CSS21/syndata.html#tokenization
|
|
249
|
+
* Assume the `u` has aleady been consumed
|
|
250
|
+
* @returns if reading the unicode was successful
|
|
251
|
+
*/
|
|
252
|
+
tryScanUnicode() {
|
|
253
|
+
const offset = this.stream.pos();
|
|
254
|
+
if (!this.stream.eos() && this._unicodeRange()) {
|
|
255
|
+
return this.finishToken(offset, TokenType.UnicodeRange);
|
|
256
|
+
}
|
|
257
|
+
this.stream.goBackTo(offset);
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
scanNext(offset) {
|
|
261
|
+
// CDO <!--
|
|
262
|
+
if (this.stream.advanceIfChars([_LAN, _BNG, _MIN, _MIN])) {
|
|
263
|
+
return this.finishToken(offset, TokenType.CDO);
|
|
264
|
+
}
|
|
265
|
+
// CDC -->
|
|
266
|
+
if (this.stream.advanceIfChars([_MIN, _MIN, _RAN])) {
|
|
267
|
+
return this.finishToken(offset, TokenType.CDC);
|
|
268
|
+
}
|
|
269
|
+
let content = [];
|
|
270
|
+
if (this.ident(content)) {
|
|
271
|
+
return this.finishToken(offset, TokenType.Ident, content.join(''));
|
|
272
|
+
}
|
|
273
|
+
// at-keyword
|
|
274
|
+
if (this.stream.advanceIfChar(_ATS)) {
|
|
275
|
+
content = ['@'];
|
|
276
|
+
if (this._name(content)) {
|
|
277
|
+
const keywordText = content.join('');
|
|
278
|
+
if (keywordText === '@charset') {
|
|
279
|
+
return this.finishToken(offset, TokenType.Charset, keywordText);
|
|
280
|
+
}
|
|
281
|
+
return this.finishToken(offset, TokenType.AtKeyword, keywordText);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
return this.finishToken(offset, TokenType.Delim);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// hash
|
|
288
|
+
if (this.stream.advanceIfChar(_HSH)) {
|
|
289
|
+
content = ['#'];
|
|
290
|
+
if (this._name(content)) {
|
|
291
|
+
return this.finishToken(offset, TokenType.Hash, content.join(''));
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
return this.finishToken(offset, TokenType.Delim);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Important
|
|
298
|
+
if (this.stream.advanceIfChar(_BNG)) {
|
|
299
|
+
return this.finishToken(offset, TokenType.Exclamation);
|
|
300
|
+
}
|
|
301
|
+
// Numbers
|
|
302
|
+
if (this._number()) {
|
|
303
|
+
const pos = this.stream.pos();
|
|
304
|
+
content = [this.stream.substring(offset, pos)];
|
|
305
|
+
if (this.stream.advanceIfChar(_PRC)) {
|
|
306
|
+
// Percentage 43%
|
|
307
|
+
return this.finishToken(offset, TokenType.Percentage);
|
|
308
|
+
}
|
|
309
|
+
else if (this.ident(content)) {
|
|
310
|
+
const dim = this.stream.substring(pos).toLowerCase();
|
|
311
|
+
const tokenType = staticUnitTable[dim];
|
|
312
|
+
if (typeof tokenType !== 'undefined') {
|
|
313
|
+
// Known dimension 43px
|
|
314
|
+
return this.finishToken(offset, tokenType, content.join(''));
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
// Unknown dimension 43ft
|
|
318
|
+
return this.finishToken(offset, TokenType.Dimension, content.join(''));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return this.finishToken(offset, TokenType.Num);
|
|
322
|
+
}
|
|
323
|
+
// String, BadString
|
|
324
|
+
content = [];
|
|
325
|
+
let tokenType = this._string(content);
|
|
326
|
+
if (tokenType !== null) {
|
|
327
|
+
return this.finishToken(offset, tokenType, content.join(''));
|
|
328
|
+
}
|
|
329
|
+
// single character tokens
|
|
330
|
+
tokenType = staticTokenTable[this.stream.peekChar()];
|
|
331
|
+
if (typeof tokenType !== 'undefined') {
|
|
332
|
+
this.stream.advance(1);
|
|
333
|
+
return this.finishToken(offset, tokenType);
|
|
334
|
+
}
|
|
335
|
+
// includes ~=
|
|
336
|
+
if (this.stream.peekChar(0) === _TLD && this.stream.peekChar(1) === _EQS) {
|
|
337
|
+
this.stream.advance(2);
|
|
338
|
+
return this.finishToken(offset, TokenType.Includes);
|
|
339
|
+
}
|
|
340
|
+
// DashMatch |=
|
|
341
|
+
if (this.stream.peekChar(0) === _PIP && this.stream.peekChar(1) === _EQS) {
|
|
342
|
+
this.stream.advance(2);
|
|
343
|
+
return this.finishToken(offset, TokenType.Dashmatch);
|
|
344
|
+
}
|
|
345
|
+
// Substring operator *=
|
|
346
|
+
if (this.stream.peekChar(0) === _MUL && this.stream.peekChar(1) === _EQS) {
|
|
347
|
+
this.stream.advance(2);
|
|
348
|
+
return this.finishToken(offset, TokenType.SubstringOperator);
|
|
349
|
+
}
|
|
350
|
+
// Substring operator ^=
|
|
351
|
+
if (this.stream.peekChar(0) === _HAT && this.stream.peekChar(1) === _EQS) {
|
|
352
|
+
this.stream.advance(2);
|
|
353
|
+
return this.finishToken(offset, TokenType.PrefixOperator);
|
|
354
|
+
}
|
|
355
|
+
// Substring operator $=
|
|
356
|
+
if (this.stream.peekChar(0) === _DLR && this.stream.peekChar(1) === _EQS) {
|
|
357
|
+
this.stream.advance(2);
|
|
358
|
+
return this.finishToken(offset, TokenType.SuffixOperator);
|
|
359
|
+
}
|
|
360
|
+
// Delim
|
|
361
|
+
this.stream.nextChar();
|
|
362
|
+
return this.finishToken(offset, TokenType.Delim);
|
|
363
|
+
}
|
|
364
|
+
trivia() {
|
|
365
|
+
while (true) {
|
|
366
|
+
const offset = this.stream.pos();
|
|
367
|
+
if (this._whitespace()) {
|
|
368
|
+
if (!this.ignoreWhitespace) {
|
|
369
|
+
return this.finishToken(offset, TokenType.Whitespace);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
else if (this.comment()) {
|
|
373
|
+
if (!this.ignoreComment) {
|
|
374
|
+
return this.finishToken(offset, TokenType.Comment);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
comment() {
|
|
383
|
+
if (this.stream.advanceIfChars([_FSL, _MUL])) {
|
|
384
|
+
let success = false, hot = false;
|
|
385
|
+
this.stream.advanceWhileChar((ch) => {
|
|
386
|
+
if (hot && ch === _FSL) {
|
|
387
|
+
success = true;
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
hot = ch === _MUL;
|
|
391
|
+
return true;
|
|
392
|
+
});
|
|
393
|
+
if (success) {
|
|
394
|
+
this.stream.advance(1);
|
|
395
|
+
}
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
_number() {
|
|
401
|
+
let npeek = 0, ch;
|
|
402
|
+
if (this.stream.peekChar() === _DOT) {
|
|
403
|
+
npeek = 1;
|
|
404
|
+
}
|
|
405
|
+
ch = this.stream.peekChar(npeek);
|
|
406
|
+
if (ch >= _0 && ch <= _9) {
|
|
407
|
+
this.stream.advance(npeek + 1);
|
|
408
|
+
this.stream.advanceWhileChar((ch) => {
|
|
409
|
+
return ch >= _0 && ch <= _9 || npeek === 0 && ch === _DOT;
|
|
410
|
+
});
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
_newline(result) {
|
|
416
|
+
const ch = this.stream.peekChar();
|
|
417
|
+
switch (ch) {
|
|
418
|
+
case _CAR:
|
|
419
|
+
case _LFD:
|
|
420
|
+
case _NWL:
|
|
421
|
+
this.stream.advance(1);
|
|
422
|
+
result.push(String.fromCharCode(ch));
|
|
423
|
+
if (ch === _CAR && this.stream.advanceIfChar(_NWL)) {
|
|
424
|
+
result.push('\n');
|
|
425
|
+
}
|
|
426
|
+
return true;
|
|
427
|
+
}
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
_escape(result, includeNewLines) {
|
|
431
|
+
let ch = this.stream.peekChar();
|
|
432
|
+
if (ch === _BSL) {
|
|
433
|
+
this.stream.advance(1);
|
|
434
|
+
ch = this.stream.peekChar();
|
|
435
|
+
let hexNumCount = 0;
|
|
436
|
+
while (hexNumCount < 6 && (ch >= _0 && ch <= _9 || ch >= _a && ch <= _f || ch >= _A && ch <= _F)) {
|
|
437
|
+
this.stream.advance(1);
|
|
438
|
+
ch = this.stream.peekChar();
|
|
439
|
+
hexNumCount++;
|
|
440
|
+
}
|
|
441
|
+
if (hexNumCount > 0) {
|
|
442
|
+
try {
|
|
443
|
+
const hexVal = parseInt(this.stream.substring(this.stream.pos() - hexNumCount), 16);
|
|
444
|
+
if (hexVal) {
|
|
445
|
+
result.push(String.fromCharCode(hexVal));
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
catch (e) {
|
|
449
|
+
// ignore
|
|
450
|
+
}
|
|
451
|
+
// optional whitespace or new line, not part of result text
|
|
452
|
+
if (ch === _WSP || ch === _TAB) {
|
|
453
|
+
this.stream.advance(1);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
this._newline([]);
|
|
457
|
+
}
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
if (ch !== _CAR && ch !== _LFD && ch !== _NWL) {
|
|
461
|
+
this.stream.advance(1);
|
|
462
|
+
result.push(String.fromCharCode(ch));
|
|
463
|
+
return true;
|
|
464
|
+
}
|
|
465
|
+
else if (includeNewLines) {
|
|
466
|
+
return this._newline(result);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
_stringChar(closeQuote, result) {
|
|
472
|
+
// not closeQuote, not backslash, not newline
|
|
473
|
+
const ch = this.stream.peekChar();
|
|
474
|
+
if (ch !== 0 && ch !== closeQuote && ch !== _BSL && ch !== _CAR && ch !== _LFD && ch !== _NWL) {
|
|
475
|
+
this.stream.advance(1);
|
|
476
|
+
result.push(String.fromCharCode(ch));
|
|
477
|
+
return true;
|
|
478
|
+
}
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
_string(result) {
|
|
482
|
+
if (this.stream.peekChar() === _SQO || this.stream.peekChar() === _DQO) {
|
|
483
|
+
const closeQuote = this.stream.nextChar();
|
|
484
|
+
result.push(String.fromCharCode(closeQuote));
|
|
485
|
+
while (this._stringChar(closeQuote, result) || this._escape(result, true)) {
|
|
486
|
+
// loop
|
|
487
|
+
}
|
|
488
|
+
if (this.stream.peekChar() === closeQuote) {
|
|
489
|
+
this.stream.nextChar();
|
|
490
|
+
result.push(String.fromCharCode(closeQuote));
|
|
491
|
+
return TokenType.String;
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
return TokenType.BadString;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
_unquotedChar(result) {
|
|
500
|
+
// not closeQuote, not backslash, not newline
|
|
501
|
+
const ch = this.stream.peekChar();
|
|
502
|
+
if (ch !== 0 && ch !== _BSL && ch !== _SQO && ch !== _DQO && ch !== _LPA && ch !== _RPA && ch !== _WSP && ch !== _TAB && ch !== _NWL && ch !== _LFD && ch !== _CAR) {
|
|
503
|
+
this.stream.advance(1);
|
|
504
|
+
result.push(String.fromCharCode(ch));
|
|
505
|
+
return true;
|
|
506
|
+
}
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
_unquotedString(result) {
|
|
510
|
+
let hasContent = false;
|
|
511
|
+
while (this._unquotedChar(result) || this._escape(result)) {
|
|
512
|
+
hasContent = true;
|
|
513
|
+
}
|
|
514
|
+
return hasContent;
|
|
515
|
+
}
|
|
516
|
+
_whitespace() {
|
|
517
|
+
const n = this.stream.advanceWhileChar((ch) => {
|
|
518
|
+
return ch === _WSP || ch === _TAB || ch === _NWL || ch === _LFD || ch === _CAR;
|
|
519
|
+
});
|
|
520
|
+
return n > 0;
|
|
521
|
+
}
|
|
522
|
+
_name(result) {
|
|
523
|
+
let matched = false;
|
|
524
|
+
while (this._identChar(result) || this._escape(result)) {
|
|
525
|
+
matched = true;
|
|
526
|
+
}
|
|
527
|
+
return matched;
|
|
528
|
+
}
|
|
529
|
+
ident(result) {
|
|
530
|
+
const pos = this.stream.pos();
|
|
531
|
+
const hasMinus = this._minus(result);
|
|
532
|
+
if (hasMinus) {
|
|
533
|
+
if (this._minus(result) /* -- */ || this._identFirstChar(result) || this._escape(result)) {
|
|
534
|
+
while (this._identChar(result) || this._escape(result)) {
|
|
535
|
+
// loop
|
|
536
|
+
}
|
|
537
|
+
return true;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
else if (this._identFirstChar(result) || this._escape(result)) {
|
|
541
|
+
while (this._identChar(result) || this._escape(result)) {
|
|
542
|
+
// loop
|
|
543
|
+
}
|
|
544
|
+
return true;
|
|
545
|
+
}
|
|
546
|
+
this.stream.goBackTo(pos);
|
|
547
|
+
return false;
|
|
548
|
+
}
|
|
549
|
+
_identFirstChar(result) {
|
|
550
|
+
const ch = this.stream.peekChar();
|
|
551
|
+
if (ch === _USC || // _
|
|
552
|
+
ch >= _a && ch <= _z || // a-z
|
|
553
|
+
ch >= _A && ch <= _Z || // A-Z
|
|
554
|
+
ch >= 0x80 && ch <= 0xFFFF) { // nonascii
|
|
555
|
+
this.stream.advance(1);
|
|
556
|
+
result.push(String.fromCharCode(ch));
|
|
557
|
+
return true;
|
|
558
|
+
}
|
|
559
|
+
return false;
|
|
560
|
+
}
|
|
561
|
+
_minus(result) {
|
|
562
|
+
const ch = this.stream.peekChar();
|
|
563
|
+
if (ch === _MIN) {
|
|
564
|
+
this.stream.advance(1);
|
|
565
|
+
result.push(String.fromCharCode(ch));
|
|
566
|
+
return true;
|
|
567
|
+
}
|
|
568
|
+
return false;
|
|
569
|
+
}
|
|
570
|
+
_identChar(result) {
|
|
571
|
+
const ch = this.stream.peekChar();
|
|
572
|
+
if (ch === _USC || // _
|
|
573
|
+
ch === _MIN || // -
|
|
574
|
+
ch >= _a && ch <= _z || // a-z
|
|
575
|
+
ch >= _A && ch <= _Z || // A-Z
|
|
576
|
+
ch >= _0 && ch <= _9 || // 0/9
|
|
577
|
+
ch >= 0x80 && ch <= 0xFFFF) { // nonascii
|
|
578
|
+
this.stream.advance(1);
|
|
579
|
+
result.push(String.fromCharCode(ch));
|
|
580
|
+
return true;
|
|
581
|
+
}
|
|
582
|
+
return false;
|
|
583
|
+
}
|
|
584
|
+
_unicodeRange() {
|
|
585
|
+
// follow https://www.w3.org/TR/CSS21/syndata.html#tokenization and https://www.w3.org/TR/css-syntax-3/#urange-syntax
|
|
586
|
+
// assume u has already been parsed
|
|
587
|
+
if (this.stream.advanceIfChar(_PLS)) {
|
|
588
|
+
const isHexDigit = (ch) => (ch >= _0 && ch <= _9 || ch >= _a && ch <= _f || ch >= _A && ch <= _F);
|
|
589
|
+
const codePoints = this.stream.advanceWhileChar(isHexDigit) + this.stream.advanceWhileChar(ch => ch === _QSM);
|
|
590
|
+
if (codePoints >= 1 && codePoints <= 6) {
|
|
591
|
+
if (this.stream.advanceIfChar(_MIN)) {
|
|
592
|
+
const digits = this.stream.advanceWhileChar(isHexDigit);
|
|
593
|
+
if (digits >= 1 && digits <= 6) {
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
return true;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
exports.Scanner = Scanner;
|
|
606
|
+
});
|