postcss-merge-rules 8.0.1 → 8.0.3

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/LICENSE-MIT CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) Ben Briggs <beneb.info@gmail.com> (http://beneb.info)
1
+ Copyright (c) Ben Briggs <beneb.info@gmail.com> (https://beneb.info)
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
package/README.md CHANGED
@@ -100,6 +100,6 @@ See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTOR
100
100
 
101
101
  ## License
102
102
 
103
- MIT © [Ben Briggs](http://beneb.info)
103
+ MIT © [Ben Briggs](https://beneb.info)
104
104
 
105
105
  [postcss]: https://github.com/postcss/postcss
package/package.json CHANGED
@@ -1,9 +1,25 @@
1
1
  {
2
2
  "name": "postcss-merge-rules",
3
- "version": "8.0.1",
3
+ "version": "8.0.3",
4
4
  "description": "Merge CSS rules with PostCSS.",
5
- "types": "types/index.d.ts",
6
- "main": "src/index.js",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./types/index.d.ts",
8
+ "default": "./src/index.js"
9
+ },
10
+ "./src": "./src/index.js",
11
+ "./src/index": "./src/index.js",
12
+ "./src/index.js": "./src/index.js",
13
+ "./src/lib/ensureCompatibility.js": "./src/lib/ensureCompatibility.js",
14
+ "./src/lib/ensureCompatibility": "./src/lib/ensureCompatibility.js",
15
+ "./package.json": "./package.json"
16
+ },
17
+ "imports": {
18
+ "#getBrowsersList": {
19
+ "node": "./src/lib/computeBrowsersToSupport.js",
20
+ "default": "./src/lib/getBrowsersForWebBuild.js"
21
+ }
22
+ },
7
23
  "files": [
8
24
  "LICENSE-MIT",
9
25
  "src",
@@ -20,14 +36,17 @@
20
36
  "author": {
21
37
  "name": "Ben Briggs",
22
38
  "email": "beneb.info@gmail.com",
23
- "url": "http://beneb.info"
39
+ "url": "https://beneb.info"
40
+ },
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "cssnano/cssnano"
24
44
  },
25
- "repository": "cssnano/cssnano",
26
45
  "dependencies": {
27
- "browserslist": "^4.28.2",
46
+ "browserslist": "^4.28.8",
28
47
  "caniuse-api": "^4.0.0",
29
- "postcss-selector-parser": "^7.1.2",
30
- "cssnano-utils": "^6.0.1"
48
+ "postcss-selector-parser": "^7.1.5",
49
+ "cssnano-utils": "^6.0.3"
31
50
  },
32
51
  "bugs": {
33
52
  "url": "https://github.com/cssnano/cssnano/issues"
@@ -36,11 +55,14 @@
36
55
  "node": "^22.11.0 || ^24.11.0 || >=26.0"
37
56
  },
38
57
  "devDependencies": {
39
- "postcss": "^8.5.15",
58
+ "postcss": "^8.5.26",
40
59
  "postcss-simple-vars": "^7.0.1",
41
- "postcss-discard-comments": "^8.0.1"
60
+ "postcss-discard-comments": "^8.0.3"
42
61
  },
43
62
  "peerDependencies": {
44
- "postcss": "^8.5.15"
63
+ "postcss": "^8.5.26"
64
+ },
65
+ "scripts": {
66
+ "test": "node --test"
45
67
  }
46
68
  }
package/src/index.js CHANGED
@@ -1,16 +1,19 @@
1
1
  'use strict';
2
- const { dirname } = require('path');
3
- const browserslist = require('browserslist');
2
+
3
+ const getBrowsersList = require('#getBrowsersList');
4
+
5
+ /** @import browserslist from 'browserslist' */
6
+
4
7
  const { sameParent } = require('cssnano-utils');
5
8
  const {
6
9
  ensureCompatibility,
7
10
  sameVendor,
8
11
  noVendor,
9
12
  } = require('./lib/ensureCompatibility');
10
-
13
+ /** @import {Declaration, Rule} from 'postcss' */
11
14
  /**
12
- * @param {import('postcss').Declaration} a
13
- * @param {import('postcss').Declaration} b
15
+ * @param {Declaration} a
16
+ * @param {Declaration} b
14
17
  * @return {boolean}
15
18
  */
16
19
  function declarationIsEqual(a, b) {
@@ -20,8 +23,8 @@ function declarationIsEqual(a, b) {
20
23
  }
21
24
 
22
25
  /**
23
- * @param {import('postcss').Declaration[]} array
24
- * @param {import('postcss').Declaration} decl
26
+ * @param {Declaration[]} array
27
+ * @param {Declaration} decl
25
28
  * @return {number}
26
29
  */
27
30
  function indexOfDeclaration(array, decl) {
@@ -30,10 +33,10 @@ function indexOfDeclaration(array, decl) {
30
33
 
31
34
  /**
32
35
  * Returns filtered array of matched or unmatched declarations
33
- * @param {import('postcss').Declaration[]} a
34
- * @param {import('postcss').Declaration[]} b
36
+ * @param {Declaration[]} a
37
+ * @param {Declaration[]} b
35
38
  * @param {boolean} [not=false]
36
- * @return {import('postcss').Declaration[]}
39
+ * @return {Declaration[]}
37
40
  */
38
41
  function intersect(a, b, not) {
39
42
  return a.filter((c) => {
@@ -43,8 +46,8 @@ function intersect(a, b, not) {
43
46
  }
44
47
 
45
48
  /**
46
- * @param {import('postcss').Declaration[]} a
47
- * @param {import('postcss').Declaration[]} b
49
+ * @param {Declaration[]} a
50
+ * @param {Declaration[]} b
48
51
  * @return {boolean}
49
52
  */
50
53
  function sameDeclarationsAndOrder(a, b) {
@@ -60,17 +63,17 @@ function sameDeclarationsAndOrder(a, b) {
60
63
  *
61
64
  * @typedef {Object} RuleMeta
62
65
  * @property {string[]} selectors - Array of selector strings for the rule
63
- * @property {import('postcss').Declaration[]} declarations - Array of declaration nodes for the rule
66
+ * @property {Declaration[]} declarations - Array of declaration nodes for the rule
64
67
  * @property {boolean} dirty - Whether the selectors have been modified and need flushing
65
68
  */
66
69
 
67
70
  /**
68
- * @param {import('postcss').Rule} ruleA
69
- * @param {import('postcss').Rule} ruleB
71
+ * @param {Rule} ruleA
72
+ * @param {Rule} ruleB
70
73
  * @param {string[]} browsers
71
74
  * @param {Map<string, boolean>} compatibilityCache
72
- * @param {WeakSet<import('postcss').Rule>} ruleCache
73
- * @param {WeakMap<import('postcss').Rule, RuleMeta>} ruleMeta
75
+ * @param {WeakSet<Rule>} ruleCache
76
+ * @param {WeakMap<Rule, RuleMeta>} ruleMeta
74
77
  * @return {boolean}
75
78
  */
76
79
  function canMerge(
@@ -131,7 +134,7 @@ function isRuleOrAtRule(node) {
131
134
  }
132
135
  /**
133
136
  * @param {import('postcss').ChildNode} node
134
- * @return {node is import('postcss').Declaration}
137
+ * @return {node is Declaration}
135
138
  */
136
139
  function isDeclaration(node) {
137
140
  return node.type === 'decl';
@@ -143,8 +146,8 @@ function isDeclaration(node) {
143
146
  * This metadata caches selectors and declarations to avoid expensive AST
144
147
  * re-parsing, especially for the selectors.
145
148
  *
146
- * @param {import('postcss').Rule} rule The PostCSS rule to get metadata for.
147
- * @param {WeakMap<import('postcss').Rule, RuleMeta>} [ruleMeta] The metadata cache.
149
+ * @param {Rule} rule The PostCSS rule to get metadata for.
150
+ * @param {WeakMap<Rule, RuleMeta>} [ruleMeta] The metadata cache.
148
151
  * @return {RuleMeta} The rule's virtual metadata.
149
152
  */
150
153
  function getMeta(rule, ruleMeta) {
@@ -170,8 +173,8 @@ function getMeta(rule, ruleMeta) {
170
173
  /**
171
174
  * Commits virtual metadata changes back to the actual PostCSS rule.
172
175
  *
173
- * @param {import('postcss').Rule} rule The PostCSS rule to flush.
174
- * @param {WeakMap<import('postcss').Rule, RuleMeta>} ruleMeta The metadata cache.
176
+ * @param {Rule} rule The PostCSS rule to flush.
177
+ * @param {WeakMap<Rule, RuleMeta>} ruleMeta The metadata cache.
175
178
  */
176
179
  function flush(rule, ruleMeta) {
177
180
  const meta = ruleMeta.get(rule);
@@ -182,15 +185,15 @@ function flush(rule, ruleMeta) {
182
185
  }
183
186
 
184
187
  /**
185
- * @param {import('postcss').Rule} rule
186
- * @return {import('postcss').Declaration[]}
188
+ * @param {Rule} rule
189
+ * @return {Declaration[]}
187
190
  */
188
191
  function getDecls(rule) {
189
192
  return rule.nodes.filter(isDeclaration);
190
193
  }
191
194
 
192
195
  /**
193
- * @param {...import('postcss').Rule} rules
196
+ * @param {...Rule} rules
194
197
  * @return {number}
195
198
  */
196
199
  function ruleLength(...rules) {
@@ -275,8 +278,8 @@ function isConflictingProp(propA, propB) {
275
278
  }
276
279
 
277
280
  /**
278
- * @param {import('postcss').Rule} first
279
- * @param {import('postcss').Rule} second
281
+ * @param {Rule} first
282
+ * @param {Rule} second
280
283
  * @return {boolean} merged
281
284
  */
282
285
  function mergeParents(first, second) {
@@ -298,31 +301,10 @@ function mergeParents(first, second) {
298
301
  }
299
302
 
300
303
  /**
301
- * @param {import('postcss').Rule} first
302
- * @param {import('postcss').Rule} second
303
- * @param {string[]} browsers
304
- * @param {Map<string, boolean>} compatibilityCache
305
- * @param {WeakSet<import('postcss').Rule>} ruleCache
306
- * @param {WeakMap<import('postcss').Rule, RuleMeta>} ruleMeta
307
- * @return {import('postcss').Rule} mergedRule
304
+ * @param {Rule} second
305
+ * @return {Rule | null}
308
306
  */
309
- function partialMerge(
310
- first,
311
- second,
312
- browsers,
313
- compatibilityCache,
314
- ruleCache,
315
- ruleMeta
316
- ) {
317
- if (ruleMeta) {
318
- flush(first, ruleMeta);
319
- }
320
- const metaFirst = getMeta(first, ruleMeta);
321
- const metaSecond = getMeta(second, ruleMeta);
322
- let intersection = intersect(metaFirst.declarations, metaSecond.declarations);
323
- if (intersection.length === 0) {
324
- return second;
325
- }
307
+ function getNextRule(second) {
326
308
  let nextRule = second.next();
327
309
  if (!nextRule) {
328
310
  // Grab next cousin
@@ -333,9 +315,32 @@ function partialMerge(
333
315
  ).next();
334
316
  nextRule = parentSibling && parentSibling.nodes && parentSibling.nodes[0];
335
317
  }
318
+ return nextRule?.type === 'rule' ? nextRule : null;
319
+ }
320
+
321
+ /**
322
+ * @param {Rule} first
323
+ * @param {Rule} second
324
+ * @param {Declaration[]} intersection
325
+ * @param {string[]} browsers
326
+ * @param {Map<string, boolean>} compatibilityCache
327
+ * @param {WeakSet<Rule>} ruleCache
328
+ * @param {WeakMap<Rule, RuleMeta>} ruleMeta
329
+ * @return {{first: Rule, second: Rule, intersection: Declaration[]}}
330
+ */
331
+ function mergeWithNextRule(
332
+ first,
333
+ second,
334
+ intersection,
335
+ browsers,
336
+ compatibilityCache,
337
+ ruleCache,
338
+ ruleMeta
339
+ ) {
340
+ const nextRule = getNextRule(second);
336
341
  if (
337
- nextRule?.type === 'rule' &&
338
- canMerge(
342
+ !nextRule ||
343
+ !canMerge(
339
344
  second,
340
345
  nextRule,
341
346
  browsers,
@@ -344,24 +349,28 @@ function partialMerge(
344
349
  ruleMeta
345
350
  )
346
351
  ) {
347
- const metaNext = getMeta(nextRule, ruleMeta);
348
- let nextIntersection = intersect(
349
- metaSecond.declarations,
350
- metaNext.declarations
351
- );
352
- if (nextIntersection.length > intersection.length) {
353
- mergeParents(second, nextRule);
354
- first = second;
355
- second = nextRule;
356
- intersection = nextIntersection;
357
- }
352
+ return { first, second, intersection };
358
353
  }
359
354
 
360
- const metaFirstActual = getMeta(first, ruleMeta);
361
- const metaSecondActual = getMeta(second, ruleMeta);
362
- let firstDecls = [...metaFirstActual.declarations];
363
- let secondDecls = [...metaSecondActual.declarations];
355
+ const nextIntersection = intersect(
356
+ getMeta(second, ruleMeta).declarations,
357
+ getMeta(nextRule, ruleMeta).declarations
358
+ );
359
+ if (nextIntersection.length <= intersection.length) {
360
+ return { first, second, intersection };
361
+ }
362
+
363
+ mergeParents(second, nextRule);
364
+ return { first: second, second: nextRule, intersection: nextIntersection };
365
+ }
364
366
 
367
+ /**
368
+ * @param {Declaration[]} intersection
369
+ * @param {Declaration[]} firstDecls
370
+ * @param {Declaration[]} secondDecls
371
+ * @return {Declaration[]}
372
+ */
373
+ function filterIntersections(intersection, firstDecls, secondDecls) {
365
374
  // Filter out intersections with later conflicts in First
366
375
  intersection = intersection.filter((decl, intersectIndex) => {
367
376
  const indexOfDecl = indexOfDeclaration(firstDecls, decl);
@@ -383,7 +392,7 @@ function partialMerge(
383
392
  });
384
393
 
385
394
  // Filter out intersections with previous conflicts in Second
386
- intersection = intersection.filter((decl) => {
395
+ return intersection.filter((decl) => {
387
396
  const nextConflictIndex = secondDecls.findIndex((d) =>
388
397
  isConflictingProp(d.prop, decl.prop)
389
398
  );
@@ -405,15 +414,20 @@ function partialMerge(
405
414
  secondDecls.splice(nextConflictIndex, 1);
406
415
  return true;
407
416
  });
417
+ }
408
418
 
409
- if (intersection.length === 0) {
410
- // Nothing to merge
411
- return second;
412
- }
413
-
419
+ /**
420
+ * @param {Rule} first
421
+ * @param {Rule} second
422
+ * @param {Declaration[]} intersection
423
+ * @param {WeakSet<Rule>} ruleCache
424
+ * @param {WeakMap<Rule, RuleMeta>} ruleMeta
425
+ * @return {Rule}
426
+ */
427
+ function buildMergedRule(first, second, intersection, ruleCache, ruleMeta) {
414
428
  const receivingBlock = second.clone();
415
- const firstSelectors = metaFirstActual.selectors;
416
- const secondSelectors = metaSecondActual.selectors;
429
+ const firstSelectors = getMeta(first, ruleMeta).selectors;
430
+ const secondSelectors = getMeta(second, ruleMeta).selectors;
417
431
 
418
432
  receivingBlock.selector = [...firstSelectors, ...secondSelectors].join();
419
433
  receivingBlock.nodes = [];
@@ -426,9 +440,9 @@ function partialMerge(
426
440
  const secondClone = second.clone({ selectors: secondSelectors });
427
441
 
428
442
  /**
429
- * @param {function(import('postcss').Declaration):void} callback
443
+ * @param {(decl: Declaration) => void} callback
430
444
  * @this void
431
- * @return {function(import('postcss').Declaration)}
445
+ * @return {(decl: Declaration) => void}
432
446
  */
433
447
  function moveDecl(callback) {
434
448
  return (decl) => {
@@ -438,10 +452,15 @@ function partialMerge(
438
452
  };
439
453
  }
440
454
  firstClone.walkDecls(
441
- moveDecl((decl) => {
442
- decl.remove();
443
- receivingBlock.append(decl);
444
- })
455
+ moveDecl(
456
+ /**
457
+ * @param {Declaration} decl
458
+ */
459
+ (decl) => {
460
+ decl.remove();
461
+ receivingBlock.append(decl);
462
+ }
463
+ )
445
464
  );
446
465
  secondClone.walkDecls(moveDecl((decl) => decl.remove()));
447
466
 
@@ -456,11 +475,11 @@ function partialMerge(
456
475
  if (merged < original) {
457
476
  first.replaceWith(firstClone);
458
477
  second.replaceWith(secondClone);
459
- [firstClone, receivingBlock, secondClone].forEach((r) => {
478
+ for (const r of [firstClone, receivingBlock, secondClone]) {
460
479
  if (r.nodes.length === 0) {
461
480
  r.remove();
462
481
  }
463
- });
482
+ }
464
483
  if (!secondClone.parent) {
465
484
  ruleCache?.add(receivingBlock);
466
485
  return receivingBlock;
@@ -470,21 +489,75 @@ function partialMerge(
470
489
  ruleMeta?.delete(first);
471
490
  ruleMeta?.delete(second);
472
491
  return secondClone;
473
- } else {
474
- receivingBlock.remove();
492
+ }
493
+
494
+ receivingBlock.remove();
495
+ return second;
496
+ }
497
+
498
+ /**
499
+ * @param {Rule} first
500
+ * @param {Rule} second
501
+ * @param {string[]} browsers
502
+ * @param {Map<string, boolean>} compatibilityCache
503
+ * @param {WeakSet<Rule>} ruleCache
504
+ * @param {WeakMap<Rule, RuleMeta>} ruleMeta
505
+ * @return {Rule} mergedRule
506
+ */
507
+ function partialMerge(
508
+ first,
509
+ second,
510
+ browsers,
511
+ compatibilityCache,
512
+ ruleCache,
513
+ ruleMeta
514
+ ) {
515
+ if (ruleMeta) {
516
+ flush(first, ruleMeta);
517
+ }
518
+ const metaFirst = getMeta(first, ruleMeta);
519
+ const metaSecond = getMeta(second, ruleMeta);
520
+ let intersection = intersect(metaFirst.declarations, metaSecond.declarations);
521
+ if (intersection.length === 0) {
475
522
  return second;
476
523
  }
524
+ const mergedNext = mergeWithNextRule(
525
+ first,
526
+ second,
527
+ intersection,
528
+ browsers,
529
+ compatibilityCache,
530
+ ruleCache,
531
+ ruleMeta
532
+ );
533
+ first = mergedNext.first;
534
+ second = mergedNext.second;
535
+ intersection = mergedNext.intersection;
536
+
537
+ const metaFirstActual = getMeta(first, ruleMeta);
538
+ const metaSecondActual = getMeta(second, ruleMeta);
539
+ const firstDecls = [...metaFirstActual.declarations];
540
+ const secondDecls = [...metaSecondActual.declarations];
541
+
542
+ intersection = filterIntersections(intersection, firstDecls, secondDecls);
543
+
544
+ if (intersection.length === 0) {
545
+ // Nothing to merge
546
+ return second;
547
+ }
548
+
549
+ return buildMergedRule(first, second, intersection, ruleCache, ruleMeta);
477
550
  }
478
551
 
479
552
  /**
480
553
  * @param {string[]} browsers
481
554
  * @param {Map<string, boolean>} compatibilityCache
482
- * @param {WeakSet<import('postcss').Rule>} ruleCache
483
- * @param {WeakMap<import('postcss').Rule, RuleMeta>} ruleMeta
484
- * @return {{ merger: function(import('postcss').Rule): void, clean: function(): void }}
555
+ * @param {WeakSet<Rule>} ruleCache
556
+ * @param {WeakMap<Rule, RuleMeta>} ruleMeta
557
+ * @return {{ merger: (rule: Rule) => void, clean: () => void }}
485
558
  */
486
559
  function selectorMerger(browsers, compatibilityCache, ruleCache, ruleMeta) {
487
- /** @type {import('postcss').Rule | null} */
560
+ /** @type {Rule | null} */
488
561
  let cache = null;
489
562
  return {
490
563
  merger(rule) {
@@ -550,7 +623,7 @@ function selectorMerger(browsers, compatibilityCache, ruleCache, ruleMeta) {
550
623
  node.remove();
551
624
  return;
552
625
  }
553
- /** @type {import('postcss').Rule} */ (cache).append(node);
626
+ /** @type {Rule} */ (cache).append(node);
554
627
  });
555
628
  getMeta(cache, ruleMeta).declarations = getDecls(cache);
556
629
  rule.remove();
@@ -584,7 +657,6 @@ function selectorMerger(browsers, compatibilityCache, ruleCache, ruleMeta) {
584
657
  */
585
658
 
586
659
  /**
587
- * @type {import('postcss').PluginCreator<Options>}
588
660
  * @param {Options} opts
589
661
  * @return {import('postcss').Plugin}
590
662
  */
@@ -597,11 +669,7 @@ function pluginCreator(opts = {}) {
597
669
  */
598
670
  prepare(result) {
599
671
  const { stats, env, from, file } = result.opts || {};
600
- const browsers = browserslist(opts.overrideBrowserslist, {
601
- stats: opts.stats || stats,
602
- path: opts.path || dirname(from || file || __filename),
603
- env: opts.env || env,
604
- });
672
+ const browsers = getBrowsersList(opts, stats, from, file, env);
605
673
 
606
674
  const compatibilityCache = new Map();
607
675
 
@@ -610,6 +678,9 @@ function pluginCreator(opts = {}) {
610
678
  const ruleMeta = new WeakMap();
611
679
 
612
680
  return {
681
+ /**
682
+ * @param {import('postcss').Root} css
683
+ */
613
684
  OnceExit(css) {
614
685
  const { merger, clean } = selectorMerger(
615
686
  browsers,
@@ -626,4 +697,6 @@ function pluginCreator(opts = {}) {
626
697
  }
627
698
 
628
699
  pluginCreator.postcss = true;
629
- module.exports = pluginCreator;
700
+ module.exports = /** @type {import('postcss').PluginCreator<Options>} */ (
701
+ pluginCreator
702
+ );
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ const browserslist = require('browserslist');
4
+ const { dirname } = require('node:path');
5
+
6
+ /**
7
+ *
8
+ * @param {{overrideBrowserslist?: string | string[] | undefined, stats?: browserslist.Options["stats"], path?: browserslist.Options["path"], env?: browserslist.Options["env"]}} options
9
+ * @param {browserslist.Options["stats"]} stats
10
+ * @param {string|undefined} from
11
+ * @param {string} [file]
12
+ * @param {browserslist.Options["env"]} [env]
13
+ * @returns {string[]}
14
+ */
15
+ module.exports = function computeBrowsersToSupport(
16
+ options,
17
+ stats,
18
+ from,
19
+ file,
20
+ env
21
+ ) {
22
+ return browserslist(options.overrideBrowserslist, {
23
+ stats: options.stats || stats,
24
+ path: options.path || dirname(from || file || __filename),
25
+ env: options.env || env,
26
+ });
27
+ };
@@ -26,14 +26,15 @@ function filterPrefixes(selector) {
26
26
  return selector.match(vendorPrefix);
27
27
  }
28
28
 
29
+ const inputPlaceholderRegex = /-ms-input-placeholder/i;
29
30
  /**
30
31
  * Internet Explorer use :-ms-input-placeholder.
31
32
  * Microsoft Edge use ::-ms-input-placeholder.
32
33
  *
33
- * @type {(selector: string) => number}
34
+ * @type {(selector: string) => boolean}
34
35
  */
35
36
  const findMsInputPlaceholder = (selector) =>
36
- ~selector.search(/-ms-input-placeholder/i);
37
+ inputPlaceholderRegex.test(selector);
37
38
 
38
39
  /**
39
40
  * @param {string[]} selectorsA
@@ -42,9 +43,9 @@ const findMsInputPlaceholder = (selector) =>
42
43
  */
43
44
  function sameVendor(selectorsA, selectorsB) {
44
45
  /** @type {(selectors: string[]) => string} */
45
- let same = (selectors) => selectors.map(filterPrefixes).join();
46
+ const same = (selectors) => selectors.map(filterPrefixes).join();
46
47
  /** @type {(selectors: string[]) => string | undefined} */
47
- let findMsVendor = (selectors) => selectors.find(findMsInputPlaceholder);
48
+ const findMsVendor = (selectors) => selectors.find(findMsInputPlaceholder);
48
49
  return (
49
50
  same(selectorsA) === same(selectorsB) &&
50
51
  !(findMsVendor(selectorsA) && findMsVendor(selectorsB))
@@ -177,7 +178,7 @@ function ensureCompatibility(selectors, browsers, compatibilityCache) {
177
178
  const { type, value } = node;
178
179
  if (type === 'pseudo') {
179
180
  const entry =
180
- pseudoElements[/** @type {keyof pseudoElements} */ (value)];
181
+ pseudoElements[/** @type keyof typeof pseudoElements*/ (value)];
181
182
  if (!entry && noVendor(value)) {
182
183
  compatible = false;
183
184
  }
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ module.exports = function () {
4
+ return [
5
+ 'and_chr 150',
6
+ 'and_ff 152',
7
+ 'and_qq 14.9',
8
+ 'and_uc 15.5',
9
+ 'android 150',
10
+ 'chrome 150',
11
+ 'chrome 149',
12
+ 'chrome 148',
13
+ 'chrome 118',
14
+ 'chrome 109',
15
+ 'edge 150',
16
+ 'edge 149',
17
+ 'edge 148',
18
+ 'firefox 152',
19
+ 'firefox 151',
20
+ 'firefox 140',
21
+ 'ios_saf 26.5',
22
+ 'ios_saf 26.4',
23
+ 'ios_saf 26.3',
24
+ 'ios_saf 18.5-18.7',
25
+ 'kaios 3.0-3.1',
26
+ 'op_mob 80',
27
+ 'opera 131',
28
+ 'opera 127',
29
+ 'safari 26.5',
30
+ 'safari 26.4',
31
+ 'safari 26.3',
32
+ 'samsung 30',
33
+ 'samsung 29',
34
+ ];
35
+ };
package/types/index.d.ts CHANGED
@@ -1,24 +1,8 @@
1
- export = pluginCreator;
2
- /**
3
- * @typedef {{ overrideBrowserslist?: string | string[] }} AutoprefixerOptions
4
- * @typedef {Pick<browserslist.Options, 'stats' | 'path' | 'env'>} BrowserslistOptions
5
- * @typedef {AutoprefixerOptions & BrowserslistOptions} Options
6
- */
7
- /**
8
- * @type {import('postcss').PluginCreator<Options>}
9
- * @param {Options} opts
10
- * @return {import('postcss').Plugin}
11
- */
12
- declare function pluginCreator(opts?: Options): import("postcss").Plugin;
13
- declare namespace pluginCreator {
14
- export { postcss, RuleMeta, AutoprefixerOptions, BrowserslistOptions, Options };
15
- }
16
- declare var postcss: true;
17
- /**
18
- * RuleMeta stores metadata about a `Rule` during the merging process.
19
- * It tracks selectors and declarations without re-parsing the AST many times.
20
- */
21
- type RuleMeta = {
1
+ declare const _exports: import("postcss").PluginCreator<Options>;
2
+ export = _exports;
3
+ import type browserslist from 'browserslist';
4
+ import type { Declaration } from 'postcss';
5
+ export type RuleMeta = {
22
6
  /**
23
7
  * - Array of selector strings for the rule
24
8
  */
@@ -26,16 +10,15 @@ type RuleMeta = {
26
10
  /**
27
11
  * - Array of declaration nodes for the rule
28
12
  */
29
- declarations: import("postcss").Declaration[];
13
+ declarations: Declaration[];
30
14
  /**
31
15
  * - Whether the selectors have been modified and need flushing
32
16
  */
33
17
  dirty: boolean;
34
18
  };
35
- type AutoprefixerOptions = {
19
+ export type AutoprefixerOptions = {
36
20
  overrideBrowserslist?: string | string[];
37
21
  };
38
- type BrowserslistOptions = Pick<browserslist.Options, "stats" | "path" | "env">;
39
- type Options = AutoprefixerOptions & BrowserslistOptions;
40
- import browserslist = require("browserslist");
22
+ export type BrowserslistOptions = Pick<browserslist.Options, 'stats' | 'path' | 'env'>;
23
+ export type Options = AutoprefixerOptions & BrowserslistOptions;
41
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":";AAmkBA;;;;GAIG;AAEH;;;;GAIG;AACH,sCAHW,OAAO,GACN,OAAO,SAAS,EAAE,MAAM,CAqCnC;;;;;;;;;;;;;eApjBa,MAAM,EAAE;;;;kBACR,OAAO,SAAS,EAAE,WAAW,EAAE;;;;WAC/B,OAAO;;2BAqgBR;IAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE;2BAC5C,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;eACpD,mBAAmB,GAAG,mBAAmB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":";;AAII,OAAQ,KAAA,YAAY,MAAM,cAAc,CAAA;AAQxC,OAAQ,KAAA,EAAC,WAAW,EAAO,MAAM,SAAS,CAAA;AAmD3C,YAAkB,QAAQ,GAC1B;;;;IAAqB,SAAS,EAAnB,MAAM,EAAE,CACnB;;;;IAA0B,YAAY,EAA3B,WAAW,EAAE,CACxB;;;;IAAoB,KAAK,EAAd,OAAO,CACpB;CAAA,CAAA;AA0kBE,YAAwD,mBAAmB,GAAjE;IAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,CAAqB;AAC3E,YAAgE,mBAAmB,GAAzE,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC,CAAqB;AACnF,YAAqD,OAAO,GAAlD,mBAAmB,GAAG,mBAAmB,CAAS"}
@@ -0,0 +1,18 @@
1
+ export = computeBrowsersToSupport;
2
+ /**
3
+ *
4
+ * @param {{overrideBrowserslist?: string | string[] | undefined, stats?: browserslist.Options["stats"], path?: browserslist.Options["path"], env?: browserslist.Options["env"]}} options
5
+ * @param {browserslist.Options["stats"]} stats
6
+ * @param {string|undefined} from
7
+ * @param {string} [file]
8
+ * @param {browserslist.Options["env"]} [env]
9
+ * @returns {string[]}
10
+ */
11
+ declare function computeBrowsersToSupport(options: {
12
+ overrideBrowserslist?: string | string[] | undefined;
13
+ stats?: browserslist.Options["stats"];
14
+ path?: browserslist.Options["path"];
15
+ env?: browserslist.Options["env"];
16
+ }, stats: browserslist.Options["stats"], from: string | undefined, file?: string, env?: browserslist.Options["env"]): string[];
17
+ import browserslist = require('browserslist');
18
+ //# sourceMappingURL=computeBrowsersToSupport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computeBrowsersToSupport.d.ts","sourceRoot":"","sources":["../../src/lib/computeBrowsersToSupport.js"],"names":[],"mappings":";AAKA;;;;;;;;GAQG;0CAED,OAAO,EARE;IAAC,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAAC,GAAG,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;CAQtK,EACP,KAAK,EARI,YAAY,CAAC,OAAO,CAAC,OAAO,CAQhC,EACL,IAAI,EARK,MAAM,GAAC,SAQZ,EACJ,IAAI,AARH,CACA,EADQ,MAQL,EACJ,GAAG,AARF,CACA,EADQ,YAAY,CAAC,OAAO,CAAC,KAAK,CAQhC,GAPQ,MAAM,EAAE;OAVf,YAAY,WAAW,cAAc"}
@@ -1,72 +1,78 @@
1
+ declare const _exports: {
2
+ sameVendor: typeof sameVendor;
3
+ noVendor: typeof noVendor;
4
+ pseudoElements: {
5
+ ':active': string;
6
+ ':after': string;
7
+ ':any-link': string;
8
+ ':before': string;
9
+ ':checked': string;
10
+ ':default': string;
11
+ ':dir': string;
12
+ ':disabled': string;
13
+ ':empty': string;
14
+ ':enabled': string;
15
+ ':first-child': string;
16
+ ':first-letter': string;
17
+ ':first-line': string;
18
+ ':first-of-type': string;
19
+ ':focus': string;
20
+ ':focus-within': string;
21
+ ':focus-visible': string;
22
+ ':has': string;
23
+ ':hover': string;
24
+ ':in-range': string;
25
+ ':indeterminate': string;
26
+ ':invalid': string;
27
+ ':is': string;
28
+ ':lang': string;
29
+ ':last-child': string;
30
+ ':last-of-type': string;
31
+ ':link': string;
32
+ ':matches': string;
33
+ ':not': string;
34
+ ':nth-child': string;
35
+ ':nth-last-child': string;
36
+ ':nth-last-of-type': string;
37
+ ':nth-of-type': string;
38
+ ':only-child': string;
39
+ ':only-of-type': string;
40
+ ':optional': string;
41
+ ':out-of-range': string;
42
+ ':placeholder-shown': string;
43
+ ':required': string;
44
+ ':root': string;
45
+ ':target': string;
46
+ '::after': string;
47
+ '::backdrop': string;
48
+ '::before': string;
49
+ '::first-letter': string;
50
+ '::first-line': string;
51
+ '::marker': string;
52
+ '::placeholder': string;
53
+ '::selection': string;
54
+ ':valid': string;
55
+ ':visited': string;
56
+ };
57
+ ensureCompatibility: typeof ensureCompatibility;
58
+ };
59
+ export = _exports;
1
60
  /**
2
61
  * @param {string[]} selectorsA
3
62
  * @param {string[]} selectorsB
4
63
  * @return {boolean}
5
64
  */
6
- export function sameVendor(selectorsA: string[], selectorsB: string[]): boolean;
65
+ declare function sameVendor(selectorsA: string[], selectorsB: string[]): boolean;
7
66
  /**
8
67
  * @param {string} selector
9
68
  * @return {boolean}
10
69
  */
11
- export function noVendor(selector: string): boolean;
12
- export const pseudoElements: {
13
- ':active': string;
14
- ':after': string;
15
- ':any-link': string;
16
- ':before': string;
17
- ':checked': string;
18
- ':default': string;
19
- ':dir': string;
20
- ':disabled': string;
21
- ':empty': string;
22
- ':enabled': string;
23
- ':first-child': string;
24
- ':first-letter': string;
25
- ':first-line': string;
26
- ':first-of-type': string;
27
- ':focus': string;
28
- ':focus-within': string;
29
- ':focus-visible': string;
30
- ':has': string;
31
- ':hover': string;
32
- ':in-range': string;
33
- ':indeterminate': string;
34
- ':invalid': string;
35
- ':is': string;
36
- ':lang': string;
37
- ':last-child': string;
38
- ':last-of-type': string;
39
- ':link': string;
40
- ':matches': string;
41
- ':not': string;
42
- ':nth-child': string;
43
- ':nth-last-child': string;
44
- ':nth-last-of-type': string;
45
- ':nth-of-type': string;
46
- ':only-child': string;
47
- ':only-of-type': string;
48
- ':optional': string;
49
- ':out-of-range': string;
50
- ':placeholder-shown': string;
51
- ':required': string;
52
- ':root': string;
53
- ':target': string;
54
- '::after': string;
55
- '::backdrop': string;
56
- '::before': string;
57
- '::first-letter': string;
58
- '::first-line': string;
59
- '::marker': string;
60
- '::placeholder': string;
61
- '::selection': string;
62
- ':valid': string;
63
- ':visited': string;
64
- };
70
+ declare function noVendor(selector: string): boolean;
65
71
  /**
66
72
  * @param {string[]} selectors
67
73
  * @param{string[]=} browsers
68
74
  * @param{Map<string,boolean>=} compatibilityCache
69
75
  * @return {boolean}
70
76
  */
71
- export function ensureCompatibility(selectors: string[], browsers?: string[] | undefined, compatibilityCache?: Map<string, boolean> | undefined): boolean;
77
+ declare function ensureCompatibility(selectors: string[], browsers?: string[] | undefined, compatibilityCache?: Map<string, boolean> | undefined): boolean;
72
78
  //# sourceMappingURL=ensureCompatibility.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ensureCompatibility.d.ts","sourceRoot":"","sources":["../../src/lib/ensureCompatibility.js"],"names":[],"mappings":"AAqCA;;;;GAIG;AACH,uCAJW,MAAM,EAAE,cACR,MAAM,EAAE,GACP,OAAO,CAWlB;AAED;;;GAGG;AACH,mCAHW,MAAM,GACL,OAAO,CAIlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoDE;AAqCF;;;;;GAKG;AACH,+CALW,MAAM,EAAE,aACT,MAAM,EAAE,YAAC,uBACT,GAAG,CAAC,MAAM,EAAC,OAAO,CAAC,YAAC,GAClB,OAAO,CA0ElB"}
1
+ {"version":3,"file":"ensureCompatibility.d.ts","sourceRoot":"","sources":["../../src/lib/ensureCompatibility.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA;;;;GAIG;AACH,iBAAS,UAAU,CAAC,UAAU,EAJnB,MAAM,EAIa,EAAE,UAAU,EAH/B,MAAM,EAGyB,GAF9B,OAAO,CAWlB;AAED;;;GAGG;AACH,iBAAS,QAAQ,CAAC,QAAQ,EAHf,MAGe,GAFd,OAAO,CAIlB;AA2FD;;;;;GAKG;AACH,iBAAS,mBAAmB,CAAC,SAAS,EAL3B,MAAM,EAKqB,EAAE,QAAQ,AAJ7C,CACA,EADO,MAAM,EAAE,YAI8B,EAAE,kBAAkB,AAHjE,CACA,EADO,GAAG,CAAC,MAAM,EAAC,OAAO,CAAC,YAGuC,GAFxD,OAAO,CA0ElB"}
@@ -0,0 +1,3 @@
1
+ export = _exports;
2
+ declare function _exports(): string[];
3
+ //# sourceMappingURL=getBrowsersForWebBuild.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getBrowsersForWebBuild.d.ts","sourceRoot":"","sources":["../../src/lib/getBrowsersForWebBuild.js"],"names":[],"mappings":""}