postcss-merge-rules 5.0.0 → 5.0.4

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/dist/index.js CHANGED
@@ -7,23 +7,17 @@ exports.default = void 0;
7
7
 
8
8
  var _browserslist = _interopRequireDefault(require("browserslist"));
9
9
 
10
- var _vendors = _interopRequireDefault(require("vendors"));
11
-
12
10
  var _cssnanoUtils = require("cssnano-utils");
13
11
 
14
- var _ensureCompatibility = _interopRequireDefault(require("./lib/ensureCompatibility"));
12
+ var _ensureCompatibility = require("./lib/ensureCompatibility");
15
13
 
16
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
15
 
18
- /** @type {string[]} */
19
- const prefixes = _vendors.default.map(v => `-${v}-`);
20
16
  /**
21
17
  * @param {postcss.Declaration} a
22
18
  * @param {postcss.Declaration} b
23
19
  * @return {boolean}
24
20
  */
25
-
26
-
27
21
  function declarationIsEqual(a, b) {
28
22
  return a.important === b.important && a.prop === b.prop && a.value === b.value;
29
23
  }
@@ -65,42 +59,12 @@ function sameDeclarationsAndOrder(a, b) {
65
59
  }
66
60
 
67
61
  return a.every((d, index) => declarationIsEqual(d, b[index]));
68
- } // Internet Explorer use :-ms-input-placeholder.
69
- // Microsoft Edge use ::-ms-input-placeholder.
70
-
71
-
72
- const findMsInputPlaceholder = selector => ~selector.search(/-ms-input-placeholder/i);
73
- /**
74
- * @param {string} selector
75
- * @return {string[]}
76
- */
77
-
78
-
79
- function filterPrefixes(selector) {
80
- return prefixes.filter(prefix => selector.indexOf(prefix) !== -1);
81
- }
82
-
83
- function sameVendor(selectorsA, selectorsB) {
84
- let same = selectors => selectors.map(filterPrefixes).join();
85
-
86
- let findMsVendor = selectors => selectors.find(findMsInputPlaceholder);
87
-
88
- return same(selectorsA) === same(selectorsB) && !(findMsVendor(selectorsA) && findMsVendor(selectorsB));
89
- }
90
- /**
91
- * @param {string} selector
92
- * @return {boolean}
93
- */
94
-
95
-
96
- function noVendor(selector) {
97
- return !filterPrefixes(selector).length;
98
62
  }
99
63
  /**
100
64
  * @param {postcss.Rule} ruleA
101
65
  * @param {postcss.Rule} ruleB
102
66
  * @param {string[]=} browsers
103
- * @param {Object.<string, boolean>=} compatibilityCache
67
+ * @param {Map<string, boolean>=} compatibilityCache
104
68
  * @return {boolean}
105
69
  */
106
70
 
@@ -110,7 +74,7 @@ function canMerge(ruleA, ruleB, browsers, compatibilityCache) {
110
74
  const b = ruleB.selectors;
111
75
  const selectors = a.concat(b);
112
76
 
113
- if (!(0, _ensureCompatibility.default)(selectors, browsers, compatibilityCache)) {
77
+ if (!(0, _ensureCompatibility.ensureCompatibility)(selectors, browsers, compatibilityCache)) {
114
78
  return false;
115
79
  }
116
80
 
@@ -123,7 +87,7 @@ function canMerge(ruleA, ruleB, browsers, compatibilityCache) {
123
87
  return false;
124
88
  }
125
89
 
126
- return parent && (selectors.every(noVendor) || sameVendor(a, b));
90
+ return parent && (selectors.every(_ensureCompatibility.noVendor) || (0, _ensureCompatibility.sameVendor)(a, b));
127
91
  }
128
92
  /**
129
93
  * @param {postcss.Rule} rule
@@ -268,24 +232,24 @@ function partialMerge(first, second) {
268
232
  const firstDecls = getDecls(first); // Filter out intersections with later conflicts in First
269
233
 
270
234
  intersection = intersection.filter((decl, intersectIndex) => {
271
- const index = indexOfDeclaration(firstDecls, decl);
272
- const nextConflictInFirst = firstDecls.slice(index + 1).find(d => isConflictingProp(d.prop, decl.prop));
235
+ const indexOfDecl = indexOfDeclaration(firstDecls, decl);
236
+ const nextConflictInFirst = firstDecls.slice(indexOfDecl + 1).filter(d => isConflictingProp(d.prop, decl.prop));
273
237
 
274
- if (!nextConflictInFirst) {
238
+ if (!nextConflictInFirst.length) {
275
239
  return true;
276
240
  }
277
241
 
278
- const nextConflictInIntersection = intersection.slice(intersectIndex + 1).find(d => isConflictingProp(d.prop, decl.prop));
242
+ const nextConflictInIntersection = intersection.slice(intersectIndex + 1).filter(d => isConflictingProp(d.prop, decl.prop));
279
243
 
280
- if (!nextConflictInIntersection) {
244
+ if (!nextConflictInIntersection.length) {
281
245
  return false;
282
246
  }
283
247
 
284
- if (declarationIsEqual(nextConflictInFirst, nextConflictInIntersection)) {
285
- return true;
248
+ if (nextConflictInFirst.length !== nextConflictInIntersection.length) {
249
+ return false;
286
250
  }
287
251
 
288
- return false;
252
+ return nextConflictInFirst.every((d, index) => declarationIsEqual(d, nextConflictInIntersection[index]));
289
253
  }); // Filter out intersections with previous conflicts in Second
290
254
 
291
255
  const secondDecls = getDecls(second);
@@ -361,7 +325,7 @@ function partialMerge(first, second) {
361
325
  }
362
326
  /**
363
327
  * @param {string[]} browsers
364
- * @param {Object.<string, boolean>} compatibilityCache
328
+ * @param {Map<string, boolean>} compatibilityCache
365
329
  * @return {function(postcss.Rule)}
366
330
  */
367
331
 
@@ -427,7 +391,7 @@ function pluginCreator() {
427
391
  path: __dirname,
428
392
  env: resultOpts.env
429
393
  });
430
- const compatibilityCache = {};
394
+ const compatibilityCache = new Map();
431
395
  return {
432
396
  OnceExit(css) {
433
397
  css.walkRules(selectorMerger(browsers, compatibilityCache));
@@ -3,8 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = ensureCompatibility;
6
+ exports.ensureCompatibility = ensureCompatibility;
7
+ exports.noVendor = noVendor;
7
8
  exports.pseudoElements = void 0;
9
+ exports.sameVendor = sameVendor;
8
10
 
9
11
  var _caniuseApi = require("caniuse-api");
10
12
 
@@ -19,9 +21,42 @@ const cssGencontent = 'css-gencontent';
19
21
  const cssFirstLetter = 'css-first-letter';
20
22
  const cssFirstLine = 'css-first-line';
21
23
  const cssInOutOfRange = 'css-in-out-of-range';
24
+ const formValidation = 'form-validation';
25
+ const vendorPrefix = /-(ah|apple|atsc|epub|hp|khtml|moz|ms|o|rim|ro|tc|wap|webkit|xv)-/;
26
+ /**
27
+ * @param {string} selector
28
+ * @return {string[]}
29
+ */
30
+
31
+ function filterPrefixes(selector) {
32
+ return selector.match(vendorPrefix);
33
+ } // Internet Explorer use :-ms-input-placeholder.
34
+ // Microsoft Edge use ::-ms-input-placeholder.
35
+
36
+
37
+ const findMsInputPlaceholder = selector => ~selector.search(/-ms-input-placeholder/i);
38
+
39
+ function sameVendor(selectorsA, selectorsB) {
40
+ let same = selectors => selectors.map(filterPrefixes).join();
41
+
42
+ let findMsVendor = selectors => selectors.find(findMsInputPlaceholder);
43
+
44
+ return same(selectorsA) === same(selectorsB) && !(findMsVendor(selectorsA) && findMsVendor(selectorsB));
45
+ }
46
+ /**
47
+ * @param {string} selector
48
+ * @return {boolean}
49
+ */
50
+
51
+
52
+ function noVendor(selector) {
53
+ return !vendorPrefix.test(selector);
54
+ }
55
+
22
56
  const pseudoElements = {
23
57
  ':active': cssSel2,
24
58
  ':after': cssGencontent,
59
+ ':any-link': 'css-any-link',
25
60
  ':before': cssGencontent,
26
61
  ':checked': cssSel3,
27
62
  ':default': 'css-default-pseudo',
@@ -40,9 +75,12 @@ const pseudoElements = {
40
75
  ':hover': cssSel2,
41
76
  ':in-range': cssInOutOfRange,
42
77
  ':indeterminate': 'css-indeterminate-pseudo',
78
+ ':invalid': formValidation,
79
+ ':is': 'css-matches-pseudo',
43
80
  ':lang': cssSel2,
44
81
  ':last-child': cssSel3,
45
82
  ':last-of-type': cssSel3,
83
+ ':link': cssSel2,
46
84
  ':matches': 'css-matches-pseudo',
47
85
  ':not': cssSel3,
48
86
  ':nth-child': cssSel3,
@@ -54,6 +92,7 @@ const pseudoElements = {
54
92
  ':optional': 'css-optional-pseudo',
55
93
  ':out-of-range': cssInOutOfRange,
56
94
  ':placeholder-shown': 'css-placeholder-shown',
95
+ ':required': formValidation,
57
96
  ':root': cssSel3,
58
97
  ':target': cssSel3,
59
98
  '::after': cssGencontent,
@@ -63,7 +102,9 @@ const pseudoElements = {
63
102
  '::first-line': cssFirstLine,
64
103
  '::marker': 'css-marker-pseudo',
65
104
  '::placeholder': 'css-placeholder',
66
- '::selection': 'css-selection'
105
+ '::selection': 'css-selection',
106
+ ':valid': formValidation,
107
+ ':visited': cssSel2
67
108
  };
68
109
  exports.pseudoElements = pseudoElements;
69
110
 
@@ -71,18 +112,22 @@ function isCssMixin(selector) {
71
112
  return selector[selector.length - 1] === ':';
72
113
  }
73
114
 
74
- const isSupportedCache = {}; // Move to util in future
115
+ function isHostPseudoClass(selector) {
116
+ return selector.includes(':host');
117
+ }
118
+
119
+ const isSupportedCache = new Map(); // Move to util in future
75
120
 
76
121
  function isSupportedCached(feature, browsers) {
77
122
  const key = JSON.stringify({
78
123
  feature,
79
124
  browsers
80
125
  });
81
- let result = isSupportedCache[key];
126
+ let result = isSupportedCache.get(key);
82
127
 
83
128
  if (!result) {
84
129
  result = (0, _caniuseApi.isSupported)(feature, browsers);
85
- isSupportedCache[key] = result;
130
+ isSupportedCache.set(key, result);
86
131
  }
87
132
 
88
133
  return result;
@@ -92,6 +137,11 @@ function ensureCompatibility(selectors, browsers, compatibilityCache) {
92
137
  // Should not merge mixins
93
138
  if (selectors.some(isCssMixin)) {
94
139
  return false;
140
+ } // Should not merge :host selector https://github.com/angular/angular-cli/issues/18672
141
+
142
+
143
+ if (selectors.some(isHostPseudoClass)) {
144
+ return false;
95
145
  }
96
146
 
97
147
  return selectors.every(selector => {
@@ -99,8 +149,8 @@ function ensureCompatibility(selectors, browsers, compatibilityCache) {
99
149
  return true;
100
150
  }
101
151
 
102
- if (compatibilityCache && selector in compatibilityCache) {
103
- return compatibilityCache[selector];
152
+ if (compatibilityCache && compatibilityCache.has(selector)) {
153
+ return compatibilityCache.get(selector);
104
154
  }
105
155
 
106
156
  let compatible = true;
@@ -114,6 +164,10 @@ function ensureCompatibility(selectors, browsers, compatibilityCache) {
114
164
  if (type === 'pseudo') {
115
165
  const entry = pseudoElements[value];
116
166
 
167
+ if (!entry && noVendor(value)) {
168
+ compatible = false;
169
+ }
170
+
117
171
  if (entry && compatible) {
118
172
  compatible = isSupportedCached(entry, browsers);
119
173
  }
@@ -162,7 +216,7 @@ function ensureCompatibility(selectors, browsers, compatibilityCache) {
162
216
  }).processSync(selector);
163
217
 
164
218
  if (compatibilityCache) {
165
- compatibilityCache[selector] = compatible;
219
+ compatibilityCache.set(selector, compatible);
166
220
  }
167
221
 
168
222
  return compatible;
package/package.json CHANGED
@@ -1,17 +1,12 @@
1
1
  {
2
2
  "name": "postcss-merge-rules",
3
- "version": "5.0.0",
3
+ "version": "5.0.4",
4
4
  "description": "Merge CSS rules with PostCSS.",
5
5
  "main": "dist/index.js",
6
6
  "files": [
7
7
  "LICENSE-MIT",
8
8
  "dist"
9
9
  ],
10
- "scripts": {
11
- "prebuild": "del-cli dist",
12
- "build": "cross-env BABEL_ENV=publish babel src --config-file ../../babel.config.js --out-dir dist --ignore \"**/__tests__/\"",
13
- "prepublish": "yarn build"
14
- },
15
10
  "keywords": [
16
11
  "css",
17
12
  "optimise",
@@ -27,11 +22,10 @@
27
22
  },
28
23
  "repository": "cssnano/cssnano",
29
24
  "dependencies": {
30
- "browserslist": "^4.16.0",
25
+ "browserslist": "^4.16.6",
31
26
  "caniuse-api": "^3.0.0",
32
- "cssnano-utils": "^2.0.0",
33
- "postcss-selector-parser": "^6.0.4",
34
- "vendors": "^1.0.3"
27
+ "cssnano-utils": "^3.0.0",
28
+ "postcss-selector-parser": "^6.0.5"
35
29
  },
36
30
  "bugs": {
37
31
  "url": "https://github.com/cssnano/cssnano/issues"
@@ -40,10 +34,15 @@
40
34
  "node": "^10 || ^12 || >=14.0"
41
35
  },
42
36
  "devDependencies": {
43
- "postcss": "^8.2.1"
37
+ "postcss": "^8.2.15",
38
+ "postcss-discard-comments": "^5.0.1"
44
39
  },
45
40
  "peerDependencies": {
46
- "postcss": "^8.2.1"
41
+ "postcss": "^8.2.15"
42
+ },
43
+ "scripts": {
44
+ "prebuild": "rimraf dist",
45
+ "build": "babel src --config-file ../../babel.config.json --out-dir dist --ignore \"**/__tests__/\""
47
46
  },
48
- "gitHead": "0e2c3bf5835bafcdc8783bef66f730a24194c8f3"
49
- }
47
+ "readme": "# [postcss][postcss]-merge-rules\n\n> Merge CSS rules with PostCSS.\n\n## Install\n\nWith [npm](https://npmjs.org/package/postcss-merge-rules) do:\n\n```\nnpm install postcss-merge-rules --save\n```\n\n## Examples\n\nThis module will attempt to merge *adjacent* CSS rules:\n\n### By declarations\n\n#### Input\n\n```css\na {\n color: blue;\n font-weight: bold\n}\n\np {\n color: blue;\n font-weight: bold\n}\n```\n\n#### Output\n\n```css\na,p {\n color: blue;\n font-weight: bold\n}\n```\n\n### By selectors\n\n#### Input\n\n```css\na {\n color: blue\n}\n\na {\n font-weight: bold\n}\n```\n\n#### Output\n\n```css\na {\n color: blue;\n font-weight: bold\n}\n```\n\n### By partial declarations\n\n#### Input\n\n```css\na {\n font-weight: bold\n}\n\np {\n color: blue;\n font-weight: bold\n}\n```\n\n#### Output\n\n```css\na,p {\n font-weight: bold\n}\n\np {\n color: blue\n}\n```\n\n## Usage\n\nSee the [PostCSS documentation](https://github.com/postcss/postcss#usage) for\nexamples for your environment.\n\n## Contributors\n\nSee [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).\n\n## License\n\nMIT © [Ben Briggs](http://beneb.info)\n\n[postcss]: https://github.com/postcss/postcss\n"
48
+ }
package/CHANGELOG.md DELETED
@@ -1,75 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- # [5.0.0](https://github.com/cssnano/cssnano/compare/postcss-merge-rules@5.0.0-rc.2...postcss-merge-rules@5.0.0) (2021-04-06)
7
-
8
- **Note:** Version bump only for package postcss-merge-rules
9
-
10
-
11
-
12
-
13
-
14
- # [5.0.0-rc.2](https://github.com/cssnano/cssnano/compare/postcss-merge-rules@5.0.0-rc.1...postcss-merge-rules@5.0.0-rc.2) (2021-03-15)
15
-
16
- **Note:** Version bump only for package postcss-merge-rules
17
-
18
-
19
-
20
-
21
-
22
- # [5.0.0-rc.1](https://github.com/cssnano/cssnano/compare/postcss-merge-rules@5.0.0-rc.0...postcss-merge-rules@5.0.0-rc.1) (2021-03-04)
23
-
24
- **Note:** Version bump only for package postcss-merge-rules
25
-
26
-
27
-
28
-
29
-
30
- # 5.0.0-rc.0 (2021-02-19)
31
-
32
-
33
- ### Bug Fixes
34
-
35
- * don't unsafe merge 'all' declaration ([#872](https://github.com/cssnano/cssnano/issues/872)) ([6ea9e5d](https://github.com/cssnano/cssnano/commit/6ea9e5dcad2d8ea22be7209332ee29d352c807de))
36
- * focus-visible issue ([#882](https://github.com/cssnano/cssnano/issues/882)) ([4cfcaaf](https://github.com/cssnano/cssnano/commit/4cfcaaf25b162ec2b0308907a408d7dba6a354c3))
37
- * **merge-rules, merge-idents:** add support for nested at-rules ([#719](https://github.com/cssnano/cssnano/issues/719)) ([cdedda7](https://github.com/cssnano/cssnano/commit/cdedda7f9d67873d872add044ad34c91616579f3))
38
- * **postcss-merge-rules:** don't change specificity of prefixed properties ([#723](https://github.com/cssnano/cssnano/issues/723)) ([863cf2b](https://github.com/cssnano/cssnano/commit/863cf2b3470d3172523a3165dc368abcfa18809c))
39
-
40
-
41
- ### chore
42
-
43
- * minimum require version of node is 10.13 ([#871](https://github.com/cssnano/cssnano/issues/871)) ([28bda24](https://github.com/cssnano/cssnano/commit/28bda243e32ce3ba89b3c358a5f78727b3732f11))
44
-
45
-
46
- ### Features
47
-
48
- * migarete to PostCSS 8 ([#975](https://github.com/cssnano/cssnano/issues/975)) ([40b82dc](https://github.com/cssnano/cssnano/commit/40b82dca7f53ac02cd4fe62846dec79b898ccb49))
49
- * **postcss-merge-rules:** merge at-rules ([#722](https://github.com/cssnano/cssnano/issues/722)) ([8d4610a](https://github.com/cssnano/cssnano/commit/8d4610a6391ddab29bcb08ef0522d0b7ce2d6582))
50
-
51
-
52
- ### BREAKING CHANGES
53
-
54
- * minimum supported `postcss` version is `8.2.1`
55
- * minimum require version of node is 10.13
56
-
57
-
58
-
59
- ## 4.1.9 (2019-02-12)
60
-
61
-
62
- ### Performance Improvements
63
-
64
- * **postcss-merge-rules:** increase perf ([#681](https://github.com/cssnano/cssnano/issues/681)) ([35bad2b](https://github.com/cssnano/cssnano/commit/35bad2b70fca5390c88eaabc24c25bb8d28b2f95))
65
-
66
-
67
-
68
- ## 4.1.1 (2018-09-24)
69
-
70
-
71
- ### Bug Fixes
72
-
73
- * handle uppercase `all` property in merge rules ([#611](https://github.com/cssnano/cssnano/issues/611)) ([0dfe335](https://github.com/cssnano/cssnano/commit/0dfe3355951fa4a080a04dca34c6d99420def7ac))
74
- * merge same atrules with difference case ([#605](https://github.com/cssnano/cssnano/issues/605)) ([ca350fd](https://github.com/cssnano/cssnano/commit/ca350fda779bab5ca2eadf70299d92f8e495a273))
75
- * **postcss-merge-longhand:** not mangle border output ([#555](https://github.com/cssnano/cssnano/issues/555)) ([9a70605](https://github.com/cssnano/cssnano/commit/9a706050b621e7795a9bf74eb7110b5c81804ffe)), closes [#553](https://github.com/cssnano/cssnano/issues/553) [#554](https://github.com/cssnano/cssnano/issues/554)