From b7165383430bc8d35a470e348e6342345ca7bcdf Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Wed, 21 May 2014 16:38:31 -0700 Subject: [PATCH] Fix parsing of selectors with commas in functions For example: .foo:matches(.bar, .baz) Thanks to @phosphoer --- History.md | 1 + index.js | 2 +- test/cases/comma-selector-function.css | 12 ++++ test/cases/comma-selector-function.json | 83 +++++++++++++++++++++++++ test/css-parse.js | 3 + 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 test/cases/comma-selector-function.css create mode 100644 test/cases/comma-selector-function.json diff --git a/History.md b/History.md index af6c4f2..4dcb78c 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ HEAD ================== + * allow commas inside selector functions * allow empty property values * changed default `options.position` value to `true` * remove comments from properties and values diff --git a/index.js b/index.js index 9c43241..8ca9806 100644 --- a/index.js +++ b/index.js @@ -196,7 +196,7 @@ module.exports = function(css, options){ .replace(/(?:"[^"]*"|'[^']*')/g, function(m) { return m.replace(/,/g, '\u200C'); }) - .split(/\s*,\s*/) + .split(/\s*(?![^(]*\)),\s*/) .map(function(s) { return s.replace(/\u200C/g, ','); }); diff --git a/test/cases/comma-selector-function.css b/test/cases/comma-selector-function.css new file mode 100644 index 0000000..196f8dc --- /dev/null +++ b/test/cases/comma-selector-function.css @@ -0,0 +1,12 @@ +.foo:matches(.bar,.baz), +.foo:matches(.bar, .baz), +.foo:matches(.bar , .baz), +.foo:matches(.bar ,.baz) { + prop: value; +} + +.foo:matches(.bar,.baz,.foobar), +.foo:matches(.bar, .baz,), +.foo:matches(,.bar , .baz) { + anotherprop: anothervalue; +} diff --git a/test/cases/comma-selector-function.json b/test/cases/comma-selector-function.json new file mode 100644 index 0000000..1c347a0 --- /dev/null +++ b/test/cases/comma-selector-function.json @@ -0,0 +1,83 @@ +{ + "type": "stylesheet", + "stylesheet": { + "rules": [ + { + "type": "rule", + "selectors": [ + ".foo:matches(.bar,.baz)", + ".foo:matches(.bar, .baz)", + ".foo:matches(.bar , .baz)", + ".foo:matches(.bar ,.baz)" + ], + "declarations": [ + { + "type": "declaration", + "property": "prop", + "value": "value", + "position": { + "start": { + "line": 5, + "column": 3 + }, + "end": { + "line": 5, + "column": 14 + }, + "source": "comma-selector-function.css" + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 6, + "column": 2 + }, + "source": "comma-selector-function.css" + } + }, + { + "type": "rule", + "selectors": [ + ".foo:matches(.bar,.baz,.foobar)", + ".foo:matches(.bar, .baz,)", + ".foo:matches(,.bar , .baz)" + ], + "declarations": [ + { + "type": "declaration", + "property": "anotherprop", + "value": "anothervalue", + "position": { + "start": { + "line": 11, + "column": 3 + }, + "end": { + "line": 11, + "column": 28 + }, + "source": "comma-selector-function.css" + } + } + ], + "position": { + "start": { + "line": 8, + "column": 1 + }, + "end": { + "line": 12, + "column": 2 + }, + "source": "comma-selector-function.css" + } + } + ] + } +} + diff --git a/test/css-parse.js b/test/css-parse.js index d166c53..c1fb09b 100644 --- a/test/css-parse.js +++ b/test/css-parse.js @@ -18,6 +18,9 @@ describe('parse(str)', function(){ var css = read(path.join('test', 'cases', file + '.css'), 'utf8'); var json = read(path.join('test', 'cases', file + '.json'), 'utf8'); var ret = parse(css, { source: file + '.css' }); + // normalize line endings from input file + json = JSON.parse(json); + json = JSON.stringify(json, null, 2); ret = JSON.stringify(ret, null, 2); ret.should.equal(json); });