From 814e7e93c75c14080b61bdab4f6ac7082155c7c0 Mon Sep 17 00:00:00 2001 From: Otto Date: Fri, 12 Feb 2016 15:53:22 +0100 Subject: [PATCH 1/7] Add failing test for #844 --- js/test/generated/beautify-css-tests.js | 6 ++++++ python/cssbeautifier/tests/generated/tests.py | 6 ++++++ test/data/css/tests.js | 8 +++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/js/test/generated/beautify-css-tests.js b/js/test/generated/beautify-css-tests.js index 158c14f78..470bab426 100644 --- a/js/test/generated/beautify-css-tests.js +++ b/js/test/generated/beautify-css-tests.js @@ -222,6 +222,12 @@ function run_css_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_bea t('.tabs{width:10px;//end of line comment\nheight:10px;//another\n}', '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px; //another\n}'); + reset_options(); + //============================================================ + // Handle LESS properties + t('tag {\n\t@{prop}: none;\n}'); + + reset_options(); //============================================================ // Psuedo-classes vs Variables diff --git a/python/cssbeautifier/tests/generated/tests.py b/python/cssbeautifier/tests/generated/tests.py index 9fdc26069..d82e80cb1 100644 --- a/python/cssbeautifier/tests/generated/tests.py +++ b/python/cssbeautifier/tests/generated/tests.py @@ -185,6 +185,12 @@ def testGenerated(self): t('.tabs{width:10px;//end of line comment\nheight:10px;//another\n}', '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px; //another\n}') + self.reset_options(); + #============================================================ + # Handle LESS properties + t('tag {\n\t@{prop}: none;\n}') + + self.reset_options(); #============================================================ # Psuedo-classes vs Variables diff --git a/test/data/css/tests.js b/test/data/css/tests.js index 1ce2efd15..8d380135a 100644 --- a/test/data/css/tests.js +++ b/test/data/css/tests.js @@ -152,6 +152,12 @@ exports.test_data = { { input: '.tabs{width:10px;//end of line comment\nheight:10px;}', output: '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px;\n}' }, { input: '.tabs{width:10px;//end of line comment\nheight:10px;//another\n}', output: '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px; //another\n}' } ], + }, { + name: "Handle LESS properties", + description: "", + tests: [ + { unchanged: 'tag {\n\t@{prop}: none;\n}' } + ], }, { name: "Psuedo-classes vs Variables", description: "", @@ -182,4 +188,4 @@ exports.test_data = { }, { }] -}; \ No newline at end of file +}; From 020b2aa9d125e3821c7662333f483d5f6ca9a07a Mon Sep 17 00:00:00 2001 From: Otto Date: Fri, 12 Feb 2016 15:55:19 +0100 Subject: [PATCH 2/7] Fix for interpolated Less properties --- python/cssbeautifier/__init__.py | 38 ++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/python/cssbeautifier/__init__.py b/python/cssbeautifier/__init__.py index 0f1d9ad64..9723dcfad 100644 --- a/python/cssbeautifier/__init__.py +++ b/python/cssbeautifier/__init__.py @@ -337,28 +337,32 @@ def beautify(self): printer.newLine() elif self.ch == '@': printer.preserveSingleSpace(isAfterSpace) - printer.push(self.ch) - # strip trailing space, if present, for hash property check - variableOrRule = self.peekString(": ,;{}()[]/='\"") + # deal with less propery mixins @{...} + if self.peek(True) == '{': + printer.push(self.eatString('}')); + else: + printer.push(self.ch) + # strip trailing space, if present, for hash property check + variableOrRule = self.peekString(": ,;{}()[]/='\"") + + if variableOrRule[-1] in ": ": + # wwe have a variable or pseudo-class, add it and insert one space before continuing + self.next() + variableOrRule = self.eatString(": ") + if variableOrRule[-1].isspace(): + variableOrRule = variableOrRule[:-1] + printer.push(variableOrRule) + printer.singleSpace(); - if variableOrRule[-1] in ": ": - # wwe have a variable or pseudo-class, add it and insert one space before continuing - self.next() - variableOrRule = self.eatString(": ") if variableOrRule[-1].isspace(): variableOrRule = variableOrRule[:-1] - printer.push(variableOrRule) - printer.singleSpace(); - - if variableOrRule[-1].isspace(): - variableOrRule = variableOrRule[:-1] - # might be a nesting at-rule - if variableOrRule in self.NESTED_AT_RULE: - printer.nestedLevel += 1 - if variableOrRule in self.CONDITIONAL_GROUP_RULE: - enteringConditionalGroup = True + # might be a nesting at-rule + if variableOrRule in self.NESTED_AT_RULE: + printer.nestedLevel += 1 + if variableOrRule in self.CONDITIONAL_GROUP_RULE: + enteringConditionalGroup = True elif self.ch == '#' and self.peek() == '{': printer.preserveSingleSpace(isAfterSpace) printer.push(self.eatString('}')); From bb0332c93617e9a15215385d4ee4b0a3a5f1e3e7 Mon Sep 17 00:00:00 2001 From: Otto Date: Fri, 12 Feb 2016 17:20:05 +0100 Subject: [PATCH 3/7] Port 'Fix for interpolated Less properties' to JS --- js/lib/beautify-css.js | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/js/lib/beautify-css.js b/js/lib/beautify-css.js index 35b5c51d2..31542e876 100644 --- a/js/lib/beautify-css.js +++ b/js/lib/beautify-css.js @@ -302,26 +302,32 @@ print.newLine(); } else if (ch === '@') { print.preserveSingleSpace(); - output.push(ch); - // strip trailing space, if present, for hash property checks - var variableOrRule = peekString(": ,;{}()[]/='\""); + // deal with less propery mixins @{...} + if (peek() == '{') { + output.push(eatString('}')); + } else { + output.push(ch); - if (variableOrRule.match(/[ :]$/)) { - // we have a variable or pseudo-class, add it and insert one space before continuing - next(); - variableOrRule = eatString(": ").replace(/\s$/, ''); - output.push(variableOrRule); - print.singleSpace(); - } + // strip trailing space, if present, for hash property checks + var variableOrRule = peekString(": ,;{}()[]/='\""); - variableOrRule = variableOrRule.replace(/\s$/, ''); + if (variableOrRule.match(/[ :]$/)) { + // we have a variable or pseudo-class, add it and insert one space before continuing + next(); + variableOrRule = eatString(": ").replace(/\s$/, ''); + output.push(variableOrRule); + print.singleSpace(); + } - // might be a nesting at-rule - if (variableOrRule in css_beautify.NESTED_AT_RULE) { - nestedLevel += 1; - if (variableOrRule in css_beautify.CONDITIONAL_GROUP_RULE) { - enteringConditionalGroup = true; + variableOrRule = variableOrRule.replace(/\s$/, ''); + + // might be a nesting at-rule + if (variableOrRule in css_beautify.NESTED_AT_RULE) { + nestedLevel += 1; + if (variableOrRule in css_beautify.CONDITIONAL_GROUP_RULE) { + enteringConditionalGroup = true; + } } } } else if (ch === '#' && peek() === '{') { @@ -487,4 +493,4 @@ global.css_beautify = css_beautify; } -}()); \ No newline at end of file +}()); From 0ad63f0b57cd502c19ea9fd1605fcbefe58d78ab Mon Sep 17 00:00:00 2001 From: Otto Date: Fri, 12 Feb 2016 17:26:44 +0100 Subject: [PATCH 4/7] Fix failing build, use === for comparison --- js/lib/beautify-css.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/lib/beautify-css.js b/js/lib/beautify-css.js index 31542e876..5bd94461d 100644 --- a/js/lib/beautify-css.js +++ b/js/lib/beautify-css.js @@ -304,7 +304,7 @@ print.preserveSingleSpace(); // deal with less propery mixins @{...} - if (peek() == '{') { + if (peek() === '{') { output.push(eatString('}')); } else { output.push(ch); @@ -493,4 +493,4 @@ global.css_beautify = css_beautify; } -}()); +}()); \ No newline at end of file From d61fe2463c22379b3e47bb17399cc6263c7ba240 Mon Sep 17 00:00:00 2001 From: Otto Date: Sat, 13 Feb 2016 09:35:42 +0100 Subject: [PATCH 5/7] Build succeeds locally but needs newline fix to pass checks --- test/data/css/tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/data/css/tests.js b/test/data/css/tests.js index 8d380135a..ceed9b3f2 100644 --- a/test/data/css/tests.js +++ b/test/data/css/tests.js @@ -188,4 +188,4 @@ exports.test_data = { }, { }] -}; +}; \ No newline at end of file From d4a164ce7034cd106ec3c63812fc95b71a92f6d4 Mon Sep 17 00:00:00 2001 From: Otto Date: Sat, 13 Feb 2016 10:12:36 +0100 Subject: [PATCH 6/7] Assure #631 is also fixed --- js/test/generated/beautify-css-tests.js | 8 +++++++- python/cssbeautifier/tests/generated/tests.py | 8 +++++++- test/data/css/tests.js | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/js/test/generated/beautify-css-tests.js b/js/test/generated/beautify-css-tests.js index 470bab426..7b82b9f0c 100644 --- a/js/test/generated/beautify-css-tests.js +++ b/js/test/generated/beautify-css-tests.js @@ -224,10 +224,16 @@ function run_css_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_bea reset_options(); //============================================================ - // Handle LESS properties + // Handle LESS property name interpolation t('tag {\n\t@{prop}: none;\n}'); + reset_options(); + //============================================================ + // Handle LESS property name interpolation, test #631 + t('.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}'); + + reset_options(); //============================================================ // Psuedo-classes vs Variables diff --git a/python/cssbeautifier/tests/generated/tests.py b/python/cssbeautifier/tests/generated/tests.py index d82e80cb1..0ec8f3f6e 100644 --- a/python/cssbeautifier/tests/generated/tests.py +++ b/python/cssbeautifier/tests/generated/tests.py @@ -187,10 +187,16 @@ def testGenerated(self): self.reset_options(); #============================================================ - # Handle LESS properties + # Handle LESS property name interpolation t('tag {\n\t@{prop}: none;\n}') + self.reset_options(); + #============================================================ + # Handle LESS property name interpolation, test #631 + t('.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}') + + self.reset_options(); #============================================================ # Psuedo-classes vs Variables diff --git a/test/data/css/tests.js b/test/data/css/tests.js index ceed9b3f2..b68a65d8e 100644 --- a/test/data/css/tests.js +++ b/test/data/css/tests.js @@ -153,11 +153,17 @@ exports.test_data = { { input: '.tabs{width:10px;//end of line comment\nheight:10px;//another\n}', output: '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px; //another\n}' } ], }, { - name: "Handle LESS properties", + name: "Handle LESS property name interpolation", description: "", tests: [ { unchanged: 'tag {\n\t@{prop}: none;\n}' } ], + }, { + name: "Handle LESS property name interpolation, test #631", + description: "", + tests: [ + { unchanged: '.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}' } + ], }, { name: "Psuedo-classes vs Variables", description: "", From 02d243c0037bbb45665af14e620c05b5700db919 Mon Sep 17 00:00:00 2001 From: Otto Date: Tue, 16 Feb 2016 20:01:12 +0100 Subject: [PATCH 7/7] Add tests to assure 020b2aa beautifies correctly and not just fixes the less interpolation bug --- js/test/generated/beautify-css-tests.js | 8 ++++++++ python/cssbeautifier/tests/generated/tests.py | 8 ++++++++ test/data/css/tests.js | 16 ++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/js/test/generated/beautify-css-tests.js b/js/test/generated/beautify-css-tests.js index 7b82b9f0c..b7ba6da5d 100644 --- a/js/test/generated/beautify-css-tests.js +++ b/js/test/generated/beautify-css-tests.js @@ -226,12 +226,20 @@ function run_css_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_bea //============================================================ // Handle LESS property name interpolation t('tag {\n\t@{prop}: none;\n}'); + t('tag{@{prop}:none;}', 'tag {\n\t@{prop}: none;\n}'); + t('tag{ @{prop}: none;}', 'tag {\n\t@{prop}: none;\n}'); + + // can also be part of property name + t('tag {\n\tdynamic-@{prop}: none;\n}'); + t('tag{dynamic-@{prop}:none;}', 'tag {\n\tdynamic-@{prop}: none;\n}'); + t('tag{ dynamic-@{prop}: none;}', 'tag {\n\tdynamic-@{prop}: none;\n}'); reset_options(); //============================================================ // Handle LESS property name interpolation, test #631 t('.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}'); + t('.generate-columns(@n,@i:1) when (@i =< @n){.column-@{i}{width:(@i * 100% / @n);}.generate-columns(@n,(@i + 1));}', '.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}'); reset_options(); diff --git a/python/cssbeautifier/tests/generated/tests.py b/python/cssbeautifier/tests/generated/tests.py index 0ec8f3f6e..600ff92f9 100644 --- a/python/cssbeautifier/tests/generated/tests.py +++ b/python/cssbeautifier/tests/generated/tests.py @@ -189,12 +189,20 @@ def testGenerated(self): #============================================================ # Handle LESS property name interpolation t('tag {\n\t@{prop}: none;\n}') + t('tag{@{prop}:none;}', 'tag {\n\t@{prop}: none;\n}') + t('tag{ @{prop}: none;}', 'tag {\n\t@{prop}: none;\n}') + + # can also be part of property name + t('tag {\n\tdynamic-@{prop}: none;\n}') + t('tag{dynamic-@{prop}:none;}', 'tag {\n\tdynamic-@{prop}: none;\n}') + t('tag{ dynamic-@{prop}: none;}', 'tag {\n\tdynamic-@{prop}: none;\n}') self.reset_options(); #============================================================ # Handle LESS property name interpolation, test #631 t('.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}') + t('.generate-columns(@n,@i:1) when (@i =< @n){.column-@{i}{width:(@i * 100% / @n);}.generate-columns(@n,(@i + 1));}', '.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}') self.reset_options(); diff --git a/test/data/css/tests.js b/test/data/css/tests.js index b68a65d8e..c7393980d 100644 --- a/test/data/css/tests.js +++ b/test/data/css/tests.js @@ -156,13 +156,25 @@ exports.test_data = { name: "Handle LESS property name interpolation", description: "", tests: [ - { unchanged: 'tag {\n\t@{prop}: none;\n}' } + { unchanged: 'tag {\n\t@{prop}: none;\n}' }, + { input: 'tag{@{prop}:none;}', output: 'tag {\n\t@{prop}: none;\n}' }, + { input: 'tag{ @{prop}: none;}', output: 'tag {\n\t@{prop}: none;\n}' }, + { + comment: "can also be part of property name", + unchanged: 'tag {\n\tdynamic-@{prop}: none;\n}' + }, + { input: 'tag{dynamic-@{prop}:none;}', output: 'tag {\n\tdynamic-@{prop}: none;\n}' }, + { input: 'tag{ dynamic-@{prop}: none;}', output: 'tag {\n\tdynamic-@{prop}: none;\n}' }, ], }, { name: "Handle LESS property name interpolation, test #631", description: "", tests: [ - { unchanged: '.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}' } + { unchanged: '.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}' }, + { + input: '.generate-columns(@n,@i:1) when (@i =< @n){.column-@{i}{width:(@i * 100% / @n);}.generate-columns(@n,(@i + 1));}', + output: '.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}' + } ], }, { name: "Psuedo-classes vs Variables",