From f21367fa016ec8d34b400d57e178d175b5d9b9e2 Mon Sep 17 00:00:00 2001 From: Jani Hartikainen Date: Wed, 17 Jun 2015 15:13:33 +0000 Subject: [PATCH 01/10] Add very basic RGB/RGBA color parsing support --- index.js | 10 ++++++++++ test/cases/colors.js | 6 ++++++ 2 files changed, 16 insertions(+) create mode 100644 test/cases/colors.js diff --git a/index.js b/index.js index d3af489..5bf22b7 100644 --- a/index.js +++ b/index.js @@ -92,9 +92,19 @@ Parser.prototype.string = function(){ return this.single() || this.double(); }; +Parser.prototype.color = function(){ + var m = /^(rgba?\([^)]*\)) */.exec(this.str); + if (!m) return m; + this.skip(m); + return { + type: 'color', + value: m[1] + } +}; Parser.prototype.value = function(){ return this.number() + || this.color() || this.ident() || this.string() || this.comma(); diff --git a/test/cases/colors.js b/test/cases/colors.js new file mode 100644 index 0000000..28f690d --- /dev/null +++ b/test/cases/colors.js @@ -0,0 +1,6 @@ +exports.string = 'rgba(1,2,3,4) rgb(9,8,7)'; + +exports.object = [ + { type: 'color', value: 'rgba(1,2,3,4)' }, + { type: 'color', value: 'rgb(9,8,7)' } +]; From 3f79311e88a66a8c253200f618975172e67dc22d Mon Sep 17 00:00:00 2001 From: Jani Hartikainen Date: Sat, 12 Nov 2016 02:58:36 +0200 Subject: [PATCH 02/10] Correctly parse strings with extra spaces in front --- index.js | 3 ++- package.json | 11 +++++++++-- test/cases/space-in-front.js | 5 +++++ test/index.js | 4 +++- 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 test/cases/space-in-front.js diff --git a/index.js b/index.js index 5bf22b7..304c72a 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,8 @@ module.exports = parse; function parse(str) { - return new Parser(str).parse(); + var cleanStr = str.replace(/^\s+|\s+$/, ''); + return new Parser(cleanStr).parse(); } function Parser(str) { diff --git a/package.json b/package.json index 086525a..c893734 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,11 @@ "name": "css-value", "version": "0.0.1", "description": "CSS value parser", - "keywords": ["css", "parser", "value"], + "keywords": [ + "css", + "parser", + "value" + ], "author": "TJ Holowaychuk ", "repository": { "type": "git", @@ -13,5 +17,8 @@ "mocha": "~1.9.0", "should": "~1.2.2" }, - "main": "index" + "main": "index", + "scripts": { + "test": "mocha -r should" + } } diff --git a/test/cases/space-in-front.js b/test/cases/space-in-front.js new file mode 100644 index 0000000..7ba1057 --- /dev/null +++ b/test/cases/space-in-front.js @@ -0,0 +1,5 @@ +exports.string = ' rgba(1,2,3,4)'; + +exports.object = [ + { type: 'color', value: 'rgba(1,2,3,4)' } +] diff --git a/test/index.js b/test/index.js index 77b6776..e38ca14 100644 --- a/test/index.js +++ b/test/index.js @@ -6,7 +6,9 @@ var readdir = fs.readdirSync; var path = require('path'); var basename = path.basename; -readdir('test/cases').forEach(function(file){ +readdir('test/cases') +.filter(function(fn) { return /\.js$/.test(fn); }) +.forEach(function(file){ var mod = require(path.resolve('test/cases/' + file)); var title = basename(file, '.js'); it('should support ' + title, function(){ From 63873d4df56159678fde07711fcff324fd7b3f0d Mon Sep 17 00:00:00 2001 From: Jani Hartikainen Date: Sat, 12 Nov 2016 06:51:42 +0200 Subject: [PATCH 03/10] linear-gradient parsing --- index.js | 56 +++++++++++++++++++++++++++++++++++------ test/cases/gradients.js | 6 +++++ 2 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 test/cases/gradients.js diff --git a/index.js b/index.js index 304c72a..f999ceb 100644 --- a/index.js +++ b/index.js @@ -11,20 +11,20 @@ function Parser(str) { } Parser.prototype.skip = function(m){ - this.str = this.str.slice(m[0].length); + this.str = this.str.slice(m.length); }; Parser.prototype.comma = function(){ var m = /^, */.exec(this.str); if (!m) return; - this.skip(m); + this.skip(m[0]); return { type: 'comma', string: ',' }; }; Parser.prototype.ident = function(){ var m = /^([\w-]+) */.exec(this.str); if (!m) return; - this.skip(m); + this.skip(m[0]); return { type: 'ident', string: m[1] @@ -34,7 +34,7 @@ Parser.prototype.ident = function(){ Parser.prototype.int = function(){ var m = /^((\d+)(\S+)?) */.exec(this.str); if (!m) return; - this.skip(m); + this.skip(m[0]); var n = ~~m[2]; var u = m[3]; @@ -49,7 +49,7 @@ Parser.prototype.int = function(){ Parser.prototype.float = function(){ var m = /^(((?:\d+)?\.\d+)(\S+)?) */.exec(this.str); if (!m) return; - this.skip(m); + this.skip(m[0]); var n = parseFloat(m[2]); var u = m[3]; @@ -68,7 +68,7 @@ Parser.prototype.number = function(){ Parser.prototype.double = function(){ var m = /^"([^"]*)" */.exec(this.str); if (!m) return m; - this.skip(m); + this.skip(m[0]); return { type: 'string', quote: '"', @@ -80,7 +80,7 @@ Parser.prototype.double = function(){ Parser.prototype.single = function(){ var m = /^'([^']*)' */.exec(this.str); if (!m) return m; - this.skip(m); + this.skip(m[0]); return { type: 'string', quote: "'", @@ -96,16 +96,56 @@ Parser.prototype.string = function(){ Parser.prototype.color = function(){ var m = /^(rgba?\([^)]*\)) */.exec(this.str); if (!m) return m; - this.skip(m); + this.skip(m[0]); return { type: 'color', value: m[1] } }; +function readToMatchingParen(str) { + if(str[0] !== '(') { + throw new Error('expected opening paren'); + } + + var opens = 0; + for(var i = 0; i < str.length; i++) { + if(str[i] === '(') { + opens++; + } + else if(str[i] === ')') { + opens--; + } + + if(opens === 0) { + break; + } + } + + if(opens !== 0) { + throw new Error('Failed parsing: No matching paren'); + } + + return str.slice(0, i + 1); +} + +Parser.prototype.gradient = function(){ + var m = /^linear-gradient/.exec(this.str); + if (!m) return m; + this.skip(m[0]); + + var gradientStr = readToMatchingParen(this.str); + this.skip(gradientStr); + return { + type: 'gradient', + value: m[0] + gradientStr + } +}; + Parser.prototype.value = function(){ return this.number() || this.color() + || this.gradient() || this.ident() || this.string() || this.comma(); diff --git a/test/cases/gradients.js b/test/cases/gradients.js new file mode 100644 index 0000000..3d8da89 --- /dev/null +++ b/test/cases/gradients.js @@ -0,0 +1,6 @@ +exports.string = 'linear-gradient(to bottom, rgb(142, 75, 75), rgb(0, 0, 0))'; + +exports.object = [ + { type: 'gradient', value: 'linear-gradient(to bottom, rgb(142, 75, 75), rgb(0, 0, 0))' } +]; + From c07b75a9348ebaf5846cacd3968a4cf57f5a35a1 Mon Sep 17 00:00:00 2001 From: Jani Hartikainen Date: Sat, 12 Nov 2016 07:03:07 +0200 Subject: [PATCH 04/10] Handle extra space between values better --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index f999ceb..b236a8c 100644 --- a/index.js +++ b/index.js @@ -143,6 +143,7 @@ Parser.prototype.gradient = function(){ }; Parser.prototype.value = function(){ + this.str = this.str.replace(/^\s+/, ''); return this.number() || this.color() || this.gradient() From 9b9904f0840f1d827a793aab092af453f0c21974 Mon Sep 17 00:00:00 2001 From: Jani Hartikainen Date: Sat, 12 Nov 2016 07:37:27 +0200 Subject: [PATCH 05/10] url(foo) support --- index.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/index.js b/index.js index b236a8c..c8e0c26 100644 --- a/index.js +++ b/index.js @@ -103,6 +103,16 @@ Parser.prototype.color = function(){ } }; +Parser.prototype.url = function(){ + var m = /^(url\([^)]*\)) */.exec(this.str); + if (!m) return m; + this.skip(m[0]); + return { + type: 'url', + value: m[1] + } +}; + function readToMatchingParen(str) { if(str[0] !== '(') { throw new Error('expected opening paren'); @@ -147,6 +157,7 @@ Parser.prototype.value = function(){ return this.number() || this.color() || this.gradient() + || this.url() || this.ident() || this.string() || this.comma(); From 4d66a9be31869e2da44bb45fe8b7a0adb26b753a Mon Sep 17 00:00:00 2001 From: Jani Hartikainen Date: Sun, 13 Nov 2016 03:51:05 +0200 Subject: [PATCH 06/10] Parse / operator (used with background position/size) --- index.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index c8e0c26..acf5dea 100644 --- a/index.js +++ b/index.js @@ -21,6 +21,13 @@ Parser.prototype.comma = function(){ return { type: 'comma', string: ',' }; }; +Parser.prototype.operator = function(){ + var m = /^\/ */.exec(this.str); + if (!m) return; + this.skip(m[0]); + return { type: 'operator', value: '/' }; +}; + Parser.prototype.ident = function(){ var m = /^([\w-]+) */.exec(this.str); if (!m) return; @@ -32,7 +39,7 @@ Parser.prototype.ident = function(){ }; Parser.prototype.int = function(){ - var m = /^((\d+)(\S+)?) */.exec(this.str); + var m = /^((\d+)([^\s\/]+)?) */.exec(this.str); if (!m) return; this.skip(m[0]); var n = ~~m[2]; @@ -47,7 +54,7 @@ Parser.prototype.int = function(){ }; Parser.prototype.float = function(){ - var m = /^(((?:\d+)?\.\d+)(\S+)?) */.exec(this.str); + var m = /^(((?:\d+)?\.\d+)([^\s\/]+)?) */.exec(this.str); if (!m) return; this.skip(m[0]); var n = parseFloat(m[2]); @@ -154,7 +161,8 @@ Parser.prototype.gradient = function(){ Parser.prototype.value = function(){ this.str = this.str.replace(/^\s+/, ''); - return this.number() + return this.operator() + || this.number() || this.color() || this.gradient() || this.url() From de45a02e1820f18310499416cbc5681b03a9c940 Mon Sep 17 00:00:00 2001 From: Jani Hartikainen Date: Sun, 13 Nov 2016 03:51:40 +0200 Subject: [PATCH 07/10] Missing tests --- test/cases/operators.js | 12 ++++++++++++ test/cases/urls.js | 6 ++++++ 2 files changed, 18 insertions(+) create mode 100644 test/cases/operators.js create mode 100644 test/cases/urls.js diff --git a/test/cases/operators.js b/test/cases/operators.js new file mode 100644 index 0000000..cc4d113 --- /dev/null +++ b/test/cases/operators.js @@ -0,0 +1,12 @@ +exports.string = '50px/50% auto/auto'; + +exports.object = [ + { type: 'number', string: '50px', unit: 'px', value: 50 }, + { type: 'operator', value: '/' }, + { type: 'number', string: '50%', unit: '%', value: 50 }, + { type: 'ident', string: 'auto' }, + { type: 'operator', value: '/' }, + { type: 'ident', string: 'auto' } +]; + + diff --git a/test/cases/urls.js b/test/cases/urls.js new file mode 100644 index 0000000..d2403e1 --- /dev/null +++ b/test/cases/urls.js @@ -0,0 +1,6 @@ +exports.string = 'url(http://foo.bar.com/whatever.png)'; + +exports.object = [ + { type: 'url', value: 'url(http://foo.bar.com/whatever.png)' } +]; + From 37fa58c6fc03b7761748aad1739f687f9498e423 Mon Sep 17 00:00:00 2001 From: ginpei Date: Tue, 24 Apr 2018 10:47:32 -0700 Subject: [PATCH 08/10] support negative numbers --- index.js | 4 ++-- test/cases/numbers.js | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index acf5dea..0c3f7c3 100644 --- a/index.js +++ b/index.js @@ -39,7 +39,7 @@ Parser.prototype.ident = function(){ }; Parser.prototype.int = function(){ - var m = /^((\d+)([^\s\/]+)?) */.exec(this.str); + var m = /^((-?\d+)([^\s\/]+)?) */.exec(this.str); if (!m) return; this.skip(m[0]); var n = ~~m[2]; @@ -54,7 +54,7 @@ Parser.prototype.int = function(){ }; Parser.prototype.float = function(){ - var m = /^(((?:\d+)?\.\d+)([^\s\/]+)?) */.exec(this.str); + var m = /^((-?(?:\d+)?\.\d+)([^\s\/]+)?) */.exec(this.str); if (!m) return; this.skip(m[0]); var n = parseFloat(m[2]); diff --git a/test/cases/numbers.js b/test/cases/numbers.js index 353aac9..2408d00 100644 --- a/test/cases/numbers.js +++ b/test/cases/numbers.js @@ -1,5 +1,5 @@ -exports.string = '1px 0 0 5% .5px .10 1.5'; +exports.string = '1px 0 0 5% .5px .10 1.5 -1 -0.1'; exports.object = [ { type: 'number', string: '1px', unit: 'px', value: 1 }, @@ -8,5 +8,7 @@ exports.object = [ { type: 'number', string: '5%', unit: '%', value: 5 }, { type: 'number', string: '.5px', unit: 'px', value: .5 }, { type: 'number', string: '.10', unit: '', value: .1 }, - { type: 'number', string: '1.5', unit: '', value: 1.5 } + { type: 'number', string: '1.5', unit: '', value: 1.5 }, + { type: 'number', string: '-1', unit: '', value: -1 }, + { type: 'number', string: '-0.1', unit: '', value: -0.1 } ]; From c8fa97683162c64dd6b3dacc51da2debce851cad Mon Sep 17 00:00:00 2001 From: Primoz Z Date: Thu, 17 Jan 2019 13:36:58 +0100 Subject: [PATCH 09/10] Support radial gradient --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 0c3f7c3..1545ad4 100644 --- a/index.js +++ b/index.js @@ -147,7 +147,7 @@ function readToMatchingParen(str) { } Parser.prototype.gradient = function(){ - var m = /^linear-gradient/.exec(this.str); + var m = /^(radial|linear)-gradient/.exec(this.str); if (!m) return m; this.skip(m[0]); From 41d350e018180be34067cf2bc8690cb328a98d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Primo=C5=BE?= Date: Mon, 21 Jan 2019 14:00:32 +0100 Subject: [PATCH 10/10] Update version to 0.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c893734..7dc6607 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "css-value", - "version": "0.0.1", + "version": "0.0.2", "description": "CSS value parser", "keywords": [ "css",