From dbb8d0277518fbafc2f09e574f4774c33c8f4d75 Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Sat, 6 Sep 2014 17:24:00 +0200 Subject: [PATCH] Parse rgb/rgba colors --- gradient-parser.js | 87 ++++++++++++++++++++++++------------ spec/gradient-parser.spec.js | 6 ++- 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/gradient-parser.js b/gradient-parser.js index b0ea32a..ccc2104 100644 --- a/gradient-parser.js +++ b/gradient-parser.js @@ -34,7 +34,10 @@ module.exports = (function() { endCall: /^\)/, comma: /^,/, hexColor: /^\#([0-9a-fA-F]+)/, - literalColor: /^([a-zA-Z]+)/ + literalColor: /^([a-zA-Z]+)/, + rgbColor: /^rgb/i, + rgbaColor: /^rgba/i, + number: /^(([0-9]*\.[0-9]+)|([0-9]+\.?))/ }; var input = '', @@ -85,6 +88,24 @@ module.exports = (function() { } function matchGradient(gradientType, pattern, orientationMatcher) { + return matchCall(pattern, function(captures) { + orientation = orientationMatcher(); + if (orientation) { + if (!scan(tokens.comma)) { + error('Missing comma before color stops'); + } + } + + colorStops = matchListing(matchColorStop); + return { + type: gradientType, + orientation: orientation, + colorStops: colorStops + }; + }); + } + + function matchCall(pattern, callback) { var captures = scan(pattern), orientation, colorStops; @@ -94,27 +115,13 @@ module.exports = (function() { error('Missing ('); } - orientation = orientationMatcher(); - if (orientation) { - if (!scan(tokens.comma)) { - error('Missing comma before color stops'); - } - } - - colorStops = matchColorStops(); - if (!colorStops.length) { - error('Missing color definitions'); - } + result = callback(captures); if (!scan(tokens.endCall)) { error('Missing )'); } - return { - type: gradientType, - orientation: orientation, - colorStops: colorStops - }; + return result; } } @@ -143,23 +150,23 @@ module.exports = (function() { } } - function matchColorStops() { - var color = matchColorStop(), - colors = []; + function matchListing(matcher) { + var captures = matcher(), + result = []; - if (color) { - colors.push(color); + if (captures) { + result.push(captures); while (scan(tokens.comma)) { - color = matchColorStop(); - if (color) { - colors.push(color); + captures = matcher(); + if (captures) { + result.push(captures); } else { error('One extra comma'); } } } - return colors; + return result; } function matchColorStop() { @@ -174,8 +181,10 @@ module.exports = (function() { } function matchColor() { - return matchLiteralColor() || - matchHexColor(); + return matchHexColor() || + matchRGBAColor() || + matchRGBColor() || + matchLiteralColor(); } function matchLiteralColor() { @@ -200,6 +209,28 @@ module.exports = (function() { } } + function matchRGBColor() { + return matchCall(tokens.rgbColor, function() { + return { + type: 'rgb', + value: matchListing(matchNumber) + }; + }); + } + + function matchRGBAColor() { + return matchCall(tokens.rgbaColor, function() { + return { + type: 'rgba', + value: matchListing(matchNumber) + }; + }); + } + + function matchNumber() { + return scan(tokens.number)[1]; + } + function matchLength() { return matchMetric(tokens.pixelValue, 'px') || matchMetric(tokens.percentageValue, '%') || diff --git a/spec/gradient-parser.spec.js b/spec/gradient-parser.spec.js index aa9ea69..cd8fd72 100644 --- a/spec/gradient-parser.spec.js +++ b/spec/gradient-parser.spec.js @@ -171,7 +171,9 @@ describe('gradient-parser.js', function () { [ {type: 'literal', unparsedValue: 'red', value: 'red'}, - {type: 'hex', unparsedValue: '#c2c2c2', value: 'c2c2c2'} + {type: 'hex', unparsedValue: '#c2c2c2', value: 'c2c2c2'}, + {type: 'rgb', unparsedValue: 'rgb(243, 226, 195)', value: ['243', '226', '195']}, + {type: 'rgba', unparsedValue: 'rgba(243, 226, 195)', value: ['243', '226', '195']} ].forEach(function(color) { describe('parse color type '+ color.type, function() { beforeEach(function() { @@ -181,7 +183,7 @@ describe('gradient-parser.js', function () { it('should parse value', function() { expect(subject.type).to.equal(color.type); - expect(subject.value).to.equal(color.value); + expect(subject.value).to.eql(color.value); }); }); });