1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | function CssSelectorParser() {
|
23 | this.pseudos = {};
|
24 | this.attrEqualityMods = {};
|
25 | this.ruleNestingOperators = {};
|
26 | this.substitutesEnabled = false;
|
27 | }
|
28 |
|
29 | CssSelectorParser.prototype.registerSelectorPseudos = function(name) {
|
30 | for (var j = 0, len = arguments.length; j < len; j++) {
|
31 | name = arguments[j];
|
32 | this.pseudos[name] = 'selector';
|
33 | }
|
34 | return this;
|
35 | };
|
36 |
|
37 | CssSelectorParser.prototype.unregisterSelectorPseudos = function(name) {
|
38 | for (var j = 0, len = arguments.length; j < len; j++) {
|
39 | name = arguments[j];
|
40 | delete this.pseudos[name];
|
41 | }
|
42 | return this;
|
43 | };
|
44 |
|
45 | CssSelectorParser.prototype.registerNumericPseudos = function(name) {
|
46 | for (var j = 0, len = arguments.length; j < len; j++) {
|
47 | name = arguments[j];
|
48 | this.pseudos[name] = 'numeric';
|
49 | }
|
50 | return this;
|
51 | };
|
52 |
|
53 | CssSelectorParser.prototype.unregisterNumericPseudos = function(name) {
|
54 | for (var j = 0, len = arguments.length; j < len; j++) {
|
55 | name = arguments[j];
|
56 | delete this.pseudos[name];
|
57 | }
|
58 | return this;
|
59 | };
|
60 |
|
61 | CssSelectorParser.prototype.registerNestingOperators = function(operator) {
|
62 | for (var j = 0, len = arguments.length; j < len; j++) {
|
63 | operator = arguments[j];
|
64 | this.ruleNestingOperators[operator] = true;
|
65 | }
|
66 | return this;
|
67 | };
|
68 |
|
69 | CssSelectorParser.prototype.unregisterNestingOperators = function(operator) {
|
70 | for (var j = 0, len = arguments.length; j < len; j++) {
|
71 | operator = arguments[j];
|
72 | delete this.ruleNestingOperators[operator];
|
73 | }
|
74 | return this;
|
75 | };
|
76 |
|
77 | CssSelectorParser.prototype.registerAttrEqualityMods = function(mod) {
|
78 | for (var j = 0, len = arguments.length; j < len; j++) {
|
79 | mod = arguments[j];
|
80 | this.attrEqualityMods[mod] = true;
|
81 | }
|
82 | return this;
|
83 | };
|
84 |
|
85 | CssSelectorParser.prototype.unregisterAttrEqualityMods = function(mod) {
|
86 | for (var j = 0, len = arguments.length; j < len; j++) {
|
87 | mod = arguments[j];
|
88 | delete this.attrEqualityMods[mod];
|
89 | }
|
90 | return this;
|
91 | };
|
92 |
|
93 | CssSelectorParser.prototype.enableSubstitutes = function() {
|
94 | this.substitutesEnabled = true;
|
95 | return this;
|
96 | };
|
97 |
|
98 | CssSelectorParser.prototype.disableSubstitutes = function() {
|
99 | this.substitutesEnabled = false;
|
100 | return this;
|
101 | };
|
102 |
|
103 | function isIdentStart(c) {
|
104 | return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c === '-') || (c === '_');
|
105 | }
|
106 |
|
107 | function isIdent(c) {
|
108 | return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c === '-' || c === '_';
|
109 | }
|
110 |
|
111 | function isHex(c) {
|
112 | return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9');
|
113 | }
|
114 |
|
115 | function isDecimal(c) {
|
116 | return c >= '0' && c <= '9';
|
117 | }
|
118 |
|
119 | function isAttrMatchOperator(chr) {
|
120 | return chr === '=' || chr === '^' || chr === '$' || chr === '*' || chr === '~';
|
121 | }
|
122 |
|
123 | var identSpecialChars = {
|
124 | '!': true,
|
125 | '"': true,
|
126 | '#': true,
|
127 | '$': true,
|
128 | '%': true,
|
129 | '&': true,
|
130 | '\'': true,
|
131 | '(': true,
|
132 | ')': true,
|
133 | '*': true,
|
134 | '+': true,
|
135 | ',': true,
|
136 | '.': true,
|
137 | '/': true,
|
138 | ';': true,
|
139 | '<': true,
|
140 | '=': true,
|
141 | '>': true,
|
142 | '?': true,
|
143 | '@': true,
|
144 | '[': true,
|
145 | '\\': true,
|
146 | ']': true,
|
147 | '^': true,
|
148 | '`': true,
|
149 | '{': true,
|
150 | '|': true,
|
151 | '}': true,
|
152 | '~': true
|
153 | };
|
154 |
|
155 | var strReplacementsRev = {
|
156 | '\n': '\\n',
|
157 | '\r': '\\r',
|
158 | '\t': '\\t',
|
159 | '\f': '\\f',
|
160 | '\v': '\\v'
|
161 | };
|
162 |
|
163 | var singleQuoteEscapeChars = {
|
164 | n: '\n',
|
165 | r: '\r',
|
166 | t: '\t',
|
167 | f: '\f',
|
168 | '\\': '\\',
|
169 | '\'': '\''
|
170 | };
|
171 |
|
172 | var doubleQuotesEscapeChars = {
|
173 | n: '\n',
|
174 | r: '\r',
|
175 | t: '\t',
|
176 | f: '\f',
|
177 | '\\': '\\',
|
178 | '"': '"'
|
179 | };
|
180 |
|
181 | function ParseContext(str, pos, pseudos, attrEqualityMods, ruleNestingOperators, substitutesEnabled) {
|
182 | var chr, getIdent, getStr, l, skipWhitespace;
|
183 | l = str.length;
|
184 | chr = null;
|
185 | getStr = function(quote, escapeTable) {
|
186 | var esc, hex, result;
|
187 | result = '';
|
188 | pos++;
|
189 | chr = str.charAt(pos);
|
190 | while (pos < l) {
|
191 | if (chr === quote) {
|
192 | pos++;
|
193 | return result;
|
194 | } else if (chr === '\\') {
|
195 | pos++;
|
196 | chr = str.charAt(pos);
|
197 | if (chr === quote) {
|
198 | result += quote;
|
199 | } else if (esc = escapeTable[chr]) {
|
200 | result += esc;
|
201 | } else if (isHex(chr)) {
|
202 | hex = chr;
|
203 | pos++;
|
204 | chr = str.charAt(pos);
|
205 | while (isHex(chr)) {
|
206 | hex += chr;
|
207 | pos++;
|
208 | chr = str.charAt(pos);
|
209 | }
|
210 | if (chr === ' ') {
|
211 | pos++;
|
212 | chr = str.charAt(pos);
|
213 | }
|
214 | result += String.fromCharCode(parseInt(hex, 16));
|
215 | continue;
|
216 | } else {
|
217 | result += chr;
|
218 | }
|
219 | } else {
|
220 | result += chr;
|
221 | }
|
222 | pos++;
|
223 | chr = str.charAt(pos);
|
224 | }
|
225 | return result;
|
226 | };
|
227 | getIdent = function(specials) {
|
228 | var result = '';
|
229 | chr = str.charAt(pos);
|
230 | while (pos < l) {
|
231 | if (isIdent(chr) || (specials && specials[chr])) {
|
232 | result += chr;
|
233 | } else if (chr === '\\') {
|
234 | pos++;
|
235 | if (pos >= l) {
|
236 | throw Error('Expected symbol but end of file reached.');
|
237 | }
|
238 | chr = str.charAt(pos);
|
239 | if (identSpecialChars[chr]) {
|
240 | result += chr;
|
241 | } else if (isHex(chr)) {
|
242 | var hex = chr;
|
243 | pos++;
|
244 | chr = str.charAt(pos);
|
245 | while (isHex(chr)) {
|
246 | hex += chr;
|
247 | pos++;
|
248 | chr = str.charAt(pos);
|
249 | }
|
250 | if (chr === ' ') {
|
251 | pos++;
|
252 | chr = str.charAt(pos);
|
253 | }
|
254 | result += String.fromCharCode(parseInt(hex, 16));
|
255 | continue;
|
256 | } else {
|
257 | result += chr;
|
258 | }
|
259 | } else {
|
260 | return result;
|
261 | }
|
262 | pos++;
|
263 | chr = str.charAt(pos);
|
264 | }
|
265 | return result;
|
266 | };
|
267 | skipWhitespace = function() {
|
268 | chr = str.charAt(pos);
|
269 | var result = false;
|
270 | while (chr === ' ' || chr === "\t" || chr === "\n" || chr === "\r" || chr === "\f") {
|
271 | result = true;
|
272 | pos++;
|
273 | chr = str.charAt(pos);
|
274 | }
|
275 | return result;
|
276 | };
|
277 | this.parse = function() {
|
278 | var res = this.parseSelector();
|
279 | if (pos < l) {
|
280 | throw Error('Rule expected but "' + str.charAt(pos) + '" found.');
|
281 | }
|
282 | return res;
|
283 | };
|
284 | this.parseSelector = function() {
|
285 | var res;
|
286 | var selector = res = this.parseSingleSelector();
|
287 | chr = str.charAt(pos);
|
288 | while (chr === ',') {
|
289 | pos++;
|
290 | skipWhitespace();
|
291 | if (res.type !== 'selectors') {
|
292 | res = {
|
293 | type: 'selectors',
|
294 | selectors: [selector]
|
295 | };
|
296 | }
|
297 | selector = this.parseSingleSelector();
|
298 | if (!selector) {
|
299 | throw Error('Rule expected after ",".');
|
300 | }
|
301 | res.selectors.push(selector);
|
302 | }
|
303 | return res;
|
304 | };
|
305 |
|
306 | this.parseSingleSelector = function() {
|
307 | skipWhitespace();
|
308 |
|
309 | let opm = str.slice(pos,pos + 4).match(/^(\>{1,3}|\+|~)/);
|
310 |
|
311 | var selector = {
|
312 | type: 'ruleSet'
|
313 | };
|
314 |
|
315 | var rule = opm ? {type: 'rule', isScope: true} : this.parseRule();
|
316 |
|
317 | if (!rule) {
|
318 | return null;
|
319 | }
|
320 | var currentRule = selector;
|
321 | while (rule) {
|
322 | rule.type = 'rule';
|
323 | currentRule.rule = rule;
|
324 | currentRule = rule;
|
325 | skipWhitespace();
|
326 | chr = str.charAt(pos);
|
327 | if (pos >= l || chr === ',' || chr === ')') {
|
328 | break;
|
329 | }
|
330 | if (ruleNestingOperators[chr]) {
|
331 | var op = chr;
|
332 | if(op == '>' && str.charAt(pos + 1) == '>' && str.charAt(pos + 2) == '>'){
|
333 | op = '>>>';
|
334 | pos = pos + 3;
|
335 | } else if(op == '>' && str.charAt(pos + 1) == '>'){
|
336 | op = '>>';
|
337 | pos = pos + 2;
|
338 | } else {
|
339 | pos++;
|
340 | }
|
341 | skipWhitespace();
|
342 | rule = this.parseRule();
|
343 |
|
344 | if (!rule) {
|
345 | if(op == '>' || op == '>>>' || op == '>>'){
|
346 | rule = {tagName: '*'}
|
347 | } else {
|
348 | throw Error('Rule expected after "' + op + '".');
|
349 | }
|
350 | }
|
351 | rule.nestingOperator = op;
|
352 | } else {
|
353 | rule = this.parseRule();
|
354 | if (rule) {
|
355 | rule.nestingOperator = null;
|
356 | }
|
357 | }
|
358 | }
|
359 | return selector;
|
360 | };
|
361 |
|
362 | this.parseRule = function() {
|
363 | var rule = null;
|
364 | while (pos < l) {
|
365 | chr = str.charAt(pos);
|
366 | if (chr === '&') {
|
367 | pos++;
|
368 | (rule = rule || {}).isScope = true;
|
369 | } else if (chr === '*') {
|
370 | pos++;
|
371 | (rule = rule || {}).tagName = '*';
|
372 | } else if (isIdentStart(chr) || chr === '\\') {
|
373 | (rule = rule || {}).tagName = getIdent();
|
374 | } else if (chr === '$' || chr === '%') {
|
375 | pos++;
|
376 | rule = rule || {};
|
377 | (rule.classNames = rule.classNames || []).push(chr + getIdent());
|
378 | } else if (chr === '.') {
|
379 | pos++;
|
380 | rule = rule || {};
|
381 | (rule.classNames = rule.classNames || []).push(getIdent());
|
382 | } else if (chr === '#') {
|
383 | pos++;
|
384 | (rule = rule || {}).id = getIdent();
|
385 | } else if (chr === '[') {
|
386 | pos++;
|
387 | skipWhitespace();
|
388 | var attr = {
|
389 | name: getIdent()
|
390 | };
|
391 | skipWhitespace();
|
392 | if (chr === ']') {
|
393 | pos++;
|
394 | } else {
|
395 | var operator = '';
|
396 | if (attrEqualityMods[chr]) {
|
397 | operator = chr;
|
398 | pos++;
|
399 | chr = str.charAt(pos);
|
400 | }
|
401 | if (pos >= l) {
|
402 | throw Error('Expected "=" but end of file reached.');
|
403 | }
|
404 | if (chr !== '=') {
|
405 | throw Error('Expected "=" but "' + chr + '" found.');
|
406 | }
|
407 | attr.operator = operator + '=';
|
408 | pos++;
|
409 | skipWhitespace();
|
410 | var attrValue = '';
|
411 | attr.valueType = 'string';
|
412 | if (chr === '"') {
|
413 | attrValue = getStr('"', doubleQuotesEscapeChars);
|
414 | } else if (chr === '\'') {
|
415 | attrValue = getStr('\'', singleQuoteEscapeChars);
|
416 | } else if (substitutesEnabled && chr === '$') {
|
417 | pos++;
|
418 | attrValue = getIdent();
|
419 | attr.valueType = 'substitute';
|
420 | } else {
|
421 | while (pos < l) {
|
422 | if (chr === ']') {
|
423 | break;
|
424 | }
|
425 | attrValue += chr;
|
426 | pos++;
|
427 | chr = str.charAt(pos);
|
428 | }
|
429 | attrValue = attrValue.trim();
|
430 | }
|
431 | skipWhitespace();
|
432 | if (pos >= l) {
|
433 | throw Error('Expected "]" but end of file reached.');
|
434 | }
|
435 | if (chr !== ']') {
|
436 | throw Error('Expected "]" but "' + chr + '" found.');
|
437 | }
|
438 | pos++;
|
439 | attr.value = attrValue;
|
440 | }
|
441 | rule = rule || {};
|
442 | (rule.attrs = rule.attrs || []).push(attr);
|
443 | } else if (chr === ':' || chr === '@') {
|
444 | let special = chr === '@';
|
445 |
|
446 | pos++;
|
447 |
|
448 | var pseudoName = ''
|
449 | while(str.charAt(pos) == '.'){
|
450 | pseudoName += '.';
|
451 | pos++;
|
452 | }
|
453 |
|
454 |
|
455 | pseudoName += getIdent({'~':true,'+':true,'.':false,'>':true,'<':true,'!':true});
|
456 | var pseudo = {
|
457 | special: special,
|
458 | name: pseudoName
|
459 | };
|
460 | if (chr === '(') {
|
461 | pos++;
|
462 | var value = '';
|
463 | skipWhitespace();
|
464 | if (pseudos[pseudoName] === 'selector') {
|
465 | pseudo.valueType = 'selector';
|
466 | value = this.parseSelector();
|
467 | } else {
|
468 | pseudo.valueType = pseudos[pseudoName] || 'string';
|
469 | if (chr === '"') {
|
470 | value = getStr('"', doubleQuotesEscapeChars);
|
471 | } else if (chr === '\'') {
|
472 | value = getStr('\'', singleQuoteEscapeChars);
|
473 | } else if (substitutesEnabled && chr === '$') {
|
474 | pos++;
|
475 | value = getIdent();
|
476 | pseudo.valueType = 'substitute';
|
477 | } else {
|
478 | while (pos < l) {
|
479 | if (chr === ')') {
|
480 | break;
|
481 | }
|
482 | value += chr;
|
483 | pos++;
|
484 | chr = str.charAt(pos);
|
485 | }
|
486 | value = value.trim();
|
487 | }
|
488 | skipWhitespace();
|
489 | }
|
490 | if (pos >= l) {
|
491 | throw Error('Expected ")" but end of file reached.');
|
492 | }
|
493 | if (chr !== ')') {
|
494 | throw Error('Expected ")" but "' + chr + '" found.');
|
495 | }
|
496 | pos++;
|
497 | pseudo.value = value;
|
498 | }
|
499 | rule = rule || {};
|
500 | (rule.pseudos = rule.pseudos || []).push(pseudo);
|
501 | } else {
|
502 | break;
|
503 | }
|
504 | }
|
505 | return rule;
|
506 | };
|
507 | return this;
|
508 | }
|
509 |
|
510 | CssSelectorParser.prototype.parse = function(str) {
|
511 | var context = new ParseContext(
|
512 | str,
|
513 | 0,
|
514 | this.pseudos,
|
515 | this.attrEqualityMods,
|
516 | this.ruleNestingOperators,
|
517 | this.substitutesEnabled
|
518 | );
|
519 | return context.parse();
|
520 | };
|
521 |
|
522 | CssSelectorParser.prototype.escapeIdentifier = function(s) {
|
523 | var result = '';
|
524 | var i = 0;
|
525 | var len = s.length;
|
526 | while (i < len) {
|
527 | var chr = s.charAt(i);
|
528 | if (identSpecialChars[chr]) {
|
529 | result += '\\' + chr;
|
530 | } else {
|
531 | if (
|
532 | !(
|
533 | chr === '_' || chr === '-' ||
|
534 | (chr >= 'A' && chr <= 'Z') ||
|
535 | (chr >= 'a' && chr <= 'z') ||
|
536 | (i !== 0 && chr >= '0' && chr <= '9')
|
537 | )
|
538 | ) {
|
539 | var charCode = chr.charCodeAt(0);
|
540 | if ((charCode & 0xF800) === 0xD800) {
|
541 | var extraCharCode = s.charCodeAt(i++);
|
542 | if ((charCode & 0xFC00) !== 0xD800 || (extraCharCode & 0xFC00) !== 0xDC00) {
|
543 | throw Error('UCS-2(decode): illegal sequence');
|
544 | }
|
545 | charCode = ((charCode & 0x3FF) << 10) + (extraCharCode & 0x3FF) + 0x10000;
|
546 | }
|
547 | result += '\\' + charCode.toString(16) + ' ';
|
548 | } else {
|
549 | result += chr;
|
550 | }
|
551 | }
|
552 | i++;
|
553 | }
|
554 | return result;
|
555 | };
|
556 |
|
557 | CssSelectorParser.prototype.escapeStr = function(s) {
|
558 | var result = '';
|
559 | var i = 0;
|
560 | var len = s.length;
|
561 | var chr, replacement;
|
562 | while (i < len) {
|
563 | chr = s.charAt(i);
|
564 | if (chr === '"') {
|
565 | chr = '\\"';
|
566 | } else if (chr === '\\') {
|
567 | chr = '\\\\';
|
568 | } else if (replacement = strReplacementsRev[chr]) {
|
569 | chr = replacement;
|
570 | }
|
571 | result += chr;
|
572 | i++;
|
573 | }
|
574 | return "\"" + result + "\"";
|
575 | };
|
576 |
|
577 | CssSelectorParser.prototype.render = function(path) {
|
578 | return this._renderEntity(path).trim();
|
579 | };
|
580 |
|
581 | CssSelectorParser.prototype._renderEntity = function(entity) {
|
582 | var currentEntity, parts, res;
|
583 | res = '';
|
584 | switch (entity.type) {
|
585 | case 'ruleSet':
|
586 | currentEntity = entity.rule;
|
587 | parts = [];
|
588 | while (currentEntity) {
|
589 | if (currentEntity.nestingOperator) {
|
590 | parts.push(currentEntity.nestingOperator);
|
591 | }
|
592 | parts.push(this._renderEntity(currentEntity));
|
593 | currentEntity = currentEntity.rule;
|
594 | }
|
595 | res = parts.join(' ');
|
596 | break;
|
597 | case 'selectors':
|
598 | res = entity.selectors.map(this._renderEntity, this).join(', ');
|
599 | break;
|
600 | case 'rule':
|
601 | let s0 = entity.s1;
|
602 | let s1 = entity.s2;
|
603 |
|
604 | if (entity.tagName) {
|
605 | if (entity.tagName === '*') {
|
606 | res = '*';
|
607 | } else {
|
608 | res = this.escapeIdentifier(entity.tagName);
|
609 | }
|
610 | }
|
611 | if (entity.id) {
|
612 | res += "#" + this.escapeIdentifier(entity.id);
|
613 | }
|
614 | if (entity.classNames) {
|
615 | let shortest = null;
|
616 |
|
617 | res += entity.classNames.map(function(cn) {
|
618 | if(cn[0] == '!') {
|
619 | return ":not(." + this.escapeIdentifier(cn.slice(1)) + ")";
|
620 | } else {
|
621 | let str = this.escapeIdentifier(cn);
|
622 | if(s1 && (!shortest || shortest.length > str.length)){
|
623 | shortest = str;
|
624 | }
|
625 | return "." + str;
|
626 | }
|
627 | }, this).join('');
|
628 |
|
629 | if(s1 > 0 && shortest && shortest.length < 9){
|
630 | while(--s1 >= 0){
|
631 | res += "." + shortest;
|
632 | }
|
633 | }
|
634 | }
|
635 |
|
636 | if(entity.pri > 0 && false){
|
637 | let i = entity.pri;
|
638 |
|
639 |
|
640 |
|
641 | while (--i >= 0) res += ":not(#P)";
|
642 | }
|
643 | if(s0 > 0){
|
644 | if(false){
|
645 | res += ":not(";
|
646 | while (s0--) res += '#_';
|
647 | while (--s1 >= 0) res += '._';
|
648 | res += ')';
|
649 | } else {
|
650 | while (--s0 >= 0) res += ":not(#_)";
|
651 | }
|
652 |
|
653 | }
|
654 | if(s1 > 0){
|
655 | while (--s0 >= 0) res += ":not(._0)";
|
656 |
|
657 |
|
658 |
|
659 |
|
660 | }
|
661 | if (entity.attrs) {
|
662 | res += entity.attrs.map(function(attr) {
|
663 | if (attr.operator) {
|
664 | if (attr.valueType === 'substitute') {
|
665 | return "[" + this.escapeIdentifier(attr.name) + attr.operator + "$" + attr.value + "]";
|
666 | } else {
|
667 | return "[" + this.escapeIdentifier(attr.name) + attr.operator + this.escapeStr(attr.value) + "]";
|
668 | }
|
669 | } else {
|
670 | return "[" + this.escapeIdentifier(attr.name) + "]";
|
671 | }
|
672 | }, this).join('');
|
673 | }
|
674 | if (entity.pseudos) {
|
675 | res += entity.pseudos.map(function(pseudo) {
|
676 | let pre = ":" + this.escapeIdentifier(pseudo.name);
|
677 | let post = "";
|
678 |
|
679 | if(pseudo.neg){
|
680 | pre = ":not(" + pre;
|
681 | post = ")";
|
682 |
|
683 | }
|
684 |
|
685 | if (pseudo.valueType) {
|
686 | if (pseudo.valueType === 'selector') {
|
687 | return pre + "(" + this._renderEntity(pseudo.value) + ")" + post;
|
688 | } else if (pseudo.valueType === 'substitute') {
|
689 | return pre + "($" + pseudo.value + ")" + post;
|
690 | } else if (pseudo.valueType === 'numeric') {
|
691 | return pre + "(" + pseudo.value + ")" + post;
|
692 | } else if (pseudo.valueType === 'raw' || pseudo.valueType === 'string' ) {
|
693 | return pre + "(" + pseudo.value + ")" + post;
|
694 | } else {
|
695 | return pre + "(" + this.escapeIdentifier(pseudo.value) + ")" + post;
|
696 | }
|
697 | } else if(pseudo.type == 'el') {
|
698 | return ':' + pre;
|
699 | } else {
|
700 | return pre + post;
|
701 | }
|
702 | }, this).join('');
|
703 | }
|
704 | break;
|
705 | default:
|
706 | throw Error('Unknown entity type: "' + entity.type(+'".'));
|
707 | }
|
708 | return res;
|
709 | };
|
710 |
|
711 | var parser = new CssSelectorParser();
|
712 | parser.registerSelectorPseudos('has','not','is','matches','any')
|
713 | parser.registerNumericPseudos('nth-child')
|
714 | parser.registerNestingOperators('>>>','>>','>', '+', '~')
|
715 | parser.registerAttrEqualityMods('^', '$', '*', '~')
|
716 |
|
717 |
|
718 | export const parse = function(v){ return parser.parse(v) }
|
719 | export const render = function(v){ return parser.render(v) }
|
720 |
|
\ | No newline at end of file |