tailwindcss 0.0.0-insiders.8259dfd → 0.0.0-insiders.8293c2d
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 +207 -2
- package/README.md +8 -4
- package/colors.js +2 -1
- package/defaultConfig.js +2 -1
- package/defaultTheme.js +2 -1
- package/lib/cli.js +94 -61
- package/lib/constants.js +1 -1
- package/lib/corePluginList.js +8 -1
- package/lib/corePlugins.js +477 -517
- package/lib/css/preflight.css +18 -5
- package/lib/featureFlags.js +5 -6
- package/lib/index.js +1 -3
- package/lib/lib/collapseDuplicateDeclarations.js +80 -0
- package/lib/lib/defaultExtractor.js +42 -0
- package/lib/lib/detectNesting.js +17 -2
- package/lib/lib/evaluateTailwindFunctions.js +10 -6
- package/lib/lib/expandApplyAtRules.js +94 -45
- package/lib/lib/expandTailwindAtRules.js +32 -33
- package/lib/lib/generateRules.js +167 -21
- package/lib/lib/normalizeTailwindDirectives.js +8 -1
- package/lib/lib/partitionApplyAtRules.js +53 -0
- package/lib/lib/resolveDefaultsAtRules.js +28 -14
- package/lib/lib/setupContextUtils.js +153 -129
- package/lib/lib/setupTrackingContext.js +11 -10
- package/lib/lib/sharedState.js +34 -5
- package/lib/lib/substituteScreenAtRules.js +7 -4
- package/lib/processTailwindFeatures.js +7 -2
- package/lib/util/buildMediaQuery.js +13 -24
- package/lib/util/color.js +23 -8
- package/lib/util/createPlugin.js +1 -2
- package/lib/util/createUtilityPlugin.js +6 -10
- package/lib/util/dataTypes.js +38 -7
- package/lib/util/defaults.js +6 -0
- package/lib/util/flattenColorPalette.js +1 -3
- package/lib/util/formatVariantSelector.js +186 -0
- package/lib/util/isValidArbitraryValue.js +64 -0
- package/lib/util/log.js +4 -0
- package/lib/util/nameClass.js +1 -0
- package/lib/util/normalizeConfig.js +63 -21
- package/lib/util/normalizeScreens.js +59 -0
- package/lib/util/parseBoxShadowValue.js +77 -0
- package/lib/util/pluginUtils.js +27 -158
- package/lib/util/prefixSelector.js +1 -3
- package/lib/util/resolveConfig.js +30 -31
- package/lib/util/resolveConfigPath.js +1 -2
- package/lib/util/toColorValue.js +1 -2
- package/lib/util/toPath.js +6 -1
- package/lib/util/transformThemeValue.js +19 -13
- package/nesting/plugin.js +4 -1
- package/package.json +19 -21
- package/peers/index.js +4621 -5626
- package/plugin.js +2 -1
- package/resolveConfig.js +2 -1
- package/src/cli.js +66 -14
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +406 -518
- package/src/css/preflight.css +18 -5
- package/src/featureFlags.js +1 -1
- package/src/index.js +1 -7
- package/src/lib/collapseDuplicateDeclarations.js +93 -0
- package/src/lib/defaultExtractor.js +48 -0
- package/src/lib/detectNesting.js +22 -3
- package/src/lib/evaluateTailwindFunctions.js +6 -3
- package/src/lib/expandApplyAtRules.js +101 -45
- package/src/lib/expandTailwindAtRules.js +33 -27
- package/src/lib/generateRules.js +178 -11
- package/src/lib/normalizeTailwindDirectives.js +6 -1
- package/src/lib/partitionApplyAtRules.js +52 -0
- package/src/lib/resolveDefaultsAtRules.js +31 -10
- package/src/lib/setupContextUtils.js +140 -84
- package/src/lib/setupTrackingContext.js +11 -10
- package/src/lib/sharedState.js +40 -4
- package/src/lib/substituteScreenAtRules.js +6 -3
- package/src/processTailwindFeatures.js +8 -2
- package/src/util/buildMediaQuery.js +14 -18
- package/src/util/color.js +20 -7
- package/src/util/dataTypes.js +43 -11
- package/src/util/defaults.js +6 -0
- package/src/util/formatVariantSelector.js +196 -0
- package/src/util/isValidArbitraryValue.js +61 -0
- package/src/util/log.js +4 -0
- package/src/util/nameClass.js +1 -1
- package/src/util/normalizeConfig.js +37 -2
- package/src/util/normalizeScreens.js +45 -0
- package/src/util/parseBoxShadowValue.js +71 -0
- package/src/util/pluginUtils.js +15 -138
- package/src/util/prefixSelector.js +1 -4
- package/src/util/resolveConfig.js +11 -1
- package/src/util/toPath.js +23 -1
- package/src/util/transformThemeValue.js +22 -7
- package/stubs/defaultConfig.stub.js +42 -16
- package/lib/lib/setupWatchingContext.js +0 -284
- package/src/lib/setupWatchingContext.js +0 -304
package/src/lib/generateRules.js
CHANGED
|
@@ -5,6 +5,10 @@ import isPlainObject from '../util/isPlainObject'
|
|
|
5
5
|
import prefixSelector from '../util/prefixSelector'
|
|
6
6
|
import { updateAllClasses } from '../util/pluginUtils'
|
|
7
7
|
import log from '../util/log'
|
|
8
|
+
import { formatVariantSelector, finalizeSelector } from '../util/formatVariantSelector'
|
|
9
|
+
import { asClass } from '../util/nameClass'
|
|
10
|
+
import { normalize } from '../util/dataTypes'
|
|
11
|
+
import isValidArbitraryValue from '../util/isValidArbitraryValue'
|
|
8
12
|
|
|
9
13
|
let classNameParser = selectorParser((selectors) => {
|
|
10
14
|
return selectors.first.filter(({ type }) => type === 'class').pop().value
|
|
@@ -108,11 +112,26 @@ function applyVariant(variant, matches, context) {
|
|
|
108
112
|
let result = []
|
|
109
113
|
|
|
110
114
|
for (let [meta, rule] of matches) {
|
|
115
|
+
// Don't generate variants for user css
|
|
116
|
+
if (meta.layer === 'user') {
|
|
117
|
+
continue
|
|
118
|
+
}
|
|
119
|
+
|
|
111
120
|
let container = postcss.root({ nodes: [rule.clone()] })
|
|
112
121
|
|
|
113
122
|
for (let [variantSort, variantFunction] of variantFunctionTuples) {
|
|
114
123
|
let clone = container.clone()
|
|
124
|
+
let collectedFormats = []
|
|
125
|
+
|
|
126
|
+
let originals = new Map()
|
|
127
|
+
|
|
128
|
+
function prepareBackup() {
|
|
129
|
+
if (originals.size > 0) return // Already prepared, chicken out
|
|
130
|
+
clone.walkRules((rule) => originals.set(rule, rule.selector))
|
|
131
|
+
}
|
|
132
|
+
|
|
115
133
|
function modifySelectors(modifierFunction) {
|
|
134
|
+
prepareBackup()
|
|
116
135
|
clone.each((rule) => {
|
|
117
136
|
if (rule.type !== 'rule') {
|
|
118
137
|
return
|
|
@@ -127,20 +146,84 @@ function applyVariant(variant, matches, context) {
|
|
|
127
146
|
})
|
|
128
147
|
})
|
|
129
148
|
})
|
|
149
|
+
|
|
130
150
|
return clone
|
|
131
151
|
}
|
|
132
152
|
|
|
133
153
|
let ruleWithVariant = variantFunction({
|
|
134
|
-
|
|
154
|
+
// Public API
|
|
155
|
+
get container() {
|
|
156
|
+
prepareBackup()
|
|
157
|
+
return clone
|
|
158
|
+
},
|
|
135
159
|
separator: context.tailwindConfig.separator,
|
|
136
160
|
modifySelectors,
|
|
161
|
+
|
|
162
|
+
// Private API for now
|
|
163
|
+
wrap(wrapper) {
|
|
164
|
+
let nodes = clone.nodes
|
|
165
|
+
clone.removeAll()
|
|
166
|
+
wrapper.append(nodes)
|
|
167
|
+
clone.append(wrapper)
|
|
168
|
+
},
|
|
169
|
+
format(selectorFormat) {
|
|
170
|
+
collectedFormats.push(selectorFormat)
|
|
171
|
+
},
|
|
137
172
|
})
|
|
138
173
|
|
|
174
|
+
if (typeof ruleWithVariant === 'string') {
|
|
175
|
+
collectedFormats.push(ruleWithVariant)
|
|
176
|
+
}
|
|
177
|
+
|
|
139
178
|
if (ruleWithVariant === null) {
|
|
140
179
|
continue
|
|
141
180
|
}
|
|
142
181
|
|
|
143
|
-
|
|
182
|
+
// We filled the `originals`, therefore we assume that somebody touched
|
|
183
|
+
// `container` or `modifySelectors`. Let's see if they did, so that we
|
|
184
|
+
// can restore the selectors, and collect the format strings.
|
|
185
|
+
if (originals.size > 0) {
|
|
186
|
+
clone.walkRules((rule) => {
|
|
187
|
+
if (!originals.has(rule)) return
|
|
188
|
+
let before = originals.get(rule)
|
|
189
|
+
if (before === rule.selector) return // No mutation happened
|
|
190
|
+
|
|
191
|
+
let modified = rule.selector
|
|
192
|
+
|
|
193
|
+
// Rebuild the base selector, this is what plugin authors would do
|
|
194
|
+
// as well. E.g.: `${variant}${separator}${className}`.
|
|
195
|
+
// However, plugin authors probably also prepend or append certain
|
|
196
|
+
// classes, pseudos, ids, ...
|
|
197
|
+
let rebuiltBase = selectorParser((selectors) => {
|
|
198
|
+
selectors.walkClasses((classNode) => {
|
|
199
|
+
classNode.value = `${variant}${context.tailwindConfig.separator}${classNode.value}`
|
|
200
|
+
})
|
|
201
|
+
}).processSync(before)
|
|
202
|
+
|
|
203
|
+
// Now that we know the original selector, the new selector, and
|
|
204
|
+
// the rebuild part in between, we can replace the part that plugin
|
|
205
|
+
// authors need to rebuild with `&`, and eventually store it in the
|
|
206
|
+
// collectedFormats. Similar to what `format('...')` would do.
|
|
207
|
+
//
|
|
208
|
+
// E.g.:
|
|
209
|
+
// variant: foo
|
|
210
|
+
// selector: .markdown > p
|
|
211
|
+
// modified (by plugin): .foo .foo\\:markdown > p
|
|
212
|
+
// rebuiltBase (internal): .foo\\:markdown > p
|
|
213
|
+
// format: .foo &
|
|
214
|
+
collectedFormats.push(modified.replace(rebuiltBase, '&'))
|
|
215
|
+
rule.selector = before
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
let withOffset = [
|
|
220
|
+
{
|
|
221
|
+
...meta,
|
|
222
|
+
sort: variantSort | meta.sort,
|
|
223
|
+
collectedFormats: (meta.collectedFormats ?? []).concat(collectedFormats),
|
|
224
|
+
},
|
|
225
|
+
clone.nodes[0],
|
|
226
|
+
]
|
|
144
227
|
result.push(withOffset)
|
|
145
228
|
}
|
|
146
229
|
}
|
|
@@ -170,15 +253,70 @@ function parseRules(rule, cache, options = {}) {
|
|
|
170
253
|
return [cache.get(rule), options]
|
|
171
254
|
}
|
|
172
255
|
|
|
256
|
+
const IS_VALID_PROPERTY_NAME = /^[a-z_-]/
|
|
257
|
+
|
|
258
|
+
function isValidPropName(name) {
|
|
259
|
+
return IS_VALID_PROPERTY_NAME.test(name)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function isParsableCssValue(property, value) {
|
|
263
|
+
try {
|
|
264
|
+
postcss.parse(`a{${property}:${value}}`).toResult()
|
|
265
|
+
return true
|
|
266
|
+
} catch (err) {
|
|
267
|
+
return false
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function extractArbitraryProperty(classCandidate, context) {
|
|
272
|
+
let [, property, value] = classCandidate.match(/^\[([a-zA-Z0-9-_]+):(\S+)\]$/) ?? []
|
|
273
|
+
|
|
274
|
+
if (value === undefined) {
|
|
275
|
+
return null
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (!isValidPropName(property)) {
|
|
279
|
+
return null
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (!isValidArbitraryValue(value)) {
|
|
283
|
+
return null
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
let normalized = normalize(value)
|
|
287
|
+
|
|
288
|
+
if (!isParsableCssValue(property, normalized)) {
|
|
289
|
+
return null
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return [
|
|
293
|
+
[
|
|
294
|
+
{ sort: context.arbitraryPropertiesSort, layer: 'utilities' },
|
|
295
|
+
() => ({
|
|
296
|
+
[asClass(classCandidate)]: {
|
|
297
|
+
[property]: normalized,
|
|
298
|
+
},
|
|
299
|
+
}),
|
|
300
|
+
],
|
|
301
|
+
]
|
|
302
|
+
}
|
|
303
|
+
|
|
173
304
|
function* resolveMatchedPlugins(classCandidate, context) {
|
|
174
305
|
if (context.candidateRuleMap.has(classCandidate)) {
|
|
175
306
|
yield [context.candidateRuleMap.get(classCandidate), 'DEFAULT']
|
|
176
307
|
}
|
|
177
308
|
|
|
309
|
+
yield* (function* (arbitraryPropertyRule) {
|
|
310
|
+
if (arbitraryPropertyRule !== null) {
|
|
311
|
+
yield [arbitraryPropertyRule, 'DEFAULT']
|
|
312
|
+
}
|
|
313
|
+
})(extractArbitraryProperty(classCandidate, context))
|
|
314
|
+
|
|
178
315
|
let candidatePrefix = classCandidate
|
|
179
316
|
let negative = false
|
|
180
317
|
|
|
181
|
-
const twConfigPrefix = context.tailwindConfig.prefix
|
|
318
|
+
const twConfigPrefix = context.tailwindConfig.prefix
|
|
319
|
+
|
|
182
320
|
const twConfigPrefixLen = twConfigPrefix.length
|
|
183
321
|
if (candidatePrefix[twConfigPrefixLen] === '-') {
|
|
184
322
|
negative = true
|
|
@@ -192,7 +330,6 @@ function* resolveMatchedPlugins(classCandidate, context) {
|
|
|
192
330
|
for (let [prefix, modifier] of candidatePermutations(candidatePrefix)) {
|
|
193
331
|
if (context.candidateRuleMap.has(prefix)) {
|
|
194
332
|
yield [context.candidateRuleMap.get(prefix), negative ? `-${modifier}` : modifier]
|
|
195
|
-
return
|
|
196
333
|
}
|
|
197
334
|
}
|
|
198
335
|
}
|
|
@@ -323,6 +460,22 @@ function* resolveMatches(candidate, context) {
|
|
|
323
460
|
}
|
|
324
461
|
|
|
325
462
|
for (let match of matches) {
|
|
463
|
+
// Apply final format selector
|
|
464
|
+
if (match[0].collectedFormats) {
|
|
465
|
+
let finalFormat = formatVariantSelector('&', ...match[0].collectedFormats)
|
|
466
|
+
let container = postcss.root({ nodes: [match[1].clone()] })
|
|
467
|
+
container.walkRules((rule) => {
|
|
468
|
+
if (inKeyframes(rule)) return
|
|
469
|
+
|
|
470
|
+
rule.selector = finalizeSelector(finalFormat, {
|
|
471
|
+
selector: rule.selector,
|
|
472
|
+
candidate,
|
|
473
|
+
context,
|
|
474
|
+
})
|
|
475
|
+
})
|
|
476
|
+
match[1] = container.nodes[0]
|
|
477
|
+
}
|
|
478
|
+
|
|
326
479
|
yield match
|
|
327
480
|
}
|
|
328
481
|
}
|
|
@@ -356,28 +509,42 @@ function generateRules(candidates, context) {
|
|
|
356
509
|
allRules.push(matches)
|
|
357
510
|
}
|
|
358
511
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
512
|
+
// Strategy based on `tailwindConfig.important`
|
|
513
|
+
let strategy = ((important) => {
|
|
514
|
+
if (important === true) {
|
|
515
|
+
return (rule) => {
|
|
362
516
|
rule.walkDecls((d) => {
|
|
363
517
|
if (d.parent.type === 'rule' && !inKeyframes(d.parent)) {
|
|
364
518
|
d.important = true
|
|
365
519
|
}
|
|
366
520
|
})
|
|
367
|
-
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (typeof important === 'string') {
|
|
525
|
+
return (rule) => {
|
|
526
|
+
rule.selectors = rule.selectors.map((selector) => {
|
|
527
|
+
return `${important} ${selector}`
|
|
528
|
+
})
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
})(context.tailwindConfig.important)
|
|
532
|
+
|
|
533
|
+
return allRules.flat(1).map(([{ sort, layer, options }, rule]) => {
|
|
534
|
+
if (options.respectImportant) {
|
|
535
|
+
if (strategy) {
|
|
368
536
|
let container = postcss.root({ nodes: [rule.clone()] })
|
|
369
537
|
container.walkRules((r) => {
|
|
370
538
|
if (inKeyframes(r)) {
|
|
371
539
|
return
|
|
372
540
|
}
|
|
373
541
|
|
|
374
|
-
r
|
|
375
|
-
return `${context.tailwindConfig.important} ${selector}`
|
|
376
|
-
})
|
|
542
|
+
strategy(r)
|
|
377
543
|
})
|
|
378
544
|
rule = container.nodes[0]
|
|
379
545
|
}
|
|
380
546
|
}
|
|
547
|
+
|
|
381
548
|
return [sort | context.layerOrder[layer], rule]
|
|
382
549
|
})
|
|
383
550
|
}
|
|
@@ -3,8 +3,13 @@ import log from '../util/log'
|
|
|
3
3
|
export default function normalizeTailwindDirectives(root) {
|
|
4
4
|
let tailwindDirectives = new Set()
|
|
5
5
|
let layerDirectives = new Set()
|
|
6
|
+
let applyDirectives = new Set()
|
|
6
7
|
|
|
7
8
|
root.walkAtRules((atRule) => {
|
|
9
|
+
if (atRule.name === 'apply') {
|
|
10
|
+
applyDirectives.add(atRule)
|
|
11
|
+
}
|
|
12
|
+
|
|
8
13
|
if (atRule.name === 'import') {
|
|
9
14
|
if (atRule.params === '"tailwindcss/base"' || atRule.params === "'tailwindcss/base'") {
|
|
10
15
|
atRule.name = 'tailwind'
|
|
@@ -74,5 +79,5 @@ export default function normalizeTailwindDirectives(root) {
|
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
return tailwindDirectives
|
|
82
|
+
return { tailwindDirectives, applyDirectives }
|
|
78
83
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
function partitionRules(root) {
|
|
2
|
+
if (!root.walkAtRules) return
|
|
3
|
+
|
|
4
|
+
let applyParents = new Set()
|
|
5
|
+
|
|
6
|
+
root.walkAtRules('apply', (rule) => {
|
|
7
|
+
applyParents.add(rule.parent)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
if (applyParents.size === 0) {
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
for (let rule of applyParents) {
|
|
15
|
+
let nodeGroups = []
|
|
16
|
+
let lastGroup = []
|
|
17
|
+
|
|
18
|
+
for (let node of rule.nodes) {
|
|
19
|
+
if (node.type === 'atrule' && node.name === 'apply') {
|
|
20
|
+
if (lastGroup.length > 0) {
|
|
21
|
+
nodeGroups.push(lastGroup)
|
|
22
|
+
lastGroup = []
|
|
23
|
+
}
|
|
24
|
+
nodeGroups.push([node])
|
|
25
|
+
} else {
|
|
26
|
+
lastGroup.push(node)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (lastGroup.length > 0) {
|
|
31
|
+
nodeGroups.push(lastGroup)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (nodeGroups.length === 1) {
|
|
35
|
+
continue
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
for (let group of [...nodeGroups].reverse()) {
|
|
39
|
+
let clone = rule.clone({ nodes: [] })
|
|
40
|
+
clone.append(group)
|
|
41
|
+
rule.after(clone)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
rule.remove()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default function expandApplyAtRules() {
|
|
49
|
+
return (root) => {
|
|
50
|
+
partitionRules(root)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -71,6 +71,8 @@ function extractElementSelector(selector) {
|
|
|
71
71
|
export default function resolveDefaultsAtRules({ tailwindConfig }) {
|
|
72
72
|
return (root) => {
|
|
73
73
|
let variableNodeMap = new Map()
|
|
74
|
+
|
|
75
|
+
/** @type {Set<import('postcss').AtRule>} */
|
|
74
76
|
let universals = new Set()
|
|
75
77
|
|
|
76
78
|
root.walkAtRules('defaults', (rule) => {
|
|
@@ -90,31 +92,50 @@ export default function resolveDefaultsAtRules({ tailwindConfig }) {
|
|
|
90
92
|
})
|
|
91
93
|
|
|
92
94
|
for (let universal of universals) {
|
|
93
|
-
|
|
95
|
+
/** @type {Map<string, Set<string>>} */
|
|
96
|
+
let selectorGroups = new Map()
|
|
94
97
|
|
|
95
98
|
let rules = variableNodeMap.get(universal.params) ?? []
|
|
96
99
|
|
|
97
100
|
for (let rule of rules) {
|
|
98
101
|
for (let selector of extractElementSelector(rule.selector)) {
|
|
102
|
+
// If selector contains a vendor prefix after a pseudo element or class,
|
|
103
|
+
// we consider them separately because merging the declarations into
|
|
104
|
+
// a single rule will cause browsers that do not understand the
|
|
105
|
+
// vendor prefix to throw out the whole rule
|
|
106
|
+
let selectorGroupName =
|
|
107
|
+
selector.includes(':-') || selector.includes('::-') ? selector : '__DEFAULT__'
|
|
108
|
+
|
|
109
|
+
let selectors = selectorGroups.get(selectorGroupName) ?? new Set()
|
|
110
|
+
selectorGroups.set(selectorGroupName, selectors)
|
|
111
|
+
|
|
99
112
|
selectors.add(selector)
|
|
100
113
|
}
|
|
101
114
|
}
|
|
102
115
|
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
if (flagEnabled(tailwindConfig, 'optimizeUniversalDefaults')) {
|
|
117
|
+
if (selectorGroups.size === 0) {
|
|
118
|
+
universal.remove()
|
|
119
|
+
continue
|
|
120
|
+
}
|
|
107
121
|
|
|
108
|
-
|
|
122
|
+
for (let [, selectors] of selectorGroups) {
|
|
123
|
+
let universalRule = postcss.rule()
|
|
109
124
|
|
|
110
|
-
|
|
111
|
-
|
|
125
|
+
universalRule.selectors = [...selectors]
|
|
126
|
+
|
|
127
|
+
universalRule.append(universal.nodes.map((node) => node.clone()))
|
|
128
|
+
universal.before(universalRule)
|
|
129
|
+
}
|
|
112
130
|
} else {
|
|
131
|
+
let universalRule = postcss.rule()
|
|
132
|
+
|
|
113
133
|
universalRule.selectors = ['*', '::before', '::after']
|
|
134
|
+
|
|
135
|
+
universalRule.append(universal.nodes)
|
|
136
|
+
universal.before(universalRule)
|
|
114
137
|
}
|
|
115
138
|
|
|
116
|
-
universalRule.append(universal.nodes)
|
|
117
|
-
universal.before(universalRule)
|
|
118
139
|
universal.remove()
|
|
119
140
|
}
|
|
120
141
|
}
|