Skip to content
15 changes: 13 additions & 2 deletions src/css/Properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ var Properties = {
"-o-animation-name" : { multi: "none | <ident>", comma: true },
"-o-animation-play-state" : { multi: "running | paused", comma: true },

"appearance" : "icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal | none | inherit",
"appearance" : "icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal | none | inherit",
"azimuth" : function (expression) {
var simple = "<angle> | leftwards | rightwards | inherit",
direction = "left-side | far-left | left | center-left | center | center-right | right | far-right | right-side",
Expand Down Expand Up @@ -284,6 +284,9 @@ var Properties = {
"empty-cells" : "show | hide | inherit",

//F
"fill" : "<paint>",
"fill-opacity" : "<opacity-value> | inherit",
"fill-rule" : "nonzero | evenodd | inherit",
"filter" : 1,
"fit" : "fill | hidden | meet | slice",
"fit-position" : 1,
Expand Down Expand Up @@ -417,7 +420,7 @@ var Properties = {
//O
"object-fit" : "fill | contain | cover | none | scale-down",
"object-position" : "<bg-position>",
"opacity" : "<number> | inherit",
"opacity" : "<opacity-value> | inherit",
"order" : "<integer>",
"-webkit-order" : "<integer>",
"orphans" : "<integer> | inherit",
Expand Down Expand Up @@ -485,6 +488,14 @@ var Properties = {
"src" : 1,
"stress" : 1,
"string-set" : 1,
"stroke" : "<paint>",
"stroke-dasharray" : "none | <dasharray> | inherit",
"stroke-dashoffset" : "<percentage> | <length> | inherit",
"stroke-linecap" : "butt | round | square | inherit",
"stroke-linejoin" : "miter | round | bevel | inherit",
"stroke-miterlimit" : "<miterlimit> | inherit",
"stroke-opacity" : "<opacity-value> | inherit",
"stroke-width" : "<percentage> | <length> | inherit",

"table-layout" : "auto | fixed | inherit",
"tab-size" : "<integer> | <length>",
Expand Down
81 changes: 80 additions & 1 deletion src/css/ValidationTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,40 @@ var ValidationTypes = {
return part.type == "color" || part == "transparent" || part == "currentColor";
},

"<icccolor>": function(part){
/* ex.:
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/local
icc-color(acmecmyk, 0.11, 0.48, 0.83, 0.00)
cielab(62.253188, 23.950124, 48.410653)
cielch(62.253188, 54.011108, 63.677091)
icc-color(FooColors, Sandy23C)
http://www.w3.org/TR/2009/WD-SVGColor12-20091001/#iccnamedcolor
~"icc-color(" name (comma-wsp number)+ ")"
~"icc-named-color(" name comma-wsp namedColor ")"
~"cielab(" lightness comma-wsp a-value comma-wsp b-value ")"
~"cielchab(" lightness comma-wsp chroma comma-wsp hue ")"
*/
return part.type == 'function' && (
part.name == 'cielab' ||
part.name == 'cielch' ||
part.name == 'cielchab' ||
part.name == 'icc-color' ||
part.name == 'icc-named-color'
);
},

"<number>": function(part){
return part.type == "number" || this["<integer>"](part);
},

"<miterlimit>": function(part){
return this["<number>"](part) && part.value >= 1;
},

"<opacity-value>": function(part){
return this["<number>"](part) && part.value >= 0 && part.value <= 1;
},

"<integer>": function(part){
return part.type == "integer";
},
Expand Down Expand Up @@ -211,7 +241,7 @@ var ValidationTypes = {
"<flex-wrap>": function(part){
return ValidationTypes.isLiteral(part, "nowrap | wrap | wrap-reverse");
},

"<feature-tag-value>": function(part){
return (part.type == "function" && /^[A-Z0-9]{4}$/i.test(part));
}
Expand Down Expand Up @@ -332,6 +362,33 @@ var ValidationTypes = {

},

"<paint>": function(expression) {
/*
none | currentColor | <color> [<icccolor>] |
<funciri> [ none | currentColor | <color> [<icccolor>] ] |
inherit
*/
var part = expression.next(), result = false;

if (ValidationTypes.simple["<uri>"](part)) {
result = true;
part = expression.next();
}
if (part && ValidationTypes.simple["<color>"](part)) {
var color = part.value;
result = true;
part = expression.next();
if (part) {
result = (color != 'currentColor') && ValidationTypes.simple["<icccolor>"](part);
}
} else if (part) {
result = ValidationTypes.isLiteral(part, "none | currentColor | inherit");
}

return result && !expression.hasNext();

},

"<shadow>": function(expression) {
//inset? && [ <length>{2,4} && <color>? ]
var result = false,
Expand Down Expand Up @@ -386,6 +443,28 @@ var ValidationTypes = {
return result;
},

"<dasharray>": function(expression){
var arrayResult = true, part, partResult;

while (expression.hasNext()) {
part = expression.next();
partResult =
part.value >= 0 && (
ValidationTypes.simple["<length>"](part) ||
ValidationTypes.simple["<percentage>"](part) ||
ValidationTypes.simple["<number>"](part)
);
partResult = partResult || part.value == ',';
arrayResult = arrayResult && partResult;
}

if (!arrayResult) {
expression.previous();
}
return arrayResult;

},

"<flex>": function(expression) {
// http://www.w3.org/TR/2014/WD-css-flexbox-1-20140325/#flex-property
// none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]
Expand Down
115 changes: 114 additions & 1 deletion tests/css/Validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,46 @@
}
}));

// test <paint>
suite.add(new ValidationTestCase({
property: "fill",

valid: [
"url('myGradient')",
"url('myGradient') inherit",
"url('myGradient') darkred",
"url('myGradient') darkred icc-color(myCmykDarkRed)",
"currentColor",
"darkred icc-color(myCmykDarkRed)",
"none",
"inherit"
],

invalid: {
"url('myGradient') icc-color(myCmykDarkRed)" : "Expected (<paint>) but found 'url('myGradient') icc-color(myCmykDarkRed)'.",
"currentColor icc-color(myCmykDarkRed)" : "Expected (<paint>) but found 'currentColor icc-color(myCmykDarkRed)'.",
"icc-color(myCmykDarkRed) darkred" : "Expected end of value but found 'darkred'.",
"icc-color(myCmykDarkRed)" : "Expected (<paint>) but found 'icc-color(myCmykDarkRed)'.",
"icc-color(myCmykDarkRed) inherit" : "Expected end of value but found 'inherit'.",
"inherit icc-color(myCmykDarkRed)" : "Expected end of value but found 'icc-color(myCmykDarkRed)'.",
"none inherit" : "Expected end of value but found 'inherit'."
}
}));

suite.add(new ValidationTestCase({
property: "fill-rule",

valid: [
"nonzero",
"evenodd",
"inherit"
],

invalid: {
"foo" : "Expected (nonzero | evenodd | inherit) but found 'foo'."
}
}));

["flex", "-ms-flex", "-webkit-flex"].forEach(function(prop_name) {
suite.add(new ValidationTestCase({
property: prop_name,
Expand Down Expand Up @@ -894,11 +934,15 @@
property: "opacity",

valid: [
"0",
"0.5",
"1"
],

invalid: {
"foo" : "Expected (<number> | inherit) but found 'foo'."
"-0.75" : "Expected (<opacity-value> | inherit) but found '-0.75'.",
"12" : "Expected (<opacity-value> | inherit) but found '12'.",
"foo" : "Expected (<opacity-value> | inherit) but found 'foo'."
}
}));

Expand All @@ -924,6 +968,75 @@
}
}));

suite.add(new ValidationTestCase({
property: "stroke-dasharray",

valid: [
"0",
"4",
"20px",
"20px 40px 30px",
"20px, 40px, 30px",
"none",
"inherit"
],

invalid: {
"-20px" : "Expected (none | <dasharray> | inherit) but found '-20px'.",
"auto" : "Expected (none | <dasharray> | inherit) but found 'auto'."
}
}));

suite.add(new ValidationTestCase({
property: "stroke-linecap",

valid: [
"butt",
"round",
"square",
"inherit"
],

invalid: {
"auto" : "Expected (butt | round | square | inherit) but found 'auto'.",
"none" : "Expected (butt | round | square | inherit) but found 'none'."
}
}));

suite.add(new ValidationTestCase({
property: "stroke-linejoin",

valid: [
"miter",
"round",
"bevel",
"inherit"
],

invalid: {
"auto" : "Expected (miter | round | bevel | inherit) but found 'auto'.",
"none" : "Expected (miter | round | bevel | inherit) but found 'none'."
}
}));

suite.add(new ValidationTestCase({
property: "stroke-miterlimit",

valid: [
"1",
"1.4",
"20",
"10",
"inherit"
],

invalid: {
"-10" : "Expected (<miterlimit> | inherit) but found '-10'.",
"0.5" : "Expected (<miterlimit> | inherit) but found '0.5'.",
"foo" : "Expected (<miterlimit> | inherit) but found 'foo'."
}
}));

suite.add(new ValidationTestCase({
property: "-ms-touch-action",

Expand Down