Skip to content

Commit 3dc7595

Browse files
committed
Move validation functions out of Properties and into ValidationTypes.
1 parent 0427cef commit 3dc7595

File tree

3 files changed

+58
-127
lines changed

3 files changed

+58
-127
lines changed

src/css/Properties.js

Lines changed: 4 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/*global Validation, ValidationTypes, ValidationError*/
21
/*exported Properties*/
32
var Properties = {
43
__proto__: null,
@@ -53,36 +52,7 @@ var Properties = {
5352
"-o-animation-play-state" : { multi: "running | paused", comma: true },
5453

5554
"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",
56-
"azimuth" : function (expression) {
57-
var simple = "<angle> | leftwards | rightwards | inherit",
58-
direction = "left-side | far-left | left | center-left | center | center-right | right | far-right | right-side",
59-
behind = false,
60-
valid = false,
61-
part;
62-
63-
if (!ValidationTypes.isAny(expression, simple)) {
64-
if (ValidationTypes.isAny(expression, "behind")) {
65-
behind = true;
66-
valid = true;
67-
}
68-
69-
if (ValidationTypes.isAny(expression, direction)) {
70-
valid = true;
71-
if (!behind) {
72-
ValidationTypes.isAny(expression, "behind");
73-
}
74-
}
75-
}
76-
77-
if (expression.hasNext()) {
78-
part = expression.next();
79-
if (valid) {
80-
throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
81-
} else {
82-
throw new ValidationError("Expected (<'azimuth'>) but found '" + part + "'.", part.line, part.col);
83-
}
84-
}
85-
},
55+
"azimuth" : "<azimuth>",
8656

8757
//B
8858
"backface-visibility" : "visible | hidden",
@@ -115,83 +85,14 @@ var Properties = {
11585
"border-image" : 1,
11686
"border-image-outset" : { multi: "<length> | <number>", max: 4 },
11787
"border-image-repeat" : { multi: "stretch | repeat | round", max: 2 },
118-
"border-image-slice" : function(expression) {
119-
120-
var valid = false,
121-
numeric = "<number> | <percentage>",
122-
fill = false,
123-
count = 0,
124-
max = 4,
125-
part;
126-
127-
if (ValidationTypes.isAny(expression, "fill")) {
128-
fill = true;
129-
valid = true;
130-
}
131-
132-
while (expression.hasNext() && count < max) {
133-
valid = ValidationTypes.isAny(expression, numeric);
134-
if (!valid) {
135-
break;
136-
}
137-
count++;
138-
}
139-
140-
141-
if (!fill) {
142-
ValidationTypes.isAny(expression, "fill");
143-
} else {
144-
valid = true;
145-
}
146-
147-
if (expression.hasNext()) {
148-
part = expression.next();
149-
if (valid) {
150-
throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
151-
} else {
152-
throw new ValidationError("Expected ([<number> | <percentage>]{1,4} && fill?) but found '" + part + "'.", part.line, part.col);
153-
}
154-
}
155-
},
88+
"border-image-slice" : "<border-image-slice>",
15689
"border-image-source" : "<image> | none",
15790
"border-image-width" : { multi: "<length> | <percentage> | <number> | auto", max: 4 },
15891
"border-left" : "<border-width> || <border-style> || <color>",
15992
"border-left-color" : "<color>",
16093
"border-left-style" : "<border-style>",
16194
"border-left-width" : "<border-width>",
162-
"border-radius" : function(expression) {
163-
164-
var valid = false,
165-
simple = "<length> | <percentage> | inherit",
166-
slash = false,
167-
count = 0,
168-
max = 8,
169-
part;
170-
171-
while (expression.hasNext() && count < max) {
172-
valid = ValidationTypes.isAny(expression, simple);
173-
if (!valid) {
174-
175-
if (String(expression.peek()) === "/" && count > 0 && !slash) {
176-
slash = true;
177-
max = count + 5;
178-
expression.next();
179-
} else {
180-
break;
181-
}
182-
}
183-
count++;
184-
}
185-
186-
if (expression.hasNext()) {
187-
part = expression.next();
188-
if (valid) {
189-
throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
190-
} else {
191-
throw new ValidationError("Expected (<'border-radius'>) but found '" + part + "'.", part.line, part.col);
192-
}
193-
}
194-
},
95+
"border-radius" : "<border-radius>",
19596
"border-right" : "<border-width> || <border-style> || <color>",
19697
"border-right-color" : "<color>",
19798
"border-right-style" : "<border-style>",
@@ -226,18 +127,7 @@ var Properties = {
226127
"-webkit-box-orient" : "horizontal | vertical | inline-axis | block-axis",
227128
"-webkit-box-pack" : "start | end | center | justify",
228129
"box-decoration-break" : "slice | clone",
229-
"box-shadow" : function (expression) {
230-
var part;
231-
232-
if (!ValidationTypes.isAny(expression, "none")) {
233-
Validation.multiProperty("<shadow>", expression, true, Infinity);
234-
} else {
235-
if (expression.hasNext()) {
236-
part = expression.next();
237-
throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
238-
}
239-
}
240-
},
130+
"box-shadow" : "<box-shadow>",
241131
"box-sizing" : "content-box | border-box",
242132
"break-after" : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column",
243133
"break-before" : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column",

src/css/ValidationTypes.js

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,11 +480,20 @@ ValidationTypes = {
480480
return this["<length>"](part) || this["<percentage>"](part) || ValidationTypes.isLiteral(part, "auto");
481481
},
482482

483-
"<padding-width>": function(part){
483+
"<nonnegative-length-or-percentage>": function(part){
484484
return (this["<length>"](part) || this["<percentage>"](part)) &&
485485
(String(part) === "0" || part.type === "function" || (part.value) >= 0);
486486
},
487487

488+
"<nonnegative-number-or-percentage>": function(part){
489+
return (this["<number>"](part) || this["<percentage>"](part)) &&
490+
(String(part) === "0" || part.type === "function" || (part.value) >= 0);
491+
},
492+
493+
"<padding-width>": function(part){
494+
return this["<nonnegative-length-or-percentage>"](part);
495+
},
496+
488497
"<shape>": function(part){
489498
return ValidationTypes.isLiteral(part, "rect() | inset-rect()");
490499
},
@@ -583,12 +592,44 @@ ValidationTypes = {
583592
// scroll-position | contents | <custom-ident>
584593
Matcher.cast("scroll-position | contents | <animateable-feature-name>"),
585594

595+
"<azimuth>":
596+
// <angle> |
597+
// [[ left-side | far-left | left | center-left | center | center-right | right | far-right | right-side ] || behind ] |
598+
// leftwards | rightwards
599+
Matcher.alt("<angle>",
600+
Matcher.cast(
601+
"left-side | far-left | left | center-left | " +
602+
"center | center-right | right | far-right | " +
603+
"right-side").oror("behind"),
604+
"leftwards", "rightwards"),
605+
586606
"<bg-position>": Matcher.cast("<position>").hash(),
587607

588608
"<bg-size>":
589609
//<bg-size> = [ <length> | <percentage> | auto ]{1,2} | cover | contain
590610
Matcher.alt("cover", "contain", Matcher.cast("<percentage> | <length> | auto").braces(1,2)),
591611

612+
"<border-image-slice>":
613+
// [<number> | <percentage>]{1,4} && fill?
614+
// *but* fill can appear between any of the numbers
615+
Matcher.many([true /* first element is required */],
616+
Matcher.cast("<nonnegative-number-or-percentage>"),
617+
Matcher.cast("<nonnegative-number-or-percentage>"),
618+
Matcher.cast("<nonnegative-number-or-percentage>"),
619+
Matcher.cast("<nonnegative-number-or-percentage>"),
620+
"fill"),
621+
622+
"<border-radius>":
623+
// [ <length> | <percentage> ]{1,4} [ / [ <length> | <percentage> ]{1,4} ]?
624+
Matcher.seq(
625+
Matcher.cast("<nonnegative-length-or-percentage>").braces(1, 4),
626+
Matcher.seq(
627+
"/",
628+
Matcher.cast("<nonnegative-length-or-percentage>").braces(1, 4)
629+
).question()),
630+
631+
"<box-shadow>": Matcher.alt("none", Matcher.cast("<shadow>").hash()),
632+
592633
"<clip-source>": Matcher.cast("<uri>"),
593634

594635
"<clip-path>":
@@ -597,9 +638,8 @@ ValidationTypes = {
597638

598639
"<dasharray>":
599640
// "list of comma and/or white space separated <length>s and
600-
// <percentage>s". We use <padding-width> to enforce the
601-
// nonnegative constraint.
602-
Matcher.cast("<padding-width>")
641+
// <percentage>s". There is a non-negative constraint.
642+
Matcher.cast("<nonnegative-length-or-percentage>")
603643
.braces(1, Infinity, "#", Matcher.cast(",").question()),
604644

605645
"<filter-function-list>":

tests/css/Validation.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@
153153

154154
invalid: {
155155
"behind behind" : "Expected end of value but found 'behind'.",
156-
"foo" : "Expected (<'azimuth'>) but found 'foo'."
156+
"foo" : "Expected (<angle> | [ left-side | far-left | left | center-left | center | center-right | right | far-right | right-side ] || behind | leftwards | rightwards) but found 'foo'."
157157
}
158158
}));
159159

@@ -426,13 +426,14 @@
426426
"5",
427427
"50% 60%",
428428
"10 15 20 23",
429-
"fill",
430429
"10 20 fill",
431-
"fill 25% 10"
430+
"fill 25% 10",
431+
"10% fill 7 12"
432432
],
433433

434434
invalid: {
435-
"foo" : "Expected ([<number> | <percentage>]{1,4} && fill?) but found 'foo'.",
435+
"foo" : "Expected (<nonnegative-number-or-percentage> && <nonnegative-number-or-percentage>? && <nonnegative-number-or-percentage>? && <nonnegative-number-or-percentage>? && fill?) but found 'foo'.",
436+
"fill" : "Expected (<nonnegative-number-or-percentage> && <nonnegative-number-or-percentage>? && <nonnegative-number-or-percentage>? && <nonnegative-number-or-percentage>? && fill?) but found 'fill'.",
436437
"50% 75% 85% 95% 105%" : "Expected end of value but found '105%'."
437438
}
438439
}));
@@ -450,8 +451,8 @@
450451
],
451452

452453
invalid: {
453-
"foo" : "Expected (<'border-radius'>) but found 'foo'.",
454-
"5px x" : "Expected (<'border-radius'>) but found 'x'.",
454+
"foo" : "Expected (<nonnegative-length-or-percentage>{1,4} [ / <nonnegative-length-or-percentage>{1,4} ]?) but found 'foo'.",
455+
"5px x" : "Expected end of value but found 'x'.",
455456
}
456457
}));
457458

@@ -588,9 +589,9 @@
588589
],
589590

590591
invalid: {
591-
"foo" : "Expected (<shadow>) but found 'foo'.",
592-
"1px" : "Expected (<shadow>) but found '1px'.",
593-
"1em red" : "Expected (<shadow>) but found '1em red'.",
592+
"foo" : "Expected (none | <shadow>#) but found 'foo'.",
593+
"1px" : "Expected (none | <shadow>#) but found '1px'.",
594+
"1em red" : "Expected (none | <shadow>#) but found '1em red'.",
594595
"1px 1px redd" : "Expected end of value but found 'redd'.",
595596
"none 1px" : "Expected end of value but found '1px'.",
596597
"inset 2px 2px 2px 2px black inset" : "Expected end of value but found 'inset'."

0 commit comments

Comments
 (0)