@@ -106,6 +106,7 @@ exports.EnumToken = void 0;
106
106
EnumToken[EnumToken["MediaFeatureAndTokenType"] = 89] = "MediaFeatureAndTokenType";
107
107
EnumToken[EnumToken["MediaFeatureOrTokenType"] = 90] = "MediaFeatureOrTokenType";
108
108
EnumToken[EnumToken["PseudoPageTokenType"] = 91] = "PseudoPageTokenType";
109
+ EnumToken[EnumToken["PseudoElementTokenType"] = 92] = "PseudoElementTokenType";
109
110
/* aliases */
110
111
EnumToken[EnumToken["Time"] = 25] = "Time";
111
112
EnumToken[EnumToken["Iden"] = 7] = "Iden";
@@ -3880,8 +3881,9 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
3880
3881
return '';
3881
3882
}
3882
3883
case exports.EnumToken.PseudoClassTokenType:
3884
+ case exports.EnumToken.PseudoElementTokenType:
3883
3885
// https://www.w3.org/TR/selectors-4/#single-colon-pseudos
3884
- if (token.typ == exports.EnumToken.PseudoClassTokenType && ['::before', '::after', '::first-line', '::first-letter'].includes(token.val)) {
3886
+ if (token.typ == exports.EnumToken.PseudoElementTokenType && ['::before', '::after', '::first-line', '::first-letter'].includes(token.val)) {
3885
3887
return token.val.slice(1);
3886
3888
}
3887
3889
case exports.EnumToken.UrlTokenTokenType:
@@ -12008,8 +12010,8 @@ function validateCompoundSelector(tokens, root, options) {
12008
12010
tokens.shift();
12009
12011
consumeWhitespace(tokens);
12010
12012
}
12011
- while (tokens.length > 0 && tokens[0].typ == exports.EnumToken.PseudoClassTokenType) {
12012
- const isPseudoElement = tokens[0].val.startsWith('::') ;
12013
+ while (tokens.length > 0 && ( tokens[0].typ == exports.EnumToken.PseudoElementTokenType || tokens[0].typ == exports.EnumToken. PseudoClassTokenType) ) {
12014
+ const isPseudoElement = tokens[0].typ == exports.EnumToken.PseudoElementTokenType ;
12013
12015
if (
12014
12016
// https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions#pseudo-elements
12015
12017
!(isPseudoElement && tokens[0].val.startsWith('::-webkit-')) &&
@@ -16318,11 +16320,11 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
16318
16320
const node = {
16319
16321
typ: exports.EnumToken.AtRuleNodeType,
16320
16322
nam: renderToken(atRule, { removeComments: true }),
16321
- tokens: t,
16323
+ // tokens: t,
16322
16324
val: raw.join('')
16323
16325
};
16324
16326
Object.defineProperties(node, {
16325
- tokens: { ...definedPropertySettings, enumerable: true , value: tokens.slice() },
16327
+ tokens: { ...definedPropertySettings, enumerable: false , value: tokens.slice() },
16326
16328
raw: { ...definedPropertySettings, value: raw }
16327
16329
});
16328
16330
if (delim.typ == exports.EnumToken.BlockStartTokenType) {
@@ -16447,7 +16449,7 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
16447
16449
};
16448
16450
Object.defineProperty(node, 'tokens', {
16449
16451
...definedPropertySettings,
16450
- enumerable: true ,
16452
+ enumerable: false ,
16451
16453
value: tokens.slice()
16452
16454
});
16453
16455
let raw = [...uniq.values()];
@@ -16920,10 +16922,16 @@ function getTokenType(val, hint) {
16920
16922
val: val.slice(0, -1),
16921
16923
chi: []
16922
16924
}
16923
- : {
16924
- typ: exports.EnumToken.PseudoClassTokenType,
16925
+ : (
16926
+ // https://www.w3.org/TR/selectors-4/#single-colon-pseudos
16927
+ val.startsWith('::') || [':before', ':after', ':first-line', ':first-letter'].includes(val) ? {
16928
+ typ: exports.EnumToken.PseudoElementTokenType,
16925
16929
val
16926
- };
16930
+ } :
16931
+ {
16932
+ typ: exports.EnumToken.PseudoClassTokenType,
16933
+ val
16934
+ });
16927
16935
}
16928
16936
if (isAtKeyword(val)) {
16929
16937
return {
@@ -17617,7 +17625,14 @@ function expandRule(node) {
17617
17625
rule.sel = splitRule(ast.sel).reduce((a, b) => a.concat([b.join('') + r]), []).join(',');
17618
17626
}
17619
17627
else {
17620
- selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(ast.sel) : arr.unshift(ast.sel, ' '));
17628
+ // selRule = splitRule(selRule.reduce((acc, curr) => acc + (acc.length > 0 ? ',' : '') + curr.join(''), ''));
17629
+ const arSelf = splitRule(ast.sel).filter(r => r.every(t => t != ':before' && t != ':after' && !t.startsWith('::'))).reduce((acc, curr) => acc.concat([curr.join('')]), []).join(',');
17630
+ if (arSelf.length == 0) {
17631
+ ast.chi.splice(i--, 1);
17632
+ continue;
17633
+ }
17634
+ //
17635
+ selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(arSelf) : arr.unshift(arSelf, ' '));
17621
17636
rule.sel = selRule.reduce((acc, curr) => {
17622
17637
acc.push(curr.join(''));
17623
17638
return acc;
@@ -17628,8 +17643,14 @@ function expandRule(node) {
17628
17643
let childSelectorCompound = [];
17629
17644
let withCompound = [];
17630
17645
let withoutCompound = [];
17631
- const rules = splitRule(ast.sel);
17646
+ // pseudo elements cannot be used with '&'
17647
+ // https://www.w3.org/TR/css-nesting-1/#example-7145ff1e
17648
+ const rules = splitRule(ast.sel).filter(r => r.every(t => t != ':before' && t != ':after' && !t.startsWith('::')));
17632
17649
const parentSelector = !node.sel.includes('&');
17650
+ if (rules.length == 0) {
17651
+ ast.chi.splice(i--, 1);
17652
+ continue;
17653
+ }
17633
17654
for (const sel of (rule.raw ?? splitRule(rule.sel))) {
17634
17655
const s = sel.join('');
17635
17656
if (s.includes('&') || parentSelector) {
@@ -19326,7 +19347,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
19326
19347
return s.join('');
19327
19348
}).join(',');
19328
19349
// @ts-ignore
19329
- let sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule;
19350
+ let sel = wrap ? node.optimized.optimized.join('') + `:is(${rule})` : rule;
19330
19351
if (rule.includes('&')) {
19331
19352
// @ts-ignore
19332
19353
rule = replaceCompound(rule, node.optimized.optimized[0]);
0 commit comments