Compare commits

..

19 commits

Author SHA1 Message Date
92b6e8011e
Merge pull request #15 from itaigilo-inv/support-more-directions
Support more directions
2021-07-21 15:34:54 +02:00
Itai Gilo
a3494b3421 Add tests 2021-07-20 15:45:38 +03:00
Itai Gilo
330ffa92cd Support more directions 2021-07-20 15:35:29 +03:00
cce801d1df
Bump version 1.0.2 2021-03-15 14:53:53 +01:00
eff630c873
Fix declaration of result 2021-03-15 14:52:59 +01:00
c4ba2836b6
Tag version 1.0.1 2021-02-20 13:51:29 +01:00
015088b929
Merge pull request #12 from pixelspark/master
Fix issue "undefined variable result" in built scripts as well
2021-02-20 13:45:33 +01:00
Tommy van der Vorst
4bfe95a98f Fix issue "undefined variable result" in built scripts as well 2021-02-01 11:21:42 +01:00
04708dcb45
Bump version to 1.0.0 2021-01-20 13:46:46 +01:00
2720da021f
Merge pull request #11 from ilyalesik/define-result
Define result variable
2021-01-19 17:13:26 +01:00
Ilia Lesik
12648a2a28 Define result variable 2019-12-25 16:05:34 +03:00
4b49f43244 Merge pull request #5 from rafaelcaricio/fixes-4
Fails when radial-gradient shape is omitted but a size is provided
2016-01-10 13:26:56 +01:00
Rafael Caricio
d0e6c24616 Fails when radial-gradient shape is omitted but a size is provided 2016-01-10 13:25:58 +01:00
Rafael Caricio
ac093b15b3 Bump version 0.2.0 2014-10-01 19:31:42 +02:00
Rafael Caricio
3559c23b44 Stringify 2014-09-20 11:37:41 +02:00
Rafael Caricio
37e8f70262 Stringify 2014-09-19 19:40:56 +02:00
Rafael Caricio
129101533e Stringify 2014-09-19 19:40:56 +02:00
Rafael Caricio
75e01de8e4 Match correctly numbers 2014-09-19 19:36:32 +02:00
Rafael Caricio
77a461fc4d Fix bower 2014-09-19 19:36:32 +02:00
13 changed files with 11681 additions and 42 deletions

View file

@ -1,2 +1,5 @@
all:
python -m SimpleHTTPServer 3000
test:
grunt

View file

@ -1,6 +1,6 @@
{
"name": "gradient-parser",
"version": "0.1.5",
"version": "1.0.0",
"main": "build/web.js",
"ignore": [
".editorconfig",
@ -10,14 +10,12 @@
".npmignore",
".travis.yml",
".umd",
"gulpfile.js",
"npm-shrinkwrap.json",
"package.json",
"index.html",
"Makefile",
"build/node.js",
"README.md",
"gruntfile.js",
"*.js",
"lib/*",
"spec/*",
"LICENSE"

View file

@ -2,7 +2,174 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var GradientParser = {};
var GradientParser = (GradientParser || {});
GradientParser.stringify = (function() {
var visitor = {
'visit_linear-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_repeating-linear-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_radial-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_repeating-radial-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_gradient': function(node) {
var orientation = visitor.visit(node.orientation);
if (orientation) {
orientation += ', ';
}
return node.type + '(' + orientation + visitor.visit(node.colorStops) + ')';
},
'visit_shape': function(node) {
var result = node.value,
at = visitor.visit(node.at),
style = visitor.visit(node.style);
if (style) {
result += ' ' + style;
}
if (at) {
result += ' at ' + at;
}
return result;
},
'visit_default-radial': function(node) {
var result = '',
at = visitor.visit(node.at);
if (at) {
result += at;
}
return result;
},
'visit_extent-keyword': function(node) {
var result = node.value,
at = visitor.visit(node.at);
if (at) {
result += ' at ' + at;
}
return result;
},
'visit_position-keyword': function(node) {
return node.value;
},
'visit_position': function(node) {
return visitor.visit(node.value.x) + ' ' + visitor.visit(node.value.y);
},
'visit_%': function(node) {
return node.value + '%';
},
'visit_em': function(node) {
return node.value + 'em';
},
'visit_px': function(node) {
return node.value + 'px';
},
'visit_literal': function(node) {
return visitor.visit_color(node.value, node);
},
'visit_hex': function(node) {
return visitor.visit_color('#' + node.value, node);
},
'visit_rgb': function(node) {
return visitor.visit_color('rgb(' + node.value.join(', ') + ')', node);
},
'visit_rgba': function(node) {
return visitor.visit_color('rgba(' + node.value.join(', ') + ')', node);
},
'visit_color': function(resultColor, node) {
var result = resultColor,
length = visitor.visit(node.length);
if (length) {
result += ' ' + length;
}
return result;
},
'visit_angular': function(node) {
return node.value + 'deg';
},
'visit_directional': function(node) {
return 'to ' + node.value;
},
'visit_array': function(elements) {
var result = '',
size = elements.length;
elements.forEach(function(element, i) {
result += visitor.visit(element);
if (i < size - 1) {
result += ', ';
}
});
return result;
},
'visit': function(element) {
if (!element) {
return '';
}
var result = '';
if (element instanceof Array) {
return visitor.visit_array(element, result);
} else if (element.type) {
var nodeVisitor = visitor['visit_' + element.type];
if (nodeVisitor) {
return nodeVisitor(element);
} else {
throw Error('Missing visitor visit_' + element.type);
}
} else {
throw Error('Invalid node.');
}
}
};
return function(root) {
return visitor.visit(root);
};
})();
// Copyright (c) 2014 Rafael Caricio. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var GradientParser = (GradientParser || {});
GradientParser.parse = (function() {
@ -98,7 +265,7 @@ GradientParser.parse = (function() {
error('Missing (');
}
result = callback(captures);
var result = callback(captures);
if (!scan(tokens.endCall)) {
error('Missing )');
@ -151,12 +318,21 @@ GradientParser.parse = (function() {
if (radialType) {
radialType.at = matchAtPosition();
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default-radial',
at: defaultPosition
};
var extent = matchExtentKeyword();
if (extent) {
radialType = extent;
var positionAt = matchAtPosition();
if (positionAt) {
radialType.at = positionAt;
}
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default-radial',
at: defaultPosition
};
}
}
}
@ -336,4 +512,5 @@ GradientParser.parse = (function() {
};
})();
exports.parse = (GradientParser || {}).parse;
exports.parse = GradientParser.parse;
exports.stringify = GradientParser.stringify;

View file

@ -1,8 +1,10 @@
var GradientParser = (window.GradientParser || {});
// Copyright (c) 2014 Rafael Caricio. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var GradientParser = {};
var GradientParser = (GradientParser || {});
GradientParser.parse = (function() {
@ -98,7 +100,7 @@ GradientParser.parse = (function() {
error('Missing (');
}
result = callback(captures);
var result = callback(captures);
if (!scan(tokens.endCall)) {
error('Missing )');
@ -151,12 +153,21 @@ GradientParser.parse = (function() {
if (radialType) {
radialType.at = matchAtPosition();
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default-radial',
at: defaultPosition
};
var extent = matchExtentKeyword();
if (extent) {
radialType = extent;
var positionAt = matchAtPosition();
if (positionAt) {
radialType.at = positionAt;
}
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default-radial',
at: defaultPosition
};
}
}
}
@ -335,3 +346,170 @@ GradientParser.parse = (function() {
return getAST();
};
})();
// Copyright (c) 2014 Rafael Caricio. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var GradientParser = (GradientParser || {});
GradientParser.stringify = (function() {
var visitor = {
'visit_linear-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_repeating-linear-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_radial-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_repeating-radial-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_gradient': function(node) {
var orientation = visitor.visit(node.orientation);
if (orientation) {
orientation += ', ';
}
return node.type + '(' + orientation + visitor.visit(node.colorStops) + ')';
},
'visit_shape': function(node) {
var result = node.value,
at = visitor.visit(node.at),
style = visitor.visit(node.style);
if (style) {
result += ' ' + style;
}
if (at) {
result += ' at ' + at;
}
return result;
},
'visit_default-radial': function(node) {
var result = '',
at = visitor.visit(node.at);
if (at) {
result += at;
}
return result;
},
'visit_extent-keyword': function(node) {
var result = node.value,
at = visitor.visit(node.at);
if (at) {
result += ' at ' + at;
}
return result;
},
'visit_position-keyword': function(node) {
return node.value;
},
'visit_position': function(node) {
return visitor.visit(node.value.x) + ' ' + visitor.visit(node.value.y);
},
'visit_%': function(node) {
return node.value + '%';
},
'visit_em': function(node) {
return node.value + 'em';
},
'visit_px': function(node) {
return node.value + 'px';
},
'visit_literal': function(node) {
return visitor.visit_color(node.value, node);
},
'visit_hex': function(node) {
return visitor.visit_color('#' + node.value, node);
},
'visit_rgb': function(node) {
return visitor.visit_color('rgb(' + node.value.join(', ') + ')', node);
},
'visit_rgba': function(node) {
return visitor.visit_color('rgba(' + node.value.join(', ') + ')', node);
},
'visit_color': function(resultColor, node) {
var result = resultColor,
length = visitor.visit(node.length);
if (length) {
result += ' ' + length;
}
return result;
},
'visit_angular': function(node) {
return node.value + 'deg';
},
'visit_directional': function(node) {
return 'to ' + node.value;
},
'visit_array': function(elements) {
var result = '',
size = elements.length;
elements.forEach(function(element, i) {
result += visitor.visit(element);
if (i < size - 1) {
result += ', ';
}
});
return result;
},
'visit': function(element) {
if (!element) {
return '';
}
var result = '';
if (element instanceof Array) {
return visitor.visit_array(element, result);
} else if (element.type) {
var nodeVisitor = visitor['visit_' + element.type];
if (nodeVisitor) {
return nodeVisitor(element);
} else {
throw Error('Missing visitor visit_' + element.type);
}
} else {
throw Error('Invalid node.');
}
}
};
return function(root) {
return visitor.visit(root);
};
})();

View file

@ -19,8 +19,8 @@ module.exports = function (grunt) {
concat: {
release: {
files: {
'build/node.js': ['lib/parser.js', 'index.js'],
'build/web.js': ['lib/parser.js']
'build/node.js': ['lib/stringify.js', 'lib/parser.js', 'index.js'],
'build/web.js': ['webify.js', 'lib/parser.js', 'lib/stringify.js']
}
}
}

View file

@ -1 +1,2 @@
exports.parse = (GradientParser || {}).parse;
exports.parse = GradientParser.parse;
exports.stringify = GradientParser.stringify;

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var GradientParser = {};
var GradientParser = (GradientParser || {});
GradientParser.parse = (function() {
@ -11,7 +11,7 @@ GradientParser.parse = (function() {
repeatingLinearGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-linear\-gradient)/i,
radialGradient: /^(\-(webkit|o|ms|moz)\-)?(radial\-gradient)/i,
repeatingRadialGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-radial\-gradient)/i,
sideOrCorner: /^to (left (top|bottom)|right (top|bottom)|left|right|top|bottom)/i,
sideOrCorner: /^to (left (top|bottom)|right (top|bottom)|top (left|right)|bottom (left|right)|left|right|top|bottom)/i,
extentKeywords: /^(closest\-side|closest\-corner|farthest\-side|farthest\-corner|contain|cover)/,
positionKeywords: /^(left|center|right|top|bottom)/i,
pixelValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))px/,
@ -98,7 +98,7 @@ GradientParser.parse = (function() {
error('Missing (');
}
result = callback(captures);
var result = callback(captures);
if (!scan(tokens.endCall)) {
error('Missing )');
@ -151,12 +151,21 @@ GradientParser.parse = (function() {
if (radialType) {
radialType.at = matchAtPosition();
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default-radial',
at: defaultPosition
};
var extent = matchExtentKeyword();
if (extent) {
radialType = extent;
var positionAt = matchAtPosition();
if (positionAt) {
radialType.at = positionAt;
}
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default-radial',
at: defaultPosition
};
}
}
}

166
lib/stringify.js Normal file
View file

@ -0,0 +1,166 @@
// Copyright (c) 2014 Rafael Caricio. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var GradientParser = (GradientParser || {});
GradientParser.stringify = (function() {
var visitor = {
'visit_linear-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_repeating-linear-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_radial-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_repeating-radial-gradient': function(node) {
return visitor.visit_gradient(node);
},
'visit_gradient': function(node) {
var orientation = visitor.visit(node.orientation);
if (orientation) {
orientation += ', ';
}
return node.type + '(' + orientation + visitor.visit(node.colorStops) + ')';
},
'visit_shape': function(node) {
var result = node.value,
at = visitor.visit(node.at),
style = visitor.visit(node.style);
if (style) {
result += ' ' + style;
}
if (at) {
result += ' at ' + at;
}
return result;
},
'visit_default-radial': function(node) {
var result = '',
at = visitor.visit(node.at);
if (at) {
result += at;
}
return result;
},
'visit_extent-keyword': function(node) {
var result = node.value,
at = visitor.visit(node.at);
if (at) {
result += ' at ' + at;
}
return result;
},
'visit_position-keyword': function(node) {
return node.value;
},
'visit_position': function(node) {
return visitor.visit(node.value.x) + ' ' + visitor.visit(node.value.y);
},
'visit_%': function(node) {
return node.value + '%';
},
'visit_em': function(node) {
return node.value + 'em';
},
'visit_px': function(node) {
return node.value + 'px';
},
'visit_literal': function(node) {
return visitor.visit_color(node.value, node);
},
'visit_hex': function(node) {
return visitor.visit_color('#' + node.value, node);
},
'visit_rgb': function(node) {
return visitor.visit_color('rgb(' + node.value.join(', ') + ')', node);
},
'visit_rgba': function(node) {
return visitor.visit_color('rgba(' + node.value.join(', ') + ')', node);
},
'visit_color': function(resultColor, node) {
var result = resultColor,
length = visitor.visit(node.length);
if (length) {
result += ' ' + length;
}
return result;
},
'visit_angular': function(node) {
return node.value + 'deg';
},
'visit_directional': function(node) {
return 'to ' + node.value;
},
'visit_array': function(elements) {
var result = '',
size = elements.length;
elements.forEach(function(element, i) {
result += visitor.visit(element);
if (i < size - 1) {
result += ', ';
}
});
return result;
},
'visit': function(element) {
if (!element) {
return '';
}
var result = '';
if (element instanceof Array) {
return visitor.visit_array(element, result);
} else if (element.type) {
var nodeVisitor = visitor['visit_' + element.type];
if (nodeVisitor) {
return nodeVisitor(element);
} else {
throw Error('Missing visitor visit_' + element.type);
}
} else {
throw Error('Invalid node.');
}
}
};
return function(root) {
return visitor.visit(root);
};
})();

10999
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{
"name": "gradient-parser",
"version": "0.1.5",
"version": "1.0.2",
"description": "Parse CSS3 gradient definitions and return an AST.",
"author": {
"name": "Rafael Carcicio",
@ -32,8 +32,8 @@
"css3",
"parser"
],
"dependencies": {},
"devDependencies": {
"expect.js": "*",
"grunt": "*",
"grunt-browserify": "^3.0.1",
"grunt-complexity": "*",

View file

@ -1,10 +1,10 @@
'use strict';
var expect = require('expect.js');
var gradients = require('build/node');
var gradients = require('../build/node');
describe('gradient-parser.js', function () {
describe('lib/parser.js', function () {
var ast,
subject;
@ -113,7 +113,7 @@ describe('gradient-parser.js', function () {
].forEach(function(metric) {
describe('parse color stop for metric '+ metric, function() {
beforeEach(function() {
ast = gradients.parse('linear-gradient(blue 10' + metric + ', transparent)');
ast = gradients.parse('linear-gradient(blue 10.3' + metric + ', transparent)');
subject = ast[0];
});
@ -124,7 +124,7 @@ describe('gradient-parser.js', function () {
it('should have the length', function() {
expect(subject.length.type).to.equal(metric);
expect(subject.length.value).to.equal('10');
expect(subject.length.value).to.equal('10.3');
});
});
});
@ -133,8 +133,12 @@ describe('gradient-parser.js', function () {
describe('parse all linear directional', function() {
[
{type: 'angular', unparsedValue: '145deg', value: '145'},
{type: 'directional', unparsedValue: 'to left top', value: 'left top'}
{type: 'angular', unparsedValue: '-145deg', value: '-145'},
{type: 'directional', unparsedValue: 'to left top', value: 'left top'},
{type: 'directional', unparsedValue: 'to top left', value: 'top left'},
{type: 'directional', unparsedValue: 'to top right', value: 'top right'},
{type: 'directional', unparsedValue: 'to bottom left', value: 'bottom left'},
{type: 'directional', unparsedValue: 'to bottom right', value: 'bottom right'}
].forEach(function(orientation) {
describe('parse orientation ' + orientation.type, function() {
beforeEach(function() {
@ -197,7 +201,10 @@ describe('gradient-parser.js', function () {
'ellipse cover',
'circle cover',
'center bottom, ellipse cover',
'circle at 87.23px -58.3px'
'circle at 87.23px -58.3px',
'farthest-side, red, blue',
'farthest-corner, red, blue',
'farthest-corner at 87.23px -58.3px, red, blue'
].forEach(function(declaration) {
it('should parse ' + declaration + ' declaration', function() {

100
spec/stringify.spec.js Normal file
View file

@ -0,0 +1,100 @@
'use strict';
var expect = require('expect.js');
var gradients = require('../build/node');
function pprint(ast) {
console.log(JSON.stringify(ast, true, 2));
}
describe('lib/stringify.js', function () {
var subject;
it('should exist', function () {
expect(typeof gradients.stringify).to.equal('function');
});
describe('serialization', function() {
it('if tree is null', function() {
expect(gradients.stringify(null)).to.equal('');
});
it('should serialize a simple gradient', function() {
var gradientDef = 'linear-gradient(black, white)';
expect(gradients.stringify(gradients.parse(gradientDef))).to.equal(gradientDef);
});
it('should serialize gradient with hex', function() {
var gradientDef = 'linear-gradient(#fff, white)';
expect(gradients.stringify(gradients.parse(gradientDef))).to.equal(gradientDef);
});
it('should serialize gradient with rgb', function() {
var gradientDef = 'linear-gradient(rgb(1, 2, 3), white)';
expect(gradients.stringify(gradients.parse(gradientDef))).to.equal(gradientDef);
});
it('should serialize gradient with rgba', function() {
var gradientDef = 'linear-gradient(rgba(1, 2, 3, .0), white)';
expect(gradients.stringify(gradients.parse(gradientDef))).to.equal(gradientDef);
});
it('should serialize gradient with deg', function() {
var gradientDef = 'linear-gradient(45deg, #fff, transparent)';
expect(gradients.stringify(gradients.parse(gradientDef))).to.equal(gradientDef);
});
it('should serialize gradient with directional', function() {
var gradientDef = 'linear-gradient(to left, #fff, transparent)';
expect(gradients.stringify(gradients.parse(gradientDef))).to.equal(gradientDef);
});
describe('all metric values', function() {
[
'px',
'em',
'%'
].forEach(function(metric) {
var expectedResult;
describe('stringify color stop for metric '+ metric, function() {
beforeEach(function() {
expectedResult = 'linear-gradient(blue 10.3' + metric + ', transparent)';
var ast = gradients.parse(expectedResult);
subject = gradients.stringify(ast);
});
it('should result as expected', function() {
expect(subject).to.equal(expectedResult);
});
});
});
});
describe('different radial declarations', function() {
[
'ellipse farthest-corner',
'ellipse cover',
'circle cover',
'center bottom, ellipse cover',
'circle at 87.23px -58.3px',
'farthest-corner, red, blue',
'farthest-corner at 87.23px -58.3px, red, blue'
].forEach(function(declaration) {
it('should parse ' + declaration + ' declaration', function() {
var expectedResult = 'radial-gradient(' + declaration + ', red, blue)';
var ast = gradients.parse(expectedResult);
subject = gradients.stringify(ast);
expect(subject).to.equal(expectedResult);
});
});
});
});
});

1
webify.js Normal file
View file

@ -0,0 +1 @@
var GradientParser = (window.GradientParser || {});