postcss-merge-rules 4.0.0-rc.0 → 4.0.2

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/README.md CHANGED
@@ -96,7 +96,7 @@ examples for your environment.
96
96
 
97
97
  ## Contributors
98
98
 
99
- See [CONTRIBUTORS.md](https://github.com/ben-eb/cssnano/blob/master/CONTRIBUTORS.md).
99
+ See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).
100
100
 
101
101
  ## License
102
102
 
package/dist/index.js CHANGED
@@ -26,81 +26,57 @@ var _ensureCompatibility2 = _interopRequireDefault(_ensureCompatibility);
26
26
 
27
27
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28
28
 
29
- var prefixes = _vendors2.default.map(function (v) {
30
- return `-${v}-`;
31
- });
29
+ const prefixes = _vendors2.default.map(v => `-${v}-`);
32
30
 
33
31
  function intersect(a, b, not) {
34
- return a.filter(function (c) {
35
- var index = ~b.indexOf(c);
32
+ return a.filter(c => {
33
+ const index = ~b.indexOf(c);
36
34
  return not ? !index : index;
37
35
  });
38
36
  }
39
37
 
40
- var different = function different(a, b) {
41
- return intersect(a, b, true).concat(intersect(b, a, true));
42
- };
43
- var filterPrefixes = function filterPrefixes(selector) {
44
- return intersect(prefixes, selector);
45
- };
38
+ // Internet Explorer use :-ms-input-placeholder.
39
+ // Microsoft Edge use ::-ms-input-placeholder.
40
+ const findMsInputPlaceholder = selector => ~selector.search(/-ms-input-placeholder/i);
41
+ const different = (a, b) => intersect(a, b, true).concat(intersect(b, a, true));
42
+ const filterPrefixes = selector => intersect(prefixes, selector);
46
43
 
47
44
  function sameVendor(selectorsA, selectorsB) {
48
- var same = function same(selectors) {
49
- return selectors.map(filterPrefixes).join();
50
- };
51
- return same(selectorsA) === same(selectorsB);
45
+ let same = selectors => selectors.map(filterPrefixes).join();
46
+ let findMsVendor = selectors => selectors.find(findMsInputPlaceholder);
47
+ return same(selectorsA) === same(selectorsB) && !(findMsVendor(selectorsA) && findMsVendor(selectorsB));
52
48
  }
53
49
 
54
- var noVendor = function noVendor(selector) {
55
- return !filterPrefixes(selector).length;
56
- };
50
+ const noVendor = selector => !filterPrefixes(selector).length;
57
51
 
58
52
  function canMerge(ruleA, ruleB, browsers, compatibilityCache) {
59
- var a = ruleA.selectors;
60
- var b = ruleB.selectors;
53
+ const a = ruleA.selectors;
54
+ const b = ruleB.selectors;
61
55
 
62
- var selectors = a.concat(b);
56
+ const selectors = a.concat(b);
63
57
 
64
58
  if (!(0, _ensureCompatibility2.default)(selectors, browsers, compatibilityCache)) {
65
59
  return false;
66
60
  }
67
61
 
68
- var parent = (0, _cssnanoUtilSameParent2.default)(ruleA, ruleB);
69
- var name = ruleA.parent.name;
70
-
62
+ const parent = (0, _cssnanoUtilSameParent2.default)(ruleA, ruleB);
63
+ const { name } = ruleA.parent;
71
64
  if (parent && name && ~name.indexOf('keyframes')) {
72
65
  return false;
73
66
  }
74
67
  return parent && (selectors.every(noVendor) || sameVendor(a, b));
75
68
  }
76
69
 
77
- var getDecls = function getDecls(rule) {
78
- return rule.nodes && rule.nodes.map(String);
79
- };
80
- var joinSelectors = function joinSelectors() {
81
- for (var _len = arguments.length, rules = Array(_len), _key = 0; _key < _len; _key++) {
82
- rules[_key] = arguments[_key];
83
- }
84
-
85
- return rules.map(function (s) {
86
- return s.selector;
87
- }).join();
88
- };
70
+ const getDecls = rule => rule.nodes && rule.nodes.map(String);
71
+ const joinSelectors = (...rules) => rules.map(s => s.selector).join();
89
72
 
90
- function ruleLength() {
91
- for (var _len2 = arguments.length, rules = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
92
- rules[_key2] = arguments[_key2];
93
- }
94
-
95
- return rules.map(function (r) {
96
- return r.nodes.length ? String(r) : '';
97
- }).join('').length;
73
+ function ruleLength(...rules) {
74
+ return rules.map(r => r.nodes.length ? String(r) : '').join('').length;
98
75
  }
99
76
 
100
77
  function splitProp(prop) {
101
- var parts = prop.split('-');
102
- var base = void 0,
103
- rest = void 0;
78
+ const parts = prop.split('-');
79
+ let base, rest;
104
80
  // Treat vendor prefixed properties as if they were unprefixed;
105
81
  // moving them when combined with non-prefixed properties can
106
82
  // cause issues. e.g. moving -webkit-background-clip when there
@@ -119,45 +95,38 @@ function isConflictingProp(propA, propB) {
119
95
  if (propA === propB) {
120
96
  return true;
121
97
  }
122
- var a = splitProp(propA);
123
- var b = splitProp(propB);
98
+ const a = splitProp(propA);
99
+ const b = splitProp(propB);
124
100
  return a[0] === b[0] && a[1].length !== b[1].length;
125
101
  }
126
102
 
127
103
  function hasConflicts(declProp, notMoved) {
128
- return notMoved.some(function (prop) {
129
- return isConflictingProp(prop, declProp);
130
- });
104
+ return notMoved.some(prop => isConflictingProp(prop, declProp));
131
105
  }
132
106
 
133
107
  function partialMerge(first, second) {
134
- var _this = this;
135
-
136
- var intersection = intersect(getDecls(first), getDecls(second));
108
+ let intersection = intersect(getDecls(first), getDecls(second));
137
109
  if (!intersection.length) {
138
110
  return second;
139
111
  }
140
- var nextRule = second.next();
112
+ let nextRule = second.next();
141
113
  if (nextRule && nextRule.type === 'rule' && canMerge(second, nextRule)) {
142
- var nextIntersection = intersect(getDecls(second), getDecls(nextRule));
114
+ let nextIntersection = intersect(getDecls(second), getDecls(nextRule));
143
115
  if (nextIntersection.length > intersection.length) {
144
116
  first = second;second = nextRule;intersection = nextIntersection;
145
117
  }
146
118
  }
147
- var recievingBlock = second.clone();
119
+ const recievingBlock = second.clone();
148
120
  recievingBlock.selector = joinSelectors(first, second);
149
121
  recievingBlock.nodes = [];
150
- second.parent.insertBefore(second, recievingBlock);
151
- var difference = different(getDecls(first), getDecls(second));
152
- var filterConflicts = function filterConflicts(decls, intersectn) {
153
- var willNotMove = [];
154
- return decls.reduce(function (willMove, decl) {
155
- var intersects = ~intersectn.indexOf(decl);
156
- var prop = decl.split(':')[0];
157
- var base = prop.split('-')[0];
158
- var canMove = difference.every(function (d) {
159
- return d.split(':')[0] !== base;
160
- });
122
+ const difference = different(getDecls(first), getDecls(second));
123
+ const filterConflicts = (decls, intersectn) => {
124
+ let willNotMove = [];
125
+ return decls.reduce((willMove, decl) => {
126
+ let intersects = ~intersectn.indexOf(decl);
127
+ let prop = decl.split(':')[0];
128
+ let base = prop.split('-')[0];
129
+ let canMove = difference.every(d => d.split(':')[0] !== base);
161
130
  if (intersects && canMove && !hasConflicts(prop, willNotMove)) {
162
131
  willMove.push(decl);
163
132
  } else {
@@ -166,30 +135,41 @@ function partialMerge(first, second) {
166
135
  return willMove;
167
136
  }, []);
168
137
  };
138
+ const containsAllDeclaration = intersectionList => {
139
+ return intersectionList.some(declaration => {
140
+ return declaration.split(':')[0].toLowerCase() === 'all';
141
+ });
142
+ };
169
143
  intersection = filterConflicts(getDecls(first).reverse(), intersection);
170
144
  intersection = filterConflicts(getDecls(second), intersection);
171
- var firstClone = first.clone();
172
- var secondClone = second.clone();
173
- var moveDecl = function moveDecl(callback) {
174
- return function (decl) {
145
+
146
+ // Rules with "all" declarations must be on top
147
+ if (containsAllDeclaration(intersection)) {
148
+ second.parent.insertBefore(first, recievingBlock);
149
+ } else {
150
+ second.parent.insertBefore(second, recievingBlock);
151
+ }
152
+
153
+ const firstClone = first.clone();
154
+ const secondClone = second.clone();
155
+ const moveDecl = callback => {
156
+ return decl => {
175
157
  if (~intersection.indexOf(String(decl))) {
176
- callback.call(_this, decl);
158
+ callback.call(this, decl);
177
159
  }
178
160
  };
179
161
  };
180
- firstClone.walkDecls(moveDecl(function (decl) {
162
+ firstClone.walkDecls(moveDecl(decl => {
181
163
  decl.remove();
182
164
  recievingBlock.append(decl);
183
165
  }));
184
- secondClone.walkDecls(moveDecl(function (decl) {
185
- return decl.remove();
186
- }));
187
- var merged = ruleLength(firstClone, recievingBlock, secondClone);
188
- var original = ruleLength(first, second);
166
+ secondClone.walkDecls(moveDecl(decl => decl.remove()));
167
+ const merged = ruleLength(firstClone, recievingBlock, secondClone);
168
+ const original = ruleLength(first, second);
189
169
  if (merged < original) {
190
170
  first.replaceWith(firstClone);
191
171
  second.replaceWith(secondClone);
192
- [firstClone, recievingBlock, secondClone].forEach(function (r) {
172
+ [firstClone, recievingBlock, secondClone].forEach(r => {
193
173
  if (!r.nodes.length) {
194
174
  r.remove();
195
175
  }
@@ -205,7 +185,7 @@ function partialMerge(first, second) {
205
185
  }
206
186
 
207
187
  function selectorMerger(browsers, compatibilityCache) {
208
- var cache = null;
188
+ let cache = null;
209
189
  return function (rule) {
210
190
  // Prime the cache with the first rule, or alternately ensure that it is
211
191
  // safe to merge both declarations before continuing
@@ -230,8 +210,8 @@ function selectorMerger(browsers, compatibilityCache) {
230
210
  // Merge when both selectors are exactly equal
231
211
  // e.g. a { color: blue } a { font-weight: bold }
232
212
  if (cache.selector === rule.selector) {
233
- var cached = getDecls(cache);
234
- rule.walk(function (decl) {
213
+ const cached = getDecls(cache);
214
+ rule.walk(decl => {
235
215
  if (~cached.indexOf(String(decl))) {
236
216
  return decl.remove();
237
217
  }
@@ -246,15 +226,15 @@ function selectorMerger(browsers, compatibilityCache) {
246
226
  };
247
227
  }
248
228
 
249
- exports.default = _postcss2.default.plugin('postcss-merge-rules', function () {
250
- return function (css, result) {
251
- var resultOpts = result.opts || {};
252
- var browsers = (0, _browserslist2.default)(null, {
229
+ exports.default = _postcss2.default.plugin('postcss-merge-rules', () => {
230
+ return (css, result) => {
231
+ const resultOpts = result.opts || {};
232
+ const browsers = (0, _browserslist2.default)(null, {
253
233
  stats: resultOpts.stats,
254
234
  path: __dirname,
255
235
  env: resultOpts.env
256
236
  });
257
- var compatibilityCache = {};
237
+ const compatibilityCache = {};
258
238
  css.walkRules(selectorMerger(browsers, compatibilityCache));
259
239
  };
260
240
  });
@@ -14,16 +14,16 @@ var _postcssSelectorParser2 = _interopRequireDefault(_postcssSelectorParser);
14
14
 
15
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
16
 
17
- var simpleSelectorRe = /^#?[-._a-z0-9 ]+$/i;
17
+ const simpleSelectorRe = /^#?[-._a-z0-9 ]+$/i;
18
18
 
19
- var cssSel2 = 'css-sel2';
20
- var cssSel3 = 'css-sel3';
21
- var cssGencontent = 'css-gencontent';
22
- var cssFirstLetter = 'css-first-letter';
23
- var cssFirstLine = 'css-first-line';
24
- var cssInOutOfRange = 'css-in-out-of-range';
19
+ const cssSel2 = 'css-sel2';
20
+ const cssSel3 = 'css-sel3';
21
+ const cssGencontent = 'css-gencontent';
22
+ const cssFirstLetter = 'css-first-letter';
23
+ const cssFirstLine = 'css-first-line';
24
+ const cssInOutOfRange = 'css-in-out-of-range';
25
25
 
26
- var pseudoElements = exports.pseudoElements = {
26
+ const pseudoElements = exports.pseudoElements = {
27
27
  ':active': cssSel2,
28
28
  ':after': cssGencontent,
29
29
  ':before': cssGencontent,
@@ -78,21 +78,19 @@ function ensureCompatibility(selectors, browsers, compatibilityCache) {
78
78
  if (selectors.some(isCssMixin)) {
79
79
  return false;
80
80
  }
81
- return selectors.every(function (selector) {
81
+ return selectors.every(selector => {
82
82
  if (simpleSelectorRe.test(selector)) {
83
83
  return true;
84
84
  }
85
85
  if (compatibilityCache && selector in compatibilityCache) {
86
86
  return compatibilityCache[selector];
87
87
  }
88
- var compatible = true;
89
- (0, _postcssSelectorParser2.default)(function (ast) {
90
- ast.walk(function (node) {
91
- var type = node.type,
92
- value = node.value;
93
-
88
+ let compatible = true;
89
+ (0, _postcssSelectorParser2.default)(ast => {
90
+ ast.walk(node => {
91
+ const { type, value } = node;
94
92
  if (type === 'pseudo') {
95
- var entry = pseudoElements[value];
93
+ const entry = pseudoElements[value];
96
94
  if (entry && compatible) {
97
95
  compatible = (0, _caniuseApi.isSupported)(entry, browsers);
98
96
  }
@@ -133,7 +131,7 @@ function ensureCompatibility(selectors, browsers, compatibilityCache) {
133
131
  return false;
134
132
  }
135
133
  });
136
- }).process(selector);
134
+ }).processSync(selector);
137
135
  if (compatibilityCache) {
138
136
  compatibilityCache[selector] = compatible;
139
137
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss-merge-rules",
3
- "version": "4.0.0-rc.0",
3
+ "version": "4.0.2",
4
4
  "description": "Merge CSS rules with PostCSS.",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -19,29 +19,29 @@
19
19
  "license": "MIT",
20
20
  "devDependencies": {
21
21
  "babel-cli": "^6.0.0",
22
- "cross-env": "^3.0.0",
23
- "postcss-discard-comments": "^4.0.0-rc.0",
24
- "postcss-simple-vars": "^3.0.0"
22
+ "cross-env": "^5.0.0",
23
+ "postcss-discard-comments": "^4.0.0",
24
+ "postcss-simple-vars": "^5.0.1"
25
25
  },
26
- "homepage": "https://github.com/ben-eb/cssnano",
26
+ "homepage": "https://github.com/cssnano/cssnano",
27
27
  "author": {
28
28
  "name": "Ben Briggs",
29
29
  "email": "beneb.info@gmail.com",
30
30
  "url": "http://beneb.info"
31
31
  },
32
- "repository": "ben-eb/cssnano",
32
+ "repository": "cssnano/cssnano",
33
33
  "dependencies": {
34
- "browserslist": "^2.0.0",
35
- "caniuse-api": "^2.0.0",
36
- "cssnano-util-same-parent": "^4.0.0-rc.0",
37
- "postcss": "^6.0.0",
38
- "postcss-selector-parser": "^2.0.0",
34
+ "browserslist": "^4.0.0",
35
+ "caniuse-api": "^3.0.0",
36
+ "cssnano-util-same-parent": "^4.0.0",
37
+ "postcss": "^7.0.0",
38
+ "postcss-selector-parser": "^3.0.0",
39
39
  "vendors": "^1.0.0"
40
40
  },
41
41
  "bugs": {
42
- "url": "https://github.com/ben-eb/cssnano/issues"
42
+ "url": "https://github.com/cssnano/cssnano/issues"
43
43
  },
44
44
  "engines": {
45
- "node": ">=4"
45
+ "node": ">=6.9.0"
46
46
  }
47
47
  }
package/dist/lib/clone.js DELETED
@@ -1,34 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- var clone = function clone(obj, parent) {
7
- if (typeof obj !== 'object' || obj === null) {
8
- return obj;
9
- }
10
- var cloned = new obj.constructor();
11
- for (var i in obj) {
12
- if (!{}.hasOwnProperty.call(obj, i)) {
13
- continue;
14
- }
15
- var value = obj[i];
16
- if (i === 'parent' && typeof value === 'object') {
17
- if (parent) {
18
- cloned[i] = parent;
19
- }
20
- } else if (i === 'source') {
21
- cloned[i] = value;
22
- } else if (value instanceof Array) {
23
- cloned[i] = value.map(function (j) {
24
- return clone(j, cloned);
25
- });
26
- } else {
27
- cloned[i] = clone(value, cloned);
28
- }
29
- }
30
- return cloned;
31
- };
32
-
33
- exports.default = clone;
34
- module.exports = exports['default'];