vscode-css-languageservice 5.4.2 → 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 +7 -1
- package/SECURITY.md +41 -0
- package/lib/esm/beautify/beautify-css.js +11 -4
- package/lib/esm/cssLanguageService.d.ts +2 -1
- package/lib/esm/cssLanguageService.js +15 -17
- package/lib/esm/cssLanguageTypes.js +2 -2
- package/lib/esm/data/webCustomData.js +356 -232
- package/lib/esm/languageFacts/builtinData.js +15 -15
- package/lib/esm/languageFacts/colors.js +66 -69
- package/lib/esm/languageFacts/dataManager.js +38 -42
- package/lib/esm/languageFacts/dataProvider.js +17 -23
- package/lib/esm/languageFacts/entry.js +22 -23
- package/lib/esm/parser/cssErrors.js +5 -7
- package/lib/esm/parser/cssNodes.js +869 -1377
- package/lib/esm/parser/cssParser.js +419 -376
- package/lib/esm/parser/cssScanner.js +168 -175
- package/lib/esm/parser/cssSymbolScope.js +107 -137
- package/lib/esm/parser/lessParser.js +177 -202
- package/lib/esm/parser/lessScanner.js +22 -43
- package/lib/esm/parser/scssErrors.js +5 -7
- package/lib/esm/parser/scssParser.js +196 -208
- package/lib/esm/parser/scssScanner.js +33 -54
- package/lib/esm/services/cssCodeActions.js +36 -40
- package/lib/esm/services/cssCompletion.js +300 -395
- package/lib/esm/services/cssFolding.js +32 -35
- package/lib/esm/services/cssFormatter.js +22 -22
- package/lib/esm/services/cssHover.js +30 -33
- package/lib/esm/services/cssNavigation.js +260 -289
- package/lib/esm/services/cssSelectionRange.js +6 -6
- package/lib/esm/services/cssValidation.js +13 -16
- package/lib/esm/services/lessCompletion.js +351 -370
- package/lib/esm/services/lint.js +161 -175
- package/lib/esm/services/lintRules.js +20 -27
- package/lib/esm/services/lintUtil.js +19 -28
- package/lib/esm/services/pathCompletion.js +84 -158
- package/lib/esm/services/scssCompletion.js +283 -307
- package/lib/esm/services/scssNavigation.js +65 -137
- package/lib/esm/services/selectorPrinting.js +131 -175
- package/lib/esm/utils/arrays.js +6 -12
- package/lib/esm/utils/objects.js +1 -1
- package/lib/esm/utils/resources.js +3 -16
- package/lib/esm/utils/strings.js +10 -12
- package/lib/umd/beautify/beautify-css.js +11 -4
- package/lib/umd/cssLanguageService.d.ts +2 -1
- package/lib/umd/cssLanguageService.js +34 -32
- package/lib/umd/cssLanguageTypes.js +4 -3
- package/lib/umd/data/webCustomData.js +355 -231
- package/lib/umd/languageFacts/colors.js +65 -68
- package/lib/umd/languageFacts/dataManager.js +41 -44
- package/lib/umd/languageFacts/dataProvider.js +17 -22
- package/lib/umd/languageFacts/entry.js +22 -23
- package/lib/umd/languageFacts/facts.js +5 -1
- package/lib/umd/parser/cssErrors.js +5 -6
- package/lib/umd/parser/cssNodes.js +870 -1307
- package/lib/umd/parser/cssParser.js +424 -380
- package/lib/umd/parser/cssScanner.js +168 -173
- package/lib/umd/parser/cssSymbolScope.js +109 -134
- package/lib/umd/parser/lessParser.js +182 -206
- package/lib/umd/parser/lessScanner.js +22 -42
- package/lib/umd/parser/scssErrors.js +5 -6
- package/lib/umd/parser/scssParser.js +202 -213
- package/lib/umd/parser/scssScanner.js +25 -45
- package/lib/umd/services/cssCodeActions.js +41 -44
- package/lib/umd/services/cssCompletion.js +308 -402
- package/lib/umd/services/cssFolding.js +35 -38
- package/lib/umd/services/cssFormatter.js +25 -25
- package/lib/umd/services/cssHover.js +36 -38
- package/lib/umd/services/cssNavigation.js +267 -295
- package/lib/umd/services/cssSelectionRange.js +8 -8
- package/lib/umd/services/cssValidation.js +17 -19
- package/lib/umd/services/lessCompletion.js +354 -372
- package/lib/umd/services/lint.js +167 -180
- package/lib/umd/services/lintRules.js +20 -24
- package/lib/umd/services/lintUtil.js +20 -28
- package/lib/umd/services/pathCompletion.js +87 -160
- package/lib/umd/services/scssCompletion.js +287 -310
- package/lib/umd/services/scssNavigation.js +69 -140
- package/lib/umd/services/selectorPrinting.js +134 -174
- package/lib/umd/utils/arrays.js +6 -12
- package/lib/umd/utils/objects.js +1 -1
- package/lib/umd/utils/resources.js +4 -17
- package/lib/umd/utils/strings.js +10 -12
- package/package.json +16 -15
|
@@ -3,15 +3,6 @@
|
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
'use strict';
|
|
6
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
7
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
8
|
-
if (ar || !(i in from)) {
|
|
9
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
10
|
-
ar[i] = from[i];
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
14
|
-
};
|
|
15
6
|
import { TokenType, Scanner } from './cssScanner';
|
|
16
7
|
import * as nodes from './cssNodes';
|
|
17
8
|
import { ParseError } from './cssErrors';
|
|
@@ -22,80 +13,74 @@ import { isDefined } from '../utils/objects';
|
|
|
22
13
|
/// https://www.w3.org/TR/CSS21/grammar.html
|
|
23
14
|
/// http://www.w3.org/TR/CSS21/syndata.html#tokenization
|
|
24
15
|
/// </summary>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (scnr === void 0) { scnr = new Scanner(); }
|
|
16
|
+
export class Parser {
|
|
17
|
+
constructor(scnr = new Scanner()) {
|
|
28
18
|
this.keyframeRegex = /^@(\-(webkit|ms|moz|o)\-)?keyframes$/i;
|
|
29
19
|
this.scanner = scnr;
|
|
30
20
|
this.token = { type: TokenType.EOF, offset: -1, len: 0, text: '' };
|
|
31
21
|
this.prevToken = undefined;
|
|
32
22
|
}
|
|
33
|
-
|
|
23
|
+
peekIdent(text) {
|
|
34
24
|
return TokenType.Ident === this.token.type && text.length === this.token.text.length && text === this.token.text.toLowerCase();
|
|
35
|
-
}
|
|
36
|
-
|
|
25
|
+
}
|
|
26
|
+
peekKeyword(text) {
|
|
37
27
|
return TokenType.AtKeyword === this.token.type && text.length === this.token.text.length && text === this.token.text.toLowerCase();
|
|
38
|
-
}
|
|
39
|
-
|
|
28
|
+
}
|
|
29
|
+
peekDelim(text) {
|
|
40
30
|
return TokenType.Delim === this.token.type && text === this.token.text;
|
|
41
|
-
}
|
|
42
|
-
|
|
31
|
+
}
|
|
32
|
+
peek(type) {
|
|
43
33
|
return type === this.token.type;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
var types = [];
|
|
47
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
48
|
-
types[_i] = arguments[_i];
|
|
49
|
-
}
|
|
34
|
+
}
|
|
35
|
+
peekOne(...types) {
|
|
50
36
|
return types.indexOf(this.token.type) !== -1;
|
|
51
|
-
}
|
|
52
|
-
|
|
37
|
+
}
|
|
38
|
+
peekRegExp(type, regEx) {
|
|
53
39
|
if (type !== this.token.type) {
|
|
54
40
|
return false;
|
|
55
41
|
}
|
|
56
42
|
return regEx.test(this.token.text);
|
|
57
|
-
}
|
|
58
|
-
|
|
43
|
+
}
|
|
44
|
+
hasWhitespace() {
|
|
59
45
|
return !!this.prevToken && (this.prevToken.offset + this.prevToken.len !== this.token.offset);
|
|
60
|
-
}
|
|
61
|
-
|
|
46
|
+
}
|
|
47
|
+
consumeToken() {
|
|
62
48
|
this.prevToken = this.token;
|
|
63
49
|
this.token = this.scanner.scan();
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
}
|
|
51
|
+
acceptUnicodeRange() {
|
|
52
|
+
const token = this.scanner.tryScanUnicode();
|
|
67
53
|
if (token) {
|
|
68
54
|
this.prevToken = token;
|
|
69
55
|
this.token = this.scanner.scan();
|
|
70
56
|
return true;
|
|
71
57
|
}
|
|
72
58
|
return false;
|
|
73
|
-
}
|
|
74
|
-
|
|
59
|
+
}
|
|
60
|
+
mark() {
|
|
75
61
|
return {
|
|
76
62
|
prev: this.prevToken,
|
|
77
63
|
curr: this.token,
|
|
78
64
|
pos: this.scanner.pos()
|
|
79
65
|
};
|
|
80
|
-
}
|
|
81
|
-
|
|
66
|
+
}
|
|
67
|
+
restoreAtMark(mark) {
|
|
82
68
|
this.prevToken = mark.prev;
|
|
83
69
|
this.token = mark.curr;
|
|
84
70
|
this.scanner.goBackTo(mark.pos);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
71
|
+
}
|
|
72
|
+
try(func) {
|
|
73
|
+
const pos = this.mark();
|
|
74
|
+
const node = func();
|
|
89
75
|
if (!node) {
|
|
90
76
|
this.restoreAtMark(pos);
|
|
91
77
|
return null;
|
|
92
78
|
}
|
|
93
79
|
return node;
|
|
94
|
-
}
|
|
95
|
-
|
|
80
|
+
}
|
|
81
|
+
acceptOneKeyword(keywords) {
|
|
96
82
|
if (TokenType.AtKeyword === this.token.type) {
|
|
97
|
-
for (
|
|
98
|
-
var keyword = keywords_1[_i];
|
|
83
|
+
for (const keyword of keywords) {
|
|
99
84
|
if (keyword.length === this.token.text.length && keyword === this.token.text.toLowerCase()) {
|
|
100
85
|
this.consumeToken();
|
|
101
86
|
return true;
|
|
@@ -103,51 +88,51 @@ var Parser = /** @class */ (function () {
|
|
|
103
88
|
}
|
|
104
89
|
}
|
|
105
90
|
return false;
|
|
106
|
-
}
|
|
107
|
-
|
|
91
|
+
}
|
|
92
|
+
accept(type) {
|
|
108
93
|
if (type === this.token.type) {
|
|
109
94
|
this.consumeToken();
|
|
110
95
|
return true;
|
|
111
96
|
}
|
|
112
97
|
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
98
|
+
}
|
|
99
|
+
acceptIdent(text) {
|
|
115
100
|
if (this.peekIdent(text)) {
|
|
116
101
|
this.consumeToken();
|
|
117
102
|
return true;
|
|
118
103
|
}
|
|
119
104
|
return false;
|
|
120
|
-
}
|
|
121
|
-
|
|
105
|
+
}
|
|
106
|
+
acceptKeyword(text) {
|
|
122
107
|
if (this.peekKeyword(text)) {
|
|
123
108
|
this.consumeToken();
|
|
124
109
|
return true;
|
|
125
110
|
}
|
|
126
111
|
return false;
|
|
127
|
-
}
|
|
128
|
-
|
|
112
|
+
}
|
|
113
|
+
acceptDelim(text) {
|
|
129
114
|
if (this.peekDelim(text)) {
|
|
130
115
|
this.consumeToken();
|
|
131
116
|
return true;
|
|
132
117
|
}
|
|
133
118
|
return false;
|
|
134
|
-
}
|
|
135
|
-
|
|
119
|
+
}
|
|
120
|
+
acceptRegexp(regEx) {
|
|
136
121
|
if (regEx.test(this.token.text)) {
|
|
137
122
|
this.consumeToken();
|
|
138
123
|
return true;
|
|
139
124
|
}
|
|
140
125
|
return false;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
126
|
+
}
|
|
127
|
+
_parseRegexp(regEx) {
|
|
128
|
+
let node = this.createNode(nodes.NodeType.Identifier);
|
|
144
129
|
do { } while (this.acceptRegexp(regEx));
|
|
145
130
|
return this.finish(node);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
131
|
+
}
|
|
132
|
+
acceptUnquotedString() {
|
|
133
|
+
const pos = this.scanner.pos();
|
|
149
134
|
this.scanner.goBackTo(this.token.offset);
|
|
150
|
-
|
|
135
|
+
const unquoted = this.scanner.scanUnquotedString();
|
|
151
136
|
if (unquoted) {
|
|
152
137
|
this.token = unquoted;
|
|
153
138
|
this.consumeToken();
|
|
@@ -155,8 +140,8 @@ var Parser = /** @class */ (function () {
|
|
|
155
140
|
}
|
|
156
141
|
this.scanner.goBackTo(pos);
|
|
157
142
|
return false;
|
|
158
|
-
}
|
|
159
|
-
|
|
143
|
+
}
|
|
144
|
+
resync(resyncTokens, resyncStopTokens) {
|
|
160
145
|
while (true) {
|
|
161
146
|
if (resyncTokens && resyncTokens.indexOf(this.token.type) !== -1) {
|
|
162
147
|
this.consumeToken();
|
|
@@ -172,14 +157,14 @@ var Parser = /** @class */ (function () {
|
|
|
172
157
|
this.token = this.scanner.scan();
|
|
173
158
|
}
|
|
174
159
|
}
|
|
175
|
-
}
|
|
176
|
-
|
|
160
|
+
}
|
|
161
|
+
createNode(nodeType) {
|
|
177
162
|
return new nodes.Node(this.token.offset, this.token.len, nodeType);
|
|
178
|
-
}
|
|
179
|
-
|
|
163
|
+
}
|
|
164
|
+
create(ctor) {
|
|
180
165
|
return new ctor(this.token.offset, this.token.len);
|
|
181
|
-
}
|
|
182
|
-
|
|
166
|
+
}
|
|
167
|
+
finish(node, error, resyncTokens, resyncStopTokens) {
|
|
183
168
|
// parseNumeric misuses error for boolean flagging (however the real error mustn't be a false)
|
|
184
169
|
// + nodelist offsets mustn't be modified, because there is a offset hack in rulesets for smartselection
|
|
185
170
|
if (!(node instanceof nodes.Nodelist)) {
|
|
@@ -189,13 +174,13 @@ var Parser = /** @class */ (function () {
|
|
|
189
174
|
// set the node end position
|
|
190
175
|
if (this.prevToken) {
|
|
191
176
|
// length with more elements belonging together
|
|
192
|
-
|
|
177
|
+
const prevEnd = this.prevToken.offset + this.prevToken.len;
|
|
193
178
|
node.length = prevEnd > node.offset ? prevEnd - node.offset : 0; // offset is taken from current token, end from previous: Use 0 for empty nodes
|
|
194
179
|
}
|
|
195
180
|
}
|
|
196
181
|
return node;
|
|
197
|
-
}
|
|
198
|
-
|
|
182
|
+
}
|
|
183
|
+
markError(node, error, resyncTokens, resyncStopTokens) {
|
|
199
184
|
if (this.token !== this.lastErrorToken) { // do not report twice on the same token
|
|
200
185
|
node.addIssue(new nodes.Marker(node, error, nodes.Level.Error, undefined, this.token.offset, this.token.len));
|
|
201
186
|
this.lastErrorToken = this.token;
|
|
@@ -203,43 +188,43 @@ var Parser = /** @class */ (function () {
|
|
|
203
188
|
if (resyncTokens || resyncStopTokens) {
|
|
204
189
|
this.resync(resyncTokens, resyncStopTokens);
|
|
205
190
|
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
191
|
+
}
|
|
192
|
+
parseStylesheet(textDocument) {
|
|
193
|
+
const versionId = textDocument.version;
|
|
194
|
+
const text = textDocument.getText();
|
|
195
|
+
const textProvider = (offset, length) => {
|
|
211
196
|
if (textDocument.version !== versionId) {
|
|
212
197
|
throw new Error('Underlying model has changed, AST is no longer valid');
|
|
213
198
|
}
|
|
214
199
|
return text.substr(offset, length);
|
|
215
200
|
};
|
|
216
201
|
return this.internalParse(text, this._parseStylesheet, textProvider);
|
|
217
|
-
}
|
|
218
|
-
|
|
202
|
+
}
|
|
203
|
+
internalParse(input, parseFunc, textProvider) {
|
|
219
204
|
this.scanner.setSource(input);
|
|
220
205
|
this.token = this.scanner.scan();
|
|
221
|
-
|
|
206
|
+
const node = parseFunc.bind(this)();
|
|
222
207
|
if (node) {
|
|
223
208
|
if (textProvider) {
|
|
224
209
|
node.textProvider = textProvider;
|
|
225
210
|
}
|
|
226
211
|
else {
|
|
227
|
-
node.textProvider =
|
|
212
|
+
node.textProvider = (offset, length) => { return input.substr(offset, length); };
|
|
228
213
|
}
|
|
229
214
|
}
|
|
230
215
|
return node;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
|
|
216
|
+
}
|
|
217
|
+
_parseStylesheet() {
|
|
218
|
+
const node = this.create(nodes.Stylesheet);
|
|
234
219
|
while (node.addChild(this._parseStylesheetStart())) {
|
|
235
220
|
// Parse statements only valid at the beginning of stylesheets.
|
|
236
221
|
}
|
|
237
|
-
|
|
222
|
+
let inRecovery = false;
|
|
238
223
|
do {
|
|
239
|
-
|
|
224
|
+
let hasMatch = false;
|
|
240
225
|
do {
|
|
241
226
|
hasMatch = false;
|
|
242
|
-
|
|
227
|
+
const statement = this._parseStylesheetStatement();
|
|
243
228
|
if (statement) {
|
|
244
229
|
node.addChild(statement);
|
|
245
230
|
hasMatch = true;
|
|
@@ -269,32 +254,31 @@ var Parser = /** @class */ (function () {
|
|
|
269
254
|
this.consumeToken();
|
|
270
255
|
} while (!this.peek(TokenType.EOF));
|
|
271
256
|
return this.finish(node);
|
|
272
|
-
}
|
|
273
|
-
|
|
257
|
+
}
|
|
258
|
+
_parseStylesheetStart() {
|
|
274
259
|
return this._parseCharset();
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
if (isNested === void 0) { isNested = false; }
|
|
260
|
+
}
|
|
261
|
+
_parseStylesheetStatement(isNested = false) {
|
|
278
262
|
if (this.peek(TokenType.AtKeyword)) {
|
|
279
263
|
return this._parseStylesheetAtStatement(isNested);
|
|
280
264
|
}
|
|
281
265
|
return this._parseRuleset(isNested);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (isNested === void 0) { isNested = false; }
|
|
266
|
+
}
|
|
267
|
+
_parseStylesheetAtStatement(isNested = false) {
|
|
285
268
|
return this._parseImport()
|
|
286
269
|
|| this._parseMedia(isNested)
|
|
287
270
|
|| this._parsePage()
|
|
288
271
|
|| this._parseFontFace()
|
|
289
272
|
|| this._parseKeyframe()
|
|
290
273
|
|| this._parseSupports(isNested)
|
|
274
|
+
|| this._parseLayer()
|
|
291
275
|
|| this._parseViewPort()
|
|
292
276
|
|| this._parseNamespace()
|
|
293
277
|
|| this._parseDocument()
|
|
294
278
|
|| this._parseUnknownAtRule();
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
|
|
279
|
+
}
|
|
280
|
+
_tryParseRuleset(isNested) {
|
|
281
|
+
const mark = this.mark();
|
|
298
282
|
if (this._parseSelector(isNested)) {
|
|
299
283
|
while (this.accept(TokenType.Comma) && this._parseSelector(isNested)) {
|
|
300
284
|
// loop
|
|
@@ -306,11 +290,10 @@ var Parser = /** @class */ (function () {
|
|
|
306
290
|
}
|
|
307
291
|
this.restoreAtMark(mark);
|
|
308
292
|
return null;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
var selectors = node.getSelectors();
|
|
293
|
+
}
|
|
294
|
+
_parseRuleset(isNested = false) {
|
|
295
|
+
const node = this.create(nodes.RuleSet);
|
|
296
|
+
const selectors = node.getSelectors();
|
|
314
297
|
if (!selectors.addChild(this._parseSelector(isNested))) {
|
|
315
298
|
return null;
|
|
316
299
|
}
|
|
@@ -320,18 +303,18 @@ var Parser = /** @class */ (function () {
|
|
|
320
303
|
}
|
|
321
304
|
}
|
|
322
305
|
return this._parseBody(node, this._parseRuleSetDeclaration.bind(this));
|
|
323
|
-
}
|
|
324
|
-
|
|
306
|
+
}
|
|
307
|
+
_parseRuleSetDeclarationAtStatement() {
|
|
325
308
|
return this._parseUnknownAtRule();
|
|
326
|
-
}
|
|
327
|
-
|
|
309
|
+
}
|
|
310
|
+
_parseRuleSetDeclaration() {
|
|
328
311
|
// https://www.w3.org/TR/css-syntax-3/#consume-a-list-of-declarations
|
|
329
312
|
if (this.peek(TokenType.AtKeyword)) {
|
|
330
313
|
return this._parseRuleSetDeclarationAtStatement();
|
|
331
314
|
}
|
|
332
315
|
return this._parseDeclaration();
|
|
333
|
-
}
|
|
334
|
-
|
|
316
|
+
}
|
|
317
|
+
_needsSemicolonAfter(node) {
|
|
335
318
|
switch (node.type) {
|
|
336
319
|
case nodes.NodeType.Keyframe:
|
|
337
320
|
case nodes.NodeType.ViewPort:
|
|
@@ -363,13 +346,13 @@ var Parser = /** @class */ (function () {
|
|
|
363
346
|
return !node.getNestedProperties();
|
|
364
347
|
}
|
|
365
348
|
return false;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
|
|
349
|
+
}
|
|
350
|
+
_parseDeclarations(parseDeclaration) {
|
|
351
|
+
const node = this.create(nodes.Declarations);
|
|
369
352
|
if (!this.accept(TokenType.CurlyL)) {
|
|
370
353
|
return null;
|
|
371
354
|
}
|
|
372
|
-
|
|
355
|
+
let decl = parseDeclaration();
|
|
373
356
|
while (node.addChild(decl)) {
|
|
374
357
|
if (this.peek(TokenType.CurlyR)) {
|
|
375
358
|
break;
|
|
@@ -390,16 +373,16 @@ var Parser = /** @class */ (function () {
|
|
|
390
373
|
return this.finish(node, ParseError.RightCurlyExpected, [TokenType.CurlyR, TokenType.SemiColon]);
|
|
391
374
|
}
|
|
392
375
|
return this.finish(node);
|
|
393
|
-
}
|
|
394
|
-
|
|
376
|
+
}
|
|
377
|
+
_parseBody(node, parseDeclaration) {
|
|
395
378
|
if (!node.setDeclarations(this._parseDeclarations(parseDeclaration))) {
|
|
396
379
|
return this.finish(node, ParseError.LeftCurlyExpected, [TokenType.CurlyR, TokenType.SemiColon]);
|
|
397
380
|
}
|
|
398
381
|
return this.finish(node);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
382
|
+
}
|
|
383
|
+
_parseSelector(isNested) {
|
|
384
|
+
const node = this.create(nodes.Selector);
|
|
385
|
+
let hasContent = false;
|
|
403
386
|
if (isNested) {
|
|
404
387
|
// nested selectors can start with a combinator
|
|
405
388
|
hasContent = node.addChild(this._parseCombinator());
|
|
@@ -409,13 +392,13 @@ var Parser = /** @class */ (function () {
|
|
|
409
392
|
node.addChild(this._parseCombinator()); // optional
|
|
410
393
|
}
|
|
411
394
|
return hasContent ? this.finish(node) : null;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
|
|
395
|
+
}
|
|
396
|
+
_parseDeclaration(stopTokens) {
|
|
397
|
+
const custonProperty = this._tryParseCustomPropertyDeclaration(stopTokens);
|
|
415
398
|
if (custonProperty) {
|
|
416
399
|
return custonProperty;
|
|
417
400
|
}
|
|
418
|
-
|
|
401
|
+
const node = this.create(nodes.Declaration);
|
|
419
402
|
if (!node.setProperty(this._parseProperty())) {
|
|
420
403
|
return null;
|
|
421
404
|
}
|
|
@@ -433,12 +416,12 @@ var Parser = /** @class */ (function () {
|
|
|
433
416
|
node.semicolonPosition = this.token.offset; // not part of the declaration, but useful information for code assist
|
|
434
417
|
}
|
|
435
418
|
return this.finish(node);
|
|
436
|
-
}
|
|
437
|
-
|
|
419
|
+
}
|
|
420
|
+
_tryParseCustomPropertyDeclaration(stopTokens) {
|
|
438
421
|
if (!this.peekRegExp(TokenType.Ident, /^--/)) {
|
|
439
422
|
return null;
|
|
440
423
|
}
|
|
441
|
-
|
|
424
|
+
const node = this.create(nodes.CustomPropertyDeclaration);
|
|
442
425
|
if (!node.setProperty(this._parseProperty())) {
|
|
443
426
|
return null;
|
|
444
427
|
}
|
|
@@ -448,11 +431,11 @@ var Parser = /** @class */ (function () {
|
|
|
448
431
|
if (this.prevToken) {
|
|
449
432
|
node.colonPosition = this.prevToken.offset;
|
|
450
433
|
}
|
|
451
|
-
|
|
434
|
+
const mark = this.mark();
|
|
452
435
|
if (this.peek(TokenType.CurlyL)) {
|
|
453
436
|
// try to parse it as nested declaration
|
|
454
|
-
|
|
455
|
-
|
|
437
|
+
const propertySet = this.create(nodes.CustomPropertySet);
|
|
438
|
+
const declarations = this._parseDeclarations(this._parseRuleSetDeclaration.bind(this));
|
|
456
439
|
if (propertySet.setDeclarations(declarations) && !declarations.isErroneous(true)) {
|
|
457
440
|
propertySet.addChild(this._parsePrio());
|
|
458
441
|
if (this.peek(TokenType.SemiColon)) {
|
|
@@ -465,10 +448,10 @@ var Parser = /** @class */ (function () {
|
|
|
465
448
|
this.restoreAtMark(mark);
|
|
466
449
|
}
|
|
467
450
|
// try to parse as expression
|
|
468
|
-
|
|
451
|
+
const expression = this._parseExpr();
|
|
469
452
|
if (expression && !expression.isErroneous(true)) {
|
|
470
453
|
this._parsePrio();
|
|
471
|
-
if (this.peekOne
|
|
454
|
+
if (this.peekOne(...(stopTokens || []), TokenType.SemiColon, TokenType.EOF)) {
|
|
472
455
|
node.setValue(expression);
|
|
473
456
|
if (this.peek(TokenType.SemiColon)) {
|
|
474
457
|
node.semicolonPosition = this.token.offset; // not part of the declaration, but useful information for code assist
|
|
@@ -483,7 +466,7 @@ var Parser = /** @class */ (function () {
|
|
|
483
466
|
return this.finish(node, ParseError.PropertyValueExpected);
|
|
484
467
|
}
|
|
485
468
|
return this.finish(node);
|
|
486
|
-
}
|
|
469
|
+
}
|
|
487
470
|
/**
|
|
488
471
|
* Parse custom property values.
|
|
489
472
|
*
|
|
@@ -495,15 +478,13 @@ var Parser = /** @class */ (function () {
|
|
|
495
478
|
* terminators like semicolons and !important directives (when not inside
|
|
496
479
|
* of delimitors).
|
|
497
480
|
*/
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
var parensDepth = 0;
|
|
506
|
-
var bracketsDepth = 0;
|
|
481
|
+
_parseCustomPropertyValue(stopTokens = [TokenType.CurlyR]) {
|
|
482
|
+
const node = this.create(nodes.Node);
|
|
483
|
+
const isTopLevel = () => curlyDepth === 0 && parensDepth === 0 && bracketsDepth === 0;
|
|
484
|
+
const onStopToken = () => stopTokens.indexOf(this.token.type) !== -1;
|
|
485
|
+
let curlyDepth = 0;
|
|
486
|
+
let parensDepth = 0;
|
|
487
|
+
let bracketsDepth = 0;
|
|
507
488
|
done: while (true) {
|
|
508
489
|
switch (this.token.type) {
|
|
509
490
|
case TokenType.SemiColon:
|
|
@@ -558,7 +539,7 @@ var Parser = /** @class */ (function () {
|
|
|
558
539
|
case TokenType.EOF:
|
|
559
540
|
// We shouldn't have reached the end of input, something is
|
|
560
541
|
// unterminated.
|
|
561
|
-
|
|
542
|
+
let error = ParseError.RightCurlyExpected;
|
|
562
543
|
if (bracketsDepth > 0) {
|
|
563
544
|
error = ParseError.RightSquareBracketExpected;
|
|
564
545
|
}
|
|
@@ -570,9 +551,9 @@ var Parser = /** @class */ (function () {
|
|
|
570
551
|
this.consumeToken();
|
|
571
552
|
}
|
|
572
553
|
return this.finish(node);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
|
|
554
|
+
}
|
|
555
|
+
_tryToParseDeclaration(stopTokens) {
|
|
556
|
+
const mark = this.mark();
|
|
576
557
|
if (this._parseProperty() && this.accept(TokenType.Colon)) {
|
|
577
558
|
// looks like a declaration, go ahead
|
|
578
559
|
this.restoreAtMark(mark);
|
|
@@ -580,10 +561,10 @@ var Parser = /** @class */ (function () {
|
|
|
580
561
|
}
|
|
581
562
|
this.restoreAtMark(mark);
|
|
582
563
|
return null;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
564
|
+
}
|
|
565
|
+
_parseProperty() {
|
|
566
|
+
const node = this.create(nodes.Property);
|
|
567
|
+
const mark = this.mark();
|
|
587
568
|
if (this.acceptDelim('*') || this.acceptDelim('_')) {
|
|
588
569
|
// support for IE 5.x, 6 and 7 star hack: see http://en.wikipedia.org/wiki/CSS_filter#Star_hack
|
|
589
570
|
if (this.hasWhitespace()) {
|
|
@@ -595,15 +576,15 @@ var Parser = /** @class */ (function () {
|
|
|
595
576
|
return this.finish(node);
|
|
596
577
|
}
|
|
597
578
|
return null;
|
|
598
|
-
}
|
|
599
|
-
|
|
579
|
+
}
|
|
580
|
+
_parsePropertyIdentifier() {
|
|
600
581
|
return this._parseIdent();
|
|
601
|
-
}
|
|
602
|
-
|
|
582
|
+
}
|
|
583
|
+
_parseCharset() {
|
|
603
584
|
if (!this.peek(TokenType.Charset)) {
|
|
604
585
|
return null;
|
|
605
586
|
}
|
|
606
|
-
|
|
587
|
+
const node = this.create(nodes.Node);
|
|
607
588
|
this.consumeToken(); // charset
|
|
608
589
|
if (!this.accept(TokenType.String)) {
|
|
609
590
|
return this.finish(node, ParseError.IdentifierExpected);
|
|
@@ -612,28 +593,51 @@ var Parser = /** @class */ (function () {
|
|
|
612
593
|
return this.finish(node, ParseError.SemiColonExpected);
|
|
613
594
|
}
|
|
614
595
|
return this.finish(node);
|
|
615
|
-
}
|
|
616
|
-
|
|
596
|
+
}
|
|
597
|
+
_parseImport() {
|
|
598
|
+
// @import [ <url> | <string> ]
|
|
599
|
+
// [ layer | layer(<layer-name>) ]?
|
|
600
|
+
// <import-condition> ;
|
|
601
|
+
// <import-conditions> = [ supports( [ <supports-condition> | <declaration> ] ) ]?
|
|
602
|
+
// <media-query-list>?
|
|
617
603
|
if (!this.peekKeyword('@import')) {
|
|
618
604
|
return null;
|
|
619
605
|
}
|
|
620
|
-
|
|
606
|
+
const node = this.create(nodes.Import);
|
|
621
607
|
this.consumeToken(); // @import
|
|
622
608
|
if (!node.addChild(this._parseURILiteral()) && !node.addChild(this._parseStringLiteral())) {
|
|
623
609
|
return this.finish(node, ParseError.URIOrStringExpected);
|
|
624
610
|
}
|
|
611
|
+
if (this.acceptIdent('layer')) {
|
|
612
|
+
if (this.accept(TokenType.ParenthesisL)) {
|
|
613
|
+
if (!node.addChild(this._parseLayerName())) {
|
|
614
|
+
return this.finish(node, ParseError.IdentifierExpected, [TokenType.SemiColon]);
|
|
615
|
+
}
|
|
616
|
+
if (!this.accept(TokenType.ParenthesisR)) {
|
|
617
|
+
return this.finish(node, ParseError.RightParenthesisExpected, [TokenType.ParenthesisR], []);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (this.acceptIdent('supports')) {
|
|
622
|
+
if (this.accept(TokenType.ParenthesisL)) {
|
|
623
|
+
node.addChild(this._tryToParseDeclaration() || this._parseSupportsCondition());
|
|
624
|
+
if (!this.accept(TokenType.ParenthesisR)) {
|
|
625
|
+
return this.finish(node, ParseError.RightParenthesisExpected, [TokenType.ParenthesisR], []);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
625
629
|
if (!this.peek(TokenType.SemiColon) && !this.peek(TokenType.EOF)) {
|
|
626
630
|
node.setMedialist(this._parseMediaQueryList());
|
|
627
631
|
}
|
|
628
632
|
return this.finish(node);
|
|
629
|
-
}
|
|
630
|
-
|
|
633
|
+
}
|
|
634
|
+
_parseNamespace() {
|
|
631
635
|
// http://www.w3.org/TR/css3-namespace/
|
|
632
636
|
// namespace : NAMESPACE_SYM S* [IDENT S*]? [STRING|URI] S* ';' S*
|
|
633
637
|
if (!this.peekKeyword('@namespace')) {
|
|
634
638
|
return null;
|
|
635
639
|
}
|
|
636
|
-
|
|
640
|
+
const node = this.create(nodes.Namespace);
|
|
637
641
|
this.consumeToken(); // @namespace
|
|
638
642
|
if (!node.addChild(this._parseURILiteral())) { // url literal also starts with ident
|
|
639
643
|
node.addChild(this._parseIdent()); // optional prefix
|
|
@@ -645,31 +649,31 @@ var Parser = /** @class */ (function () {
|
|
|
645
649
|
return this.finish(node, ParseError.SemiColonExpected);
|
|
646
650
|
}
|
|
647
651
|
return this.finish(node);
|
|
648
|
-
}
|
|
649
|
-
|
|
652
|
+
}
|
|
653
|
+
_parseFontFace() {
|
|
650
654
|
if (!this.peekKeyword('@font-face')) {
|
|
651
655
|
return null;
|
|
652
656
|
}
|
|
653
|
-
|
|
657
|
+
const node = this.create(nodes.FontFace);
|
|
654
658
|
this.consumeToken(); // @font-face
|
|
655
659
|
return this._parseBody(node, this._parseRuleSetDeclaration.bind(this));
|
|
656
|
-
}
|
|
657
|
-
|
|
660
|
+
}
|
|
661
|
+
_parseViewPort() {
|
|
658
662
|
if (!this.peekKeyword('@-ms-viewport') &&
|
|
659
663
|
!this.peekKeyword('@-o-viewport') &&
|
|
660
664
|
!this.peekKeyword('@viewport')) {
|
|
661
665
|
return null;
|
|
662
666
|
}
|
|
663
|
-
|
|
667
|
+
const node = this.create(nodes.ViewPort);
|
|
664
668
|
this.consumeToken(); // @-ms-viewport
|
|
665
669
|
return this._parseBody(node, this._parseRuleSetDeclaration.bind(this));
|
|
666
|
-
}
|
|
667
|
-
|
|
670
|
+
}
|
|
671
|
+
_parseKeyframe() {
|
|
668
672
|
if (!this.peekRegExp(TokenType.AtKeyword, this.keyframeRegex)) {
|
|
669
673
|
return null;
|
|
670
674
|
}
|
|
671
|
-
|
|
672
|
-
|
|
675
|
+
const node = this.create(nodes.Keyframe);
|
|
676
|
+
const atNode = this.create(nodes.Node);
|
|
673
677
|
this.consumeToken(); // atkeyword
|
|
674
678
|
node.setKeyword(this.finish(atNode));
|
|
675
679
|
if (atNode.matches('@-ms-keyframes')) { // -ms-keyframes never existed
|
|
@@ -679,12 +683,12 @@ var Parser = /** @class */ (function () {
|
|
|
679
683
|
return this.finish(node, ParseError.IdentifierExpected, [TokenType.CurlyR]);
|
|
680
684
|
}
|
|
681
685
|
return this._parseBody(node, this._parseKeyframeSelector.bind(this));
|
|
682
|
-
}
|
|
683
|
-
|
|
686
|
+
}
|
|
687
|
+
_parseKeyframeIdent() {
|
|
684
688
|
return this._parseIdent([nodes.ReferenceType.Keyframe]);
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
|
|
689
|
+
}
|
|
690
|
+
_parseKeyframeSelector() {
|
|
691
|
+
const node = this.create(nodes.KeyframeSelector);
|
|
688
692
|
if (!node.addChild(this._parseIdent()) && !this.accept(TokenType.Percentage)) {
|
|
689
693
|
return null;
|
|
690
694
|
}
|
|
@@ -694,10 +698,10 @@ var Parser = /** @class */ (function () {
|
|
|
694
698
|
}
|
|
695
699
|
}
|
|
696
700
|
return this._parseBody(node, this._parseRuleSetDeclaration.bind(this));
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
+
}
|
|
702
|
+
_tryParseKeyframeSelector() {
|
|
703
|
+
const node = this.create(nodes.KeyframeSelector);
|
|
704
|
+
const pos = this.mark();
|
|
701
705
|
if (!node.addChild(this._parseIdent()) && !this.accept(TokenType.Percentage)) {
|
|
702
706
|
return null;
|
|
703
707
|
}
|
|
@@ -712,20 +716,66 @@ var Parser = /** @class */ (function () {
|
|
|
712
716
|
return null;
|
|
713
717
|
}
|
|
714
718
|
return this._parseBody(node, this._parseRuleSetDeclaration.bind(this));
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
|
|
719
|
+
}
|
|
720
|
+
_parseLayer() {
|
|
721
|
+
// @layer layer-name {rules}
|
|
722
|
+
// @layer layer-name;
|
|
723
|
+
// @layer layer-name, layer-name, layer-name;
|
|
724
|
+
// @layer {rules}
|
|
725
|
+
if (!this.peekKeyword('@layer')) {
|
|
726
|
+
return null;
|
|
727
|
+
}
|
|
728
|
+
const node = this.create(nodes.Layer);
|
|
729
|
+
this.consumeToken(); // @layer
|
|
730
|
+
const names = this._parseLayerNameList();
|
|
731
|
+
if (names) {
|
|
732
|
+
node.setNames(names);
|
|
733
|
+
}
|
|
734
|
+
if ((!names || names.getChildren().length === 1) && this.peek(TokenType.CurlyL)) {
|
|
735
|
+
return this._parseBody(node, this._parseStylesheetStatement.bind(this));
|
|
736
|
+
}
|
|
737
|
+
if (!this.accept(TokenType.SemiColon)) {
|
|
738
|
+
return this.finish(node, ParseError.SemiColonExpected);
|
|
739
|
+
}
|
|
740
|
+
return this.finish(node);
|
|
741
|
+
}
|
|
742
|
+
_parseLayerNameList() {
|
|
743
|
+
const node = this.createNode(nodes.NodeType.LayerNameList);
|
|
744
|
+
if (!node.addChild(this._parseLayerName())) {
|
|
745
|
+
return null;
|
|
746
|
+
}
|
|
747
|
+
while (this.accept(TokenType.Comma)) {
|
|
748
|
+
if (!node.addChild(this._parseLayerName())) {
|
|
749
|
+
return this.finish(node, ParseError.IdentifierExpected);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
return this.finish(node);
|
|
753
|
+
}
|
|
754
|
+
_parseLayerName() {
|
|
755
|
+
// <layer-name> = <ident> [ '.' <ident> ]*
|
|
756
|
+
if (!this.peek(TokenType.Ident)) {
|
|
757
|
+
return null;
|
|
758
|
+
}
|
|
759
|
+
const node = this.createNode(nodes.NodeType.LayerName);
|
|
760
|
+
node.addChild(this._parseIdent());
|
|
761
|
+
while (!this.hasWhitespace() && this.acceptDelim('.')) {
|
|
762
|
+
if (this.hasWhitespace() || !node.addChild(this._parseIdent())) {
|
|
763
|
+
return this.finish(node, ParseError.IdentifierExpected);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
return this.finish(node);
|
|
767
|
+
}
|
|
768
|
+
_parseSupports(isNested = false) {
|
|
718
769
|
// SUPPORTS_SYM S* supports_condition '{' S* ruleset* '}' S*
|
|
719
770
|
if (!this.peekKeyword('@supports')) {
|
|
720
771
|
return null;
|
|
721
772
|
}
|
|
722
|
-
|
|
773
|
+
const node = this.create(nodes.Supports);
|
|
723
774
|
this.consumeToken(); // @supports
|
|
724
775
|
node.addChild(this._parseSupportsCondition());
|
|
725
776
|
return this._parseBody(node, this._parseSupportsDeclaration.bind(this, isNested));
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
if (isNested === void 0) { isNested = false; }
|
|
777
|
+
}
|
|
778
|
+
_parseSupportsDeclaration(isNested = false) {
|
|
729
779
|
if (isNested) {
|
|
730
780
|
// if nested, the body can contain rulesets, but also declarations
|
|
731
781
|
return this._tryParseRuleset(true)
|
|
@@ -733,8 +783,8 @@ var Parser = /** @class */ (function () {
|
|
|
733
783
|
|| this._parseStylesheetStatement(true);
|
|
734
784
|
}
|
|
735
785
|
return this._parseStylesheetStatement(false);
|
|
736
|
-
}
|
|
737
|
-
|
|
786
|
+
}
|
|
787
|
+
_parseSupportsCondition() {
|
|
738
788
|
// supports_condition : supports_negation | supports_conjunction | supports_disjunction | supports_condition_in_parens ;
|
|
739
789
|
// supports_condition_in_parens: ( '(' S* supports_condition S* ')' ) | supports_declaration_condition | general_enclosed ;
|
|
740
790
|
// supports_negation: NOT S+ supports_condition_in_parens ;
|
|
@@ -742,23 +792,23 @@ var Parser = /** @class */ (function () {
|
|
|
742
792
|
// supports_disjunction: supports_condition_in_parens ( S+ OR S+ supports_condition_in_parens )+;
|
|
743
793
|
// supports_declaration_condition: '(' S* declaration ')';
|
|
744
794
|
// general_enclosed: ( FUNCTION | '(' ) ( any | unused )* ')' ;
|
|
745
|
-
|
|
795
|
+
const node = this.create(nodes.SupportsCondition);
|
|
746
796
|
if (this.acceptIdent('not')) {
|
|
747
797
|
node.addChild(this._parseSupportsConditionInParens());
|
|
748
798
|
}
|
|
749
799
|
else {
|
|
750
800
|
node.addChild(this._parseSupportsConditionInParens());
|
|
751
801
|
if (this.peekRegExp(TokenType.Ident, /^(and|or)$/i)) {
|
|
752
|
-
|
|
802
|
+
const text = this.token.text.toLowerCase();
|
|
753
803
|
while (this.acceptIdent(text)) {
|
|
754
804
|
node.addChild(this._parseSupportsConditionInParens());
|
|
755
805
|
}
|
|
756
806
|
}
|
|
757
807
|
}
|
|
758
808
|
return this.finish(node);
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
|
|
809
|
+
}
|
|
810
|
+
_parseSupportsConditionInParens() {
|
|
811
|
+
const node = this.create(nodes.SupportsCondition);
|
|
762
812
|
if (this.accept(TokenType.ParenthesisL)) {
|
|
763
813
|
if (this.prevToken) {
|
|
764
814
|
node.lParent = this.prevToken.offset;
|
|
@@ -777,10 +827,10 @@ var Parser = /** @class */ (function () {
|
|
|
777
827
|
return this.finish(node);
|
|
778
828
|
}
|
|
779
829
|
else if (this.peek(TokenType.Ident)) {
|
|
780
|
-
|
|
830
|
+
const pos = this.mark();
|
|
781
831
|
this.consumeToken();
|
|
782
832
|
if (!this.hasWhitespace() && this.accept(TokenType.ParenthesisL)) {
|
|
783
|
-
|
|
833
|
+
let openParentCount = 1;
|
|
784
834
|
while (this.token.type !== TokenType.EOF && openParentCount !== 0) {
|
|
785
835
|
if (this.token.type === TokenType.ParenthesisL) {
|
|
786
836
|
openParentCount++;
|
|
@@ -797,9 +847,8 @@ var Parser = /** @class */ (function () {
|
|
|
797
847
|
}
|
|
798
848
|
}
|
|
799
849
|
return this.finish(node, ParseError.LeftParenthesisExpected, [], [TokenType.ParenthesisL]);
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
if (isNested === void 0) { isNested = false; }
|
|
850
|
+
}
|
|
851
|
+
_parseMediaDeclaration(isNested = false) {
|
|
803
852
|
if (isNested) {
|
|
804
853
|
// if nested, the body can contain rulesets, but also declarations
|
|
805
854
|
return this._tryParseRuleset(true)
|
|
@@ -807,23 +856,22 @@ var Parser = /** @class */ (function () {
|
|
|
807
856
|
|| this._parseStylesheetStatement(true);
|
|
808
857
|
}
|
|
809
858
|
return this._parseStylesheetStatement(false);
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
if (isNested === void 0) { isNested = false; }
|
|
859
|
+
}
|
|
860
|
+
_parseMedia(isNested = false) {
|
|
813
861
|
// MEDIA_SYM S* media_query_list '{' S* ruleset* '}' S*
|
|
814
862
|
// media_query_list : S* [media_query [ ',' S* media_query ]* ]?
|
|
815
863
|
if (!this.peekKeyword('@media')) {
|
|
816
864
|
return null;
|
|
817
865
|
}
|
|
818
|
-
|
|
866
|
+
const node = this.create(nodes.Media);
|
|
819
867
|
this.consumeToken(); // @media
|
|
820
868
|
if (!node.addChild(this._parseMediaQueryList())) {
|
|
821
869
|
return this.finish(node, ParseError.MediaQueryExpected);
|
|
822
870
|
}
|
|
823
871
|
return this._parseBody(node, this._parseMediaDeclaration.bind(this, isNested));
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
|
|
872
|
+
}
|
|
873
|
+
_parseMediaQueryList() {
|
|
874
|
+
const node = this.create(nodes.Medialist);
|
|
827
875
|
if (!node.addChild(this._parseMediaQuery())) {
|
|
828
876
|
return this.finish(node, ParseError.MediaQueryExpected);
|
|
829
877
|
}
|
|
@@ -833,11 +881,11 @@ var Parser = /** @class */ (function () {
|
|
|
833
881
|
}
|
|
834
882
|
}
|
|
835
883
|
return this.finish(node);
|
|
836
|
-
}
|
|
837
|
-
|
|
884
|
+
}
|
|
885
|
+
_parseMediaQuery() {
|
|
838
886
|
// <media-query> = <media-condition> | [ not | only ]? <media-type> [ and <media-condition-without-or> ]?
|
|
839
|
-
|
|
840
|
-
|
|
887
|
+
const node = this.create(nodes.MediaQuery);
|
|
888
|
+
const pos = this.mark();
|
|
841
889
|
this.acceptIdent('not');
|
|
842
890
|
if (!this.peek(TokenType.ParenthesisL)) {
|
|
843
891
|
if (this.acceptIdent('only')) {
|
|
@@ -855,10 +903,10 @@ var Parser = /** @class */ (function () {
|
|
|
855
903
|
node.addChild(this._parseMediaCondition());
|
|
856
904
|
}
|
|
857
905
|
return this.finish(node);
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
906
|
+
}
|
|
907
|
+
_parseRatio() {
|
|
908
|
+
const pos = this.mark();
|
|
909
|
+
const node = this.create(nodes.RatioValue);
|
|
862
910
|
if (!this._parseNumeric()) {
|
|
863
911
|
return null;
|
|
864
912
|
}
|
|
@@ -870,16 +918,16 @@ var Parser = /** @class */ (function () {
|
|
|
870
918
|
return this.finish(node, ParseError.NumberExpected);
|
|
871
919
|
}
|
|
872
920
|
return this.finish(node);
|
|
873
|
-
}
|
|
874
|
-
|
|
921
|
+
}
|
|
922
|
+
_parseMediaCondition() {
|
|
875
923
|
// <media-condition> = <media-not> | <media-and> | <media-or> | <media-in-parens>
|
|
876
924
|
// <media-not> = not <media-in-parens>
|
|
877
925
|
// <media-and> = <media-in-parens> [ and <media-in-parens> ]+
|
|
878
926
|
// <media-or> = <media-in-parens> [ or <media-in-parens> ]+
|
|
879
927
|
// <media-in-parens> = ( <media-condition> ) | <media-feature> | <general-enclosed>
|
|
880
|
-
|
|
928
|
+
const node = this.create(nodes.MediaCondition);
|
|
881
929
|
this.acceptIdent('not');
|
|
882
|
-
|
|
930
|
+
let parseExpression = true;
|
|
883
931
|
while (parseExpression) {
|
|
884
932
|
if (!this.accept(TokenType.ParenthesisL)) {
|
|
885
933
|
return this.finish(node, ParseError.LeftParenthesisExpected, [], [TokenType.CurlyL]);
|
|
@@ -898,23 +946,22 @@ var Parser = /** @class */ (function () {
|
|
|
898
946
|
parseExpression = this.acceptIdent('and') || this.acceptIdent('or');
|
|
899
947
|
}
|
|
900
948
|
return this.finish(node);
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
var node = this.create(nodes.MediaFeature);
|
|
949
|
+
}
|
|
950
|
+
_parseMediaFeature() {
|
|
951
|
+
const resyncStopToken = [TokenType.ParenthesisR];
|
|
952
|
+
const node = this.create(nodes.MediaFeature);
|
|
906
953
|
// <media-feature> = ( [ <mf-plain> | <mf-boolean> | <mf-range> ] )
|
|
907
954
|
// <mf-plain> = <mf-name> : <mf-value>
|
|
908
955
|
// <mf-boolean> = <mf-name>
|
|
909
956
|
// <mf-range> = <mf-name> [ '<' | '>' ]? '='? <mf-value> | <mf-value> [ '<' | '>' ]? '='? <mf-name> | <mf-value> '<' '='? <mf-name> '<' '='? <mf-value> | <mf-value> '>' '='? <mf-name> '>' '='? <mf-value>
|
|
910
|
-
|
|
911
|
-
if (
|
|
912
|
-
if (!
|
|
913
|
-
|
|
957
|
+
const parseRangeOperator = () => {
|
|
958
|
+
if (this.acceptDelim('<') || this.acceptDelim('>')) {
|
|
959
|
+
if (!this.hasWhitespace()) {
|
|
960
|
+
this.acceptDelim('=');
|
|
914
961
|
}
|
|
915
962
|
return true;
|
|
916
963
|
}
|
|
917
|
-
else if (
|
|
964
|
+
else if (this.acceptDelim('=')) {
|
|
918
965
|
return true;
|
|
919
966
|
}
|
|
920
967
|
return false;
|
|
@@ -956,33 +1003,33 @@ var Parser = /** @class */ (function () {
|
|
|
956
1003
|
return this.finish(node, ParseError.IdentifierExpected, [], resyncStopToken);
|
|
957
1004
|
}
|
|
958
1005
|
return this.finish(node);
|
|
959
|
-
}
|
|
960
|
-
|
|
1006
|
+
}
|
|
1007
|
+
_parseMediaFeatureName() {
|
|
961
1008
|
return this._parseIdent();
|
|
962
|
-
}
|
|
963
|
-
|
|
1009
|
+
}
|
|
1010
|
+
_parseMediaFeatureValue() {
|
|
964
1011
|
return this._parseRatio() || this._parseTermExpression();
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
|
|
1012
|
+
}
|
|
1013
|
+
_parseMedium() {
|
|
1014
|
+
const node = this.create(nodes.Node);
|
|
968
1015
|
if (node.addChild(this._parseIdent())) {
|
|
969
1016
|
return this.finish(node);
|
|
970
1017
|
}
|
|
971
1018
|
else {
|
|
972
1019
|
return null;
|
|
973
1020
|
}
|
|
974
|
-
}
|
|
975
|
-
|
|
1021
|
+
}
|
|
1022
|
+
_parsePageDeclaration() {
|
|
976
1023
|
return this._parsePageMarginBox() || this._parseRuleSetDeclaration();
|
|
977
|
-
}
|
|
978
|
-
|
|
1024
|
+
}
|
|
1025
|
+
_parsePage() {
|
|
979
1026
|
// http://www.w3.org/TR/css3-page/
|
|
980
1027
|
// page_rule : PAGE_SYM S* page_selector_list '{' S* page_body '}' S*
|
|
981
1028
|
// page_body : /* Can be empty */ declaration? [ ';' S* page_body ]? | page_margin_box page_body
|
|
982
1029
|
if (!this.peekKeyword('@page')) {
|
|
983
1030
|
return null;
|
|
984
1031
|
}
|
|
985
|
-
|
|
1032
|
+
const node = this.create(nodes.Page);
|
|
986
1033
|
this.consumeToken();
|
|
987
1034
|
if (node.addChild(this._parsePageSelector())) {
|
|
988
1035
|
while (this.accept(TokenType.Comma)) {
|
|
@@ -992,25 +1039,25 @@ var Parser = /** @class */ (function () {
|
|
|
992
1039
|
}
|
|
993
1040
|
}
|
|
994
1041
|
return this._parseBody(node, this._parsePageDeclaration.bind(this));
|
|
995
|
-
}
|
|
996
|
-
|
|
1042
|
+
}
|
|
1043
|
+
_parsePageMarginBox() {
|
|
997
1044
|
// page_margin_box : margin_sym S* '{' S* declaration? [ ';' S* declaration? ]* '}' S*
|
|
998
1045
|
if (!this.peek(TokenType.AtKeyword)) {
|
|
999
1046
|
return null;
|
|
1000
1047
|
}
|
|
1001
|
-
|
|
1048
|
+
const node = this.create(nodes.PageBoxMarginBox);
|
|
1002
1049
|
if (!this.acceptOneKeyword(languageFacts.pageBoxDirectives)) {
|
|
1003
1050
|
this.markError(node, ParseError.UnknownAtRule, [], [TokenType.CurlyL]);
|
|
1004
1051
|
}
|
|
1005
1052
|
return this._parseBody(node, this._parseRuleSetDeclaration.bind(this));
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1053
|
+
}
|
|
1054
|
+
_parsePageSelector() {
|
|
1008
1055
|
// page_selector : pseudo_page+ | IDENT pseudo_page*
|
|
1009
1056
|
// pseudo_page : ':' [ "left" | "right" | "first" | "blank" ];
|
|
1010
1057
|
if (!this.peek(TokenType.Ident) && !this.peek(TokenType.Colon)) {
|
|
1011
1058
|
return null;
|
|
1012
1059
|
}
|
|
1013
|
-
|
|
1060
|
+
const node = this.create(nodes.Node);
|
|
1014
1061
|
node.addChild(this._parseIdent()); // optional ident
|
|
1015
1062
|
if (this.accept(TokenType.Colon)) {
|
|
1016
1063
|
if (!node.addChild(this._parseIdent())) { // optional ident
|
|
@@ -1018,29 +1065,29 @@ var Parser = /** @class */ (function () {
|
|
|
1018
1065
|
}
|
|
1019
1066
|
}
|
|
1020
1067
|
return this.finish(node);
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1068
|
+
}
|
|
1069
|
+
_parseDocument() {
|
|
1023
1070
|
// -moz-document is experimental but has been pushed to css4
|
|
1024
1071
|
if (!this.peekKeyword('@-moz-document')) {
|
|
1025
1072
|
return null;
|
|
1026
1073
|
}
|
|
1027
|
-
|
|
1074
|
+
const node = this.create(nodes.Document);
|
|
1028
1075
|
this.consumeToken(); // @-moz-document
|
|
1029
1076
|
this.resync([], [TokenType.CurlyL]); // ignore all the rules
|
|
1030
1077
|
return this._parseBody(node, this._parseStylesheetStatement.bind(this));
|
|
1031
|
-
}
|
|
1078
|
+
}
|
|
1032
1079
|
// https://www.w3.org/TR/css-syntax-3/#consume-an-at-rule
|
|
1033
|
-
|
|
1080
|
+
_parseUnknownAtRule() {
|
|
1034
1081
|
if (!this.peek(TokenType.AtKeyword)) {
|
|
1035
1082
|
return null;
|
|
1036
1083
|
}
|
|
1037
|
-
|
|
1084
|
+
const node = this.create(nodes.UnknownAtRule);
|
|
1038
1085
|
node.addChild(this._parseUnknownAtRuleName());
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1086
|
+
const isTopLevel = () => curlyDepth === 0 && parensDepth === 0 && bracketsDepth === 0;
|
|
1087
|
+
let curlyLCount = 0;
|
|
1088
|
+
let curlyDepth = 0;
|
|
1089
|
+
let parensDepth = 0;
|
|
1090
|
+
let bracketsDepth = 0;
|
|
1044
1091
|
done: while (true) {
|
|
1045
1092
|
switch (this.token.type) {
|
|
1046
1093
|
case TokenType.SemiColon:
|
|
@@ -1109,15 +1156,15 @@ var Parser = /** @class */ (function () {
|
|
|
1109
1156
|
this.consumeToken();
|
|
1110
1157
|
}
|
|
1111
1158
|
return node;
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1159
|
+
}
|
|
1160
|
+
_parseUnknownAtRuleName() {
|
|
1161
|
+
const node = this.create(nodes.Node);
|
|
1115
1162
|
if (this.accept(TokenType.AtKeyword)) {
|
|
1116
1163
|
return this.finish(node);
|
|
1117
1164
|
}
|
|
1118
1165
|
return node;
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1166
|
+
}
|
|
1167
|
+
_parseOperator() {
|
|
1121
1168
|
// these are operators for binary expressions
|
|
1122
1169
|
if (this.peekDelim('/') ||
|
|
1123
1170
|
this.peekDelim('*') ||
|
|
@@ -1129,27 +1176,27 @@ var Parser = /** @class */ (function () {
|
|
|
1129
1176
|
this.peek(TokenType.PrefixOperator) ||
|
|
1130
1177
|
this.peek(TokenType.SuffixOperator) ||
|
|
1131
1178
|
this.peekDelim('=')) { // doesn't stick to the standard here
|
|
1132
|
-
|
|
1179
|
+
const node = this.createNode(nodes.NodeType.Operator);
|
|
1133
1180
|
this.consumeToken();
|
|
1134
1181
|
return this.finish(node);
|
|
1135
1182
|
}
|
|
1136
1183
|
else {
|
|
1137
1184
|
return null;
|
|
1138
1185
|
}
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1186
|
+
}
|
|
1187
|
+
_parseUnaryOperator() {
|
|
1141
1188
|
if (!this.peekDelim('+') && !this.peekDelim('-')) {
|
|
1142
1189
|
return null;
|
|
1143
1190
|
}
|
|
1144
|
-
|
|
1191
|
+
const node = this.create(nodes.Node);
|
|
1145
1192
|
this.consumeToken();
|
|
1146
1193
|
return this.finish(node);
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1194
|
+
}
|
|
1195
|
+
_parseCombinator() {
|
|
1149
1196
|
if (this.peekDelim('>')) {
|
|
1150
|
-
|
|
1197
|
+
const node = this.create(nodes.Node);
|
|
1151
1198
|
this.consumeToken();
|
|
1152
|
-
|
|
1199
|
+
const mark = this.mark();
|
|
1153
1200
|
if (!this.hasWhitespace() && this.acceptDelim('>')) {
|
|
1154
1201
|
if (!this.hasWhitespace() && this.acceptDelim('>')) {
|
|
1155
1202
|
node.type = nodes.NodeType.SelectorCombinatorShadowPiercingDescendant;
|
|
@@ -1161,21 +1208,21 @@ var Parser = /** @class */ (function () {
|
|
|
1161
1208
|
return this.finish(node);
|
|
1162
1209
|
}
|
|
1163
1210
|
else if (this.peekDelim('+')) {
|
|
1164
|
-
|
|
1211
|
+
const node = this.create(nodes.Node);
|
|
1165
1212
|
this.consumeToken();
|
|
1166
1213
|
node.type = nodes.NodeType.SelectorCombinatorSibling;
|
|
1167
1214
|
return this.finish(node);
|
|
1168
1215
|
}
|
|
1169
1216
|
else if (this.peekDelim('~')) {
|
|
1170
|
-
|
|
1217
|
+
const node = this.create(nodes.Node);
|
|
1171
1218
|
this.consumeToken();
|
|
1172
1219
|
node.type = nodes.NodeType.SelectorCombinatorAllSiblings;
|
|
1173
1220
|
return this.finish(node);
|
|
1174
1221
|
}
|
|
1175
1222
|
else if (this.peekDelim('/')) {
|
|
1176
|
-
|
|
1223
|
+
const node = this.create(nodes.Node);
|
|
1177
1224
|
this.consumeToken();
|
|
1178
|
-
|
|
1225
|
+
const mark = this.mark();
|
|
1179
1226
|
if (!this.hasWhitespace() && this.acceptIdent('deep') && !this.hasWhitespace() && this.acceptDelim('/')) {
|
|
1180
1227
|
node.type = nodes.NodeType.SelectorCombinatorShadowPiercingDescendant;
|
|
1181
1228
|
return this.finish(node);
|
|
@@ -1183,12 +1230,12 @@ var Parser = /** @class */ (function () {
|
|
|
1183
1230
|
this.restoreAtMark(mark);
|
|
1184
1231
|
}
|
|
1185
1232
|
return null;
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1233
|
+
}
|
|
1234
|
+
_parseSimpleSelector() {
|
|
1188
1235
|
// simple_selector
|
|
1189
1236
|
// : element_name [ HASH | class | attrib | pseudo ]* | [ HASH | class | attrib | pseudo ]+ ;
|
|
1190
|
-
|
|
1191
|
-
|
|
1237
|
+
const node = this.create(nodes.SimpleSelector);
|
|
1238
|
+
let c = 0;
|
|
1192
1239
|
if (node.addChild(this._parseElementName())) {
|
|
1193
1240
|
c++;
|
|
1194
1241
|
}
|
|
@@ -1196,18 +1243,18 @@ var Parser = /** @class */ (function () {
|
|
|
1196
1243
|
c++;
|
|
1197
1244
|
}
|
|
1198
1245
|
return c > 0 ? this.finish(node) : null;
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1246
|
+
}
|
|
1247
|
+
_parseSimpleSelectorBody() {
|
|
1201
1248
|
return this._parsePseudo() || this._parseHash() || this._parseClass() || this._parseAttrib();
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1249
|
+
}
|
|
1250
|
+
_parseSelectorIdent() {
|
|
1204
1251
|
return this._parseIdent();
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1252
|
+
}
|
|
1253
|
+
_parseHash() {
|
|
1207
1254
|
if (!this.peek(TokenType.Hash) && !this.peekDelim('#')) {
|
|
1208
1255
|
return null;
|
|
1209
1256
|
}
|
|
1210
|
-
|
|
1257
|
+
const node = this.createNode(nodes.NodeType.IdentifierSelector);
|
|
1211
1258
|
if (this.acceptDelim('#')) {
|
|
1212
1259
|
if (this.hasWhitespace() || !node.addChild(this._parseSelectorIdent())) {
|
|
1213
1260
|
return this.finish(node, ParseError.IdentifierExpected);
|
|
@@ -1217,33 +1264,33 @@ var Parser = /** @class */ (function () {
|
|
|
1217
1264
|
this.consumeToken(); // TokenType.Hash
|
|
1218
1265
|
}
|
|
1219
1266
|
return this.finish(node);
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1267
|
+
}
|
|
1268
|
+
_parseClass() {
|
|
1222
1269
|
// class: '.' IDENT ;
|
|
1223
1270
|
if (!this.peekDelim('.')) {
|
|
1224
1271
|
return null;
|
|
1225
1272
|
}
|
|
1226
|
-
|
|
1273
|
+
const node = this.createNode(nodes.NodeType.ClassSelector);
|
|
1227
1274
|
this.consumeToken(); // '.'
|
|
1228
1275
|
if (this.hasWhitespace() || !node.addChild(this._parseSelectorIdent())) {
|
|
1229
1276
|
return this.finish(node, ParseError.IdentifierExpected);
|
|
1230
1277
|
}
|
|
1231
1278
|
return this.finish(node);
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1279
|
+
}
|
|
1280
|
+
_parseElementName() {
|
|
1234
1281
|
// element_name: (ns? '|')? IDENT | '*';
|
|
1235
|
-
|
|
1236
|
-
|
|
1282
|
+
const pos = this.mark();
|
|
1283
|
+
const node = this.createNode(nodes.NodeType.ElementNameSelector);
|
|
1237
1284
|
node.addChild(this._parseNamespacePrefix());
|
|
1238
1285
|
if (!node.addChild(this._parseSelectorIdent()) && !this.acceptDelim('*')) {
|
|
1239
1286
|
this.restoreAtMark(pos);
|
|
1240
1287
|
return null;
|
|
1241
1288
|
}
|
|
1242
1289
|
return this.finish(node);
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1290
|
+
}
|
|
1291
|
+
_parseNamespacePrefix() {
|
|
1292
|
+
const pos = this.mark();
|
|
1293
|
+
const node = this.createNode(nodes.NodeType.NamespacePrefix);
|
|
1247
1294
|
if (!node.addChild(this._parseIdent()) && !this.acceptDelim('*')) {
|
|
1248
1295
|
// ns is optional
|
|
1249
1296
|
}
|
|
@@ -1252,13 +1299,13 @@ var Parser = /** @class */ (function () {
|
|
|
1252
1299
|
return null;
|
|
1253
1300
|
}
|
|
1254
1301
|
return this.finish(node);
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1302
|
+
}
|
|
1303
|
+
_parseAttrib() {
|
|
1257
1304
|
// attrib : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S* [ IDENT | STRING ] S* ]? ']'
|
|
1258
1305
|
if (!this.peek(TokenType.BracketL)) {
|
|
1259
1306
|
return null;
|
|
1260
1307
|
}
|
|
1261
|
-
|
|
1308
|
+
const node = this.create(nodes.AttributeSelector);
|
|
1262
1309
|
this.consumeToken(); // BracketL
|
|
1263
1310
|
// Optional attrib namespace
|
|
1264
1311
|
node.setNamespacePrefix(this._parseNamespacePrefix());
|
|
@@ -1274,23 +1321,22 @@ var Parser = /** @class */ (function () {
|
|
|
1274
1321
|
return this.finish(node, ParseError.RightSquareBracketExpected);
|
|
1275
1322
|
}
|
|
1276
1323
|
return this.finish(node);
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
var _this = this;
|
|
1324
|
+
}
|
|
1325
|
+
_parsePseudo() {
|
|
1280
1326
|
// pseudo: ':' [ IDENT | FUNCTION S* [IDENT S*]? ')' ]
|
|
1281
|
-
|
|
1327
|
+
const node = this._tryParsePseudoIdentifier();
|
|
1282
1328
|
if (node) {
|
|
1283
1329
|
if (!this.hasWhitespace() && this.accept(TokenType.ParenthesisL)) {
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
if (!selectors.addChild(
|
|
1330
|
+
const tryAsSelector = () => {
|
|
1331
|
+
const selectors = this.create(nodes.Node);
|
|
1332
|
+
if (!selectors.addChild(this._parseSelector(true))) {
|
|
1287
1333
|
return null;
|
|
1288
1334
|
}
|
|
1289
|
-
while (
|
|
1335
|
+
while (this.accept(TokenType.Comma) && selectors.addChild(this._parseSelector(true))) {
|
|
1290
1336
|
// loop
|
|
1291
1337
|
}
|
|
1292
|
-
if (
|
|
1293
|
-
return
|
|
1338
|
+
if (this.peek(TokenType.ParenthesisR)) {
|
|
1339
|
+
return this.finish(selectors);
|
|
1294
1340
|
}
|
|
1295
1341
|
return null;
|
|
1296
1342
|
};
|
|
@@ -1302,13 +1348,13 @@ var Parser = /** @class */ (function () {
|
|
|
1302
1348
|
return this.finish(node);
|
|
1303
1349
|
}
|
|
1304
1350
|
return null;
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1351
|
+
}
|
|
1352
|
+
_tryParsePseudoIdentifier() {
|
|
1307
1353
|
if (!this.peek(TokenType.Colon)) {
|
|
1308
1354
|
return null;
|
|
1309
1355
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1356
|
+
const pos = this.mark();
|
|
1357
|
+
const node = this.createNode(nodes.NodeType.PseudoSelector);
|
|
1312
1358
|
this.consumeToken(); // Colon
|
|
1313
1359
|
if (this.hasWhitespace()) {
|
|
1314
1360
|
this.restoreAtMark(pos);
|
|
@@ -1320,29 +1366,28 @@ var Parser = /** @class */ (function () {
|
|
|
1320
1366
|
return this.finish(node, ParseError.IdentifierExpected);
|
|
1321
1367
|
}
|
|
1322
1368
|
return this.finish(node);
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1369
|
+
}
|
|
1370
|
+
_tryParsePrio() {
|
|
1371
|
+
const mark = this.mark();
|
|
1372
|
+
const prio = this._parsePrio();
|
|
1327
1373
|
if (prio) {
|
|
1328
1374
|
return prio;
|
|
1329
1375
|
}
|
|
1330
1376
|
this.restoreAtMark(mark);
|
|
1331
1377
|
return null;
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1378
|
+
}
|
|
1379
|
+
_parsePrio() {
|
|
1334
1380
|
if (!this.peek(TokenType.Exclamation)) {
|
|
1335
1381
|
return null;
|
|
1336
1382
|
}
|
|
1337
|
-
|
|
1383
|
+
const node = this.createNode(nodes.NodeType.Prio);
|
|
1338
1384
|
if (this.accept(TokenType.Exclamation) && this.acceptIdent('important')) {
|
|
1339
1385
|
return this.finish(node);
|
|
1340
1386
|
}
|
|
1341
1387
|
return null;
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
var node = this.create(nodes.Expression);
|
|
1388
|
+
}
|
|
1389
|
+
_parseExpr(stopOnComma = false) {
|
|
1390
|
+
const node = this.create(nodes.Expression);
|
|
1346
1391
|
if (!node.addChild(this._parseBinaryExpr())) {
|
|
1347
1392
|
return null;
|
|
1348
1393
|
}
|
|
@@ -1358,23 +1403,23 @@ var Parser = /** @class */ (function () {
|
|
|
1358
1403
|
}
|
|
1359
1404
|
}
|
|
1360
1405
|
return this.finish(node);
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1406
|
+
}
|
|
1407
|
+
_parseUnicodeRange() {
|
|
1363
1408
|
if (!this.peekIdent('u')) {
|
|
1364
1409
|
return null;
|
|
1365
1410
|
}
|
|
1366
|
-
|
|
1411
|
+
const node = this.create(nodes.UnicodeRange);
|
|
1367
1412
|
if (!this.acceptUnicodeRange()) {
|
|
1368
1413
|
return null;
|
|
1369
1414
|
}
|
|
1370
1415
|
return this.finish(node);
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1416
|
+
}
|
|
1417
|
+
_parseNamedLine() {
|
|
1373
1418
|
// https://www.w3.org/TR/css-grid-1/#named-lines
|
|
1374
1419
|
if (!this.peek(TokenType.BracketL)) {
|
|
1375
1420
|
return null;
|
|
1376
1421
|
}
|
|
1377
|
-
|
|
1422
|
+
const node = this.createNode(nodes.NodeType.GridLine);
|
|
1378
1423
|
this.consumeToken();
|
|
1379
1424
|
while (node.addChild(this._parseIdent())) {
|
|
1380
1425
|
// repeat
|
|
@@ -1383,9 +1428,9 @@ var Parser = /** @class */ (function () {
|
|
|
1383
1428
|
return this.finish(node, ParseError.RightSquareBracketExpected);
|
|
1384
1429
|
}
|
|
1385
1430
|
return this.finish(node);
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
|
|
1431
|
+
}
|
|
1432
|
+
_parseBinaryExpr(preparsedLeft, preparsedOper) {
|
|
1433
|
+
let node = this.create(nodes.BinaryExpression);
|
|
1389
1434
|
if (!node.setLeft((preparsedLeft || this._parseTerm()))) {
|
|
1390
1435
|
return null;
|
|
1391
1436
|
}
|
|
@@ -1397,21 +1442,21 @@ var Parser = /** @class */ (function () {
|
|
|
1397
1442
|
}
|
|
1398
1443
|
// things needed for multiple binary expressions
|
|
1399
1444
|
node = this.finish(node);
|
|
1400
|
-
|
|
1445
|
+
const operator = this._parseOperator();
|
|
1401
1446
|
if (operator) {
|
|
1402
1447
|
node = this._parseBinaryExpr(node, operator);
|
|
1403
1448
|
}
|
|
1404
1449
|
return this.finish(node);
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1450
|
+
}
|
|
1451
|
+
_parseTerm() {
|
|
1452
|
+
let node = this.create(nodes.Term);
|
|
1408
1453
|
node.setOperator(this._parseUnaryOperator()); // optional
|
|
1409
1454
|
if (node.setExpression(this._parseTermExpression())) {
|
|
1410
1455
|
return this.finish(node);
|
|
1411
1456
|
}
|
|
1412
1457
|
return null;
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1458
|
+
}
|
|
1459
|
+
_parseTermExpression() {
|
|
1415
1460
|
return this._parseURILiteral() || // url before function
|
|
1416
1461
|
this._parseUnicodeRange() ||
|
|
1417
1462
|
this._parseFunction() || // function before ident
|
|
@@ -1421,20 +1466,20 @@ var Parser = /** @class */ (function () {
|
|
|
1421
1466
|
this._parseHexColor() ||
|
|
1422
1467
|
this._parseOperation() ||
|
|
1423
1468
|
this._parseNamedLine();
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1469
|
+
}
|
|
1470
|
+
_parseOperation() {
|
|
1426
1471
|
if (!this.peek(TokenType.ParenthesisL)) {
|
|
1427
1472
|
return null;
|
|
1428
1473
|
}
|
|
1429
|
-
|
|
1474
|
+
const node = this.create(nodes.Node);
|
|
1430
1475
|
this.consumeToken(); // ParenthesisL
|
|
1431
1476
|
node.addChild(this._parseExpr());
|
|
1432
1477
|
if (!this.accept(TokenType.ParenthesisR)) {
|
|
1433
1478
|
return this.finish(node, ParseError.RightParenthesisExpected);
|
|
1434
1479
|
}
|
|
1435
1480
|
return this.finish(node);
|
|
1436
|
-
}
|
|
1437
|
-
|
|
1481
|
+
}
|
|
1482
|
+
_parseNumeric() {
|
|
1438
1483
|
if (this.peek(TokenType.Num) ||
|
|
1439
1484
|
this.peek(TokenType.Percentage) ||
|
|
1440
1485
|
this.peek(TokenType.Resolution) ||
|
|
@@ -1445,26 +1490,26 @@ var Parser = /** @class */ (function () {
|
|
|
1445
1490
|
this.peek(TokenType.Time) ||
|
|
1446
1491
|
this.peek(TokenType.Dimension) ||
|
|
1447
1492
|
this.peek(TokenType.Freq)) {
|
|
1448
|
-
|
|
1493
|
+
const node = this.create(nodes.NumericValue);
|
|
1449
1494
|
this.consumeToken();
|
|
1450
1495
|
return this.finish(node);
|
|
1451
1496
|
}
|
|
1452
1497
|
return null;
|
|
1453
|
-
}
|
|
1454
|
-
|
|
1498
|
+
}
|
|
1499
|
+
_parseStringLiteral() {
|
|
1455
1500
|
if (!this.peek(TokenType.String) && !this.peek(TokenType.BadString)) {
|
|
1456
1501
|
return null;
|
|
1457
1502
|
}
|
|
1458
|
-
|
|
1503
|
+
const node = this.createNode(nodes.NodeType.StringLiteral);
|
|
1459
1504
|
this.consumeToken();
|
|
1460
1505
|
return this.finish(node);
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1506
|
+
}
|
|
1507
|
+
_parseURILiteral() {
|
|
1463
1508
|
if (!this.peekRegExp(TokenType.Ident, /^url(-prefix)?$/i)) {
|
|
1464
1509
|
return null;
|
|
1465
1510
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1511
|
+
const pos = this.mark();
|
|
1512
|
+
const node = this.createNode(nodes.NodeType.URILiteral);
|
|
1468
1513
|
this.accept(TokenType.Ident);
|
|
1469
1514
|
if (this.hasWhitespace() || !this.peek(TokenType.ParenthesisL)) {
|
|
1470
1515
|
this.restoreAtMark(pos);
|
|
@@ -1478,29 +1523,29 @@ var Parser = /** @class */ (function () {
|
|
|
1478
1523
|
return this.finish(node, ParseError.RightParenthesisExpected);
|
|
1479
1524
|
}
|
|
1480
1525
|
return this.finish(node);
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
|
-
|
|
1526
|
+
}
|
|
1527
|
+
_parseURLArgument() {
|
|
1528
|
+
const node = this.create(nodes.Node);
|
|
1484
1529
|
if (!this.accept(TokenType.String) && !this.accept(TokenType.BadString) && !this.acceptUnquotedString()) {
|
|
1485
1530
|
return null;
|
|
1486
1531
|
}
|
|
1487
1532
|
return this.finish(node);
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1533
|
+
}
|
|
1534
|
+
_parseIdent(referenceTypes) {
|
|
1490
1535
|
if (!this.peek(TokenType.Ident)) {
|
|
1491
1536
|
return null;
|
|
1492
1537
|
}
|
|
1493
|
-
|
|
1538
|
+
const node = this.create(nodes.Identifier);
|
|
1494
1539
|
if (referenceTypes) {
|
|
1495
1540
|
node.referenceTypes = referenceTypes;
|
|
1496
1541
|
}
|
|
1497
1542
|
node.isCustomProperty = this.peekRegExp(TokenType.Ident, /^--/);
|
|
1498
1543
|
this.consumeToken();
|
|
1499
1544
|
return this.finish(node);
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1545
|
+
}
|
|
1546
|
+
_parseFunction() {
|
|
1547
|
+
const pos = this.mark();
|
|
1548
|
+
const node = this.create(nodes.Function);
|
|
1504
1549
|
if (!node.setIdentifier(this._parseFunctionIdentifier())) {
|
|
1505
1550
|
return null;
|
|
1506
1551
|
}
|
|
@@ -1522,12 +1567,12 @@ var Parser = /** @class */ (function () {
|
|
|
1522
1567
|
return this.finish(node, ParseError.RightParenthesisExpected);
|
|
1523
1568
|
}
|
|
1524
1569
|
return this.finish(node);
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1570
|
+
}
|
|
1571
|
+
_parseFunctionIdentifier() {
|
|
1527
1572
|
if (!this.peek(TokenType.Ident)) {
|
|
1528
1573
|
return null;
|
|
1529
1574
|
}
|
|
1530
|
-
|
|
1575
|
+
const node = this.create(nodes.Identifier);
|
|
1531
1576
|
node.referenceTypes = [nodes.ReferenceType.Function];
|
|
1532
1577
|
if (this.acceptIdent('progid')) {
|
|
1533
1578
|
// support for IE7 specific filters: 'progid:DXImageTransform.Microsoft.MotionBlur(strength=13, direction=310)'
|
|
@@ -1540,24 +1585,22 @@ var Parser = /** @class */ (function () {
|
|
|
1540
1585
|
}
|
|
1541
1586
|
this.consumeToken();
|
|
1542
1587
|
return this.finish(node);
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
|
|
1588
|
+
}
|
|
1589
|
+
_parseFunctionArgument() {
|
|
1590
|
+
const node = this.create(nodes.FunctionArgument);
|
|
1546
1591
|
if (node.setValue(this._parseExpr(true))) {
|
|
1547
1592
|
return this.finish(node);
|
|
1548
1593
|
}
|
|
1549
1594
|
return null;
|
|
1550
|
-
}
|
|
1551
|
-
|
|
1595
|
+
}
|
|
1596
|
+
_parseHexColor() {
|
|
1552
1597
|
if (this.peekRegExp(TokenType.Hash, /^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/g)) {
|
|
1553
|
-
|
|
1598
|
+
const node = this.create(nodes.HexColorValue);
|
|
1554
1599
|
this.consumeToken();
|
|
1555
1600
|
return this.finish(node);
|
|
1556
1601
|
}
|
|
1557
1602
|
else {
|
|
1558
1603
|
return null;
|
|
1559
1604
|
}
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
}());
|
|
1563
|
-
export { Parser };
|
|
1605
|
+
}
|
|
1606
|
+
}
|