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 +14 -50
- package/dist/lib/ensureCompatibility.js +62 -8
- package/package.json +13 -14
- package/CHANGELOG.md +0 -75
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 =
|
|
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 {
|
|
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.
|
|
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
|
|
272
|
-
const nextConflictInFirst = firstDecls.slice(
|
|
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).
|
|
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 (
|
|
285
|
-
return
|
|
248
|
+
if (nextConflictInFirst.length !== nextConflictInIntersection.length) {
|
|
249
|
+
return false;
|
|
286
250
|
}
|
|
287
251
|
|
|
288
|
-
return
|
|
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 {
|
|
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.
|
|
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
|
-
|
|
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
|
|
126
|
+
let result = isSupportedCache.get(key);
|
|
82
127
|
|
|
83
128
|
if (!result) {
|
|
84
129
|
result = (0, _caniuseApi.isSupported)(feature, browsers);
|
|
85
|
-
isSupportedCache
|
|
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
|
|
103
|
-
return compatibilityCache
|
|
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
|
|
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.
|
|
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.
|
|
25
|
+
"browserslist": "^4.16.6",
|
|
31
26
|
"caniuse-api": "^3.0.0",
|
|
32
|
-
"cssnano-utils": "^
|
|
33
|
-
"postcss-selector-parser": "^6.0.
|
|
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.
|
|
37
|
+
"postcss": "^8.2.15",
|
|
38
|
+
"postcss-discard-comments": "^5.0.1"
|
|
44
39
|
},
|
|
45
40
|
"peerDependencies": {
|
|
46
|
-
"postcss": "^8.2.
|
|
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
|
-
"
|
|
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)
|