Match radial declarations

This commit is contained in:
Rafael Caricio 2014-09-07 15:26:45 +02:00
parent da4f2bed43
commit cae89479ff
2 changed files with 125 additions and 7 deletions

View file

@ -79,12 +79,12 @@ module.exports = (function() {
matchGradient(
'radial-gradient',
tokens.radialGradient,
matchRadialOrientation) ||
matchListRadialOrientations) ||
matchGradient(
'repeating-radial-gradient',
tokens.repeatingRadialGradient,
matchRadialOrientation);
matchListRadialOrientations);
}
function matchGradient(gradientType, pattern, orientationMatcher) {
@ -128,9 +128,6 @@ module.exports = (function() {
matchAngle();
}
function matchRadialOrientation() {
}
function matchSideOrCorner() {
return match('directional', tokens.sideOrCorner, 1);
}
@ -139,6 +136,102 @@ module.exports = (function() {
return match('angular', tokens.angleValue, 1);
}
function matchListRadialOrientations() {
var radialOrientations,
radialOrientation = matchRadialOrientation(),
lookaheadCache;
if (radialOrientation) {
radialOrientations = [];
radialOrientations.push(radialOrientation);
lookaheadCache = input;
if (scan(tokens.comma)) {
radialOrientation = matchRadialOrientation();
if (radialOrientation) {
radialOrientations.push(radialOrientation);
} else {
input = lookaheadCache;
}
}
}
return radialOrientations;
}
function matchRadialOrientation() {
var radialType = matchCircle() ||
matchEllipse();
if (radialType) {
radialType.at = matchAtPosition();
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default',
at: defaultPosition
};
}
}
return radialType;
}
function matchCircle() {
var circle = match('shape', /^(circle)/i, 0);
if (circle) {
circle.style = matchLength() || matchExtentKeyword();
}
return circle;
}
function matchEllipse() {
var ellipse = match('shape', /^(ellipse)/i, 0);
if (ellipse) {
ellipse.style = matchExtentKeyword() || matchDistance();
}
return ellipse;
}
function matchExtentKeyword() {
return match('extent-keyword', /^(closest\-side|closest\-corner|farthest\-side|farthest\-corner|contain|cover)/, 1);
}
function matchAtPosition() {
if (match('position', /^at/, 0)) {
var positioning = matchPositioning();
if (!positioning) {
error('Missing positioning value');
}
return positioning;
}
}
function matchPositioning() {
var location = matchCoordinates();
if (location.x || location.y) {
return {
type: 'position',
value: location
};
}
}
function matchCoordinates() {
return {
x: matchDistance(),
y: matchDistance()
};
}
function matchListing(matcher) {
var captures = matcher(),
result = [];
@ -165,7 +258,7 @@ module.exports = (function() {
error('Expected color definition');
}
color.length = matchLength();
color.length = matchDistance();
return color;
}
@ -206,9 +299,18 @@ module.exports = (function() {
return scan(tokens.number)[1];
}
function matchDistance() {
return match('%', tokens.percentageValue, 1) ||
matchPositionKeyword() ||
matchLength();
}
function matchPositionKeyword() {
return match('positionKeyword', /^(left|center|right|top|bottom)/i, 1);
}
function matchLength() {
return match('px', tokens.pixelValue, 1) ||
match('%', tokens.percentageValue, 1) ||
match('em', tokens.emValue, 1);
}

View file

@ -218,4 +218,20 @@ describe('gradient-parser.js', function () {
});
});
describe('different radial declarations', function() {
[
'ellipse farthest-corner',
'ellipse cover',
'circle cover',
'center bottom, ellipse cover',
'circle at 119px 58px'
].forEach(function(declaration) {
it('should parse ' + declaration + ' declaration', function() {
ast = gradients.parse('radial-gradient(' + declaration + ', red, blue)');
});
});
});
});