Skip to content

Commit b345d05

Browse files
committed
Merge pull request #201 from cscott/font-family
Validate `font-family` and the `font` compound property.
2 parents 889093c + 5e0bbd8 commit b345d05

File tree

3 files changed

+320
-20
lines changed

3 files changed

+320
-20
lines changed

src/css/Properties.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ var Properties = {
1818
"animation-duration" : { multi: "<time>", comma: true },
1919
"animation-fill-mode" : { multi: "none | forwards | backwards | both", comma: true },
2020
"animation-iteration-count" : { multi: "<number> | infinite", comma: true },
21-
"animation-name" : { multi: "none | <ident>", comma: true },
21+
"animation-name" : { multi: "none | initial | inherit | unset | <single-animation-name>", comma: true },
2222
"animation-play-state" : { multi: "running | paused", comma: true },
2323
"animation-timing-function" : 1,
2424

@@ -27,29 +27,29 @@ var Properties = {
2727
"-moz-animation-direction" : { multi: "normal | alternate", comma: true },
2828
"-moz-animation-duration" : { multi: "<time>", comma: true },
2929
"-moz-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
30-
"-moz-animation-name" : { multi: "none | <ident>", comma: true },
30+
"-moz-animation-name" : { multi: "none | initial | inherit | unset | <single-animation-name>", comma: true },
3131
"-moz-animation-play-state" : { multi: "running | paused", comma: true },
3232

3333
"-ms-animation-delay" : { multi: "<time>", comma: true },
3434
"-ms-animation-direction" : { multi: "normal | alternate", comma: true },
3535
"-ms-animation-duration" : { multi: "<time>", comma: true },
3636
"-ms-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
37-
"-ms-animation-name" : { multi: "none | <ident>", comma: true },
37+
"-ms-animation-name" : { multi: "none | initial | inherit | unset | <single-animation-name>", comma: true },
3838
"-ms-animation-play-state" : { multi: "running | paused", comma: true },
3939

4040
"-webkit-animation-delay" : { multi: "<time>", comma: true },
4141
"-webkit-animation-direction" : { multi: "normal | alternate", comma: true },
4242
"-webkit-animation-duration" : { multi: "<time>", comma: true },
4343
"-webkit-animation-fill-mode" : { multi: "none | forwards | backwards | both", comma: true },
4444
"-webkit-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
45-
"-webkit-animation-name" : { multi: "none | <ident>", comma: true },
45+
"-webkit-animation-name" : { multi: "none | initial | inherit | unset | <single-animation-name>", comma: true },
4646
"-webkit-animation-play-state" : { multi: "running | paused", comma: true },
4747

4848
"-o-animation-delay" : { multi: "<time>", comma: true },
4949
"-o-animation-direction" : { multi: "normal | alternate", comma: true },
5050
"-o-animation-duration" : { multi: "<time>", comma: true },
5151
"-o-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
52-
"-o-animation-name" : { multi: "none | <ident>", comma: true },
52+
"-o-animation-name" : { multi: "none | initial | inherit | unset | <single-animation-name>", comma: true },
5353
"-o-animation-play-state" : { multi: "running | paused", comma: true },
5454

5555
"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",
@@ -315,18 +315,22 @@ var Properties = {
315315
"-ms-flex-wrap" : "nowrap | wrap | wrap-reverse",
316316
"float" : "left | right | none | inherit",
317317
"float-offset" : 1,
318-
"font" : 1,
319-
"font-family" : 1,
318+
"font" : "<font-shorthand> | caption | icon | menu | message-box | small-caption | status-bar | inherit",
319+
"font-family" : "<font-family> | inherit",
320320
"font-feature-settings" : "<feature-tag-value> | normal | inherit",
321321
"font-kerning" : "auto | normal | none | initial | inherit | unset",
322-
"font-size" : "<absolute-size> | <relative-size> | <length> | <percentage> | inherit",
322+
"font-size" : "<font-size> | inherit",
323323
"font-size-adjust" : "<number> | none | inherit",
324-
"font-stretch" : "normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | inherit",
325-
"font-style" : "normal | italic | oblique | inherit",
326-
"font-variant" : "normal | small-caps | inherit",
327-
"font-variant-caps" : "normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps",
324+
"font-stretch" : "<font-stretch> | inherit",
325+
"font-style" : "<font-style> | inherit",
326+
"font-variant" : "<font-variant> | normal | none | inherit",
327+
"font-variant-alternates" : "<font-variant-alternates> | normal | inherit",
328+
"font-variant-caps" : "<font-variant-caps> | normal | inherit",
329+
"font-variant-east-asian" : "<font-variant-east-asian> | normal | inherit",
330+
"font-variant-ligatures" : "<font-variant-ligatures> | normal | none | inherit",
331+
"font-variant-numeric" : "<font-variant-numeric> | normal | inherit",
328332
"font-variant-position" : "normal | sub | super | inherit | initial | unset",
329-
"font-weight" : "normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit",
333+
"font-weight" : "<font-weight> | inherit",
330334

331335
//G
332336
"glyph-orientation-horizontal" : "<glyph-angle> | inherit",
@@ -384,7 +388,7 @@ var Properties = {
384388
//L
385389
"left" : "<margin-width> | inherit",
386390
"letter-spacing" : "<length> | normal | inherit",
387-
"line-height" : "<number> | <length> | <percentage> | normal | inherit",
391+
"line-height" : "<line-height> | inherit",
388392
"line-break" : "auto | loose | normal | strict",
389393
"line-stacking" : 1,
390394
"line-stacking-ruby" : "exclude-ruby | include-ruby",
@@ -557,7 +561,7 @@ var Properties = {
557561
"white-space-collapse" : 1,
558562
"widows" : "<integer> | inherit",
559563
"width" : "<length> | <percentage> | <content-sizing> | auto | inherit",
560-
"will-change" : { multi: "<ident>", comma: true },
564+
"will-change" : "<will-change> | inherit | initial | unset",
561565
"word-break" : "normal | keep-all | break-all",
562566
"word-spacing" : "<length> | normal | inherit",
563567
"word-wrap" : "normal | break-word",

src/css/ValidationTypes.js

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,21 @@ ValidationTypes = {
376376
return part.type === "identifier" || part.wasIdent;
377377
},
378378

379+
"<single-animation-name>": function(part) {
380+
return this["<ident>"](part) &&
381+
/^-?[a-z_][-a-z0-9_]+$/i.test(part) &&
382+
!/^(none|unset|initial|inherit)$/i.test(part);
383+
},
384+
385+
"<animateable-feature-name>": function(part) {
386+
return this["<ident>"](part) &&
387+
!/^(unset|initial|inherit|will-change|auto|scroll-position|contents)$/i.test(part);
388+
},
389+
390+
"<string>": function(part){
391+
return part.type === "string";
392+
},
393+
379394
"<length>": function(part){
380395
if (part.type === "function" && /^(?:\-(?:ms|moz|o|webkit)\-)?calc/i.test(part)){
381396
return true;
@@ -528,12 +543,46 @@ ValidationTypes = {
528543
part, "blur() | brightness() | contrast() | custom() | " +
529544
"drop-shadow() | grayscale() | hue-rotate() | invert() | " +
530545
"opacity() | saturate() | sepia()");
546+
},
547+
548+
"<generic-family>": function(part){
549+
return ValidationTypes.isLiteral(part, "serif | sans-serif | cursive | fantasy | monospace");
550+
},
551+
552+
"<ident-not-generic-family>": function(part){
553+
return this["<ident>"](part) && !this["<generic-family>"](part);
554+
},
555+
556+
"<font-size>": function(part){
557+
var result = this["<absolute-size>"](part) || this["<relative-size>"](part) || this["<length>"](part) || this["<percentage>"](part);
558+
return result;
559+
},
560+
561+
"<font-stretch>": function(part){
562+
return ValidationTypes.isLiteral(part, "normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded");
563+
},
564+
565+
"<font-style>": function(part){
566+
return ValidationTypes.isLiteral(part, "normal | italic | oblique");
567+
},
568+
569+
"<font-weight>": function(part){
570+
return ValidationTypes.isLiteral(part, "normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900");
571+
},
572+
573+
"<line-height>": function(part){
574+
var result = this["<number>"](part) || this["<length>"](part) || this["<percentage>"](part) || ValidationTypes.isLiteral(part, "normal");
575+
return result;
531576
}
532577
},
533578

534579
complex: {
535580
__proto__: null,
536581

582+
"<animateable-feature>":
583+
// scroll-position | contents | <custom-ident>
584+
Matcher.cast("scroll-position | contents | <animateable-feature-name>"),
585+
537586
"<bg-position>": Matcher.cast("<position>").hash(),
538587

539588
"<bg-size>":
@@ -622,8 +671,88 @@ ValidationTypes = {
622671
// * inherit
623672
Matcher.alt("none", "inherit", Matcher.cast("<flex-grow>").then(Matcher.cast("<flex-shrink>").question()).oror("<flex-basis>")),
624673

674+
"<font-family>":
675+
// [ <family-name> | <generic-family> ]#
676+
Matcher.cast("<generic-family> | <family-name>").hash(),
677+
678+
"<family-name>":
679+
// <string> | <IDENT>+
680+
Matcher.alt("<string>",
681+
Matcher.seq("<ident-not-generic-family>",
682+
Matcher.cast("<ident>").star())),
683+
684+
"<font-variant-alternates>":
685+
Matcher.oror(// stylistic(<feature-value-name>)
686+
"stylistic()",
687+
"historical-forms",
688+
// styleset(<feature-value-name> #)
689+
"styleset()",
690+
// character-variant(<feature-value-name> #)
691+
"character-variant()",
692+
// swash(<feature-value-name>)
693+
"swash()",
694+
// ornaments(<feature-value-name>)
695+
"ornaments()",
696+
// annotation(<feature-value-name>)
697+
"annotation()"),
698+
699+
"<font-variant-caps>":
700+
Matcher.cast("small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps"),
701+
702+
"<font-variant-css21>":
703+
Matcher.cast("normal | small-caps"),
704+
705+
"<font-variant-ligatures>":
706+
Matcher.oror(// <common-lig-values>
707+
"common-ligatures | no-common-ligatures",
708+
// <discretionary-lig-values>
709+
"discretionary-ligatures | no-discretionary-ligatures",
710+
// <historical-lig-values>
711+
"historical-ligatures | no-historical-ligatures",
712+
// <contextual-alt-values>
713+
"contextual | no-contextual"),
714+
715+
"<font-variant-numeric>":
716+
Matcher.oror(// <numeric-figure-values>
717+
"lining-nums | oldstyle-nums",
718+
// <numeric-spacing-values>
719+
"proportional-nums | tabular-nums",
720+
// <numeric-fraction-values>
721+
"diagonal-fractions | stacked-fractions",
722+
"ordinal",
723+
"slashed-zero"),
724+
725+
"<font-variant-east-asian>":
726+
Matcher.oror(// <east-asian-variant-values>
727+
"jis78 | jis83 | jis90 | jis04 | simplified | traditional",
728+
// <east-asian-width-values>
729+
"full-width | proportional-width",
730+
"ruby"),
731+
732+
"<font-shorthand>":
733+
Matcher.seq(Matcher.oror("<font-style>",
734+
"<font-variant-css21>",
735+
"<font-weight>",
736+
"<font-stretch>").question(),
737+
"<font-size>",
738+
Matcher.seq("/", "<line-height>").question(),
739+
"<font-family>"),
740+
625741
"<text-decoration>":
626742
// none | [ underline || overline || line-through || blink ] | inherit
627-
Matcher.oror("underline", "overline", "line-through", "blink")
743+
Matcher.oror("underline", "overline", "line-through", "blink"),
744+
745+
"<will-change>":
746+
// auto | <animateable-feature>#
747+
Matcher.alt("auto", Matcher.cast("<animateable-feature>").hash())
628748
}
629749
};
750+
751+
// Because this is defined relative to other complex validation types,
752+
// we need to define it *after* the rest of the types are initialized.
753+
ValidationTypes.complex["<font-variant>"] =
754+
Matcher.oror({ expand: "<font-variant-ligatures>" },
755+
{ expand: "<font-variant-alternates>" },
756+
"<font-variant-caps>",
757+
{ expand: "<font-variant-numeric>" },
758+
{ expand: "<font-variant-east-asian>" });

0 commit comments

Comments
 (0)