diff --git a/.csscomb.json b/.csscomb.json index ebdee3be..d9a54687 100644 --- a/.csscomb.json +++ b/.csscomb.json @@ -9,6 +9,7 @@ "block-indent": true, "stick-brace": "\n", "strip-spaces": true, + "unitless-zero": true, "always-semicolon": true, "sort-order": [ [ diff --git a/README.md b/README.md index 88b2432d..c019d7e1 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Example configuration: "block-indent": true, "stick-brace": true, "strip-spaces": true, + "unitless-zero": true, "always-semicolon": true } ``` diff --git a/lib/csscomb.js b/lib/csscomb.js index 6b75a25a..dbdbe08b 100644 --- a/lib/csscomb.js +++ b/lib/csscomb.js @@ -18,6 +18,7 @@ var Comb = function() { 'colon-space', 'rule-indent', 'block-indent', + 'unitless-zero', 'sort-order' ]; this._config = {}; diff --git a/lib/options/unitless-zero.js b/lib/options/unitless-zero.js new file mode 100644 index 00000000..0e450b33 --- /dev/null +++ b/lib/options/unitless-zero.js @@ -0,0 +1,34 @@ +module.exports = { + + /** + * Sets handler value. + * + * @param {Boolean} value Option value + * @returns {Object} + */ + setValue: function(value) { + if (value === true) { + this._value = value; + return this; + } + }, + + /** + * Processes tree node. + * @param {String} nodeType + * @param {node} node + */ + process: function(nodeType, node) { + if (nodeType === 'value' || nodeType === 'braces') { + node.forEach(function(child, index) { + if ( + (child[0] === 'percentage' || + child[0] === 'dimension' && ['cm', 'em', 'ex', 'pt', 'px'].indexOf(child[2][1]) !== -1) && + child[1][1] === '0') { + node[index] = child[1]; + } + }); + } + } + +}; diff --git a/test/integral.expect.css b/test/integral.expect.css index 17c4c646..7eb53c5f 100644 --- a/test/integral.expect.css +++ b/test/integral.expect.css @@ -1,5 +1,5 @@ /* foobar */ -@media all and (min-width:0px) +@media all and (min-width:0) { /* :before — бордер */ .radio-button_theme_normal .radio-button__radio:before @@ -50,7 +50,7 @@ div p em border-bottom: 1px solid red; } -@media all and (min-width:0px) +@media all and (min-width:0) { /* В нажатом состоянии смещается вниз на 1px вся кнопка, текст не смещается */ .button_pressed_yes.button_shadow_yes diff --git a/test/integral.origin.css b/test/integral.origin.css index 209830fa..bbd8f845 100644 --- a/test/integral.origin.css +++ b/test/integral.origin.css @@ -26,8 +26,8 @@ /* _focused_yes */ .radio-button_theme_normal .radio-button__radio_focused_yes:before { - -moz-box-shadow: 0 0 6px 2px rgba(255,204,0,.7), 0 1px 0 rgba(0,0,0,.07); - box-shadow: 0 0 6px 2px rgba(255,204,0,.7), 0 1px 0 rgba(0,0,0,.07); + -moz-box-shadow: 0 0 6px 2px rgba(255,204,0,.7), 0px 1px 0px rgba(0,0,0,.07); + box-shadow: 0 0 6px 2px rgba(255,204,0,.7), 0px 1px 0px rgba(0,0,0,.07); } } diff --git a/test/unitless-zero.js b/test/unitless-zero.js new file mode 100644 index 00000000..6e6b2b9e --- /dev/null +++ b/test/unitless-zero.js @@ -0,0 +1,45 @@ +var Comb = require('../lib/csscomb'); +var assert = require('assert'); + +describe('options/unitless-zero', function() { + var comb; + + beforeEach(function() { + comb = new Comb(); + }); + + it('Should remove units in zero-valued dimensions', function() { + comb.configure({ 'unitless-zero': true }); + assert.equal( + comb.processString( + 'div { margin: 0em; padding: 0px }' + ), + 'div { margin: 0; padding: 0 }' + ); + assert.equal( + comb.processString( + 'div { margin: 0% }' + ), + 'div { margin: 0 }' + ); + }); + + it('Should remove units in zero-valued media-query params', function() { + comb.configure({ 'unitless-zero': true }); + assert.equal( + comb.processString('@media all and (min-width: 0px) { div { margin: 0em; padding: 0px } }'), + '@media all and (min-width: 0) { div { margin: 0; padding: 0 } }' + ); + }); + + it('Should not remove units (degs) in rotate property', function() { + comb.configure({ 'unitless-zero': true }); + assert.equal( + comb.processString( + 'div { -webkit-transform: rotate(0deg); }' + ), + 'div { -webkit-transform: rotate(0deg); }' + ); + }); + +});