From 363cdb8cb884668e7fdf4a5be2fdf6b3702aec27 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Wed, 19 Feb 2014 07:38:15 +0000 Subject: [PATCH] Fixes #241 - incorrect handling of :not() selectors. Since :not() can have multiple selectors passed in, e.g. :not(div,span), commas need to be handled in a more clever way. --- History.md | 5 +++++ lib/selectors/optimizer.js | 39 ++++++++++++++++++++++++++++++++----- test/data/issue-241-min.css | 2 ++ test/data/issue-241.css | 2 ++ 4 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 test/data/issue-241-min.css create mode 100644 test/data/issue-241.css diff --git a/History.md b/History.md index 0415f48d..5486e308 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +[2.1.1 / 2014-xx-xx (UNRELEASED)](https://github.com/GoalSmashers/clean-css/compare/v2.1.0...v2.1.1) +================== + +* Fixed issue [#241](https://github.com/GoalSmashers/clean-css/issues/241) - incorrect handling of :not() selectors. + [2.1.0 / 2014-02-13](https://github.com/GoalSmashers/clean-css/compare/v2.0.8...v2.1.0) ================== diff --git a/lib/selectors/optimizer.js b/lib/selectors/optimizer.js index df1c867b..6fc38985 100644 --- a/lib/selectors/optimizer.js +++ b/lib/selectors/optimizer.js @@ -14,13 +14,42 @@ module.exports = function Optimizer(data, context, options) { var cleanUpSelector = function(selectors) { var plain = []; - selectors = selectors.split(','); + var cursor = 0; + var lastComma = 0; + var noBrackets = selectors.indexOf('(') == -1; + var withinBrackets = function(idx) { + if (noBrackets) + return false; + + var previousOpening = selectors.lastIndexOf('(', idx); + var previousClosing = selectors.lastIndexOf(')', idx); + + if (previousOpening == -1) + return false; + if (previousClosing > 0 && previousClosing < idx) + return false; + + return true; + }; - for (var i = 0, l = selectors.length; i < l; i++) { - var sel = selectors[i]; + while (true) { + var nextComma = selectors.indexOf(',', cursor + 1); + var selector; - if (plain.indexOf(sel) == -1) - plain.push(sel); + if (nextComma === -1) { + nextComma = selectors.length; + } else if (withinBrackets(nextComma)) { + cursor = nextComma + 1; + continue; + } + selector = selectors.substring(lastComma, nextComma); + lastComma = cursor = nextComma + 1; + + if (plain.indexOf(selector) == -1) + plain.push(selector); + + if (nextComma === selectors.length) + break; } return plain.sort().join(','); diff --git a/test/data/issue-241-min.css b/test/data/issue-241-min.css new file mode 100644 index 00000000..2ca76423 --- /dev/null +++ b/test/data/issue-241-min.css @@ -0,0 +1,2 @@ +.c4:not(.c1,.c2){width:1px} +@media (min-width:1px){.c3{width:1px}} diff --git a/test/data/issue-241.css b/test/data/issue-241.css new file mode 100644 index 00000000..5ac7875d --- /dev/null +++ b/test/data/issue-241.css @@ -0,0 +1,2 @@ +.c4:not(.c1, .c2){width: 1px;} +@media (min-width: 1px) { .c3{width: 1px;} } -- 2.34.1