CssSchema.java revision 1af054935066ae9db1476bef96ff224410edb1f4
1// Copyright (c) 2013, Mike Samuel
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7//
8// Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// Neither the name of the OWASP nor the names of its contributors may
14// be used to endorse or promote products derived from this software
15// without specific prior written permission.
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27// POSSIBILITY OF SUCH DAMAGE.
28
29package org.owasp.html;
30
31import java.util.SortedSet;
32
33import com.google.common.collect.ImmutableMap;
34import com.google.common.collect.ImmutableSet;
35import com.google.common.collect.Sets;
36
37/** Describes the kinds of tokens a CSS property's value can safely contain. */
38@TCB
39public final class CssSchema {
40
41  static final class Property {
42    /** A bitfield of BIT_* constants describing groups of allowed tokens. */
43    final int bits;
44    /** Specific allowed values. */
45    final ImmutableSet<String> literals;
46    /**
47     * Maps lower-case function tokens to the schema key for their parameters.
48     */
49    final ImmutableMap<String, String> fnKeys;
50
51    private Property(
52        int bits, ImmutableSet<String> literals,
53        ImmutableMap<String, String> fnKeys) {
54      this.bits = bits;
55      this.literals = literals;
56      this.fnKeys = fnKeys;
57    }
58  }
59
60  static final int BIT_QUANTITY = 1;
61  static final int BIT_HASH_VALUE = 2;
62  static final int BIT_NEGATIVE = 4;
63  static final int BIT_STRING = 8;
64  static final int BIT_URL = 16;
65  static final int BIT_UNRESERVED_WORD = 64;
66  static final int BIT_UNICODE_RANGE = 128;
67
68  public static final Property DISALLOWED = new Property(
69      0, ImmutableSet.<String>of(), ImmutableMap.<String, String>of());
70
71  private final ImmutableMap<String, Property> properties;
72
73  CssSchema(ImmutableMap<String, Property> properties) {
74    this.properties = properties;
75  }
76
77  /** The schema for the named property or function key. */
78  public Property forKey(String propertyName) {
79    Property property = properties.get(Strings.toLowerCase(propertyName));
80    return property == null ? DISALLOWED : property;
81  }
82
83  /** Maps lower-cased CSS property names to information about them. */
84  private static final ImmutableMap<String, Property> DEFAULT_PROPERTIES;
85  static {
86    ImmutableMap<String, String> zeroFns = ImmutableMap.of();
87    ImmutableMap.Builder<String, Property> builder
88        = ImmutableMap.builder();
89    ImmutableSet<String> mozBorderRadiusLiterals0 = ImmutableSet.of("/");
90    ImmutableSet<String> mozOpacityLiterals0 = ImmutableSet.of("inherit");
91    ImmutableSet<String> mozOutlineLiterals0 = ImmutableSet.of("aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow", "honeydew", "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen");
92    ImmutableSet<String> mozOutlineLiterals1 = ImmutableSet.of("dashed", "dotted", "double", "groove", "outset", "ridge", "solid");
93    ImmutableSet<String> mozOutlineLiterals2 = ImmutableSet.of("thick", "thin");
94    ImmutableSet<String> mozOutlineLiterals3 = ImmutableSet.of("hidden", "inherit", "inset", "invert", "medium", "none");
95    ImmutableMap<String, String> mozOutlineFunctions = ImmutableMap.<String, String>of("rgb(", "rgb()", "rgba(", "rgba()");
96    ImmutableSet<String> mozOutlineColorLiterals0 = ImmutableSet.of("inherit", "invert");
97    ImmutableSet<String> mozOutlineStyleLiterals0 = ImmutableSet.of("hidden", "inherit", "inset", "none");
98    ImmutableSet<String> mozOutlineWidthLiterals0 = ImmutableSet.of("inherit", "medium");
99    ImmutableSet<String> oTextOverflowLiterals0 = ImmutableSet.of("clip", "ellipsis");
100    ImmutableSet<String> azimuthLiterals0 = ImmutableSet.of("behind", "center-left", "center-right", "far-left", "far-right", "left-side", "leftwards", "right-side", "rightwards");
101    ImmutableSet<String> azimuthLiterals1 = ImmutableSet.of("left", "right");
102    ImmutableSet<String> azimuthLiterals2 = ImmutableSet.of("center", "inherit");
103    ImmutableSet<String> backgroundLiterals0 = ImmutableSet.of("border-box", "contain", "content-box", "cover", "padding-box");
104    ImmutableSet<String> backgroundLiterals1 = ImmutableSet.of("no-repeat", "repeat-x", "repeat-y", "round", "space");
105    ImmutableSet<String> backgroundLiterals2 = ImmutableSet.of("bottom", "top");
106    ImmutableSet<String> backgroundLiterals3 = ImmutableSet.of(",", "/", "auto", "center", "fixed", "inherit", "local", "none", "repeat", "scroll", "transparent");
107    ImmutableMap<String, String> backgroundFunctions = ImmutableMap.<String, String>builder().put("image(", "image()").put("linear-gradient(", "linear-gradient()").put("radial-gradient(", "radial-gradient()").put("repeating-linear-gradient(", "repeating-linear-gradient()").put("repeating-radial-gradient(", "repeating-radial-gradient()").put("rgb(", "rgb()").put("rgba(", "rgba()").build();
108    ImmutableSet<String> backgroundAttachmentLiterals0 = ImmutableSet.of(",", "fixed", "local", "scroll");
109    ImmutableSet<String> backgroundColorLiterals0 = ImmutableSet.of("inherit", "transparent");
110    ImmutableSet<String> backgroundImageLiterals0 = ImmutableSet.of(",", "none");
111    ImmutableMap<String, String> backgroundImageFunctions = ImmutableMap.<String, String>of("image(", "image()", "linear-gradient(", "linear-gradient()", "radial-gradient(", "radial-gradient()", "repeating-linear-gradient(", "repeating-linear-gradient()", "repeating-radial-gradient(", "repeating-radial-gradient()");
112    ImmutableSet<String> backgroundPositionLiterals0 = ImmutableSet.of(",", "center");
113    ImmutableSet<String> backgroundRepeatLiterals0 = ImmutableSet.of(",", "repeat");
114    ImmutableSet<String> borderLiterals0 = ImmutableSet.of("hidden", "inherit", "inset", "medium", "none", "transparent");
115    ImmutableSet<String> borderCollapseLiterals0 = ImmutableSet.of("collapse", "inherit", "separate");
116    ImmutableSet<String> bottomLiterals0 = ImmutableSet.of("auto", "inherit");
117    ImmutableSet<String> boxShadowLiterals0 = ImmutableSet.of(",", "inset", "none");
118    //ImmutableSet<String> clearLiterals0 = ImmutableSet.of("both", "inherit", "none");
119    //ImmutableMap<String, String> clipFunctions = ImmutableMap.<String, String>of("rect(", "rect()");
120    ImmutableSet<String> contentLiterals0 = ImmutableSet.of("none", "normal");
121    ImmutableSet<String> cueLiterals0 = ImmutableSet.of("inherit", "none");
122    //ImmutableSet<String> cursorLiterals0 = ImmutableSet.of("all-scroll", "col-resize", "crosshair", "default", "e-resize", "hand", "help", "move", "n-resize", "ne-resize", "no-drop", "not-allowed", "nw-resize", "pointer", "progress", "row-resize", "s-resize", "se-resize", "sw-resize", "text", "vertical-text", "w-resize", "wait");
123    //ImmutableSet<String> cursorLiterals1 = ImmutableSet.of(",", "auto", "inherit");
124    ImmutableSet<String> directionLiterals0 = ImmutableSet.of("ltr", "rtl");
125    //ImmutableSet<String> displayLiterals0 = ImmutableSet.of("-moz-inline-box", "-moz-inline-stack", "block", "inline", "inline-block", "inline-table", "list-item", "run-in", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group");
126    ImmutableSet<String> elevationLiterals0 = ImmutableSet.of("above", "below", "higher", "level", "lower");
127    ImmutableSet<String> emptyCellsLiterals0 = ImmutableSet.of("hide", "show");
128    //ImmutableMap<String, String> filterFunctions = ImmutableMap.<String, String>of("alpha(", "alpha()");
129    ImmutableSet<String> fontLiterals0 = ImmutableSet.of("100", "200", "300", "400", "500", "600", "700", "800", "900", "bold", "bolder", "lighter");
130    ImmutableSet<String> fontLiterals1 = ImmutableSet.of("large", "larger", "small", "smaller", "x-large", "x-small", "xx-large", "xx-small");
131    ImmutableSet<String> fontLiterals2 = ImmutableSet.of("caption", "icon", "menu", "message-box", "small-caption", "status-bar");
132    ImmutableSet<String> fontLiterals3 = ImmutableSet.of("cursive", "fantasy", "monospace", "sans-serif", "serif");
133    ImmutableSet<String> fontLiterals4 = ImmutableSet.of("italic", "oblique");
134    ImmutableSet<String> fontLiterals5 = ImmutableSet.of(",", "/", "inherit", "medium", "normal", "small-caps");
135    ImmutableSet<String> fontFamilyLiterals0 = ImmutableSet.of(",", "inherit");
136    ImmutableSet<String> fontStretchLiterals0 = ImmutableSet.of("condensed", "expanded", "extra-condensed", "extra-expanded", "narrower", "semi-condensed", "semi-expanded", "ultra-condensed", "ultra-expanded", "wider");
137    ImmutableSet<String> fontStretchLiterals1 = ImmutableSet.of("normal");
138    ImmutableSet<String> fontStyleLiterals0 = ImmutableSet.of("inherit", "normal");
139    ImmutableSet<String> fontVariantLiterals0 = ImmutableSet.of("inherit", "normal", "small-caps");
140    ImmutableSet<String> listStyleLiterals0 = ImmutableSet.of("armenian", "cjk-decimal", "decimal", "decimal-leading-zero", "disc", "disclosure-closed", "disclosure-open", "ethiopic-numeric", "georgian", "hebrew", "hiragana", "hiragana-iroha", "japanese-formal", "japanese-informal", "katakana", "katakana-iroha", "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal", "lower-alpha", "lower-greek", "lower-latin", "lower-roman", "simp-chinese-formal", "simp-chinese-informal", "square", "trad-chinese-formal", "trad-chinese-informal", "upper-alpha", "upper-latin", "upper-roman");
141    ImmutableSet<String> listStyleLiterals1 = ImmutableSet.of("inside", "outside");
142    ImmutableSet<String> listStyleLiterals2 = ImmutableSet.of("circle", "inherit", "none");
143    ImmutableSet<String> maxHeightLiterals0 = ImmutableSet.of("auto", "inherit", "none");
144    //ImmutableSet<String> overflowLiterals0 = ImmutableSet.of("auto", "hidden", "inherit", "scroll", "visible");
145    //ImmutableSet<String> overflowXLiterals0 = ImmutableSet.of("no-content", "no-display");
146    //ImmutableSet<String> overflowXLiterals1 = ImmutableSet.of("auto", "hidden", "scroll", "visible");
147    //ImmutableSet<String> pageBreakAfterLiterals0 = ImmutableSet.of("always", "auto", "avoid", "inherit");
148    //ImmutableSet<String> pageBreakInsideLiterals0 = ImmutableSet.of("auto", "avoid", "inherit");
149    ImmutableSet<String> pitchLiterals0 = ImmutableSet.of("high", "low", "x-high", "x-low");
150    //ImmutableSet<String> playDuringLiterals0 = ImmutableSet.of("auto", "inherit", "mix", "none", "repeat");
151    //ImmutableSet<String> positionLiterals0 = ImmutableSet.of("absolute", "relative", "static");
152    ImmutableSet<String> speakLiterals0 = ImmutableSet.of("inherit", "none", "normal", "spell-out");
153    ImmutableSet<String> speakHeaderLiterals0 = ImmutableSet.of("always", "inherit", "once");
154    ImmutableSet<String> speakNumeralLiterals0 = ImmutableSet.of("continuous", "digits");
155    ImmutableSet<String> speakPunctuationLiterals0 = ImmutableSet.of("code", "inherit", "none");
156    ImmutableSet<String> speechRateLiterals0 = ImmutableSet.of("fast", "faster", "slow", "slower", "x-fast", "x-slow");
157    ImmutableSet<String> tableLayoutLiterals0 = ImmutableSet.of("auto", "fixed", "inherit");
158    ImmutableSet<String> textAlignLiterals0 = ImmutableSet.of("center", "inherit", "justify");
159    ImmutableSet<String> textDecorationLiterals0 = ImmutableSet.of("blink", "line-through", "overline", "underline");
160    ImmutableSet<String> textTransformLiterals0 = ImmutableSet.of("capitalize", "lowercase", "uppercase");
161    ImmutableSet<String> textWrapLiterals0 = ImmutableSet.of("suppress", "unrestricted");
162    ImmutableSet<String> unicodeBidiLiterals0 = ImmutableSet.of("bidi-override", "embed");
163    ImmutableSet<String> verticalAlignLiterals0 = ImmutableSet.of("baseline", "middle", "sub", "super", "text-bottom", "text-top");
164    //ImmutableSet<String> visibilityLiterals0 = ImmutableSet.of("collapse", "hidden", "inherit", "visible");
165    ImmutableSet<String> voiceFamilyLiterals0 = ImmutableSet.of("child", "female", "male");
166    ImmutableSet<String> volumeLiterals0 = ImmutableSet.of("loud", "silent", "soft", "x-loud", "x-soft");
167    ImmutableSet<String> whiteSpaceLiterals0 = ImmutableSet.of("-moz-pre-wrap", "-o-pre-wrap", "-pre-wrap", "nowrap", "pre", "pre-line", "pre-wrap");
168    ImmutableSet<String> wordWrapLiterals0 = ImmutableSet.of("break-word", "normal");
169    ImmutableSet<String> rgb$FunLiterals0 = ImmutableSet.of(",");
170    ImmutableSet<String> linearGradient$FunLiterals0 = ImmutableSet.of(",", "to");
171    ImmutableSet<String> radialGradient$FunLiterals0 = ImmutableSet.of("at", "closest-corner", "closest-side", "ellipse", "farthest-corner", "farthest-side");
172    ImmutableSet<String> radialGradient$FunLiterals1 = ImmutableSet.of(",", "center", "circle");
173    ImmutableSet<String> rect$FunLiterals0 = ImmutableSet.of(",", "auto");
174    ImmutableSet<String> alpha$FunLiterals0 = ImmutableSet.of("=", "opacity");
175    Property mozBorderRadius = new Property(5, mozBorderRadiusLiterals0, zeroFns);
176    builder.put("-moz-border-radius", mozBorderRadius);
177    Property mozBorderRadiusBottomleft = new Property(5, ImmutableSet.<String>of(), zeroFns);
178    builder.put("-moz-border-radius-bottomleft", mozBorderRadiusBottomleft);
179    //CssSchema mozOpacity = new CssSchema(1, mozOpacityLiterals0, zeroFns);
180    //builder.put("-moz-opacity", mozOpacity);
181    @SuppressWarnings("unchecked")
182    Property mozOutline = new Property(7, union(mozOutlineLiterals0, mozOutlineLiterals1, mozOutlineLiterals2, mozOutlineLiterals3), mozOutlineFunctions);
183    builder.put("-moz-outline", mozOutline);
184    @SuppressWarnings("unchecked")
185    Property mozOutlineColor = new Property(2, union(mozOutlineColorLiterals0, mozOutlineLiterals0), mozOutlineFunctions);
186    builder.put("-moz-outline-color", mozOutlineColor);
187    @SuppressWarnings("unchecked")
188    Property mozOutlineStyle = new Property(0, union(mozOutlineLiterals1, mozOutlineStyleLiterals0), zeroFns);
189    builder.put("-moz-outline-style", mozOutlineStyle);
190    @SuppressWarnings("unchecked")
191    Property mozOutlineWidth = new Property(5, union(mozOutlineLiterals2, mozOutlineWidthLiterals0), zeroFns);
192    builder.put("-moz-outline-width", mozOutlineWidth);
193    Property oTextOverflow = new Property(0, oTextOverflowLiterals0, zeroFns);
194    builder.put("-o-text-overflow", oTextOverflow);
195    @SuppressWarnings("unchecked")
196    Property azimuth = new Property(5, union(azimuthLiterals0, azimuthLiterals1, azimuthLiterals2), zeroFns);
197    builder.put("azimuth", azimuth);
198    @SuppressWarnings("unchecked")
199    Property background = new Property(23, union(azimuthLiterals1, backgroundLiterals0, backgroundLiterals1, backgroundLiterals2, backgroundLiterals3, mozOutlineLiterals0), backgroundFunctions);
200    builder.put("background", background);
201    builder.put("background-attachment", new Property(0, backgroundAttachmentLiterals0, zeroFns));
202    @SuppressWarnings("unchecked")
203    Property backgroundColor = new Property(258, union(backgroundColorLiterals0, mozOutlineLiterals0), mozOutlineFunctions);
204    builder.put("background-color", backgroundColor);
205    builder.put("background-image", new Property(16, backgroundImageLiterals0, backgroundImageFunctions));
206    @SuppressWarnings("unchecked")
207    Property backgroundPosition = new Property(5, union(azimuthLiterals1, backgroundLiterals2, backgroundPositionLiterals0), zeroFns);
208    builder.put("background-position", backgroundPosition);
209    @SuppressWarnings("unchecked")
210    Property backgroundRepeat = new Property(0, union(backgroundLiterals1, backgroundRepeatLiterals0), zeroFns);
211    builder.put("background-repeat", backgroundRepeat);
212    @SuppressWarnings("unchecked")
213    Property border = new Property(7, union(borderLiterals0, mozOutlineLiterals0, mozOutlineLiterals1, mozOutlineLiterals2), mozOutlineFunctions);
214    builder.put("border", border);
215    @SuppressWarnings("unchecked")
216    Property borderBottomColor = new Property(2, union(backgroundColorLiterals0, mozOutlineLiterals0), mozOutlineFunctions);
217    builder.put("border-bottom-color", borderBottomColor);
218    builder.put("border-collapse", new Property(0, borderCollapseLiterals0, zeroFns));
219    Property borderSpacing = new Property(5, mozOpacityLiterals0, zeroFns);
220    builder.put("border-spacing", borderSpacing);
221    //CssSchema bottom = new CssSchema(5, bottomLiterals0, zeroFns);
222    //builder.put("bottom", bottom);
223    @SuppressWarnings("unchecked")
224    Property boxShadow = new Property(7, union(boxShadowLiterals0, mozOutlineLiterals0), mozOutlineFunctions);
225    builder.put("box-shadow", boxShadow);
226    @SuppressWarnings("unchecked")
227    Property captionSide = new Property(0, union(backgroundLiterals2, mozOpacityLiterals0), zeroFns);
228    builder.put("caption-side", captionSide);
229    //@SuppressWarnings("unchecked")
230    //CssSchema clear = new CssSchema(0, union(azimuthLiterals1, clearLiterals0), zeroFns);
231    //builder.put("clear", clear);
232    //builder.put("clip", new CssSchema(0, bottomLiterals0, clipFunctions));
233    @SuppressWarnings("unchecked")
234    Property color = new Property(258, union(mozOpacityLiterals0, mozOutlineLiterals0), mozOutlineFunctions);
235    builder.put("color", color);
236    //builder.put("content", new CssSchema(8, contentLiterals0, zeroFns));
237    Property cue = new Property(16, cueLiterals0, zeroFns);
238    builder.put("cue", cue);
239    //@SuppressWarnings("unchecked")
240    //CssSchema cursor = new CssSchema(272, union(cursorLiterals0, cursorLiterals1), zeroFns);
241    //builder.put("cursor", cursor);
242    @SuppressWarnings("unchecked")
243    Property direction = new Property(0, union(directionLiterals0, mozOpacityLiterals0), zeroFns);
244    builder.put("direction", direction);
245    //@SuppressWarnings("unchecked")
246    //CssSchema display = new CssSchema(0, union(cueLiterals0, displayLiterals0), zeroFns);
247    //builder.put("display", display);
248    @SuppressWarnings("unchecked")
249    Property elevation = new Property(5, union(elevationLiterals0, mozOpacityLiterals0), zeroFns);
250    builder.put("elevation", elevation);
251    @SuppressWarnings("unchecked")
252    Property emptyCells = new Property(0, union(emptyCellsLiterals0, mozOpacityLiterals0), zeroFns);
253    builder.put("empty-cells", emptyCells);
254    //builder.put("filter", new CssSchema(0, ImmutableSet.<String>of(), filterFunctions));
255    //@SuppressWarnings("unchecked")
256    //CssSchema cssFloat = new CssSchema(0, union(azimuthLiterals1, cueLiterals0), zeroFns);
257    //builder.put("float", cssFloat);
258    @SuppressWarnings("unchecked")
259    Property font = new Property(73, union(fontLiterals0, fontLiterals1, fontLiterals2, fontLiterals3, fontLiterals4, fontLiterals5), zeroFns);
260    builder.put("font", font);
261    @SuppressWarnings("unchecked")
262    Property fontFamily = new Property(72, union(fontFamilyLiterals0, fontLiterals3), zeroFns);
263    builder.put("font-family", fontFamily);
264    @SuppressWarnings("unchecked")
265    Property fontSize = new Property(1, union(fontLiterals1, mozOutlineWidthLiterals0), zeroFns);
266    builder.put("font-size", fontSize);
267    @SuppressWarnings("unchecked")
268    Property fontStretch = new Property(0, union(fontStretchLiterals0, fontStretchLiterals1), zeroFns);
269    builder.put("font-stretch", fontStretch);
270    @SuppressWarnings("unchecked")
271    Property fontStyle = new Property(0, union(fontLiterals4, fontStyleLiterals0), zeroFns);
272    builder.put("font-style", fontStyle);
273    builder.put("font-variant", new Property(0, fontVariantLiterals0, zeroFns));
274    @SuppressWarnings("unchecked")
275    Property fontWeight = new Property(0, union(fontLiterals0, fontStyleLiterals0), zeroFns);
276    builder.put("font-weight", fontWeight);
277    Property height = new Property(5, bottomLiterals0, zeroFns);
278    builder.put("height", height);
279    Property letterSpacing = new Property(5, fontStyleLiterals0, zeroFns);
280    builder.put("letter-spacing", letterSpacing);
281    builder.put("line-height", new Property(1, fontStyleLiterals0, zeroFns));
282    @SuppressWarnings("unchecked")
283    Property listStyle = new Property(16, union(listStyleLiterals0, listStyleLiterals1, listStyleLiterals2), backgroundImageFunctions);
284    builder.put("list-style", listStyle);
285    builder.put("list-style-image", new Property(16, cueLiterals0, backgroundImageFunctions));
286    @SuppressWarnings("unchecked")
287    Property listStylePosition = new Property(0, union(listStyleLiterals1, mozOpacityLiterals0), zeroFns);
288    builder.put("list-style-position", listStylePosition);
289    @SuppressWarnings("unchecked")
290    Property listStyleType = new Property(0, union(listStyleLiterals0, listStyleLiterals2), zeroFns);
291    builder.put("list-style-type", listStyleType);
292    Property margin = new Property(1, bottomLiterals0, zeroFns);
293    builder.put("margin", margin);
294    Property maxHeight = new Property(1, maxHeightLiterals0, zeroFns);
295    builder.put("max-height", maxHeight);
296    //CssSchema opacity = new CssSchema(1, mozOpacityLiterals0, zeroFns);
297    //builder.put("opacity", opacity);
298    //builder.put("overflow", new CssSchema(0, overflowLiterals0, zeroFns));
299    //@SuppressWarnings("unchecked")
300    //CssSchema overflowX = new CssSchema(0, union(overflowXLiterals0, overflowXLiterals1), zeroFns);
301    //builder.put("overflow-x", overflowX);
302    Property padding = new Property(1, mozOpacityLiterals0, zeroFns);
303    builder.put("padding", padding);
304    //@SuppressWarnings("unchecked")
305    //CssSchema pageBreakAfter = new CssSchema(0, union(azimuthLiterals1, pageBreakAfterLiterals0), zeroFns);
306    //builder.put("page-break-after", pageBreakAfter);
307    //builder.put("page-break-inside", new CssSchema(0, pageBreakInsideLiterals0, zeroFns));
308    @SuppressWarnings("unchecked")
309    Property pitch = new Property(5, union(mozOutlineWidthLiterals0, pitchLiterals0), zeroFns);
310    builder.put("pitch", pitch);
311    //builder.put("play-during", new CssSchema(16, playDuringLiterals0, zeroFns));
312    //@SuppressWarnings("unchecked")
313    //CssSchema position = new CssSchema(0, union(mozOpacityLiterals0, positionLiterals0), zeroFns);
314    //builder.put("position", position);
315    builder.put("quotes", new Property(8, cueLiterals0, zeroFns));
316    builder.put("speak", new Property(0, speakLiterals0, zeroFns));
317    builder.put("speak-header", new Property(0, speakHeaderLiterals0, zeroFns));
318    @SuppressWarnings("unchecked")
319    Property speakNumeral = new Property(0, union(mozOpacityLiterals0, speakNumeralLiterals0), zeroFns);
320    builder.put("speak-numeral", speakNumeral);
321    builder.put("speak-punctuation", new Property(0, speakPunctuationLiterals0, zeroFns));
322    @SuppressWarnings("unchecked")
323    Property speechRate = new Property(5, union(mozOutlineWidthLiterals0, speechRateLiterals0), zeroFns);
324    builder.put("speech-rate", speechRate);
325    builder.put("table-layout", new Property(0, tableLayoutLiterals0, zeroFns));
326    @SuppressWarnings("unchecked")
327    Property textAlign = new Property(0, union(azimuthLiterals1, textAlignLiterals0), zeroFns);
328    builder.put("text-align", textAlign);
329    @SuppressWarnings("unchecked")
330    Property textDecoration = new Property(0, union(cueLiterals0, textDecorationLiterals0), zeroFns);
331    builder.put("text-decoration", textDecoration);
332    @SuppressWarnings("unchecked")
333    Property textTransform = new Property(0, union(cueLiterals0, textTransformLiterals0), zeroFns);
334    builder.put("text-transform", textTransform);
335    @SuppressWarnings("unchecked")
336    Property textWrap = new Property(0, union(contentLiterals0, textWrapLiterals0), zeroFns);
337    builder.put("text-wrap", textWrap);
338    @SuppressWarnings("unchecked")
339    Property unicodeBidi = new Property(0, union(fontStyleLiterals0, unicodeBidiLiterals0), zeroFns);
340    builder.put("unicode-bidi", unicodeBidi);
341    @SuppressWarnings("unchecked")
342    Property verticalAlign = new Property(5, union(backgroundLiterals2, mozOpacityLiterals0, verticalAlignLiterals0), zeroFns);
343    builder.put("vertical-align", verticalAlign);
344    //builder.put("visibility", new CssSchema(0, visibilityLiterals0, zeroFns));
345    @SuppressWarnings("unchecked")
346    Property voiceFamily = new Property(8, union(fontFamilyLiterals0, voiceFamilyLiterals0), zeroFns);
347    builder.put("voice-family", voiceFamily);
348    @SuppressWarnings("unchecked")
349    Property volume = new Property(1, union(mozOutlineWidthLiterals0, volumeLiterals0), zeroFns);
350    builder.put("volume", volume);
351    @SuppressWarnings("unchecked")
352    Property whiteSpace = new Property(0, union(fontStyleLiterals0, whiteSpaceLiterals0), zeroFns);
353    builder.put("white-space", whiteSpace);
354    builder.put("word-wrap", new Property(0, wordWrapLiterals0, zeroFns));
355    //builder.put("zoom", new CssSchema(1, fontStretchLiterals1, zeroFns));
356    Property rgb$Fun = new Property(1, rgb$FunLiterals0, zeroFns);
357    builder.put("rgb()", rgb$Fun);
358    @SuppressWarnings("unchecked")
359    Property image$Fun = new Property(18, union(mozOutlineLiterals0, rgb$FunLiterals0), mozOutlineFunctions);
360    builder.put("image()", image$Fun);
361    @SuppressWarnings("unchecked")
362    Property linearGradient$Fun = new Property(7, union(azimuthLiterals1, backgroundLiterals2, linearGradient$FunLiterals0, mozOutlineLiterals0), mozOutlineFunctions);
363    builder.put("linear-gradient()", linearGradient$Fun);
364    @SuppressWarnings("unchecked")
365    Property radialGradient$Fun = new Property(7, union(azimuthLiterals1, backgroundLiterals2, mozOutlineLiterals0, radialGradient$FunLiterals0, radialGradient$FunLiterals1), mozOutlineFunctions);
366    builder.put("radial-gradient()", radialGradient$Fun);
367    builder.put("rect()", new Property(5, rect$FunLiterals0, zeroFns));
368    builder.put("alpha()", new Property(1, alpha$FunLiterals0, zeroFns));
369    builder.put("-moz-border-radius-bottomright", mozBorderRadiusBottomleft);
370    builder.put("-moz-border-radius-topleft", mozBorderRadiusBottomleft);
371    builder.put("-moz-border-radius-topright", mozBorderRadiusBottomleft);
372    builder.put("-moz-box-shadow", boxShadow);
373    builder.put("-webkit-border-bottom-left-radius", mozBorderRadiusBottomleft);
374    builder.put("-webkit-border-bottom-right-radius", mozBorderRadiusBottomleft);
375    builder.put("-webkit-border-radius", mozBorderRadius);
376    builder.put("-webkit-border-radius-bottom-left", mozBorderRadiusBottomleft);
377    builder.put("-webkit-border-radius-bottom-right", mozBorderRadiusBottomleft);
378    builder.put("-webkit-border-radius-top-left", mozBorderRadiusBottomleft);
379    builder.put("-webkit-border-radius-top-right", mozBorderRadiusBottomleft);
380    builder.put("-webkit-border-top-left-radius", mozBorderRadiusBottomleft);
381    builder.put("-webkit-border-top-right-radius", mozBorderRadiusBottomleft);
382    builder.put("-webkit-box-shadow", boxShadow);
383    builder.put("border-bottom", border);
384    builder.put("border-bottom-left-radius", mozBorderRadiusBottomleft);
385    builder.put("border-bottom-right-radius", mozBorderRadiusBottomleft);
386    builder.put("border-bottom-style", mozOutlineStyle);
387    builder.put("border-bottom-width", mozOutlineWidth);
388    builder.put("border-color", borderBottomColor);
389    builder.put("border-left", border);
390    builder.put("border-left-color", borderBottomColor);
391    builder.put("border-left-style", mozOutlineStyle);
392    builder.put("border-left-width", mozOutlineWidth);
393    builder.put("border-radius", mozBorderRadius);
394    builder.put("border-right", border);
395    builder.put("border-right-color", borderBottomColor);
396    builder.put("border-right-style", mozOutlineStyle);
397    builder.put("border-right-width", mozOutlineWidth);
398    builder.put("border-style", mozOutlineStyle);
399    builder.put("border-top", border);
400    builder.put("border-top-color", borderBottomColor);
401    builder.put("border-top-left-radius", mozBorderRadiusBottomleft);
402    builder.put("border-top-right-radius", mozBorderRadiusBottomleft);
403    builder.put("border-top-style", mozOutlineStyle);
404    builder.put("border-top-width", mozOutlineWidth);
405    builder.put("border-width", mozOutlineWidth);
406    builder.put("cue-after", cue);
407    builder.put("cue-before", cue);
408    //builder.put("left", height);
409    builder.put("margin-bottom", margin);
410    builder.put("margin-left", margin);
411    builder.put("margin-right", margin);
412    builder.put("margin-top", margin);
413    builder.put("max-width", maxHeight);
414    builder.put("min-height", margin);
415    builder.put("min-width", margin);
416    builder.put("outline", mozOutline);
417    builder.put("outline-color", mozOutlineColor);
418    builder.put("outline-style", mozOutlineStyle);
419    builder.put("outline-width", mozOutlineWidth);
420    //builder.put("overflow-y", overflowX);
421    builder.put("padding-bottom", padding);
422    builder.put("padding-left", padding);
423    builder.put("padding-right", padding);
424    builder.put("padding-top", padding);
425    //builder.put("page-break-before", pageBreakAfter);
426    builder.put("pause", borderSpacing);
427    builder.put("pause-after", borderSpacing);
428    builder.put("pause-before", borderSpacing);
429    builder.put("pitch-range", borderSpacing);
430    builder.put("richness", borderSpacing);
431    //builder.put("right", height);
432    builder.put("stress", borderSpacing);
433    builder.put("text-indent", borderSpacing);
434    builder.put("text-overflow", oTextOverflow);
435    builder.put("text-shadow", boxShadow);
436    //builder.put("top", height);
437    builder.put("width", margin);
438    builder.put("word-spacing", letterSpacing);
439    //builder.put("z-index", bottom);
440    builder.put("rgba()", rgb$Fun);
441    builder.put("repeating-linear-gradient()", linearGradient$Fun);
442    builder.put("repeating-radial-gradient()", radialGradient$Fun);
443    DEFAULT_PROPERTIES = builder.build();
444  }
445
446  private static <T> ImmutableSet<T> union(ImmutableSet<T>... subsets) {
447    ImmutableSet.Builder<T> all = ImmutableSet.builder();
448    for (ImmutableSet<T> subset : subsets) {
449      all.addAll(subset);
450    }
451    return all.build();
452  }
453
454  static final CssSchema DEFAULT = new CssSchema(DEFAULT_PROPERTIES);
455
456  /** Dumps key and literal list to stdout for easy examination. */
457  public static void main(String... argv) {
458    SortedSet<String> keys = Sets.newTreeSet();
459    SortedSet<String> literals = Sets.newTreeSet();
460    for (ImmutableMap.Entry<String, Property> e
461         : DEFAULT_PROPERTIES.entrySet()) {
462      keys.add(e.getKey());
463      literals.addAll(e.getValue().literals);
464    }
465    for (String key : keys) {
466      System.out.println(key);
467    }
468    System.out.println();
469    for (String literal : literals) {
470      System.out.println(literal);
471    }
472  }
473}
474