001 // Copyright (c) 2013, Mike Samuel
002 // All rights reserved.
003 //
004 // Redistribution and use in source and binary forms, with or without
005 // modification, are permitted provided that the following conditions
006 // are met:
007 //
008 // Redistributions of source code must retain the above copyright
009 // notice, this list of conditions and the following disclaimer.
010 // Redistributions in binary form must reproduce the above copyright
011 // notice, this list of conditions and the following disclaimer in the
012 // documentation and/or other materials provided with the distribution.
013 // Neither the name of the OWASP nor the names of its contributors may
014 // be used to endorse or promote products derived from this software
015 // without specific prior written permission.
016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
017 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
018 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
019 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
020 // COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
021 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
022 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
024 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
025 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
026 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
027 // POSSIBILITY OF SUCH DAMAGE.
028
029 package org.owasp.html;
030
031 import java.util.SortedSet;
032
033 import com.google.common.collect.ImmutableMap;
034 import com.google.common.collect.ImmutableSet;
035 import com.google.common.collect.Sets;
036
037 /** Describes the kinds of tokens a CSS property's value can safely contain. */
038 @TCB
039 public final class CssSchema {
040
041 static final class Property {
042 /** A bitfield of BIT_* constants describing groups of allowed tokens. */
043 final int bits;
044 /** Specific allowed values. */
045 final ImmutableSet<String> literals;
046 /**
047 * Maps lower-case function tokens to the schema key for their parameters.
048 */
049 final ImmutableMap<String, String> fnKeys;
050
051 private Property(
052 int bits, ImmutableSet<String> literals,
053 ImmutableMap<String, String> fnKeys) {
054 this.bits = bits;
055 this.literals = literals;
056 this.fnKeys = fnKeys;
057 }
058 }
059
060 static final int BIT_QUANTITY = 1;
061 static final int BIT_HASH_VALUE = 2;
062 static final int BIT_NEGATIVE = 4;
063 static final int BIT_STRING = 8;
064 static final int BIT_URL = 16;
065 static final int BIT_UNRESERVED_WORD = 64;
066 static final int BIT_UNICODE_RANGE = 128;
067
068 public static final Property DISALLOWED = new Property(
069 0, ImmutableSet.<String>of(), ImmutableMap.<String, String>of());
070
071 private final ImmutableMap<String, Property> properties;
072
073 CssSchema(ImmutableMap<String, Property> properties) {
074 this.properties = properties;
075 }
076
077 /** The schema for the named property or function key. */
078 public Property forKey(String propertyName) {
079 Property property = properties.get(Strings.toLowerCase(propertyName));
080 return property == null ? DISALLOWED : property;
081 }
082
083 /** Maps lower-cased CSS property names to information about them. */
084 private static final ImmutableMap<String, Property> DEFAULT_PROPERTIES;
085 static {
086 ImmutableMap<String, String> zeroFns = ImmutableMap.of();
087 ImmutableMap.Builder<String, Property> builder
088 = ImmutableMap.builder();
089 ImmutableSet<String> mozBorderRadiusLiterals0 = ImmutableSet.of("/");
090 ImmutableSet<String> mozOpacityLiterals0 = ImmutableSet.of("inherit");
091 ImmutableSet<String> mozOutlineLiterals0 = ImmutableSet.of(
092 "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
093 "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
094 "burlywood", "cadetblue", "chartreuse", "chocolate", "coral",
095 "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
096 "darkgoldenrod", "darkgray", "darkgreen", "darkkhaki", "darkmagenta",
097 "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon",
098 "darkseagreen", "darkslateblue", "darkslategray", "darkturquoise",
099 "darkviolet", "deeppink", "deepskyblue", "dimgray", "dodgerblue",
100 "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro",
101 "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow",
102 "honeydew", "hotpink", "indianred", "indigo", "ivory", "khaki",
103 "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
104 "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgreen",
105 "lightgrey", "lightpink", "lightsalmon", "lightseagreen",
106 "lightskyblue", "lightslategray", "lightsteelblue", "lightyellow",
107 "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine",
108 "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
109 "mediumslateblue", "mediumspringgreen", "mediumturquoise",
110 "mediumvioletred", "midnightblue", "mintcream", "mistyrose",
111 "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab",
112 "orange", "orangered", "orchid", "palegoldenrod", "palegreen",
113 "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru",
114 "pink", "plum", "powderblue", "purple", "red", "rosybrown", "royalblue",
115 "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna",
116 "silver", "skyblue", "slateblue", "slategray", "snow", "springgreen",
117 "steelblue", "tan", "teal", "thistle", "tomato", "turquoise", "violet",
118 "wheat", "white", "whitesmoke", "yellow", "yellowgreen");
119 ImmutableSet<String> mozOutlineLiterals1 = ImmutableSet.of(
120 "dashed", "dotted", "double", "groove", "outset", "ridge", "solid");
121 ImmutableSet<String> mozOutlineLiterals2 = ImmutableSet.of("thick", "thin");
122 ImmutableSet<String> mozOutlineLiterals3 = ImmutableSet.of(
123 "hidden", "inherit", "inset", "invert", "medium", "none");
124 ImmutableMap<String, String> mozOutlineFunctions =
125 ImmutableMap.<String, String>of("rgb(", "rgb()", "rgba(", "rgba()");
126 ImmutableSet<String> mozOutlineColorLiterals0 =
127 ImmutableSet.of("inherit", "invert");
128 ImmutableSet<String> mozOutlineStyleLiterals0 =
129 ImmutableSet.of("hidden", "inherit", "inset", "none");
130 ImmutableSet<String> mozOutlineWidthLiterals0 =
131 ImmutableSet.of("inherit", "medium");
132 ImmutableSet<String> oTextOverflowLiterals0 =
133 ImmutableSet.of("clip", "ellipsis");
134 ImmutableSet<String> azimuthLiterals0 = ImmutableSet.of(
135 "behind", "center-left", "center-right", "far-left", "far-right",
136 "left-side", "leftwards", "right-side", "rightwards");
137 ImmutableSet<String> azimuthLiterals1 = ImmutableSet.of("left", "right");
138 ImmutableSet<String> azimuthLiterals2 =
139 ImmutableSet.of("center", "inherit");
140 ImmutableSet<String> backgroundLiterals0 = ImmutableSet.of(
141 "border-box", "contain", "content-box", "cover", "padding-box");
142 ImmutableSet<String> backgroundLiterals1 =
143 ImmutableSet.of("no-repeat", "repeat-x", "repeat-y", "round", "space");
144 ImmutableSet<String> backgroundLiterals2 = ImmutableSet.of("bottom", "top");
145 ImmutableSet<String> backgroundLiterals3 = ImmutableSet.of(
146 ",", "/", "auto", "center", "fixed", "inherit", "local", "none",
147 "repeat", "scroll", "transparent");
148 ImmutableMap<String, String> backgroundFunctions =
149 ImmutableMap.<String, String>builder()
150 .put("image(", "image()")
151 .put("linear-gradient(", "linear-gradient()")
152 .put("radial-gradient(", "radial-gradient()")
153 .put("repeating-linear-gradient(", "repeating-linear-gradient()")
154 .put("repeating-radial-gradient(", "repeating-radial-gradient()")
155 .put("rgb(", "rgb()").put("rgba(", "rgba()")
156 .build();
157 ImmutableSet<String> backgroundAttachmentLiterals0 =
158 ImmutableSet.of(",", "fixed", "local", "scroll");
159 ImmutableSet<String> backgroundColorLiterals0 =
160 ImmutableSet.of("inherit", "transparent");
161 ImmutableSet<String> backgroundImageLiterals0 =
162 ImmutableSet.of(",", "none");
163 ImmutableMap<String, String> backgroundImageFunctions =
164 ImmutableMap.<String, String>of(
165 "image(", "image()",
166 "linear-gradient(", "linear-gradient()",
167 "radial-gradient(", "radial-gradient()",
168 "repeating-linear-gradient(", "repeating-linear-gradient()",
169 "repeating-radial-gradient(", "repeating-radial-gradient()");
170 ImmutableSet<String> backgroundPositionLiterals0 = ImmutableSet.of(
171 ",", "center");
172 ImmutableSet<String> backgroundRepeatLiterals0 = ImmutableSet.of(
173 ",", "repeat");
174 ImmutableSet<String> borderLiterals0 = ImmutableSet.of(
175 "hidden", "inherit", "inset", "medium", "none", "transparent");
176 ImmutableSet<String> borderCollapseLiterals0 = ImmutableSet.of(
177 "collapse", "inherit", "separate");
178 ImmutableSet<String> bottomLiterals0 = ImmutableSet.of("auto", "inherit");
179 ImmutableSet<String> boxShadowLiterals0 = ImmutableSet.of(
180 ",", "inset", "none");
181 //ImmutableSet<String> clearLiterals0 = ImmutableSet.of(
182 // "both", "inherit", "none");
183 //ImmutableMap<String, String> clipFunctions =
184 // ImmutableMap.<String, String>of("rect(", "rect()");
185 ImmutableSet<String> contentLiterals0 = ImmutableSet.of("none", "normal");
186 ImmutableSet<String> cueLiterals0 = ImmutableSet.of("inherit", "none");
187 //ImmutableSet<String> cursorLiterals0 = ImmutableSet.of(
188 // "all-scroll", "col-resize", "crosshair", "default", "e-resize",
189 // "hand", "help", "move", "n-resize", "ne-resize", "no-drop",
190 // "not-allowed", "nw-resize", "pointer", "progress", "row-resize",
191 // "s-resize", "se-resize", "sw-resize", "text", "vertical-text",
192 // "w-resize", "wait");
193 //ImmutableSet<String> cursorLiterals1 = ImmutableSet.of(
194 // ",", "auto", "inherit");
195 ImmutableSet<String> directionLiterals0 = ImmutableSet.of("ltr", "rtl");
196 //ImmutableSet<String> displayLiterals0 = ImmutableSet.of(
197 // "-moz-inline-box", "-moz-inline-stack", "block", "inline",
198 // "inline-block", "inline-table", "list-item", "run-in", "table",
199 // "table-caption", "table-cell", "table-column", "table-column-group",
200 // "table-footer-group", "table-header-group", "table-row",
201 // "table-row-group");
202 ImmutableSet<String> elevationLiterals0 = ImmutableSet.of(
203 "above", "below", "higher", "level", "lower");
204 ImmutableSet<String> emptyCellsLiterals0 = ImmutableSet.of("hide", "show");
205 //ImmutableMap<String, String> filterFunctions =
206 // ImmutableMap.<String, String>of("alpha(", "alpha()");
207 ImmutableSet<String> fontLiterals0 = ImmutableSet.of(
208 "100", "200", "300", "400", "500", "600", "700", "800", "900", "bold",
209 "bolder", "lighter");
210 ImmutableSet<String> fontLiterals1 = ImmutableSet.of(
211 "large", "larger", "small", "smaller", "x-large", "x-small",
212 "xx-large", "xx-small");
213 ImmutableSet<String> fontLiterals2 = ImmutableSet.of(
214 "caption", "icon", "menu", "message-box", "small-caption",
215 "status-bar");
216 ImmutableSet<String> fontLiterals3 = ImmutableSet.of(
217 "cursive", "fantasy", "monospace", "sans-serif", "serif");
218 ImmutableSet<String> fontLiterals4 = ImmutableSet.of("italic", "oblique");
219 ImmutableSet<String> fontLiterals5 = ImmutableSet.of(
220 ",", "/", "inherit", "medium", "normal", "small-caps");
221 ImmutableSet<String> fontFamilyLiterals0 = ImmutableSet.of(",", "inherit");
222 ImmutableSet<String> fontStretchLiterals0 = ImmutableSet.of(
223 "condensed", "expanded", "extra-condensed", "extra-expanded",
224 "narrower", "semi-condensed", "semi-expanded", "ultra-condensed",
225 "ultra-expanded", "wider");
226 ImmutableSet<String> fontStretchLiterals1 = ImmutableSet.of("normal");
227 ImmutableSet<String> fontStyleLiterals0 = ImmutableSet.of(
228 "inherit", "normal");
229 ImmutableSet<String> fontVariantLiterals0 = ImmutableSet.of(
230 "inherit", "normal", "small-caps");
231 ImmutableSet<String> listStyleLiterals0 = ImmutableSet.of(
232 "armenian", "cjk-decimal", "decimal", "decimal-leading-zero", "disc",
233 "disclosure-closed", "disclosure-open", "ethiopic-numeric", "georgian",
234 "hebrew", "hiragana", "hiragana-iroha", "japanese-formal",
235 "japanese-informal", "katakana", "katakana-iroha",
236 "korean-hangul-formal", "korean-hanja-formal",
237 "korean-hanja-informal", "lower-alpha", "lower-greek", "lower-latin",
238 "lower-roman", "simp-chinese-formal", "simp-chinese-informal",
239 "square", "trad-chinese-formal", "trad-chinese-informal",
240 "upper-alpha", "upper-latin", "upper-roman");
241 ImmutableSet<String> listStyleLiterals1 = ImmutableSet.of(
242 "inside", "outside");
243 ImmutableSet<String> listStyleLiterals2 = ImmutableSet.of(
244 "circle", "inherit", "none");
245 ImmutableSet<String> maxHeightLiterals0 = ImmutableSet.of(
246 "auto", "inherit", "none");
247 //ImmutableSet<String> overflowLiterals0 = ImmutableSet.of(
248 // "auto", "hidden", "inherit", "scroll", "visible");
249 //ImmutableSet<String> overflowXLiterals0 = ImmutableSet.of(
250 // "no-content", "no-display");
251 //ImmutableSet<String> overflowXLiterals1 = ImmutableSet.of(
252 // "auto", "hidden", "scroll", "visible");
253 //ImmutableSet<String> pageBreakAfterLiterals0 = ImmutableSet.of(
254 // "always", "auto", "avoid", "inherit");
255 //ImmutableSet<String> pageBreakInsideLiterals0 = ImmutableSet.of(
256 // "auto", "avoid", "inherit");
257 ImmutableSet<String> pitchLiterals0 = ImmutableSet.of(
258 "high", "low", "x-high", "x-low");
259 //ImmutableSet<String> playDuringLiterals0 = ImmutableSet.of(
260 // "auto", "inherit", "mix", "none", "repeat");
261 //ImmutableSet<String> positionLiterals0 = ImmutableSet.of(
262 // "absolute", "relative", "static");
263 ImmutableSet<String> speakLiterals0 = ImmutableSet.of(
264 "inherit", "none", "normal", "spell-out");
265 ImmutableSet<String> speakHeaderLiterals0 = ImmutableSet.of(
266 "always", "inherit", "once");
267 ImmutableSet<String> speakNumeralLiterals0 = ImmutableSet.of(
268 "continuous", "digits");
269 ImmutableSet<String> speakPunctuationLiterals0 = ImmutableSet.of(
270 "code", "inherit", "none");
271 ImmutableSet<String> speechRateLiterals0 = ImmutableSet.of(
272 "fast", "faster", "slow", "slower", "x-fast", "x-slow");
273 ImmutableSet<String> tableLayoutLiterals0 = ImmutableSet.of(
274 "auto", "fixed", "inherit");
275 ImmutableSet<String> textAlignLiterals0 = ImmutableSet.of(
276 "center", "inherit", "justify");
277 ImmutableSet<String> textDecorationLiterals0 = ImmutableSet.of(
278 "blink", "line-through", "overline", "underline");
279 ImmutableSet<String> textTransformLiterals0 = ImmutableSet.of(
280 "capitalize", "lowercase", "uppercase");
281 ImmutableSet<String> textWrapLiterals0 = ImmutableSet.of(
282 "suppress", "unrestricted");
283 ImmutableSet<String> unicodeBidiLiterals0 = ImmutableSet.of(
284 "bidi-override", "embed");
285 ImmutableSet<String> verticalAlignLiterals0 = ImmutableSet.of(
286 "baseline", "middle", "sub", "super", "text-bottom", "text-top");
287 //ImmutableSet<String> visibilityLiterals0 = ImmutableSet.of(
288 // "collapse", "hidden", "inherit", "visible");
289 ImmutableSet<String> voiceFamilyLiterals0 = ImmutableSet.of(
290 "child", "female", "male");
291 ImmutableSet<String> volumeLiterals0 = ImmutableSet.of(
292 "loud", "silent", "soft", "x-loud", "x-soft");
293 ImmutableSet<String> whiteSpaceLiterals0 = ImmutableSet.of(
294 "-moz-pre-wrap", "-o-pre-wrap", "-pre-wrap", "nowrap", "pre",
295 "pre-line", "pre-wrap");
296 ImmutableSet<String> wordWrapLiterals0 = ImmutableSet.of(
297 "break-word", "normal");
298 ImmutableSet<String> rgb$FunLiterals0 = ImmutableSet.of(",");
299 ImmutableSet<String> linearGradient$FunLiterals0 = ImmutableSet.of(
300 ",", "to");
301 ImmutableSet<String> radialGradient$FunLiterals0 = ImmutableSet.of(
302 "at", "closest-corner", "closest-side", "ellipse", "farthest-corner",
303 "farthest-side");
304 ImmutableSet<String> radialGradient$FunLiterals1 = ImmutableSet.of(
305 ",", "center", "circle");
306 ImmutableSet<String> rect$FunLiterals0 = ImmutableSet.of(",", "auto");
307 ImmutableSet<String> alpha$FunLiterals0 = ImmutableSet.of("=", "opacity");
308 Property mozBorderRadius =
309 new Property(5, mozBorderRadiusLiterals0, zeroFns);
310 builder.put("-moz-border-radius", mozBorderRadius);
311 Property mozBorderRadiusBottomleft =
312 new Property(5, ImmutableSet.<String>of(), zeroFns);
313 builder.put("-moz-border-radius-bottomleft", mozBorderRadiusBottomleft);
314 //CssSchema mozOpacity = new Property(1, mozOpacityLiterals0, zeroFns);
315 //builder.put("-moz-opacity", mozOpacity);
316 @SuppressWarnings("unchecked")
317 Property mozOutline = new Property(
318 7,
319 union(mozOutlineLiterals0, mozOutlineLiterals1, mozOutlineLiterals2,
320 mozOutlineLiterals3),
321 mozOutlineFunctions);
322 builder.put("-moz-outline", mozOutline);
323 @SuppressWarnings("unchecked")
324 Property mozOutlineColor = new Property(
325 2, union(mozOutlineColorLiterals0, mozOutlineLiterals0),
326 mozOutlineFunctions);
327 builder.put("-moz-outline-color", mozOutlineColor);
328 @SuppressWarnings("unchecked")
329 Property mozOutlineStyle = new Property(
330 0, union(mozOutlineLiterals1, mozOutlineStyleLiterals0), zeroFns);
331 builder.put("-moz-outline-style", mozOutlineStyle);
332 @SuppressWarnings("unchecked")
333 Property mozOutlineWidth = new Property(
334 5, union(mozOutlineLiterals2, mozOutlineWidthLiterals0), zeroFns);
335 builder.put("-moz-outline-width", mozOutlineWidth);
336 Property oTextOverflow = new Property(0, oTextOverflowLiterals0, zeroFns);
337 builder.put("-o-text-overflow", oTextOverflow);
338 @SuppressWarnings("unchecked")
339 Property azimuth = new Property(
340 5, union(azimuthLiterals0, azimuthLiterals1, azimuthLiterals2),
341 zeroFns);
342 builder.put("azimuth", azimuth);
343 @SuppressWarnings("unchecked")
344 Property background = new Property(
345 23,
346 union(azimuthLiterals1, backgroundLiterals0, backgroundLiterals1,
347 backgroundLiterals2, backgroundLiterals3, mozOutlineLiterals0),
348 backgroundFunctions);
349 builder.put("background", background);
350 builder.put("background-attachment",
351 new Property(0, backgroundAttachmentLiterals0, zeroFns));
352 @SuppressWarnings("unchecked")
353 Property backgroundColor = new Property(
354 258, union(backgroundColorLiterals0, mozOutlineLiterals0),
355 mozOutlineFunctions);
356 builder.put("background-color", backgroundColor);
357 builder.put("background-image",
358 new Property(16, backgroundImageLiterals0,
359 backgroundImageFunctions));
360 @SuppressWarnings("unchecked")
361 Property backgroundPosition = new Property(
362 5,
363 union(azimuthLiterals1, backgroundLiterals2,
364 backgroundPositionLiterals0),
365 zeroFns);
366 builder.put("background-position", backgroundPosition);
367 @SuppressWarnings("unchecked")
368 Property backgroundRepeat = new Property(
369 0, union(backgroundLiterals1, backgroundRepeatLiterals0), zeroFns);
370 builder.put("background-repeat", backgroundRepeat);
371 @SuppressWarnings("unchecked")
372 Property border = new Property(
373 7,
374 union(borderLiterals0, mozOutlineLiterals0, mozOutlineLiterals1,
375 mozOutlineLiterals2),
376 mozOutlineFunctions);
377 builder.put("border", border);
378 @SuppressWarnings("unchecked")
379 Property borderBottomColor = new Property(
380 2, union(backgroundColorLiterals0, mozOutlineLiterals0),
381 mozOutlineFunctions);
382 builder.put("border-bottom-color", borderBottomColor);
383 builder.put("border-collapse",
384 new Property(0, borderCollapseLiterals0, zeroFns));
385 Property borderSpacing = new Property(5, mozOpacityLiterals0, zeroFns);
386 builder.put("border-spacing", borderSpacing);
387 //Property bottom = new Property(5, bottomLiterals0, zeroFns);
388 //builder.put("bottom", bottom);
389 @SuppressWarnings("unchecked")
390 Property boxShadow = new Property(
391 7, union(boxShadowLiterals0, mozOutlineLiterals0), mozOutlineFunctions);
392 builder.put("box-shadow", boxShadow);
393 @SuppressWarnings("unchecked")
394 Property captionSide = new Property(
395 0, union(backgroundLiterals2, mozOpacityLiterals0), zeroFns);
396 builder.put("caption-side", captionSide);
397 //@SuppressWarnings("unchecked")
398 //Property clear = new Property(
399 // 0, union(azimuthLiterals1, clearLiterals0), zeroFns);
400 //builder.put("clear", clear);
401 //builder.put("clip", new Property(0, bottomLiterals0, clipFunctions));
402 @SuppressWarnings("unchecked")
403 Property color = new Property(
404 258, union(mozOpacityLiterals0, mozOutlineLiterals0),
405 mozOutlineFunctions);
406 builder.put("color", color);
407 //builder.put("content", new Property(8, contentLiterals0, zeroFns));
408 Property cue = new Property(16, cueLiterals0, zeroFns);
409 builder.put("cue", cue);
410 //@SuppressWarnings("unchecked")
411 //Property cursor = new Property(
412 // 272, union(cursorLiterals0, cursorLiterals1), zeroFns);
413 //builder.put("cursor", cursor);
414 @SuppressWarnings("unchecked")
415 Property direction = new Property(
416 0, union(directionLiterals0, mozOpacityLiterals0), zeroFns);
417 builder.put("direction", direction);
418 //@SuppressWarnings("unchecked")
419 //Property display = new Property(
420 // 0, union(cueLiterals0, displayLiterals0), zeroFns);
421 //builder.put("display", display);
422 @SuppressWarnings("unchecked")
423 Property elevation = new Property(
424 5, union(elevationLiterals0, mozOpacityLiterals0), zeroFns);
425 builder.put("elevation", elevation);
426 @SuppressWarnings("unchecked")
427 Property emptyCells = new Property(
428 0, union(emptyCellsLiterals0, mozOpacityLiterals0), zeroFns);
429 builder.put("empty-cells", emptyCells);
430 //builder.put("filter",
431 // new Property(0, ImmutableSet.<String>of(), filterFunctions));
432 //@SuppressWarnings("unchecked")
433 //Property cssFloat = new Property(
434 // 0, union(azimuthLiterals1, cueLiterals0), zeroFns);
435 //builder.put("float", cssFloat);
436 @SuppressWarnings("unchecked")
437 Property font = new Property(
438 73,
439 union(fontLiterals0, fontLiterals1, fontLiterals2, fontLiterals3,
440 fontLiterals4, fontLiterals5),
441 zeroFns);
442 builder.put("font", font);
443 @SuppressWarnings("unchecked")
444 Property fontFamily = new Property(
445 72, union(fontFamilyLiterals0, fontLiterals3), zeroFns);
446 builder.put("font-family", fontFamily);
447 @SuppressWarnings("unchecked")
448 Property fontSize = new Property(
449 1, union(fontLiterals1, mozOutlineWidthLiterals0), zeroFns);
450 builder.put("font-size", fontSize);
451 @SuppressWarnings("unchecked")
452 Property fontStretch = new Property(
453 0, union(fontStretchLiterals0, fontStretchLiterals1), zeroFns);
454 builder.put("font-stretch", fontStretch);
455 @SuppressWarnings("unchecked")
456 Property fontStyle = new Property(
457 0, union(fontLiterals4, fontStyleLiterals0), zeroFns);
458 builder.put("font-style", fontStyle);
459 builder.put("font-variant", new Property(
460 0, fontVariantLiterals0, zeroFns));
461 @SuppressWarnings("unchecked")
462 Property fontWeight = new Property(
463 0, union(fontLiterals0, fontStyleLiterals0), zeroFns);
464 builder.put("font-weight", fontWeight);
465 Property height = new Property(5, bottomLiterals0, zeroFns);
466 builder.put("height", height);
467 Property letterSpacing = new Property(5, fontStyleLiterals0, zeroFns);
468 builder.put("letter-spacing", letterSpacing);
469 builder.put("line-height", new Property(1, fontStyleLiterals0, zeroFns));
470 @SuppressWarnings("unchecked")
471 Property listStyle = new Property(
472 16,
473 union(listStyleLiterals0, listStyleLiterals1, listStyleLiterals2),
474 backgroundImageFunctions);
475 builder.put("list-style", listStyle);
476 builder.put("list-style-image", new Property(
477 16, cueLiterals0, backgroundImageFunctions));
478 @SuppressWarnings("unchecked")
479 Property listStylePosition = new Property(
480 0, union(listStyleLiterals1, mozOpacityLiterals0), zeroFns);
481 builder.put("list-style-position", listStylePosition);
482 @SuppressWarnings("unchecked")
483 Property listStyleType = new Property(
484 0, union(listStyleLiterals0, listStyleLiterals2), zeroFns);
485 builder.put("list-style-type", listStyleType);
486 Property margin = new Property(1, bottomLiterals0, zeroFns);
487 builder.put("margin", margin);
488 Property maxHeight = new Property(1, maxHeightLiterals0, zeroFns);
489 builder.put("max-height", maxHeight);
490 //Property opacity = new Property(1, mozOpacityLiterals0, zeroFns);
491 //builder.put("opacity", opacity);
492 //builder.put("overflow", new Property(0, overflowLiterals0, zeroFns));
493 //@SuppressWarnings("unchecked")
494 //Property overflowX = new Property(
495 // 0, union(overflowXLiterals0, overflowXLiterals1), zeroFns);
496 //builder.put("overflow-x", overflowX);
497 Property padding = new Property(1, mozOpacityLiterals0, zeroFns);
498 builder.put("padding", padding);
499 //@SuppressWarnings("unchecked")
500 //Property pageBreakAfter = new Property(
501 // 0, union(azimuthLiterals1, pageBreakAfterLiterals0), zeroFns);
502 //builder.put("page-break-after", pageBreakAfter);
503 //builder.put("page-break-inside", new Property(
504 // 0, pageBreakInsideLiterals0, zeroFns));
505 @SuppressWarnings("unchecked")
506 Property pitch = new Property(
507 5, union(mozOutlineWidthLiterals0, pitchLiterals0), zeroFns);
508 builder.put("pitch", pitch);
509 //builder.put("play-during", new Property(
510 // 16, playDuringLiterals0, zeroFns));
511 //@SuppressWarnings("unchecked")
512 //Property position = new Property(
513 // 0, union(mozOpacityLiterals0, positionLiterals0), zeroFns);
514 //builder.put("position", position);
515 builder.put("quotes", new Property(8, cueLiterals0, zeroFns));
516 builder.put("speak", new Property(0, speakLiterals0, zeroFns));
517 builder.put("speak-header", new Property(
518 0, speakHeaderLiterals0, zeroFns));
519 @SuppressWarnings("unchecked")
520 Property speakNumeral = new Property(
521 0, union(mozOpacityLiterals0, speakNumeralLiterals0), zeroFns);
522 builder.put("speak-numeral", speakNumeral);
523 builder.put("speak-punctuation", new Property(
524 0, speakPunctuationLiterals0, zeroFns));
525 @SuppressWarnings("unchecked")
526 Property speechRate = new Property(
527 5, union(mozOutlineWidthLiterals0, speechRateLiterals0), zeroFns);
528 builder.put("speech-rate", speechRate);
529 builder.put("table-layout", new Property(
530 0, tableLayoutLiterals0, zeroFns));
531 @SuppressWarnings("unchecked")
532 Property textAlign = new Property(
533 0, union(azimuthLiterals1, textAlignLiterals0), zeroFns);
534 builder.put("text-align", textAlign);
535 @SuppressWarnings("unchecked")
536 Property textDecoration = new Property(
537 0, union(cueLiterals0, textDecorationLiterals0), zeroFns);
538 builder.put("text-decoration", textDecoration);
539 @SuppressWarnings("unchecked")
540 Property textTransform = new Property(
541 0, union(cueLiterals0, textTransformLiterals0), zeroFns);
542 builder.put("text-transform", textTransform);
543 @SuppressWarnings("unchecked")
544 Property textWrap = new Property(
545 0, union(contentLiterals0, textWrapLiterals0), zeroFns);
546 builder.put("text-wrap", textWrap);
547 @SuppressWarnings("unchecked")
548 Property unicodeBidi = new Property(
549 0, union(fontStyleLiterals0, unicodeBidiLiterals0), zeroFns);
550 builder.put("unicode-bidi", unicodeBidi);
551 @SuppressWarnings("unchecked")
552 Property verticalAlign = new Property(
553 5,
554 union(backgroundLiterals2, mozOpacityLiterals0, verticalAlignLiterals0),
555 zeroFns);
556 builder.put("vertical-align", verticalAlign);
557 //builder.put("visibility", new Property(0, visibilityLiterals0, zeroFns));
558 @SuppressWarnings("unchecked")
559 Property voiceFamily = new Property(
560 8, union(fontFamilyLiterals0, voiceFamilyLiterals0), zeroFns);
561 builder.put("voice-family", voiceFamily);
562 @SuppressWarnings("unchecked")
563 Property volume = new Property(
564 1, union(mozOutlineWidthLiterals0, volumeLiterals0), zeroFns);
565 builder.put("volume", volume);
566 @SuppressWarnings("unchecked")
567 Property whiteSpace = new Property(
568 0, union(fontStyleLiterals0, whiteSpaceLiterals0), zeroFns);
569 builder.put("white-space", whiteSpace);
570 builder.put("word-wrap", new Property(0, wordWrapLiterals0, zeroFns));
571 //builder.put("zoom", new Property(1, fontStretchLiterals1, zeroFns));
572 Property rgb$Fun = new Property(1, rgb$FunLiterals0, zeroFns);
573 builder.put("rgb()", rgb$Fun);
574 @SuppressWarnings("unchecked")
575 Property image$Fun = new Property(
576 18, union(mozOutlineLiterals0, rgb$FunLiterals0), mozOutlineFunctions);
577 builder.put("image()", image$Fun);
578 @SuppressWarnings("unchecked")
579 Property linearGradient$Fun = new Property(
580 7,
581 union(azimuthLiterals1, backgroundLiterals2,
582 linearGradient$FunLiterals0, mozOutlineLiterals0),
583 mozOutlineFunctions);
584 builder.put("linear-gradient()", linearGradient$Fun);
585 @SuppressWarnings("unchecked")
586 Property radialGradient$Fun = new Property(
587 7,
588 union(azimuthLiterals1, backgroundLiterals2, mozOutlineLiterals0,
589 radialGradient$FunLiterals0, radialGradient$FunLiterals1),
590 mozOutlineFunctions);
591 builder.put("radial-gradient()", radialGradient$Fun);
592 builder.put("rect()", new Property(5, rect$FunLiterals0, zeroFns));
593 builder.put("alpha()", new Property(1, alpha$FunLiterals0, zeroFns));
594 builder.put("-moz-border-radius-bottomright", mozBorderRadiusBottomleft);
595 builder.put("-moz-border-radius-topleft", mozBorderRadiusBottomleft);
596 builder.put("-moz-border-radius-topright", mozBorderRadiusBottomleft);
597 builder.put("-moz-box-shadow", boxShadow);
598 builder.put("-webkit-border-bottom-left-radius", mozBorderRadiusBottomleft);
599 builder.put("-webkit-border-bottom-right-radius",
600 mozBorderRadiusBottomleft);
601 builder.put("-webkit-border-radius", mozBorderRadius);
602 builder.put("-webkit-border-radius-bottom-left", mozBorderRadiusBottomleft);
603 builder.put("-webkit-border-radius-bottom-right",
604 mozBorderRadiusBottomleft);
605 builder.put("-webkit-border-radius-top-left", mozBorderRadiusBottomleft);
606 builder.put("-webkit-border-radius-top-right", mozBorderRadiusBottomleft);
607 builder.put("-webkit-border-top-left-radius", mozBorderRadiusBottomleft);
608 builder.put("-webkit-border-top-right-radius", mozBorderRadiusBottomleft);
609 builder.put("-webkit-box-shadow", boxShadow);
610 builder.put("border-bottom", border);
611 builder.put("border-bottom-left-radius", mozBorderRadiusBottomleft);
612 builder.put("border-bottom-right-radius", mozBorderRadiusBottomleft);
613 builder.put("border-bottom-style", mozOutlineStyle);
614 builder.put("border-bottom-width", mozOutlineWidth);
615 builder.put("border-color", borderBottomColor);
616 builder.put("border-left", border);
617 builder.put("border-left-color", borderBottomColor);
618 builder.put("border-left-style", mozOutlineStyle);
619 builder.put("border-left-width", mozOutlineWidth);
620 builder.put("border-radius", mozBorderRadius);
621 builder.put("border-right", border);
622 builder.put("border-right-color", borderBottomColor);
623 builder.put("border-right-style", mozOutlineStyle);
624 builder.put("border-right-width", mozOutlineWidth);
625 builder.put("border-style", mozOutlineStyle);
626 builder.put("border-top", border);
627 builder.put("border-top-color", borderBottomColor);
628 builder.put("border-top-left-radius", mozBorderRadiusBottomleft);
629 builder.put("border-top-right-radius", mozBorderRadiusBottomleft);
630 builder.put("border-top-style", mozOutlineStyle);
631 builder.put("border-top-width", mozOutlineWidth);
632 builder.put("border-width", mozOutlineWidth);
633 builder.put("cue-after", cue);
634 builder.put("cue-before", cue);
635 //builder.put("left", height);
636 builder.put("margin-bottom", margin);
637 builder.put("margin-left", margin);
638 builder.put("margin-right", margin);
639 builder.put("margin-top", margin);
640 builder.put("max-width", maxHeight);
641 builder.put("min-height", margin);
642 builder.put("min-width", margin);
643 builder.put("outline", mozOutline);
644 builder.put("outline-color", mozOutlineColor);
645 builder.put("outline-style", mozOutlineStyle);
646 builder.put("outline-width", mozOutlineWidth);
647 //builder.put("overflow-y", overflowX);
648 builder.put("padding-bottom", padding);
649 builder.put("padding-left", padding);
650 builder.put("padding-right", padding);
651 builder.put("padding-top", padding);
652 //builder.put("page-break-before", pageBreakAfter);
653 builder.put("pause", borderSpacing);
654 builder.put("pause-after", borderSpacing);
655 builder.put("pause-before", borderSpacing);
656 builder.put("pitch-range", borderSpacing);
657 builder.put("richness", borderSpacing);
658 //builder.put("right", height);
659 builder.put("stress", borderSpacing);
660 builder.put("text-indent", borderSpacing);
661 builder.put("text-overflow", oTextOverflow);
662 builder.put("text-shadow", boxShadow);
663 //builder.put("top", height);
664 builder.put("width", margin);
665 builder.put("word-spacing", letterSpacing);
666 //builder.put("z-index", bottom);
667 builder.put("rgba()", rgb$Fun);
668 builder.put("repeating-linear-gradient()", linearGradient$Fun);
669 builder.put("repeating-radial-gradient()", radialGradient$Fun);
670 DEFAULT_PROPERTIES = builder.build();
671 }
672
673 private static <T> ImmutableSet<T> union(ImmutableSet<T>... subsets) {
674 ImmutableSet.Builder<T> all = ImmutableSet.builder();
675 for (ImmutableSet<T> subset : subsets) {
676 all.addAll(subset);
677 }
678 return all.build();
679 }
680
681 static final CssSchema DEFAULT = new CssSchema(DEFAULT_PROPERTIES);
682
683 /** Dumps key and literal list to stdout for easy examination. */
684 public static void main(String... argv) {
685 SortedSet<String> keys = Sets.newTreeSet();
686 SortedSet<String> literals = Sets.newTreeSet();
687 for (ImmutableMap.Entry<String, Property> e
688 : DEFAULT_PROPERTIES.entrySet()) {
689 keys.add(e.getKey());
690 literals.addAll(e.getValue().literals);
691 }
692 for (String key : keys) {
693 System.out.println(key);
694 }
695 System.out.println();
696 for (String literal : literals) {
697 System.out.println(literal);
698 }
699 }
700 }