Skip to content

Commit fff530f

Browse files
committed
Merge pull request #116 from malept/flexbox-fixes
Fix flexbox-related property value parsing
2 parents d9c4b1f + cfd9661 commit fff530f

File tree

3 files changed

+208
-4
lines changed

3 files changed

+208
-4
lines changed

src/css/Properties.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,23 +285,23 @@ var Properties = {
285285
"filter" : 1,
286286
"fit" : "fill | hidden | meet | slice",
287287
"fit-position" : 1,
288-
"flex" : "none | [ <flex-grow> <flex-shrink>? || <flex-basis>",
288+
"flex" : "<flex>",
289289
"flex-basis" : "<width>",
290290
"flex-direction" : "row | row-reverse | column | column-reverse",
291291
"flex-flow" : "<flex-direction> || <flex-wrap>",
292292
"flex-grow" : "<number>",
293293
"flex-shrink" : "<number>",
294294
"flex-wrap" : "nowrap | wrap | wrap-reverse",
295-
"-webkit-flex" : "none | [ <flex-grow> <flex-shrink>? || <flex-basis>",
295+
"-webkit-flex" : "<flex>",
296296
"-webkit-flex-basis" : "<width>",
297297
"-webkit-flex-direction" : "row | row-reverse | column | column-reverse",
298298
"-webkit-flex-flow" : "<flex-direction> || <flex-wrap>",
299299
"-webkit-flex-grow" : "<number>",
300300
"-webkit-flex-shrink" : "<number>",
301301
"-webkit-flex-wrap" : "nowrap | wrap | wrap-reverse",
302-
"-ms-flex" : "[[ <number> <number>? ] || [ <length> || <percentage> || auto ] ] | none",
302+
"-ms-flex" : "<flex>",
303303
"-ms-flex-align" : "start | end | center | stretch | baseline",
304-
"-ms-flex-direction" : "row | column | row-reverse | column-reverse | inherit",
304+
"-ms-flex-direction" : "row | row-reverse | column | column-reverse | inherit",
305305
"-ms-flex-order" : "<number>",
306306
"-ms-flex-pack" : "start | end | center | justify",
307307
"-ms-flex-wrap" : "nowrap | wrap | wrap-reverse",

src/css/ValidationTypes.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,30 @@ var ValidationTypes = {
186186

187187
"<time>": function(part) {
188188
return part.type == "time";
189+
},
190+
191+
"<flex-grow>": function(part){
192+
return this["<number>"](part);
193+
},
194+
195+
"<flex-shrink>": function(part){
196+
return this["<number>"](part);
197+
},
198+
199+
"<width>": function(part){
200+
return this["<margin-width>"](part);
201+
},
202+
203+
"<flex-basis>": function(part){
204+
return this["<width>"](part);
205+
},
206+
207+
"<flex-direction>": function(part){
208+
return ValidationTypes.isLiteral(part, "row | row-reverse | column | column-reverse");
209+
},
210+
211+
"<flex-wrap>": function(part){
212+
return ValidationTypes.isLiteral(part, "nowrap | wrap | wrap-reverse");
189213
}
190214
},
191215

@@ -355,6 +379,50 @@ var ValidationTypes = {
355379
ValidationTypes.isAny(expression, simple);
356380
}
357381

382+
return result;
383+
},
384+
385+
"<flex>": function(expression) {
386+
// http://www.w3.org/TR/2014/WD-css-flexbox-1-20140325/#flex-property
387+
// none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]
388+
// Valid syntaxes, according to https://developer.mozilla.org/en-US/docs/Web/CSS/flex#Syntax
389+
// * none
390+
// * <flex-grow>
391+
// * <flex-basis>
392+
// * <flex-grow> <flex-basis>
393+
// * <flex-grow> <flex-shrink>
394+
// * <flex-grow> <flex-shrink> <flex-basis>
395+
// * inherit
396+
var part,
397+
result = false;
398+
if (ValidationTypes.isAny(expression, "none | inherit")) {
399+
result = true;
400+
} else {
401+
if (ValidationTypes.isType(expression, "<flex-grow>")) {
402+
if (expression.peek()) {
403+
if (ValidationTypes.isType(expression, "<flex-shrink>")) {
404+
if (expression.peek()) {
405+
result = ValidationTypes.isType(expression, "<flex-basis>");
406+
} else {
407+
result = true;
408+
}
409+
} else if (ValidationTypes.isType(expression, "<flex-basis>")) {
410+
result = expression.peek() === null;
411+
}
412+
} else {
413+
result = true;
414+
}
415+
} else if (ValidationTypes.isType(expression, "<flex-basis>")) {
416+
result = true;
417+
}
418+
}
419+
420+
if (!result) {
421+
// Generate a more verbose error than "Expected <flex>..."
422+
part = expression.peek();
423+
throw new ValidationError("Expected (none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]) but found '" + expression.value.text + "'.", part.line, part.col);
424+
}
425+
358426
return result;
359427
}
360428
}

tests/css/Validation.js

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,142 @@
648648
}
649649
}));
650650

651+
["flex", "-ms-flex", "-webkit-flex"].forEach(function(prop_name) {
652+
suite.add(new ValidationTestCase({
653+
property: prop_name,
654+
655+
valid: [
656+
"1",
657+
"inherit",
658+
// From http://www.w3.org/TR/2014/WD-css-flexbox-1-20140325/#flex-common
659+
// "initial", // FIXME this needs to be integrated as a univerally acceptable value
660+
"0 auto",
661+
"0 1 auto",
662+
"auto",
663+
"none",
664+
"1 1 0%"
665+
],
666+
667+
invalid: {
668+
"foo": "Expected (none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]) but found 'foo'."
669+
}
670+
}));
671+
});
672+
673+
["flex-basis", "-webkit-flex-basis"].forEach(function(prop_name) {
674+
suite.add(new ValidationTestCase({
675+
property: prop_name,
676+
677+
valid: [
678+
// "initial", // FIXME this needs to be integrated as a univerally acceptable value
679+
"auto",
680+
"12px",
681+
"3em",
682+
"0"
683+
],
684+
685+
invalid: {
686+
"foo": "Expected (<width>) but found 'foo'."
687+
}
688+
}));
689+
});
690+
691+
["flex-direction", "-ms-flex-direction", "-webkit-flex-direction"].forEach(function(prop_name) {
692+
var prop_definition = "row | row-reverse | column | column-reverse";
693+
if (prop_name == "-ms-flex-direction") {
694+
prop_definition += " | inherit";
695+
}
696+
var valid_values = [
697+
// "initial", // FIXME this needs to be integrated as a univerally acceptable value
698+
"row",
699+
"row-reverse",
700+
"column",
701+
"column-reverse"
702+
];
703+
if (prop_name == "-ms-flex-direction") {
704+
valid_values.push("inherit");
705+
}
706+
suite.add(new ValidationTestCase({
707+
property: prop_name,
708+
709+
valid: valid_values,
710+
711+
invalid: {
712+
"foo": "Expected (" + prop_definition + ") but found 'foo'."
713+
}
714+
}));
715+
});
716+
717+
["flex-flow", "-webkit-flex-flow"].forEach(function(prop_name) {
718+
suite.add(new ValidationTestCase({
719+
property: prop_name,
720+
721+
valid: [
722+
// "initial", // FIXME this needs to be integrated as a univerally acceptable value
723+
// from http://www.w3.org/TR/2014/WD-css-flexbox-1-20140325/#flex-flow-property
724+
"row",
725+
"column wrap",
726+
"row-reverse wrap-reverse",
727+
"wrap"
728+
],
729+
730+
invalid: {
731+
"foo": "Expected (<flex-direction> || <flex-wrap>) but found 'foo'."
732+
}
733+
}));
734+
});
735+
736+
["flex-grow", "-webkit-flex-grow"].forEach(function(prop_name) {
737+
suite.add(new ValidationTestCase({
738+
property: prop_name,
739+
740+
valid: [
741+
// "initial", // FIXME this needs to be integrated as a univerally acceptable value
742+
"0",
743+
"1",
744+
"1.5"
745+
],
746+
747+
invalid: {
748+
"foo": "Expected (<number>) but found 'foo'."
749+
}
750+
}));
751+
});
752+
753+
["flex-shrink", "-webkit-flex-shrink"].forEach(function(prop_name) {
754+
suite.add(new ValidationTestCase({
755+
property: prop_name,
756+
757+
valid: [
758+
// "initial", // FIXME this needs to be integrated as a univerally acceptable value
759+
"0",
760+
"1",
761+
"1.5"
762+
],
763+
764+
invalid: {
765+
"foo": "Expected (<number>) but found 'foo'."
766+
}
767+
}));
768+
});
769+
770+
["flex-wrap", "-ms-flex-wrap", "-webkit-flex-wrap"].forEach(function(prop_name) {
771+
suite.add(new ValidationTestCase({
772+
property: prop_name,
773+
774+
valid: [
775+
// "initial", // FIXME this needs to be integrated as a univerally acceptable value
776+
"nowrap",
777+
"wrap",
778+
"wrap-reverse"
779+
],
780+
781+
invalid: {
782+
"foo": "Expected (nowrap | wrap | wrap-reverse) but found 'foo'."
783+
}
784+
}));
785+
});
786+
651787
suite.add(new ValidationTestCase({
652788
property: "text-rendering",
653789

0 commit comments

Comments
 (0)