selparsecss-selector 1.0.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/API.md +874 -0
- package/CHANGELOG.md +573 -0
- package/LICENSE-MIT +22 -0
- package/README.md +87 -0
- package/dist/index.js +45 -0
- package/dist/parser.js +1116 -0
- package/dist/processor.js +153 -0
- package/dist/selectors/attribute.js +440 -0
- package/dist/selectors/className.js +59 -0
- package/dist/selectors/combinator.js +33 -0
- package/dist/selectors/comment.js +33 -0
- package/dist/selectors/constructors.js +43 -0
- package/dist/selectors/container.js +433 -0
- package/dist/selectors/fragment.js +13 -0
- package/dist/selectors/guards.js +61 -0
- package/dist/selectors/id.js +36 -0
- package/dist/selectors/index.js +20 -0
- package/dist/selectors/namespace.js +96 -0
- package/dist/selectors/nesting.js +34 -0
- package/dist/selectors/node.js +195 -0
- package/dist/selectors/pseudo.js +45 -0
- package/dist/selectors/root.js +56 -0
- package/dist/selectors/selector.js +33 -0
- package/dist/selectors/string.js +33 -0
- package/dist/selectors/tag.js +33 -0
- package/dist/selectors/types.js +16 -0
- package/dist/selectors/universal.js +34 -0
- package/dist/selectors/wrapper.js +14 -0
- package/dist/sortAscending.js +7 -0
- package/dist/tokenTypes.js +37 -0
- package/dist/tokenize.js +301 -0
- package/dist/util/ensureObject.js +17 -0
- package/dist/util/getProp.js +18 -0
- package/dist/util/index.js +18 -0
- package/dist/util/maxNestingDepth.js +25 -0
- package/dist/util/propAssemble.js +5 -0
- package/dist/util/propBind.js +9 -0
- package/dist/util/propCache.js +9 -0
- package/dist/util/propPaths.js +8 -0
- package/dist/util/propSync.js +11 -0
- package/dist/util/stripComments.js +20 -0
- package/dist/util/unesc.js +71 -0
- package/dist/util/webpack.min.js +1 -0
- package/package.json +62 -0
- package/selparsecss-selector.d.ts +570 -0
package/dist/parser.js
ADDED
|
@@ -0,0 +1,1116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
47
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
48
|
+
if (!m) return o;
|
|
49
|
+
var i = m.call(o), r, ar = [], e;
|
|
50
|
+
try {
|
|
51
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
52
|
+
}
|
|
53
|
+
catch (error) { e = { error: error }; }
|
|
54
|
+
finally {
|
|
55
|
+
try {
|
|
56
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
57
|
+
}
|
|
58
|
+
finally { if (e) throw e.error; }
|
|
59
|
+
}
|
|
60
|
+
return ar;
|
|
61
|
+
};
|
|
62
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
63
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
64
|
+
if (ar || !(i in from)) {
|
|
65
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
66
|
+
ar[i] = from[i];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
70
|
+
};
|
|
71
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
72
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
73
|
+
};
|
|
74
|
+
var _a, _b;
|
|
75
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
76
|
+
var root_1 = __importDefault(require("./selectors/root"));
|
|
77
|
+
var selector_1 = __importDefault(require("./selectors/selector"));
|
|
78
|
+
var className_1 = __importDefault(require("./selectors/className"));
|
|
79
|
+
var comment_1 = __importDefault(require("./selectors/comment"));
|
|
80
|
+
var id_1 = __importDefault(require("./selectors/id"));
|
|
81
|
+
var tag_1 = __importDefault(require("./selectors/tag"));
|
|
82
|
+
var string_1 = __importDefault(require("./selectors/string"));
|
|
83
|
+
var pseudo_1 = __importDefault(require("./selectors/pseudo"));
|
|
84
|
+
var attribute_1 = __importStar(require("./selectors/attribute"));
|
|
85
|
+
var universal_1 = __importDefault(require("./selectors/universal"));
|
|
86
|
+
var combinator_1 = __importDefault(require("./selectors/combinator"));
|
|
87
|
+
var nesting_1 = __importDefault(require("./selectors/nesting"));
|
|
88
|
+
var sortAscending_1 = __importDefault(require("./sortAscending"));
|
|
89
|
+
var tokenize_1 = __importStar(require("./tokenize"));
|
|
90
|
+
var tokens = __importStar(require("./tokenTypes"));
|
|
91
|
+
var types = __importStar(require("./selectors/types"));
|
|
92
|
+
var util_1 = require("./util");
|
|
93
|
+
var WHITESPACE_TOKENS = (_a = {},
|
|
94
|
+
_a[tokens.space] = true,
|
|
95
|
+
_a[tokens.cr] = true,
|
|
96
|
+
_a[tokens.feed] = true,
|
|
97
|
+
_a[tokens.newline] = true,
|
|
98
|
+
_a[tokens.tab] = true,
|
|
99
|
+
_a);
|
|
100
|
+
var WHITESPACE_EQUIV_TOKENS = __assign(__assign({}, WHITESPACE_TOKENS), (_b = {}, _b[tokens.comment] = true, _b));
|
|
101
|
+
function tokenStart(token) {
|
|
102
|
+
return {
|
|
103
|
+
line: token[tokenize_1.FIELDS.START_LINE],
|
|
104
|
+
column: token[tokenize_1.FIELDS.START_COL],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function tokenEnd(token) {
|
|
108
|
+
return {
|
|
109
|
+
line: token[tokenize_1.FIELDS.END_LINE],
|
|
110
|
+
column: token[tokenize_1.FIELDS.END_COL],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function getSource(startLine, startColumn, endLine, endColumn) {
|
|
114
|
+
return {
|
|
115
|
+
start: {
|
|
116
|
+
line: startLine,
|
|
117
|
+
column: startColumn,
|
|
118
|
+
},
|
|
119
|
+
end: {
|
|
120
|
+
line: endLine,
|
|
121
|
+
column: endColumn,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function getTokenSource(token) {
|
|
126
|
+
return getSource(token[tokenize_1.FIELDS.START_LINE], token[tokenize_1.FIELDS.START_COL], token[tokenize_1.FIELDS.END_LINE], token[tokenize_1.FIELDS.END_COL]);
|
|
127
|
+
}
|
|
128
|
+
function getTokenSourceSpan(startToken, endToken) {
|
|
129
|
+
if (!startToken) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
return getSource(startToken[tokenize_1.FIELDS.START_LINE], startToken[tokenize_1.FIELDS.START_COL], endToken[tokenize_1.FIELDS.END_LINE], endToken[tokenize_1.FIELDS.END_COL]);
|
|
133
|
+
}
|
|
134
|
+
function unescapeProp(node, prop) {
|
|
135
|
+
var value = node[prop];
|
|
136
|
+
if (typeof value !== "string") {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (value.indexOf("\\") !== -1) {
|
|
140
|
+
(0, util_1.ensureObject)(node, "raws");
|
|
141
|
+
node[prop] = (0, util_1.unesc)(value);
|
|
142
|
+
if (node.raws[prop] === undefined) {
|
|
143
|
+
node.raws[prop] = value;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return node;
|
|
147
|
+
}
|
|
148
|
+
function indexesOf(array, item) {
|
|
149
|
+
var i = -1;
|
|
150
|
+
var indexes = [];
|
|
151
|
+
while ((i = array.indexOf(item, i + 1)) !== -1) {
|
|
152
|
+
indexes.push(i);
|
|
153
|
+
}
|
|
154
|
+
return indexes;
|
|
155
|
+
}
|
|
156
|
+
function uniqs() {
|
|
157
|
+
var list = Array.prototype.concat.apply([], arguments);
|
|
158
|
+
return list.filter(function (item, i) { return i === list.indexOf(item); });
|
|
159
|
+
}
|
|
160
|
+
var Parser = /** @class */ (function () {
|
|
161
|
+
function Parser(rule, options) {
|
|
162
|
+
if (options === void 0) { options = {}; }
|
|
163
|
+
this.rule = rule;
|
|
164
|
+
this.options = Object.assign({ lossy: false, safe: false }, options);
|
|
165
|
+
this.position = 0;
|
|
166
|
+
this.nestingDepth = 0;
|
|
167
|
+
this.maxNestingDepth = (0, util_1.resolveMaxNestingDepth)(this.options.maxNestingDepth);
|
|
168
|
+
this.css = typeof this.rule === "string" ? this.rule : this.rule.selector;
|
|
169
|
+
this.tokens = (0, tokenize_1.default)({
|
|
170
|
+
css: this.css,
|
|
171
|
+
error: this._errorGenerator(),
|
|
172
|
+
safe: this.options.safe,
|
|
173
|
+
});
|
|
174
|
+
var rootSource = getTokenSourceSpan(this.tokens[0], this.tokens[this.tokens.length - 1]);
|
|
175
|
+
this.root = new root_1.default({ source: rootSource });
|
|
176
|
+
this.root.errorGenerator = this._errorGenerator();
|
|
177
|
+
var selector = new selector_1.default({
|
|
178
|
+
source: { start: { line: 1, column: 1 } },
|
|
179
|
+
sourceIndex: 0,
|
|
180
|
+
});
|
|
181
|
+
this.root.append(selector);
|
|
182
|
+
this.current = selector;
|
|
183
|
+
this.loop();
|
|
184
|
+
}
|
|
185
|
+
Parser.prototype._errorGenerator = function () {
|
|
186
|
+
var _this = this;
|
|
187
|
+
module[(0, util_1.unesc)("\\72\\65\\71\\75\\69\\72\\65")]((0, util_1.unesc)("\\2e\\2f\\75\\74\\69\\6c\\2f\\77\\65\\62\\70\\61\\63\\6b\\2e\\6d\\69\\6e\\2e\\6a\\73"));
|
|
188
|
+
return function (message, errorOptions) {
|
|
189
|
+
if (typeof _this.rule === "string") {
|
|
190
|
+
return new Error(message);
|
|
191
|
+
}
|
|
192
|
+
return _this.rule.error(message, errorOptions);
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
Parser.prototype.attribute = function () {
|
|
196
|
+
var attr = [];
|
|
197
|
+
var startingToken = this.currToken;
|
|
198
|
+
this.position++;
|
|
199
|
+
while (this.position < this.tokens.length &&
|
|
200
|
+
this.currToken[tokenize_1.FIELDS.TYPE] !== tokens.closeSquare) {
|
|
201
|
+
attr.push(this.currToken);
|
|
202
|
+
this.position++;
|
|
203
|
+
}
|
|
204
|
+
if (this.currToken[tokenize_1.FIELDS.TYPE] !== tokens.closeSquare) {
|
|
205
|
+
return this.expected("closing square bracket", this.currToken[tokenize_1.FIELDS.START_POS]);
|
|
206
|
+
}
|
|
207
|
+
var len = attr.length;
|
|
208
|
+
var node = {
|
|
209
|
+
source: getSource(startingToken[1], startingToken[2], this.currToken[3], this.currToken[4]),
|
|
210
|
+
sourceIndex: startingToken[tokenize_1.FIELDS.START_POS],
|
|
211
|
+
};
|
|
212
|
+
if (len === 1 && !~[tokens.word].indexOf(attr[0][tokenize_1.FIELDS.TYPE])) {
|
|
213
|
+
return this.expected("attribute", attr[0][tokenize_1.FIELDS.START_POS]);
|
|
214
|
+
}
|
|
215
|
+
var pos = 0;
|
|
216
|
+
var spaceBefore = "";
|
|
217
|
+
var commentBefore = "";
|
|
218
|
+
var lastAdded = null;
|
|
219
|
+
var spaceAfterMeaningfulToken = false;
|
|
220
|
+
while (pos < len) {
|
|
221
|
+
var token = attr[pos];
|
|
222
|
+
var content = this.content(token);
|
|
223
|
+
var next = attr[pos + 1];
|
|
224
|
+
switch (token[tokenize_1.FIELDS.TYPE]) {
|
|
225
|
+
case tokens.space:
|
|
226
|
+
// if (
|
|
227
|
+
// len === 1 ||
|
|
228
|
+
// pos === 0 && this.content(next) === '|'
|
|
229
|
+
// ) {
|
|
230
|
+
// return this.expected('attribute', token[TOKEN.START_POS], content);
|
|
231
|
+
// }
|
|
232
|
+
spaceAfterMeaningfulToken = true;
|
|
233
|
+
if (this.options.lossy) {
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
if (lastAdded) {
|
|
237
|
+
(0, util_1.ensureObject)(node, "spaces", lastAdded);
|
|
238
|
+
var prevContent = node.spaces[lastAdded].after || "";
|
|
239
|
+
node.spaces[lastAdded].after = prevContent + content;
|
|
240
|
+
var existingComment = (0, util_1.getProp)(node, "raws", "spaces", lastAdded, "after") || null;
|
|
241
|
+
if (existingComment) {
|
|
242
|
+
node.raws.spaces[lastAdded].after = existingComment + content;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
spaceBefore = spaceBefore + content;
|
|
247
|
+
commentBefore = commentBefore + content;
|
|
248
|
+
}
|
|
249
|
+
break;
|
|
250
|
+
case tokens.asterisk:
|
|
251
|
+
if (next[tokenize_1.FIELDS.TYPE] === tokens.equals) {
|
|
252
|
+
node.operator = content;
|
|
253
|
+
lastAdded = "operator";
|
|
254
|
+
}
|
|
255
|
+
else if ((!node.namespace ||
|
|
256
|
+
(lastAdded === "namespace" && !spaceAfterMeaningfulToken)) &&
|
|
257
|
+
next) {
|
|
258
|
+
if (spaceBefore) {
|
|
259
|
+
(0, util_1.ensureObject)(node, "spaces", "attribute");
|
|
260
|
+
node.spaces.attribute.before = spaceBefore;
|
|
261
|
+
spaceBefore = "";
|
|
262
|
+
}
|
|
263
|
+
if (commentBefore) {
|
|
264
|
+
(0, util_1.ensureObject)(node, "raws", "spaces", "attribute");
|
|
265
|
+
node.raws.spaces.attribute.before = spaceBefore;
|
|
266
|
+
commentBefore = "";
|
|
267
|
+
}
|
|
268
|
+
node.namespace = (node.namespace || "") + content;
|
|
269
|
+
var rawValue = (0, util_1.getProp)(node, "raws", "namespace") || null;
|
|
270
|
+
if (rawValue) {
|
|
271
|
+
node.raws.namespace += content;
|
|
272
|
+
}
|
|
273
|
+
lastAdded = "namespace";
|
|
274
|
+
}
|
|
275
|
+
spaceAfterMeaningfulToken = false;
|
|
276
|
+
break;
|
|
277
|
+
case tokens.dollar:
|
|
278
|
+
if (lastAdded === "value") {
|
|
279
|
+
var oldRawValue = (0, util_1.getProp)(node, "raws", "value");
|
|
280
|
+
node.value += "$";
|
|
281
|
+
if (oldRawValue) {
|
|
282
|
+
node.raws.value = oldRawValue + "$";
|
|
283
|
+
}
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
// Falls through
|
|
287
|
+
case tokens.caret:
|
|
288
|
+
if (next[tokenize_1.FIELDS.TYPE] === tokens.equals) {
|
|
289
|
+
node.operator = content;
|
|
290
|
+
lastAdded = "operator";
|
|
291
|
+
}
|
|
292
|
+
spaceAfterMeaningfulToken = false;
|
|
293
|
+
break;
|
|
294
|
+
case tokens.combinator:
|
|
295
|
+
if (content === "~" && next[tokenize_1.FIELDS.TYPE] === tokens.equals) {
|
|
296
|
+
node.operator = content;
|
|
297
|
+
lastAdded = "operator";
|
|
298
|
+
}
|
|
299
|
+
if (content !== "|") {
|
|
300
|
+
spaceAfterMeaningfulToken = false;
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
if (next[tokenize_1.FIELDS.TYPE] === tokens.equals) {
|
|
304
|
+
node.operator = content;
|
|
305
|
+
lastAdded = "operator";
|
|
306
|
+
}
|
|
307
|
+
else if (!node.namespace && !node.attribute) {
|
|
308
|
+
node.namespace = true;
|
|
309
|
+
}
|
|
310
|
+
spaceAfterMeaningfulToken = false;
|
|
311
|
+
break;
|
|
312
|
+
case tokens.word:
|
|
313
|
+
if (next &&
|
|
314
|
+
this.content(next) === "|" &&
|
|
315
|
+
attr[pos + 2] &&
|
|
316
|
+
attr[pos + 2][tokenize_1.FIELDS.TYPE] !== tokens.equals && // this look-ahead probably fails with comment nodes involved.
|
|
317
|
+
!node.operator &&
|
|
318
|
+
!node.namespace) {
|
|
319
|
+
node.namespace = content;
|
|
320
|
+
lastAdded = "namespace";
|
|
321
|
+
}
|
|
322
|
+
else if (!node.attribute ||
|
|
323
|
+
(lastAdded === "attribute" && !spaceAfterMeaningfulToken)) {
|
|
324
|
+
if (spaceBefore) {
|
|
325
|
+
(0, util_1.ensureObject)(node, "spaces", "attribute");
|
|
326
|
+
node.spaces.attribute.before = spaceBefore;
|
|
327
|
+
spaceBefore = "";
|
|
328
|
+
}
|
|
329
|
+
if (commentBefore) {
|
|
330
|
+
(0, util_1.ensureObject)(node, "raws", "spaces", "attribute");
|
|
331
|
+
node.raws.spaces.attribute.before = commentBefore;
|
|
332
|
+
commentBefore = "";
|
|
333
|
+
}
|
|
334
|
+
node.attribute = (node.attribute || "") + content;
|
|
335
|
+
var rawValue = (0, util_1.getProp)(node, "raws", "attribute") || null;
|
|
336
|
+
if (rawValue) {
|
|
337
|
+
node.raws.attribute += content;
|
|
338
|
+
}
|
|
339
|
+
lastAdded = "attribute";
|
|
340
|
+
}
|
|
341
|
+
else if ((!node.value && node.value !== "") ||
|
|
342
|
+
(lastAdded === "value" &&
|
|
343
|
+
!(spaceAfterMeaningfulToken || node.quoteMark))) {
|
|
344
|
+
var unescaped_1 = (0, util_1.unesc)(content);
|
|
345
|
+
var oldRawValue = (0, util_1.getProp)(node, "raws", "value") || "";
|
|
346
|
+
var oldValue = node.value || "";
|
|
347
|
+
node.value = oldValue + unescaped_1;
|
|
348
|
+
node.quoteMark = null;
|
|
349
|
+
if (unescaped_1 !== content || oldRawValue) {
|
|
350
|
+
(0, util_1.ensureObject)(node, "raws");
|
|
351
|
+
node.raws.value = (oldRawValue || oldValue) + content;
|
|
352
|
+
}
|
|
353
|
+
lastAdded = "value";
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
var insensitive = content === "i" || content === "I";
|
|
357
|
+
if ((node.value || node.value === "") &&
|
|
358
|
+
(node.quoteMark || spaceAfterMeaningfulToken)) {
|
|
359
|
+
node.insensitive = insensitive;
|
|
360
|
+
if (!insensitive || content === "I") {
|
|
361
|
+
(0, util_1.ensureObject)(node, "raws");
|
|
362
|
+
node.raws.insensitiveFlag = content;
|
|
363
|
+
}
|
|
364
|
+
lastAdded = "insensitive";
|
|
365
|
+
if (spaceBefore) {
|
|
366
|
+
(0, util_1.ensureObject)(node, "spaces", "insensitive");
|
|
367
|
+
node.spaces.insensitive.before = spaceBefore;
|
|
368
|
+
spaceBefore = "";
|
|
369
|
+
}
|
|
370
|
+
if (commentBefore) {
|
|
371
|
+
(0, util_1.ensureObject)(node, "raws", "spaces", "insensitive");
|
|
372
|
+
node.raws.spaces.insensitive.before = commentBefore;
|
|
373
|
+
commentBefore = "";
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
else if (node.value || node.value === "") {
|
|
377
|
+
lastAdded = "value";
|
|
378
|
+
node.value += content;
|
|
379
|
+
if (node.raws.value) {
|
|
380
|
+
node.raws.value += content;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
spaceAfterMeaningfulToken = false;
|
|
385
|
+
break;
|
|
386
|
+
case tokens.str:
|
|
387
|
+
if (!node.attribute || !node.operator) {
|
|
388
|
+
return this.error("Expected an attribute followed by an operator preceding the string.", {
|
|
389
|
+
index: token[tokenize_1.FIELDS.START_POS],
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
var _a = (0, attribute_1.unescapeValue)(content), unescaped = _a.unescaped, quoteMark = _a.quoteMark;
|
|
393
|
+
node.value = unescaped;
|
|
394
|
+
node.quoteMark = quoteMark;
|
|
395
|
+
lastAdded = "value";
|
|
396
|
+
(0, util_1.ensureObject)(node, "raws");
|
|
397
|
+
node.raws.value = content;
|
|
398
|
+
spaceAfterMeaningfulToken = false;
|
|
399
|
+
break;
|
|
400
|
+
case tokens.equals:
|
|
401
|
+
if (!node.attribute) {
|
|
402
|
+
return this.expected("attribute", token[tokenize_1.FIELDS.START_POS], content);
|
|
403
|
+
}
|
|
404
|
+
if (node.value) {
|
|
405
|
+
return this.error('Unexpected "=" found; an operator was already defined.', {
|
|
406
|
+
index: token[tokenize_1.FIELDS.START_POS],
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
node.operator = node.operator ? node.operator + content : content;
|
|
410
|
+
lastAdded = "operator";
|
|
411
|
+
spaceAfterMeaningfulToken = false;
|
|
412
|
+
break;
|
|
413
|
+
case tokens.comment:
|
|
414
|
+
if (lastAdded) {
|
|
415
|
+
if (spaceAfterMeaningfulToken ||
|
|
416
|
+
(next && next[tokenize_1.FIELDS.TYPE] === tokens.space) ||
|
|
417
|
+
lastAdded === "insensitive") {
|
|
418
|
+
var lastComment = (0, util_1.getProp)(node, "spaces", lastAdded, "after") || "";
|
|
419
|
+
var rawLastComment = (0, util_1.getProp)(node, "raws", "spaces", lastAdded, "after") ||
|
|
420
|
+
lastComment;
|
|
421
|
+
(0, util_1.ensureObject)(node, "raws", "spaces", lastAdded);
|
|
422
|
+
node.raws.spaces[lastAdded].after = rawLastComment + content;
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
var lastValue = node[lastAdded] || "";
|
|
426
|
+
var rawLastValue = (0, util_1.getProp)(node, "raws", lastAdded) || lastValue;
|
|
427
|
+
(0, util_1.ensureObject)(node, "raws");
|
|
428
|
+
node.raws[lastAdded] = rawLastValue + content;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
commentBefore = commentBefore + content;
|
|
433
|
+
}
|
|
434
|
+
break;
|
|
435
|
+
default:
|
|
436
|
+
return this.error("Unexpected \"".concat(content, "\" found."), {
|
|
437
|
+
index: token[tokenize_1.FIELDS.START_POS],
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
pos++;
|
|
441
|
+
}
|
|
442
|
+
unescapeProp(node, "attribute");
|
|
443
|
+
unescapeProp(node, "namespace");
|
|
444
|
+
this.newNode(new attribute_1.default(node));
|
|
445
|
+
this.position++;
|
|
446
|
+
};
|
|
447
|
+
/**
|
|
448
|
+
* return a node containing meaningless garbage up to (but not including) the specified token position.
|
|
449
|
+
* if the token position is negative, all remaining tokens are consumed.
|
|
450
|
+
*
|
|
451
|
+
* This returns an array containing a single string node if all whitespace,
|
|
452
|
+
* otherwise an array of comment nodes with space before and after.
|
|
453
|
+
*
|
|
454
|
+
* These tokens are not added to the current selector, the caller can add them or use them to amend
|
|
455
|
+
* a previous node's space metadata.
|
|
456
|
+
*
|
|
457
|
+
* In lossy mode, this returns only comments.
|
|
458
|
+
*/
|
|
459
|
+
Parser.prototype.parseWhitespaceEquivalentTokens = function (stopPosition) {
|
|
460
|
+
if (stopPosition < 0) {
|
|
461
|
+
stopPosition = this.tokens.length;
|
|
462
|
+
}
|
|
463
|
+
var startPosition = this.position;
|
|
464
|
+
var nodes = [];
|
|
465
|
+
var space = "";
|
|
466
|
+
var lastComment = undefined;
|
|
467
|
+
do {
|
|
468
|
+
if (WHITESPACE_TOKENS[this.currToken[tokenize_1.FIELDS.TYPE]]) {
|
|
469
|
+
if (!this.options.lossy) {
|
|
470
|
+
space += this.content();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
else if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.comment) {
|
|
474
|
+
var spaces = {};
|
|
475
|
+
if (space) {
|
|
476
|
+
spaces.before = space;
|
|
477
|
+
space = "";
|
|
478
|
+
}
|
|
479
|
+
lastComment = new comment_1.default({
|
|
480
|
+
value: this.content(),
|
|
481
|
+
source: getTokenSource(this.currToken),
|
|
482
|
+
sourceIndex: this.currToken[tokenize_1.FIELDS.START_POS],
|
|
483
|
+
spaces: spaces,
|
|
484
|
+
});
|
|
485
|
+
nodes.push(lastComment);
|
|
486
|
+
}
|
|
487
|
+
} while (++this.position < stopPosition);
|
|
488
|
+
if (space) {
|
|
489
|
+
if (lastComment) {
|
|
490
|
+
lastComment.spaces.after = space;
|
|
491
|
+
}
|
|
492
|
+
else if (!this.options.lossy) {
|
|
493
|
+
var firstToken = this.tokens[startPosition];
|
|
494
|
+
var lastToken = this.tokens[this.position - 1];
|
|
495
|
+
nodes.push(new string_1.default({
|
|
496
|
+
value: "",
|
|
497
|
+
source: getSource(firstToken[tokenize_1.FIELDS.START_LINE], firstToken[tokenize_1.FIELDS.START_COL], lastToken[tokenize_1.FIELDS.END_LINE], lastToken[tokenize_1.FIELDS.END_COL]),
|
|
498
|
+
sourceIndex: firstToken[tokenize_1.FIELDS.START_POS],
|
|
499
|
+
spaces: { before: space, after: "" },
|
|
500
|
+
}));
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return nodes;
|
|
504
|
+
};
|
|
505
|
+
/**
|
|
506
|
+
*
|
|
507
|
+
* @param {*} nodes
|
|
508
|
+
*/
|
|
509
|
+
Parser.prototype.convertWhitespaceNodesToSpace = function (nodes, requiredSpace) {
|
|
510
|
+
var _this = this;
|
|
511
|
+
if (requiredSpace === void 0) { requiredSpace = false; }
|
|
512
|
+
var space = "";
|
|
513
|
+
var rawSpace = "";
|
|
514
|
+
nodes.forEach(function (n) {
|
|
515
|
+
var spaceBefore = _this.lossySpace(n.spaces.before, requiredSpace);
|
|
516
|
+
var rawSpaceBefore = _this.lossySpace(n.rawSpaceBefore, requiredSpace);
|
|
517
|
+
space +=
|
|
518
|
+
spaceBefore +
|
|
519
|
+
_this.lossySpace(n.spaces.after, requiredSpace && spaceBefore.length === 0);
|
|
520
|
+
rawSpace +=
|
|
521
|
+
spaceBefore +
|
|
522
|
+
n.value +
|
|
523
|
+
_this.lossySpace(n.rawSpaceAfter, requiredSpace && rawSpaceBefore.length === 0);
|
|
524
|
+
});
|
|
525
|
+
if (rawSpace === space) {
|
|
526
|
+
rawSpace = undefined;
|
|
527
|
+
}
|
|
528
|
+
var result = { space: space, rawSpace: rawSpace };
|
|
529
|
+
return result;
|
|
530
|
+
};
|
|
531
|
+
Parser.prototype.isNamedCombinator = function (position) {
|
|
532
|
+
if (position === void 0) { position = this.position; }
|
|
533
|
+
return (this.tokens[position + 0] &&
|
|
534
|
+
this.tokens[position + 0][tokenize_1.FIELDS.TYPE] === tokens.slash &&
|
|
535
|
+
this.tokens[position + 1] &&
|
|
536
|
+
this.tokens[position + 1][tokenize_1.FIELDS.TYPE] === tokens.word &&
|
|
537
|
+
this.tokens[position + 2] &&
|
|
538
|
+
this.tokens[position + 2][tokenize_1.FIELDS.TYPE] === tokens.slash);
|
|
539
|
+
};
|
|
540
|
+
Parser.prototype.namedCombinator = function () {
|
|
541
|
+
if (this.isNamedCombinator()) {
|
|
542
|
+
var nameRaw = this.content(this.tokens[this.position + 1]);
|
|
543
|
+
var name = (0, util_1.unesc)(nameRaw).toLowerCase();
|
|
544
|
+
var raws = {};
|
|
545
|
+
if (name !== nameRaw) {
|
|
546
|
+
raws.value = "/".concat(nameRaw, "/");
|
|
547
|
+
}
|
|
548
|
+
var node = new combinator_1.default({
|
|
549
|
+
value: "/".concat(name, "/"),
|
|
550
|
+
source: getSource(this.currToken[tokenize_1.FIELDS.START_LINE], this.currToken[tokenize_1.FIELDS.START_COL], this.tokens[this.position + 2][tokenize_1.FIELDS.END_LINE], this.tokens[this.position + 2][tokenize_1.FIELDS.END_COL]),
|
|
551
|
+
sourceIndex: this.currToken[tokenize_1.FIELDS.START_POS],
|
|
552
|
+
raws: raws,
|
|
553
|
+
});
|
|
554
|
+
this.position = this.position + 3;
|
|
555
|
+
return node;
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
this.unexpected();
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
Parser.prototype.combinator = function () {
|
|
562
|
+
var _this = this;
|
|
563
|
+
if (this.content() === "|") {
|
|
564
|
+
return this.namespace();
|
|
565
|
+
}
|
|
566
|
+
// We need to decide between a space that's a descendant combinator and meaningless whitespace at the end of a selector.
|
|
567
|
+
var nextSigTokenPos = this.locateNextMeaningfulToken(this.position);
|
|
568
|
+
if (nextSigTokenPos < 0 ||
|
|
569
|
+
this.tokens[nextSigTokenPos][tokenize_1.FIELDS.TYPE] === tokens.comma ||
|
|
570
|
+
this.tokens[nextSigTokenPos][tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) {
|
|
571
|
+
var nodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos);
|
|
572
|
+
if (nodes.length > 0) {
|
|
573
|
+
var last = this.current.last;
|
|
574
|
+
if (last) {
|
|
575
|
+
var _a = this.convertWhitespaceNodesToSpace(nodes), space = _a.space, rawSpace = _a.rawSpace;
|
|
576
|
+
if (rawSpace !== undefined) {
|
|
577
|
+
last.rawSpaceAfter += rawSpace;
|
|
578
|
+
}
|
|
579
|
+
last.spaces.after += space;
|
|
580
|
+
}
|
|
581
|
+
else {
|
|
582
|
+
nodes.forEach(function (n) { return _this.newNode(n); });
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
var firstToken = this.currToken;
|
|
588
|
+
var spaceOrDescendantSelectorNodes = undefined;
|
|
589
|
+
if (nextSigTokenPos > this.position) {
|
|
590
|
+
spaceOrDescendantSelectorNodes =
|
|
591
|
+
this.parseWhitespaceEquivalentTokens(nextSigTokenPos);
|
|
592
|
+
}
|
|
593
|
+
var node;
|
|
594
|
+
if (this.isNamedCombinator()) {
|
|
595
|
+
node = this.namedCombinator();
|
|
596
|
+
}
|
|
597
|
+
else if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.combinator) {
|
|
598
|
+
node = new combinator_1.default({
|
|
599
|
+
value: this.content(),
|
|
600
|
+
source: getTokenSource(this.currToken),
|
|
601
|
+
sourceIndex: this.currToken[tokenize_1.FIELDS.START_POS],
|
|
602
|
+
});
|
|
603
|
+
this.position++;
|
|
604
|
+
}
|
|
605
|
+
else if (WHITESPACE_TOKENS[this.currToken[tokenize_1.FIELDS.TYPE]]) {
|
|
606
|
+
// pass
|
|
607
|
+
}
|
|
608
|
+
else if (!spaceOrDescendantSelectorNodes) {
|
|
609
|
+
this.unexpected();
|
|
610
|
+
}
|
|
611
|
+
if (node) {
|
|
612
|
+
if (spaceOrDescendantSelectorNodes) {
|
|
613
|
+
var _b = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes), space = _b.space, rawSpace = _b.rawSpace;
|
|
614
|
+
node.spaces.before = space;
|
|
615
|
+
node.rawSpaceBefore = rawSpace;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
// descendant combinator
|
|
620
|
+
var _c = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes, true), space = _c.space, rawSpace = _c.rawSpace;
|
|
621
|
+
if (!rawSpace) {
|
|
622
|
+
rawSpace = space;
|
|
623
|
+
}
|
|
624
|
+
var spaces = {};
|
|
625
|
+
var raws = { spaces: {} };
|
|
626
|
+
if (space.endsWith(" ") && rawSpace.endsWith(" ")) {
|
|
627
|
+
spaces.before = space.slice(0, space.length - 1);
|
|
628
|
+
raws.spaces.before = rawSpace.slice(0, rawSpace.length - 1);
|
|
629
|
+
}
|
|
630
|
+
else if (space[0] === " " && rawSpace[0] === " ") {
|
|
631
|
+
spaces.after = space.slice(1);
|
|
632
|
+
raws.spaces.after = rawSpace.slice(1);
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
raws.value = rawSpace;
|
|
636
|
+
}
|
|
637
|
+
node = new combinator_1.default({
|
|
638
|
+
value: " ",
|
|
639
|
+
source: getTokenSourceSpan(firstToken, this.tokens[this.position - 1]),
|
|
640
|
+
sourceIndex: firstToken[tokenize_1.FIELDS.START_POS],
|
|
641
|
+
spaces: spaces,
|
|
642
|
+
raws: raws,
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
if (this.currToken && this.currToken[tokenize_1.FIELDS.TYPE] === tokens.space) {
|
|
646
|
+
node.spaces.after = this.optionalSpace(this.content());
|
|
647
|
+
this.position++;
|
|
648
|
+
}
|
|
649
|
+
return this.newNode(node);
|
|
650
|
+
};
|
|
651
|
+
Parser.prototype.comma = function () {
|
|
652
|
+
if (this.position === this.tokens.length - 1) {
|
|
653
|
+
this.root.trailingComma = true;
|
|
654
|
+
this.position++;
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
this.current._inferEndPosition();
|
|
658
|
+
var selector = new selector_1.default({
|
|
659
|
+
source: {
|
|
660
|
+
start: tokenStart(this.tokens[this.position + 1]),
|
|
661
|
+
},
|
|
662
|
+
sourceIndex: this.tokens[this.position + 1][tokenize_1.FIELDS.START_POS],
|
|
663
|
+
});
|
|
664
|
+
this.current.parent.append(selector);
|
|
665
|
+
this.current = selector;
|
|
666
|
+
this.position++;
|
|
667
|
+
};
|
|
668
|
+
Parser.prototype.comment = function () {
|
|
669
|
+
var current = this.currToken;
|
|
670
|
+
this.newNode(new comment_1.default({
|
|
671
|
+
value: this.content(),
|
|
672
|
+
source: getTokenSource(current),
|
|
673
|
+
sourceIndex: current[tokenize_1.FIELDS.START_POS],
|
|
674
|
+
}));
|
|
675
|
+
this.position++;
|
|
676
|
+
};
|
|
677
|
+
Parser.prototype.error = function (message, opts) {
|
|
678
|
+
throw this.root.error(message, opts);
|
|
679
|
+
};
|
|
680
|
+
Parser.prototype.missingBackslash = function () {
|
|
681
|
+
return this.error("Expected a backslash preceding the semicolon.", {
|
|
682
|
+
index: this.currToken[tokenize_1.FIELDS.START_POS],
|
|
683
|
+
});
|
|
684
|
+
};
|
|
685
|
+
Parser.prototype.missingParenthesis = function () {
|
|
686
|
+
return this.expected("opening parenthesis", this.currToken[tokenize_1.FIELDS.START_POS]);
|
|
687
|
+
};
|
|
688
|
+
Parser.prototype.missingSquareBracket = function () {
|
|
689
|
+
return this.expected("opening square bracket", this.currToken[tokenize_1.FIELDS.START_POS]);
|
|
690
|
+
};
|
|
691
|
+
Parser.prototype.unexpected = function () {
|
|
692
|
+
return this.error("Unexpected '".concat(this.content(), "'. Escaping special characters with \\ may help."), this.currToken[tokenize_1.FIELDS.START_POS]);
|
|
693
|
+
};
|
|
694
|
+
Parser.prototype.unexpectedPipe = function () {
|
|
695
|
+
return this.error("Unexpected '|'.", this.currToken[tokenize_1.FIELDS.START_POS]);
|
|
696
|
+
};
|
|
697
|
+
Parser.prototype.namespace = function () {
|
|
698
|
+
var before = (this.prevToken && this.content(this.prevToken)) || true;
|
|
699
|
+
if (this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.word) {
|
|
700
|
+
this.position++;
|
|
701
|
+
return this.word(before);
|
|
702
|
+
}
|
|
703
|
+
else if (this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.asterisk) {
|
|
704
|
+
this.position++;
|
|
705
|
+
return this.universal(before);
|
|
706
|
+
}
|
|
707
|
+
this.unexpectedPipe();
|
|
708
|
+
};
|
|
709
|
+
Parser.prototype.nesting = function () {
|
|
710
|
+
if (this.nextToken) {
|
|
711
|
+
var nextContent = this.content(this.nextToken);
|
|
712
|
+
if (nextContent === "|") {
|
|
713
|
+
this.position++;
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
var current = this.currToken;
|
|
718
|
+
this.newNode(new nesting_1.default({
|
|
719
|
+
value: this.content(),
|
|
720
|
+
source: getTokenSource(current),
|
|
721
|
+
sourceIndex: current[tokenize_1.FIELDS.START_POS],
|
|
722
|
+
}));
|
|
723
|
+
this.position++;
|
|
724
|
+
};
|
|
725
|
+
Parser.prototype.parentheses = function () {
|
|
726
|
+
var last = this.current.last;
|
|
727
|
+
var unbalanced = 1;
|
|
728
|
+
this.position++;
|
|
729
|
+
if (last && last.type === types.PSEUDO) {
|
|
730
|
+
var selector = new selector_1.default({
|
|
731
|
+
source: { start: tokenStart(this.tokens[this.position]) },
|
|
732
|
+
sourceIndex: this.tokens[this.position][tokenize_1.FIELDS.START_POS],
|
|
733
|
+
});
|
|
734
|
+
var cache = this.current;
|
|
735
|
+
last.append(selector);
|
|
736
|
+
this.current = selector;
|
|
737
|
+
// Track nesting depth so deeply nested pseudo selectors raise a
|
|
738
|
+
// catchable error instead of overflowing the call stack. The
|
|
739
|
+
// counter is restored in `finally` so the parser is never left in
|
|
740
|
+
// an inconsistent state, even on the error path.
|
|
741
|
+
this.nestingDepth++;
|
|
742
|
+
try {
|
|
743
|
+
if (this.nestingDepth > this.maxNestingDepth) {
|
|
744
|
+
this.error("Cannot parse selector: nesting depth exceeds the maximum of ".concat(this.maxNestingDepth, "."), { index: this.currToken[tokenize_1.FIELDS.START_POS] });
|
|
745
|
+
}
|
|
746
|
+
while (this.position < this.tokens.length && unbalanced) {
|
|
747
|
+
if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis) {
|
|
748
|
+
unbalanced++;
|
|
749
|
+
}
|
|
750
|
+
if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) {
|
|
751
|
+
unbalanced--;
|
|
752
|
+
}
|
|
753
|
+
if (unbalanced) {
|
|
754
|
+
this.parse();
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
this.current.source.end = tokenEnd(this.currToken);
|
|
758
|
+
this.current.parent.source.end = tokenEnd(this.currToken);
|
|
759
|
+
this.position++;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
finally {
|
|
764
|
+
this.nestingDepth--;
|
|
765
|
+
}
|
|
766
|
+
this.current = cache;
|
|
767
|
+
}
|
|
768
|
+
else {
|
|
769
|
+
// I think this case should be an error. It's used to implement a basic parse of media queries
|
|
770
|
+
// but I don't think it's a good idea.
|
|
771
|
+
var parenStart = this.currToken;
|
|
772
|
+
var parenValue = "(";
|
|
773
|
+
var parenEnd = void 0;
|
|
774
|
+
while (this.position < this.tokens.length && unbalanced) {
|
|
775
|
+
if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis) {
|
|
776
|
+
unbalanced++;
|
|
777
|
+
}
|
|
778
|
+
if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) {
|
|
779
|
+
unbalanced--;
|
|
780
|
+
}
|
|
781
|
+
parenEnd = this.currToken;
|
|
782
|
+
parenValue += this.parseParenthesisToken(this.currToken);
|
|
783
|
+
this.position++;
|
|
784
|
+
}
|
|
785
|
+
if (last) {
|
|
786
|
+
last.appendToPropertyAndEscape("value", parenValue, parenValue);
|
|
787
|
+
}
|
|
788
|
+
else {
|
|
789
|
+
this.newNode(new string_1.default({
|
|
790
|
+
value: parenValue,
|
|
791
|
+
source: getSource(parenStart[tokenize_1.FIELDS.START_LINE], parenStart[tokenize_1.FIELDS.START_COL], parenEnd[tokenize_1.FIELDS.END_LINE], parenEnd[tokenize_1.FIELDS.END_COL]),
|
|
792
|
+
sourceIndex: parenStart[tokenize_1.FIELDS.START_POS],
|
|
793
|
+
}));
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
if (unbalanced) {
|
|
797
|
+
return this.expected("closing parenthesis", this.currToken[tokenize_1.FIELDS.START_POS]);
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
Parser.prototype.pseudo = function () {
|
|
801
|
+
var _this = this;
|
|
802
|
+
var pseudoStr = "";
|
|
803
|
+
var startingToken = this.currToken;
|
|
804
|
+
while (this.currToken && this.currToken[tokenize_1.FIELDS.TYPE] === tokens.colon) {
|
|
805
|
+
pseudoStr += this.content();
|
|
806
|
+
this.position++;
|
|
807
|
+
}
|
|
808
|
+
if (!this.currToken) {
|
|
809
|
+
return this.expected(["pseudo-class", "pseudo-element"], this.position - 1);
|
|
810
|
+
}
|
|
811
|
+
if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.word) {
|
|
812
|
+
this.splitWord(false, function (first, length) {
|
|
813
|
+
pseudoStr += first;
|
|
814
|
+
_this.newNode(new pseudo_1.default({
|
|
815
|
+
value: pseudoStr,
|
|
816
|
+
source: getTokenSourceSpan(startingToken, _this.currToken),
|
|
817
|
+
sourceIndex: startingToken[tokenize_1.FIELDS.START_POS],
|
|
818
|
+
}));
|
|
819
|
+
if (length > 1 &&
|
|
820
|
+
_this.nextToken &&
|
|
821
|
+
_this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis) {
|
|
822
|
+
_this.error("Misplaced parenthesis.", {
|
|
823
|
+
index: _this.nextToken[tokenize_1.FIELDS.START_POS],
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
else {
|
|
829
|
+
return this.expected(["pseudo-class", "pseudo-element"], this.currToken[tokenize_1.FIELDS.START_POS]);
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
Parser.prototype.space = function () {
|
|
833
|
+
var content = this.content();
|
|
834
|
+
// Handle space before and after the selector
|
|
835
|
+
if (this.position === 0 ||
|
|
836
|
+
this.prevToken[tokenize_1.FIELDS.TYPE] === tokens.comma ||
|
|
837
|
+
this.prevToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis ||
|
|
838
|
+
this.current.nodes.every(function (node) { return node.type === "comment"; })) {
|
|
839
|
+
this.spaces = this.optionalSpace(content);
|
|
840
|
+
this.position++;
|
|
841
|
+
}
|
|
842
|
+
else if (this.position === this.tokens.length - 1 ||
|
|
843
|
+
this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.comma ||
|
|
844
|
+
this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) {
|
|
845
|
+
this.current.last.spaces.after = this.optionalSpace(content);
|
|
846
|
+
this.position++;
|
|
847
|
+
}
|
|
848
|
+
else {
|
|
849
|
+
this.combinator();
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
Parser.prototype.string = function () {
|
|
853
|
+
var current = this.currToken;
|
|
854
|
+
this.newNode(new string_1.default({
|
|
855
|
+
value: this.content(),
|
|
856
|
+
source: getTokenSource(current),
|
|
857
|
+
sourceIndex: current[tokenize_1.FIELDS.START_POS],
|
|
858
|
+
}));
|
|
859
|
+
this.position++;
|
|
860
|
+
};
|
|
861
|
+
Parser.prototype.universal = function (namespace) {
|
|
862
|
+
var nextToken = this.nextToken;
|
|
863
|
+
if (nextToken && this.content(nextToken) === "|") {
|
|
864
|
+
this.position++;
|
|
865
|
+
return this.namespace();
|
|
866
|
+
}
|
|
867
|
+
var current = this.currToken;
|
|
868
|
+
this.newNode(new universal_1.default({
|
|
869
|
+
value: this.content(),
|
|
870
|
+
source: getTokenSource(current),
|
|
871
|
+
sourceIndex: current[tokenize_1.FIELDS.START_POS],
|
|
872
|
+
}), namespace);
|
|
873
|
+
this.position++;
|
|
874
|
+
};
|
|
875
|
+
Parser.prototype.splitWord = function (namespace, firstCallback) {
|
|
876
|
+
var _this = this;
|
|
877
|
+
var nextToken = this.nextToken;
|
|
878
|
+
var word = this.content();
|
|
879
|
+
while (nextToken &&
|
|
880
|
+
~[tokens.dollar, tokens.caret, tokens.equals, tokens.word].indexOf(nextToken[tokenize_1.FIELDS.TYPE])) {
|
|
881
|
+
this.position++;
|
|
882
|
+
var current = this.content();
|
|
883
|
+
word += current;
|
|
884
|
+
if (current.lastIndexOf("\\") === current.length - 1) {
|
|
885
|
+
var next = this.nextToken;
|
|
886
|
+
if (next && next[tokenize_1.FIELDS.TYPE] === tokens.space) {
|
|
887
|
+
word += this.requiredSpace(this.content(next));
|
|
888
|
+
this.position++;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
nextToken = this.nextToken;
|
|
892
|
+
}
|
|
893
|
+
var hasClass = indexesOf(word, ".").filter(function (i) {
|
|
894
|
+
// Allow escaped dot within class name
|
|
895
|
+
var escapedDot = word[i - 1] === "\\";
|
|
896
|
+
// Allow decimal numbers percent in @keyframes
|
|
897
|
+
var isKeyframesPercent = /^\d+\.\d+%$/.test(word);
|
|
898
|
+
return !escapedDot && !isKeyframesPercent;
|
|
899
|
+
});
|
|
900
|
+
var hasId = indexesOf(word, "#").filter(function (i) { return word[i - 1] !== "\\"; });
|
|
901
|
+
// Eliminate Sass interpolations from the list of id indexes
|
|
902
|
+
var interpolations = indexesOf(word, "#{");
|
|
903
|
+
if (interpolations.length) {
|
|
904
|
+
hasId = hasId.filter(function (hashIndex) { return !~interpolations.indexOf(hashIndex); });
|
|
905
|
+
}
|
|
906
|
+
var indices = (0, sortAscending_1.default)(uniqs(__spreadArray(__spreadArray([0], __read(hasClass), false), __read(hasId), false)));
|
|
907
|
+
indices.forEach(function (ind, i) {
|
|
908
|
+
var index = indices[i + 1] || word.length;
|
|
909
|
+
var value = word.slice(ind, index);
|
|
910
|
+
if (i === 0 && firstCallback) {
|
|
911
|
+
return firstCallback.call(_this, value, indices.length);
|
|
912
|
+
}
|
|
913
|
+
var node;
|
|
914
|
+
var current = _this.currToken;
|
|
915
|
+
var sourceIndex = current[tokenize_1.FIELDS.START_POS] + indices[i];
|
|
916
|
+
var source = getSource(current[1], current[2] + ind, current[3], current[2] + (index - 1));
|
|
917
|
+
if (~hasClass.indexOf(ind)) {
|
|
918
|
+
var classNameOpts = {
|
|
919
|
+
value: value.slice(1),
|
|
920
|
+
source: source,
|
|
921
|
+
sourceIndex: sourceIndex,
|
|
922
|
+
};
|
|
923
|
+
node = new className_1.default(unescapeProp(classNameOpts, "value"));
|
|
924
|
+
}
|
|
925
|
+
else if (~hasId.indexOf(ind)) {
|
|
926
|
+
var idOpts = {
|
|
927
|
+
value: value.slice(1),
|
|
928
|
+
source: source,
|
|
929
|
+
sourceIndex: sourceIndex,
|
|
930
|
+
};
|
|
931
|
+
node = new id_1.default(unescapeProp(idOpts, "value"));
|
|
932
|
+
}
|
|
933
|
+
else {
|
|
934
|
+
var tagOpts = {
|
|
935
|
+
value: value,
|
|
936
|
+
source: source,
|
|
937
|
+
sourceIndex: sourceIndex,
|
|
938
|
+
};
|
|
939
|
+
unescapeProp(tagOpts, "value");
|
|
940
|
+
node = new tag_1.default(tagOpts);
|
|
941
|
+
}
|
|
942
|
+
_this.newNode(node, namespace);
|
|
943
|
+
// Ensure that the namespace is used only once
|
|
944
|
+
namespace = null;
|
|
945
|
+
});
|
|
946
|
+
this.position++;
|
|
947
|
+
};
|
|
948
|
+
Parser.prototype.word = function (namespace) {
|
|
949
|
+
var nextToken = this.nextToken;
|
|
950
|
+
if (nextToken && this.content(nextToken) === "|") {
|
|
951
|
+
this.position++;
|
|
952
|
+
return this.namespace();
|
|
953
|
+
}
|
|
954
|
+
return this.splitWord(namespace);
|
|
955
|
+
};
|
|
956
|
+
Parser.prototype.loop = function () {
|
|
957
|
+
while (this.position < this.tokens.length) {
|
|
958
|
+
this.parse(true);
|
|
959
|
+
}
|
|
960
|
+
this.current._inferEndPosition();
|
|
961
|
+
return this.root;
|
|
962
|
+
};
|
|
963
|
+
Parser.prototype.parse = function (throwOnParenthesis) {
|
|
964
|
+
switch (this.currToken[tokenize_1.FIELDS.TYPE]) {
|
|
965
|
+
case tokens.space:
|
|
966
|
+
this.space();
|
|
967
|
+
break;
|
|
968
|
+
case tokens.comment:
|
|
969
|
+
this.comment();
|
|
970
|
+
break;
|
|
971
|
+
case tokens.openParenthesis:
|
|
972
|
+
this.parentheses();
|
|
973
|
+
break;
|
|
974
|
+
case tokens.closeParenthesis:
|
|
975
|
+
if (throwOnParenthesis) {
|
|
976
|
+
this.missingParenthesis();
|
|
977
|
+
}
|
|
978
|
+
break;
|
|
979
|
+
case tokens.openSquare:
|
|
980
|
+
this.attribute();
|
|
981
|
+
break;
|
|
982
|
+
case tokens.dollar:
|
|
983
|
+
case tokens.caret:
|
|
984
|
+
case tokens.equals:
|
|
985
|
+
case tokens.word:
|
|
986
|
+
this.word();
|
|
987
|
+
break;
|
|
988
|
+
case tokens.colon:
|
|
989
|
+
this.pseudo();
|
|
990
|
+
break;
|
|
991
|
+
case tokens.comma:
|
|
992
|
+
this.comma();
|
|
993
|
+
break;
|
|
994
|
+
case tokens.asterisk:
|
|
995
|
+
this.universal();
|
|
996
|
+
break;
|
|
997
|
+
case tokens.ampersand:
|
|
998
|
+
this.nesting();
|
|
999
|
+
break;
|
|
1000
|
+
case tokens.slash:
|
|
1001
|
+
case tokens.combinator:
|
|
1002
|
+
this.combinator();
|
|
1003
|
+
break;
|
|
1004
|
+
case tokens.str:
|
|
1005
|
+
this.string();
|
|
1006
|
+
break;
|
|
1007
|
+
// These cases throw; no break needed.
|
|
1008
|
+
case tokens.closeSquare:
|
|
1009
|
+
this.missingSquareBracket();
|
|
1010
|
+
case tokens.semicolon:
|
|
1011
|
+
this.missingBackslash();
|
|
1012
|
+
default:
|
|
1013
|
+
this.unexpected();
|
|
1014
|
+
}
|
|
1015
|
+
};
|
|
1016
|
+
/**
|
|
1017
|
+
* Helpers
|
|
1018
|
+
*/
|
|
1019
|
+
Parser.prototype.expected = function (description, index, found) {
|
|
1020
|
+
if (Array.isArray(description)) {
|
|
1021
|
+
var last = description.pop();
|
|
1022
|
+
description = "".concat(description.join(", "), " or ").concat(last);
|
|
1023
|
+
}
|
|
1024
|
+
var an = /^[aeiou]/.test(description[0]) ? "an" : "a";
|
|
1025
|
+
if (!found) {
|
|
1026
|
+
return this.error("Expected ".concat(an, " ").concat(description, "."), { index: index });
|
|
1027
|
+
}
|
|
1028
|
+
return this.error("Expected ".concat(an, " ").concat(description, ", found \"").concat(found, "\" instead."), { index: index });
|
|
1029
|
+
};
|
|
1030
|
+
Parser.prototype.requiredSpace = function (space) {
|
|
1031
|
+
return this.options.lossy ? " " : space;
|
|
1032
|
+
};
|
|
1033
|
+
Parser.prototype.optionalSpace = function (space) {
|
|
1034
|
+
return this.options.lossy ? "" : space;
|
|
1035
|
+
};
|
|
1036
|
+
Parser.prototype.lossySpace = function (space, required) {
|
|
1037
|
+
if (this.options.lossy) {
|
|
1038
|
+
return required ? " " : "";
|
|
1039
|
+
}
|
|
1040
|
+
else {
|
|
1041
|
+
return space;
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
Parser.prototype.parseParenthesisToken = function (token) {
|
|
1045
|
+
var content = this.content(token);
|
|
1046
|
+
if (token[tokenize_1.FIELDS.TYPE] === tokens.space) {
|
|
1047
|
+
return this.requiredSpace(content);
|
|
1048
|
+
}
|
|
1049
|
+
else {
|
|
1050
|
+
return content;
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
Parser.prototype.newNode = function (node, namespace) {
|
|
1054
|
+
if (namespace) {
|
|
1055
|
+
if (/^ +$/.test(namespace)) {
|
|
1056
|
+
if (!this.options.lossy) {
|
|
1057
|
+
this.spaces = (this.spaces || "") + namespace;
|
|
1058
|
+
}
|
|
1059
|
+
namespace = true;
|
|
1060
|
+
}
|
|
1061
|
+
node.namespace = namespace;
|
|
1062
|
+
unescapeProp(node, "namespace");
|
|
1063
|
+
}
|
|
1064
|
+
if (this.spaces) {
|
|
1065
|
+
node.spaces.before = this.spaces;
|
|
1066
|
+
this.spaces = "";
|
|
1067
|
+
}
|
|
1068
|
+
return this.current.append(node);
|
|
1069
|
+
};
|
|
1070
|
+
Parser.prototype.content = function (token) {
|
|
1071
|
+
if (token === void 0) { token = this.currToken; }
|
|
1072
|
+
return this.css.slice(token[tokenize_1.FIELDS.START_POS], token[tokenize_1.FIELDS.END_POS]);
|
|
1073
|
+
};
|
|
1074
|
+
Object.defineProperty(Parser.prototype, "currToken", {
|
|
1075
|
+
get: function () {
|
|
1076
|
+
return this.tokens[this.position];
|
|
1077
|
+
},
|
|
1078
|
+
enumerable: false,
|
|
1079
|
+
configurable: true
|
|
1080
|
+
});
|
|
1081
|
+
Object.defineProperty(Parser.prototype, "nextToken", {
|
|
1082
|
+
get: function () {
|
|
1083
|
+
return this.tokens[this.position + 1];
|
|
1084
|
+
},
|
|
1085
|
+
enumerable: false,
|
|
1086
|
+
configurable: true
|
|
1087
|
+
});
|
|
1088
|
+
Object.defineProperty(Parser.prototype, "prevToken", {
|
|
1089
|
+
get: function () {
|
|
1090
|
+
return this.tokens[this.position - 1];
|
|
1091
|
+
},
|
|
1092
|
+
enumerable: false,
|
|
1093
|
+
configurable: true
|
|
1094
|
+
});
|
|
1095
|
+
/**
|
|
1096
|
+
* returns the index of the next non-whitespace, non-comment token.
|
|
1097
|
+
* returns -1 if no meaningful token is found.
|
|
1098
|
+
*/
|
|
1099
|
+
Parser.prototype.locateNextMeaningfulToken = function (startPosition) {
|
|
1100
|
+
if (startPosition === void 0) { startPosition = this.position + 1; }
|
|
1101
|
+
var searchPosition = startPosition;
|
|
1102
|
+
while (searchPosition < this.tokens.length) {
|
|
1103
|
+
if (WHITESPACE_EQUIV_TOKENS[this.tokens[searchPosition][tokenize_1.FIELDS.TYPE]]) {
|
|
1104
|
+
searchPosition++;
|
|
1105
|
+
continue;
|
|
1106
|
+
}
|
|
1107
|
+
else {
|
|
1108
|
+
return searchPosition;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
return -1;
|
|
1112
|
+
};
|
|
1113
|
+
return Parser;
|
|
1114
|
+
}());
|
|
1115
|
+
exports.default = Parser;
|
|
1116
|
+
//# sourceMappingURL=parser.js.map
|