postcss-merge-longhand
Advanced tools
Comparing version 4.0.2 to 4.0.3
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
value: true | ||
}); | ||
@@ -16,4 +16,10 @@ | ||
exports.default = prop => !isInherit(prop) && !isInitial(prop) && !(0, _isCustomProp2.default)(prop); | ||
exports.default = (prop, includeCustomProps = true) => { | ||
if (includeCustomProps && (0, _isCustomProp2.default)(prop)) { | ||
return false; | ||
} | ||
return !isInherit(prop) && !isInitial(prop); | ||
}; | ||
module.exports = exports['default']; |
@@ -18,6 +18,15 @@ 'use strict'; | ||
exports.default = (...props) => { | ||
if (props.some(hasInherit) || props.some(hasInitial) || props.some(_isCustomProp2.default)) { | ||
return props.every(hasInherit) || props.every(hasInitial) || props.every(_isCustomProp2.default); | ||
exports.default = (props, includeCustomProps = true) => { | ||
if (props.some(hasInherit) && !props.every(hasInherit)) { | ||
return false; | ||
} | ||
if (props.some(hasInitial) && !props.every(hasInitial)) { | ||
return false; | ||
} | ||
if (includeCustomProps && props.some(_isCustomProp2.default) && !props.every(_isCustomProp2.default)) { | ||
return false; | ||
} | ||
return props.every(unimportant) || props.every(important); | ||
@@ -24,0 +33,0 @@ }; |
@@ -43,2 +43,6 @@ 'use strict'; | ||
var _minifyWsc = require('../minifyWsc'); | ||
var _minifyWsc2 = _interopRequireDefault(_minifyWsc); | ||
var _canMerge = require('../canMerge'); | ||
@@ -68,2 +72,8 @@ | ||
var _parseWsc = require('../parseWsc'); | ||
var _parseWsc2 = _interopRequireDefault(_parseWsc); | ||
var _validateWsc = require('../validateWsc'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -98,39 +108,8 @@ | ||
const widths = ['thin', 'medium', 'thick']; | ||
const styles = ['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset']; | ||
const isValueCustomProp = value => value.search(/var\s*\(\s*--/i); | ||
function isStyle(value) { | ||
return !!~styles.indexOf(value); | ||
function canMergeValues(values) { | ||
return !values.some(isValueCustomProp) || values.every(isValueCustomProp); | ||
} | ||
function isWidth(value) { | ||
return !!~widths.indexOf(value) || /^(\d+(\.\d+)?|\.\d+)(\w+)?$/.test(value); | ||
} | ||
function parseWsc(value) { | ||
if (value === 'none' || value === 'none none' || value === 'none none currentColor') { | ||
return ['none', 'none', 'currentColor']; | ||
} | ||
let [width, style, color] = defaults; | ||
const values = _postcss.list.space(value); | ||
if (values.length > 1 && isStyle(values[1]) && values[0] === 'none') { | ||
values.unshift(); | ||
width = 'none'; | ||
} | ||
values.forEach(v => { | ||
if (isStyle(v)) { | ||
style = v; | ||
} else if (isWidth(v)) { | ||
width = v; | ||
} else { | ||
color = v; | ||
} | ||
}); | ||
return [width, style, color]; | ||
} | ||
function getColorValue(decl) { | ||
@@ -141,3 +120,3 @@ if (decl.prop.substr(-5) === 'color') { | ||
return parseWsc(decl.value)[2]; | ||
return (0, _parseWsc2.default)(decl.value)[2] || defaults[2]; | ||
} | ||
@@ -206,3 +185,3 @@ | ||
rule.walkDecls(/^border/, decl => { | ||
if (!(0, _canExplode2.default)(decl)) { | ||
if (!(0, _canExplode2.default)(decl, false)) { | ||
return; | ||
@@ -218,17 +197,21 @@ } | ||
if (prop === 'border') { | ||
directions.forEach(direction => { | ||
(0, _insertCloned2.default)(decl.parent, decl, { prop: direction }); | ||
}); | ||
return decl.remove(); | ||
if ((0, _validateWsc.isValidWsc)((0, _parseWsc2.default)(decl.value))) { | ||
directions.forEach(direction => { | ||
(0, _insertCloned2.default)(decl.parent, decl, { prop: direction }); | ||
}); | ||
return decl.remove(); | ||
} | ||
} | ||
// border-trbl -> border-trbl-wsc | ||
if (directions.some(direction => prop === direction)) { | ||
let values = parseWsc(decl.value); | ||
wsc.forEach((d, i) => { | ||
(0, _insertCloned2.default)(decl.parent, decl, { | ||
prop: `${prop}-${d}`, | ||
value: values[i] | ||
let values = (0, _parseWsc2.default)(decl.value); | ||
if ((0, _validateWsc.isValidWsc)(values)) { | ||
wsc.forEach((d, i) => { | ||
(0, _insertCloned2.default)(decl.parent, decl, { | ||
prop: `${prop}-${d}`, | ||
value: values[i] || defaults[i] | ||
}); | ||
}); | ||
}); | ||
return decl.remove(); | ||
return decl.remove(); | ||
} | ||
} | ||
@@ -256,3 +239,3 @@ // border-wsc -> border-trbl-wsc | ||
(0, _mergeRules2.default)(rule, wsc.map(style => borderProperty(direction, style)), (rules, lastNode) => { | ||
if ((0, _canMerge2.default)(...rules) && !rules.some(_stylehacks.detect)) { | ||
if ((0, _canMerge2.default)(rules, false) && !rules.some(_stylehacks.detect)) { | ||
(0, _insertCloned2.default)(lastNode.parent, lastNode, { | ||
@@ -272,3 +255,3 @@ prop, | ||
(0, _mergeRules2.default)(rule, _trbl2.default.map(direction => borderProperty(direction, style)), (rules, lastNode) => { | ||
if ((0, _canMerge2.default)(...rules) && !rules.some(_stylehacks.detect)) { | ||
if ((0, _canMerge2.default)(rules) && !rules.some(_stylehacks.detect)) { | ||
(0, _insertCloned2.default)(lastNode.parent, lastNode, { | ||
@@ -289,7 +272,16 @@ prop, | ||
} | ||
const values = rules.map(node => (0, _parseWsc2.default)(node.value)); | ||
if (!values.every(_validateWsc.isValidWsc)) { | ||
return; | ||
} | ||
wsc.forEach((d, i) => { | ||
(0, _insertCloned2.default)(lastNode.parent, lastNode, { | ||
prop: borderProperty(d), | ||
value: (0, _minifyTrbl2.default)(rules.map(node => _postcss.list.space(node.value)[i])) | ||
}); | ||
const value = values.map(v => v[i] || defaults[i]); | ||
if (canMergeValues(value)) { | ||
(0, _insertCloned2.default)(lastNode.parent, lastNode, { | ||
prop: borderProperty(d), | ||
value: (0, _minifyTrbl2.default)(value) | ||
}); | ||
} else { | ||
(0, _insertCloned2.default)(lastNode.parent, lastNode); | ||
} | ||
}); | ||
@@ -307,8 +299,11 @@ rules.forEach(_remove2.default); | ||
} | ||
const [width, style, color] = rules; | ||
const values = rules.map(node => (0, _parseTrbl2.default)(node.value)); | ||
const mapped = [0, 1, 2, 3].map(i => [values[0][i], values[1][i], values[2][i]].join(' ')); | ||
if (!canMergeValues(mapped)) { | ||
return; | ||
} | ||
const [width, style, color] = rules; | ||
const reduced = getDistinctShorthands(mapped); | ||
if (isCloseEnough(mapped) && (0, _canMerge2.default)(...rules)) { | ||
if (isCloseEnough(mapped) && (0, _canMerge2.default)(rules, false)) { | ||
const first = mapped.indexOf(reduced[0]) !== mapped.lastIndexOf(reduced[0]); | ||
@@ -376,2 +371,33 @@ | ||
// border-trbl -> border | ||
// border-trbl -> border + border-trbl | ||
(0, _mergeRules2.default)(rule, directions, (rules, lastNode) => { | ||
if (rules.some(_stylehacks.detect)) { | ||
return; | ||
} | ||
const values = rules.map(node => (0, _parseWsc2.default)(node.value).map((value, i) => value || defaults[i]).join(' ')); | ||
const reduced = getDistinctShorthands(values); | ||
if (isCloseEnough(values)) { | ||
const first = values.indexOf(reduced[0]) !== values.lastIndexOf(reduced[0]); | ||
rule.insertBefore(lastNode, Object.assign(lastNode.clone(), { | ||
prop: 'border', | ||
value: (0, _minifyWsc2.default)(first ? values[0] : values[1]) | ||
})); | ||
if (reduced[1]) { | ||
const value = first ? reduced[1] : reduced[0]; | ||
const prop = directions[values.indexOf(value)]; | ||
rule.insertBefore(lastNode, Object.assign(lastNode.clone(), { | ||
prop: prop, | ||
value: (0, _minifyWsc2.default)(value) | ||
})); | ||
} | ||
rules.forEach(_remove2.default); | ||
return true; | ||
} | ||
}); | ||
// optimize border-trbl | ||
@@ -426,5 +452,9 @@ let decls = (0, _getDecls2.default)(rule, directions); | ||
} | ||
const values = parseWsc(decl.value); | ||
const nextValues = parseWsc(nextDecl.value); | ||
const values = (0, _parseWsc2.default)(decl.value); | ||
const nextValues = (0, _parseWsc2.default)(nextDecl.value); | ||
if (!(0, _validateWsc.isValidWsc)(values) || !(0, _validateWsc.isValidWsc)(nextValues)) { | ||
return; | ||
} | ||
const config = { | ||
@@ -442,10 +472,4 @@ values, | ||
// clean-up values | ||
rule.walkDecls(/^border($|-(top|right|bottom|left))/, decl => { | ||
const value = [...parseWsc(decl.value), ''].reduceRight((prev, cur, i, arr) => { | ||
if (cur === defaults[i] && arr[i - 1] !== cur) { | ||
return prev; | ||
} | ||
return cur + ' ' + prev; | ||
}).trim() || defaults[0]; | ||
decl.value = (0, _minifyTrbl2.default)(value || defaults[0]); | ||
rule.walkDecls(/^border($|-(top|right|bottom|left)$)/, decl => { | ||
decl.value = (0, _minifyWsc2.default)(decl.value); | ||
}); | ||
@@ -470,3 +494,3 @@ | ||
// remove properties of lower precedence | ||
const lesser = decls.filter(node => !(0, _stylehacks.detect)(lastNode) && !(0, _stylehacks.detect)(node) && node !== lastNode && node.important === lastNode.important && getLevel(node.prop) > getLevel(lastNode.prop) && (!!~node.prop.indexOf(lastNode.prop) || node.prop.endsWith(lastPart))); | ||
const lesser = decls.filter(node => !(0, _stylehacks.detect)(lastNode) && !(0, _stylehacks.detect)(node) && !(0, _isCustomProp2.default)(lastNode) && node !== lastNode && node.important === lastNode.important && getLevel(node.prop) > getLevel(lastNode.prop) && (!!~node.prop.indexOf(lastNode.prop) || node.prop.endsWith(lastPart))); | ||
@@ -473,0 +497,0 @@ lesser.forEach(_remove2.default); |
@@ -97,3 +97,3 @@ 'use strict'; | ||
(0, _mergeRules2.default)(rule, properties, (rules, lastNode) => { | ||
if ((0, _canMerge2.default)(...rules) && !rules.some(_stylehacks.detect)) { | ||
if ((0, _canMerge2.default)(rules) && !rules.some(_stylehacks.detect)) { | ||
(0, _insertCloned2.default)(lastNode.parent, lastNode, { | ||
@@ -100,0 +100,0 @@ prop, |
@@ -125,3 +125,3 @@ 'use strict'; | ||
(0, _mergeRules2.default)(rule, properties, (rules, lastNode) => { | ||
if ((0, _canMerge2.default)(...rules) && !rules.some(_stylehacks.detect)) { | ||
if ((0, _canMerge2.default)(rules) && !rules.some(_stylehacks.detect)) { | ||
(0, _insertCloned2.default)(lastNode.parent, lastNode, { | ||
@@ -128,0 +128,0 @@ prop: 'columns', |
@@ -22,2 +22,19 @@ 'use strict'; | ||
function isConflictingProp(propA, propB) { | ||
if (!propB.prop || propB.important !== propA.important) { | ||
return; | ||
} | ||
const parts = propA.prop.split('-'); | ||
return parts.some(() => { | ||
parts.pop(); | ||
return parts.join('-') === propB.prop; | ||
}); | ||
} | ||
function hasConflicts(match, nodes) { | ||
const firstNode = Math.min.apply(null, match.map(n => nodes.indexOf(n))); | ||
const lastNode = Math.max.apply(null, match.map(n => nodes.indexOf(n))); | ||
const between = nodes.slice(firstNode + 1, lastNode); | ||
return match.some(a => between.some(b => isConflictingProp(a, b))); | ||
} | ||
function mergeRules(rule, properties, callback) { | ||
@@ -29,3 +46,3 @@ let decls = (0, _getDecls2.default)(rule, properties); | ||
const rules = (0, _getRules2.default)(props, properties); | ||
if ((0, _hasAllProps2.default)(rules, ...properties)) { | ||
if ((0, _hasAllProps2.default)(rules, ...properties) && !hasConflicts(rules, rule.nodes)) { | ||
if (callback(rules, last, props)) { | ||
@@ -32,0 +49,0 @@ decls = decls.filter(node => !~rules.indexOf(node)); |
{ | ||
"name": "postcss-merge-longhand", | ||
"version": "4.0.2", | ||
"version": "4.0.3", | ||
"description": "Merge longhand properties into shorthand with PostCSS.", | ||
@@ -33,2 +33,3 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"css-color-names": "0.0.4", | ||
"postcss": "^6.0.0", | ||
@@ -35,0 +36,0 @@ "postcss-value-parser": "^3.0.0", |
45409
32
1012
4
+ Addedcss-color-names@0.0.4
+ Addedcss-color-names@0.0.4(transitive)
+ Addedelectron-to-chromium@1.4.769(transitive)