• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2010 Nikita Vasilyev. All rights reserved.
3 * Copyright (C) 2010 Joseph Pecoraro. All rights reserved.
4 * Copyright (C) 2010 Google Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *     * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *     * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 *     * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/**
34 * @constructor
35 * @param {!Array.<!{name: string, longhands: !Array.<string>}|string>} properties
36 */
37WebInspector.CSSMetadata = function(properties)
38{
39    this._values = /** !Array.<string> */ ([]);
40    this._longhands = {};
41    this._shorthands = {};
42    for (var i = 0; i < properties.length; ++i) {
43        var property = properties[i];
44        if (typeof property === "string") {
45            this._values.push(property);
46            continue;
47        }
48        var propertyName = property.name;
49        this._values.push(propertyName);
50
51        var longhands = properties[i].longhands;
52        if (longhands) {
53            this._longhands[propertyName] = longhands;
54            for (var j = 0; j < longhands.length; ++j) {
55                var longhandName = longhands[j];
56                var shorthands = this._shorthands[longhandName];
57                if (!shorthands) {
58                    shorthands = [];
59                    this._shorthands[longhandName] = shorthands;
60                }
61                shorthands.push(propertyName);
62            }
63        }
64    }
65    this._values.sort();
66}
67
68/**
69 * @type {!WebInspector.CSSMetadata}
70 */
71WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata([]);
72
73/**
74 * @param {string} propertyName
75 * @return {boolean}
76 */
77WebInspector.CSSMetadata.isColorAwareProperty = function(propertyName)
78{
79    return WebInspector.CSSMetadata._colorAwareProperties[propertyName] === true;
80}
81
82/**
83 * @return {!Object.<string, boolean>}
84 */
85WebInspector.CSSMetadata.colors = function()
86{
87    if (!WebInspector.CSSMetadata._colorsKeySet)
88        WebInspector.CSSMetadata._colorsKeySet = WebInspector.CSSMetadata._colors.keySet();
89    return WebInspector.CSSMetadata._colorsKeySet;
90}
91
92// Taken from http://www.w3.org/TR/CSS21/propidx.html.
93WebInspector.CSSMetadata.InheritedProperties = [
94    "azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation",
95    "empty-cells", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font", "letter-spacing",
96    "line-height", "list-style-image", "list-style-position", "list-style-type", "list-style", "orphans", "pitch-range",
97    "pitch", "quotes", "resize", "richness", "speak-header", "speak-numeral", "speak-punctuation", "speak", "speech-rate", "stress",
98    "text-align", "text-indent", "text-transform", "text-shadow", "visibility", "voice-family", "volume", "white-space", "widows",
99    "word-spacing", "zoom"
100].keySet();
101
102// These non-standard Blink-specific properties augment the InheritedProperties.
103WebInspector.CSSMetadata.NonStandardInheritedProperties = [
104    "-webkit-font-smoothing"
105].keySet();
106
107/**
108 * @param {string} name
109 * @return {string}
110 */
111WebInspector.CSSMetadata.canonicalPropertyName = function(name)
112{
113    if (!name || name.length < 9 || name.charAt(0) !== "-")
114        return name.toLowerCase();
115    var match = name.match(/(?:-webkit-)(.+)/);
116    var propertiesSet = WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet();
117    var hasSupportedProperties = WebInspector.CSSMetadata.cssPropertiesMetainfo._values.length > 0;
118    if (!match || (hasSupportedProperties && !propertiesSet.hasOwnProperty(match[1].toLowerCase())))
119        return name.toLowerCase();
120    return match[1].toLowerCase();
121}
122
123/**
124 * @param {string} propertyName
125 * @return {boolean}
126 */
127WebInspector.CSSMetadata.isPropertyInherited = function(propertyName)
128{
129    return !!(WebInspector.CSSMetadata.InheritedProperties[WebInspector.CSSMetadata.canonicalPropertyName(propertyName)]
130            || WebInspector.CSSMetadata.NonStandardInheritedProperties[propertyName.toLowerCase()]);
131}
132
133WebInspector.CSSMetadata._colors = [
134    "aqua", "black", "blue", "fuchsia", "gray", "green", "lime", "maroon", "navy", "olive", "orange", "purple", "red",
135    "silver", "teal", "white", "yellow", "transparent", "currentcolor", "grey", "aliceblue", "antiquewhite",
136    "aquamarine", "azure", "beige", "bisque", "blanchedalmond", "blueviolet", "brown", "burlywood", "cadetblue",
137    "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
138    "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange",
139    "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey",
140    "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
141    "floralwhite", "forestgreen", "gainsboro", "ghostwhite", "gold", "goldenrod", "greenyellow", "honeydew", "hotpink",
142    "indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
143    "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
144    "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
145    "limegreen", "linen", "magenta", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
146    "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream",
147    "mistyrose", "moccasin", "navajowhite", "oldlace", "olivedrab", "orangered", "orchid", "palegoldenrod", "palegreen",
148    "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "rosybrown",
149    "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "skyblue", "slateblue",
150    "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "thistle", "tomato", "turquoise", "violet",
151    "wheat", "whitesmoke", "yellowgreen"
152];
153
154WebInspector.CSSMetadata._colorAwareProperties = [
155    "background", "background-color", "background-image", "border", "border-color", "border-top", "border-right", "border-bottom",
156    "border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "box-shadow", "color",
157    "fill", "outline", "outline-color", "stroke", "text-line-through-color", "text-overline-color",
158    "text-shadow", "text-underline-color", "-webkit-box-shadow", "-webkit-column-rule-color",
159    "-webkit-text-decoration-color", "-webkit-text-emphasis", "-webkit-text-emphasis-color"
160].keySet();
161
162WebInspector.CSSMetadata._propertyDataMap = {
163    "table-layout": { values: [
164        "auto", "fixed"
165    ] },
166    "visibility": { values: [
167        "hidden", "visible", "collapse"
168    ] },
169    "background-repeat": { values: [
170        "repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round"
171    ] },
172    "content": { values: [
173        "list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote"
174    ] },
175    "list-style-image": { values: [
176        "none"
177    ] },
178    "clear": { values: [
179        "none", "left", "right", "both"
180    ] },
181    "text-underline-mode": { values: [
182        "continuous", "skip-white-space"
183    ] },
184    "overflow-x": { values: [
185        "hidden", "auto", "visible", "overlay", "scroll"
186    ] },
187    "stroke-linejoin": { values: [
188        "round", "miter", "bevel"
189    ] },
190    "baseline-shift": { values: [
191        "baseline", "sub", "super"
192    ] },
193    "border-bottom-width": { values: [
194        "medium", "thick", "thin"
195    ] },
196    "marquee-speed": { values: [
197        "normal", "slow", "fast"
198    ] },
199    "margin-top-collapse": { values: [
200        "collapse", "separate", "discard"
201    ] },
202    "max-height": { values: [
203        "none"
204    ] },
205    "box-orient": { values: [
206        "horizontal", "vertical", "inline-axis", "block-axis"
207    ], },
208    "font-stretch": { values: [
209        "normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
210        "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
211    ] },
212    "text-underline-style": { values: [
213        "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
214    ] },
215    "text-overline-mode": { values: [
216        "continuous", "skip-white-space"
217    ] },
218    "-webkit-background-composite": { values: [
219        "highlight", "clear", "copy", "source-over", "source-in", "source-out", "source-atop", "destination-over",
220        "destination-in", "destination-out", "destination-atop", "xor", "plus-darker", "plus-lighter"
221    ] },
222    "border-left-width": { values: [
223        "medium", "thick", "thin"
224    ] },
225    "box-shadow": { values: [
226        "inset", "none"
227    ] },
228    "-webkit-writing-mode": { values: [
229        "lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt"
230    ] },
231    "text-line-through-mode": { values: [
232        "continuous", "skip-white-space"
233    ] },
234    "border-collapse": { values: [
235        "collapse", "separate"
236    ] },
237    "page-break-inside": { values: [
238        "auto", "avoid"
239    ] },
240    "border-top-width": { values: [
241        "medium", "thick", "thin"
242    ] },
243    "outline-color": { values: [
244        "invert"
245    ] },
246    "text-line-through-style": { values: [
247        "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
248    ] },
249    "outline-style": { values: [
250        "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
251    ] },
252    "cursor": { values: [
253        "none", "copy", "auto", "crosshair", "default", "pointer", "move", "vertical-text", "cell", "context-menu",
254        "alias", "progress", "no-drop", "not-allowed", "-webkit-zoom-in", "-webkit-zoom-out", "e-resize", "ne-resize",
255        "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize",
256        "nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "wait", "help", "all-scroll", "-webkit-grab",
257        "-webkit-grabbing"
258    ] },
259    "border-width": { values: [
260        "medium", "thick", "thin"
261    ] },
262    "border-style": { values: [
263        "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
264    ] },
265    "size": { values: [
266        "a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait"
267    ] },
268    "background-size": { values: [
269        "contain", "cover"
270    ] },
271    "direction": { values: [
272        "ltr", "rtl"
273    ] },
274    "marquee-direction": { values: [
275        "left", "right", "auto", "reverse", "forwards", "backwards", "ahead", "up", "down"
276    ] },
277    "enable-background": { values: [
278        "accumulate", "new"
279    ] },
280    "float": { values: [
281        "none", "left", "right"
282    ] },
283    "overflow-y": { values: [
284        "hidden", "auto", "visible", "overlay", "scroll"
285    ] },
286    "margin-bottom-collapse": { values: [
287        "collapse",  "separate", "discard"
288    ] },
289    "box-reflect": { values: [
290        "left", "right", "above", "below"
291    ] },
292    "overflow": { values: [
293        "hidden", "auto", "visible", "overlay", "scroll"
294    ] },
295    "text-rendering": { values: [
296        "auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision"
297    ] },
298    "text-align": { values: [
299        "-webkit-auto", "start", "end", "left", "right", "center", "justify", "-webkit-left", "-webkit-right", "-webkit-center"
300    ] },
301    "list-style-position": { values: [
302        "outside", "inside", "hanging"
303    ] },
304    "margin-bottom": { values: [
305        "auto"
306    ] },
307    "color-interpolation": { values: [
308        "linearrgb"
309    ] },
310    "background-origin": { values: [
311        "border-box", "content-box", "padding-box"
312    ] },
313    "word-wrap": { values: [
314        "normal", "break-word"
315    ] },
316    "font-weight": { values: [
317        "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"
318    ] },
319    "margin-before-collapse": { values: [
320        "collapse", "separate", "discard"
321    ] },
322    "text-overline-width": { values: [
323        "normal", "medium", "auto", "thick", "thin"
324    ] },
325    "text-transform": { values: [
326        "none", "capitalize", "uppercase", "lowercase"
327    ] },
328    "border-right-style": { values: [
329        "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
330    ] },
331    "border-left-style": { values: [
332        "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
333    ] },
334    "-webkit-text-emphasis": { values: [
335        "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
336    ] },
337    "font-style": { values: [
338        "italic", "oblique", "normal"
339    ] },
340    "speak": { values: [
341        "none", "normal", "spell-out", "digits", "literal-punctuation", "no-punctuation"
342    ] },
343    "color-rendering": { values: [
344        "auto", "optimizeSpeed", "optimizeQuality"
345    ] },
346    "list-style-type": { values: [
347        "none", "inline", "disc", "circle", "square", "decimal", "decimal-leading-zero", "arabic-indic", "binary", "bengali",
348        "cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lower-hexadecimal", "lao", "malayalam",
349        "mongolian", "myanmar", "octal", "oriya", "persian", "urdu", "telugu", "tibetan", "thai", "upper-hexadecimal",
350        "lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "afar",
351        "ethiopic-halehame-aa-et", "ethiopic-halehame-aa-er", "amharic", "ethiopic-halehame-am-et", "amharic-abegede",
352        "ethiopic-abegede-am-et", "cjk-earthly-branch", "cjk-heavenly-stem", "ethiopic", "ethiopic-halehame-gez",
353        "ethiopic-abegede", "ethiopic-abegede-gez", "hangul-consonant", "hangul", "lower-norwegian", "oromo",
354        "ethiopic-halehame-om-et", "sidama", "ethiopic-halehame-sid-et", "somali", "ethiopic-halehame-so-et", "tigre",
355        "ethiopic-halehame-tig", "tigrinya-er", "ethiopic-halehame-ti-er", "tigrinya-er-abegede",
356        "ethiopic-abegede-ti-er", "tigrinya-et", "ethiopic-halehame-ti-et", "tigrinya-et-abegede",
357        "ethiopic-abegede-ti-et", "upper-greek", "upper-norwegian", "asterisks", "footnotes", "hebrew", "armenian",
358        "lower-armenian", "upper-armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha",
359        "katakana-iroha"
360    ] },
361    "-webkit-text-combine": { values: [
362        "none", "horizontal"
363    ] },
364    "outline": { values: [
365        "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
366    ] },
367    "font": { values: [
368        "caption", "icon", "menu", "message-box", "small-caption", "-webkit-mini-control", "-webkit-small-control",
369        "-webkit-control", "status-bar", "italic", "oblique", "small-caps", "normal", "bold", "bolder", "lighter",
370        "100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium",
371        "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger", "serif", "sans-serif", "cursive",
372        "fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
373    ] },
374    "dominant-baseline": { values: [
375        "middle", "auto", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging",
376        "mathematical", "use-script", "no-change", "reset-size"
377    ] },
378    "display": { values: [
379        "none", "inline", "block", "list-item", "run-in", "compact", "inline-block", "table", "inline-table",
380        "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group",
381        "table-column", "table-cell", "table-caption", "-webkit-box", "-webkit-inline-box",
382        "flex", "inline-flex", "grid", "inline-grid"
383    ] },
384    "-webkit-text-emphasis-position": { values: [
385        "over", "under"
386    ] },
387    "image-rendering": { values: [
388        "auto", "optimizeSpeed", "optimizeQuality"
389    ] },
390    "alignment-baseline": { values: [
391        "baseline", "middle", "auto", "before-edge", "after-edge", "central", "text-before-edge", "text-after-edge",
392        "ideographic", "alphabetic", "hanging", "mathematical"
393    ] },
394    "outline-width": { values: [
395        "medium", "thick", "thin"
396    ] },
397    "text-line-through-width": { values: [
398        "normal", "medium", "auto", "thick", "thin"
399    ] },
400    "box-align": { values: [
401        "baseline", "center", "stretch", "start", "end"
402    ] },
403    "border-right-width": { values: [
404        "medium", "thick", "thin"
405    ] },
406    "border-top-style": { values: [
407        "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
408    ] },
409    "line-height": { values: [
410        "normal"
411    ] },
412    "text-overflow": { values: [
413        "clip", "ellipsis"
414    ] },
415    "overflow-wrap": { values: [
416        "normal", "break-word"
417    ] },
418    "box-direction": { values: [
419        "normal", "reverse"
420    ] },
421    "margin-after-collapse": { values: [
422        "collapse", "separate", "discard"
423    ] },
424    "page-break-before": { values: [
425        "left", "right", "auto", "always", "avoid"
426    ] },
427    "border-image": { values: [
428        "repeat", "stretch"
429    ] },
430    "text-decoration": { values: [
431        "blink", "line-through", "overline", "underline"
432    ] },
433    "position": { values: [
434        "absolute", "fixed", "relative", "static"
435    ] },
436    "font-family": { values: [
437        "serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
438    ] },
439    "text-overflow-mode": { values: [
440        "clip", "ellipsis"
441    ] },
442    "border-bottom-style": { values: [
443        "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
444    ] },
445    "unicode-bidi": { values: [
446        "normal", "bidi-override", "embed", "isolate", "isolate-override", "plaintext"
447    ] },
448    "clip-rule": { values: [
449        "nonzero", "evenodd"
450    ] },
451    "margin-left": { values: [
452        "auto"
453    ] },
454    "margin-top": { values: [
455        "auto"
456    ] },
457    "zoom": { values: [
458        "normal", "document", "reset"
459    ] },
460    "text-overline-style": { values: [
461        "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
462    ] },
463    "max-width": { values: [
464        "none"
465    ] },
466    "caption-side": { values: [
467        "top", "bottom"
468    ] },
469    "empty-cells": { values: [
470        "hide", "show"
471    ] },
472    "pointer-events": { values: [
473        "none", "all", "auto", "visible", "visiblepainted", "visiblefill", "visiblestroke", "painted", "fill", "stroke", "bounding-box"
474    ] },
475    "letter-spacing": { values: [
476        "normal"
477    ] },
478    "background-clip": { values: [
479        "border-box", "content-box", "padding-box"
480    ] },
481    "-webkit-font-smoothing": { values: [
482        "none", "auto", "antialiased", "subpixel-antialiased"
483    ] },
484    "border": { values: [
485        "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
486    ] },
487    "font-size": { values: [
488        "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller",
489        "larger"
490    ] },
491    "font-variant": { values: [
492        "small-caps", "normal"
493    ] },
494    "vertical-align": { values: [
495        "baseline", "middle", "sub", "super", "text-top", "text-bottom", "top", "bottom", "-webkit-baseline-middle"
496    ] },
497    "marquee-style": { values: [
498        "none", "scroll", "slide", "alternate"
499    ] },
500    "white-space": { values: [
501        "normal", "nowrap", "pre", "pre-line", "pre-wrap"
502    ] },
503    "text-underline-width": { values: [
504        "normal", "medium", "auto", "thick", "thin"
505    ] },
506    "box-lines": { values: [
507        "single", "multiple"
508    ] },
509    "page-break-after": { values: [
510        "left", "right", "auto", "always", "avoid"
511    ] },
512    "clip-path": { values: [
513        "none"
514    ] },
515    "margin": { values: [
516        "auto"
517    ] },
518    "marquee-repetition": { values: [
519        "infinite"
520    ] },
521    "margin-right": { values: [
522        "auto"
523    ] },
524    "word-break": { values: [
525        "normal", "break-all", "break-word"
526    ] },
527    "word-spacing": { values: [
528        "normal"
529    ] },
530    "-webkit-text-emphasis-style": { values: [
531        "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
532    ] },
533    "transform": { values: [
534        "scale", "scaleX", "scaleY", "scale3d", "rotate", "rotateX", "rotateY", "rotateZ", "rotate3d", "skew", "skewX", "skewY",
535        "translate", "translateX", "translateY", "translateZ", "translate3d", "matrix", "matrix3d", "perspective"
536    ] },
537    "image-resolution": { values: [
538        "from-image", "snap"
539    ] },
540    "box-sizing": { values: [
541        "content-box", "padding-box", "border-box"
542    ] },
543    "clip": { values: [
544        "auto"
545    ] },
546    "resize": { values: [
547        "none", "both", "horizontal", "vertical"
548    ] },
549    "align-content": { values: [
550        "flex-start", "flex-end", "center", "space-between", "space-around", "stretch"
551    ] },
552    "align-items": {  values: [
553        "flex-start", "flex-end", "center", "baseline", "stretch"
554    ] },
555    "align-self": {  values: [
556        "auto", "flex-start", "flex-end", "center", "baseline", "stretch"
557    ] },
558    "flex-direction": { values: [
559        "row", "row-reverse", "column", "column-reverse"
560    ] },
561    "justify-content": { values: [
562        "flex-start", "flex-end", "center", "space-between", "space-around"
563    ] },
564    "flex-wrap": { values: [
565        "nowrap", "wrap", "wrap-reverse"
566    ] },
567    "-webkit-animation-timing-function": { values: [
568        "ease", "linear", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "steps", "cubic-bezier"
569    ] },
570    "-webkit-animation-direction": { values: [
571        "normal", "reverse", "alternate", "alternate-reverse"
572    ] },
573    "-webkit-animation-play-state": { values: [
574        "running", "paused"
575    ] },
576    "-webkit-animation-fill-mode": { values: [
577        "none", "forwards", "backwards", "both"
578    ] },
579    "-webkit-backface-visibility": { values: [
580        "visible", "hidden"
581    ] },
582    "-webkit-box-decoration-break": { values: [
583        "slice", "clone"
584    ] },
585    "-webkit-column-break-after": { values: [
586        "auto", "always", "avoid", "left", "right", "page", "column", "avoid-page", "avoid-column"
587    ] },
588    "-webkit-column-break-before": { values: [
589        "auto", "always", "avoid", "left", "right", "page", "column", "avoid-page", "avoid-column"
590    ] },
591    "-webkit-column-break-inside": { values: [
592        "auto", "avoid", "avoid-page", "avoid-column"
593    ] },
594    "-webkit-column-span": { values: [
595        "none", "all"
596    ] },
597    "-webkit-column-count": { values: [
598        "auto"
599    ] },
600    "-webkit-column-gap": { values: [
601        "normal"
602    ] },
603    "-webkit-line-break": { values: [
604        "auto", "loose", "normal", "strict"
605    ] },
606    "-webkit-perspective": { values: [
607        "none"
608    ] },
609    "-webkit-perspective-origin": { values: [
610        "left", "center", "right", "top", "bottom"
611    ] },
612    "text-align-last": { values: [
613        "auto", "start", "end", "left", "right", "center", "justify"
614    ] },
615    "-webkit-text-decoration-line": { values: [
616        "none", "underline", "overline", "line-through", "blink"
617    ] },
618    "-webkit-text-decoration-style": { values: [
619        "solid", "double", "dotted", "dashed", "wavy"
620    ] },
621    "-webkit-text-decoration-skip": { values: [
622        "none", "objects", "spaces", "ink", "edges", "box-decoration"
623    ] },
624    "-webkit-transform-origin": { values: [
625        "left", "center", "right", "top", "bottom"
626    ] },
627    "-webkit-transform-style": { values: [
628        "flat", "preserve-3d"
629    ] },
630    "-webkit-transition-timing-function": { values: [
631        "ease", "linear", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "steps", "cubic-bezier"
632    ] },
633
634    "-webkit-flex": { m: "flexbox" },
635    "-webkit-flex-basis": { m: "flexbox" },
636    "-webkit-flex-flow": { m: "flexbox" },
637    "-webkit-flex-grow": { m: "flexbox" },
638    "-webkit-flex-shrink": { m: "flexbox" },
639    "-webkit-animation": { m: "animations" },
640    "-webkit-animation-delay": { m: "animations" },
641    "-webkit-animation-duration": { m: "animations" },
642    "-webkit-animation-iteration-count": { m: "animations" },
643    "-webkit-animation-name": { m: "animations" },
644    "-webkit-column-rule": { m: "multicol" },
645    "-webkit-column-rule-color": { m: "multicol", a: "crc" },
646    "-webkit-column-rule-style": { m: "multicol", a: "crs" },
647    "-webkit-column-rule-width": { m: "multicol", a: "crw" },
648    "-webkit-column-width": { m: "multicol", a: "cw" },
649    "-webkit-columns": { m: "multicol" },
650    "-webkit-order": { m: "flexbox" },
651    "-webkit-text-decoration-color": { m: "text-decor" },
652    "-webkit-text-emphasis-color": { m: "text-decor" },
653    "-webkit-transition": { m: "transitions" },
654    "-webkit-transition-delay": { m: "transitions" },
655    "-webkit-transition-duration": { m: "transitions" },
656    "-webkit-transition-property": { m: "transitions" },
657    "background": { m: "background" },
658    "background-attachment": { m: "background" },
659    "background-color": { m: "background" },
660    "background-image": { m: "background" },
661    "background-position": { m: "background" },
662    "background-position-x": { m: "background" },
663    "background-position-y": { m: "background" },
664    "background-repeat-x": { m: "background" },
665    "background-repeat-y": { m: "background" },
666    "border-top": { m: "background" },
667    "border-right": { m: "background" },
668    "border-bottom": { m: "background" },
669    "border-left": { m: "background" },
670    "border-radius": { m: "background" },
671    "bottom": { m: "visuren" },
672    "color": { m: "color", a: "foreground" },
673    "counter-increment": { m: "generate" },
674    "counter-reset": { m: "generate" },
675    "grid-template-columns": { m: "grid" },
676    "grid-template-rows": { m: "grid" },
677    "height": { m: "box" },
678    "image-orientation": { m: "images" },
679    "left": { m: "visuren" },
680    "list-style": { m: "lists" },
681    "min-height": { m: "box" },
682    "min-width": { m: "box" },
683    "opacity": { m: "color", a: "transparency" },
684    "orphans": { m: "page" },
685    "outline-offset": { m: "ui" },
686    "padding": { m: "box", a: "padding1" },
687    "padding-bottom": { m: "box" },
688    "padding-left": { m: "box" },
689    "padding-right": { m: "box" },
690    "padding-top": { m: "box" },
691    "page": { m: "page" },
692    "quotes": { m: "generate" },
693    "right": { m: "visuren" },
694    "tab-size": { m: "text" },
695    "text-indent": { m: "text" },
696    "text-shadow": { m: "text-decor" },
697    "top": { m: "visuren" },
698    "unicode-range": { m: "fonts", a: "descdef-unicode-range" },
699    "widows": { m: "page" },
700    "width": { m: "box" },
701    "z-index": { m: "visuren" }
702}
703
704/**
705 * @param {string} propertyName
706 * @return {!WebInspector.CSSMetadata}
707 */
708WebInspector.CSSMetadata.keywordsForProperty = function(propertyName)
709{
710    var acceptedKeywords = ["inherit", "initial"];
711    var descriptor = WebInspector.CSSMetadata.descriptor(propertyName);
712    if (descriptor && descriptor.values)
713        acceptedKeywords.push.apply(acceptedKeywords, descriptor.values);
714    if (propertyName in WebInspector.CSSMetadata._colorAwareProperties)
715        acceptedKeywords.push.apply(acceptedKeywords, WebInspector.CSSMetadata._colors);
716    return new WebInspector.CSSMetadata(acceptedKeywords);
717}
718
719/**
720 * @param {string} propertyName
721 * @return {?Object}
722 */
723WebInspector.CSSMetadata.descriptor = function(propertyName)
724{
725    if (!propertyName)
726        return null;
727    var unprefixedName = propertyName.replace(/^-webkit-/, "");
728    var entry = WebInspector.CSSMetadata._propertyDataMap[propertyName];
729    if (!entry && unprefixedName !== propertyName)
730        entry = WebInspector.CSSMetadata._propertyDataMap[unprefixedName];
731    return entry || null;
732}
733
734WebInspector.CSSMetadata.initializeWithSupportedProperties = function(properties)
735{
736    WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata(properties);
737}
738
739/**
740 * @return {!Object.<string, boolean>}
741 */
742WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet = function()
743{
744    if (!WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet)
745        WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet = WebInspector.CSSMetadata.cssPropertiesMetainfo.keySet();
746    return WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet;
747}
748
749// Weight of CSS properties based on their usage on a few popular websites: https://gist.github.com/3751436
750WebInspector.CSSMetadata.Weight = {
751    "-webkit-animation": 1,
752    "-webkit-animation-duration": 1,
753    "-webkit-animation-iteration-count": 1,
754    "-webkit-animation-name": 1,
755    "-webkit-animation-timing-function": 1,
756    "-webkit-appearance": 1,
757    "-webkit-background-clip": 2,
758    "-webkit-border-horizontal-spacing": 1,
759    "-webkit-border-vertical-spacing": 1,
760    "-webkit-box-shadow": 24,
761    "-webkit-font-smoothing": 2,
762    "-webkit-transition": 8,
763    "-webkit-transition-delay": 7,
764    "-webkit-transition-duration": 7,
765    "-webkit-transition-property": 7,
766    "-webkit-transition-timing-function": 6,
767    "-webkit-user-select": 1,
768    "background": 222,
769    "background-attachment": 144,
770    "background-clip": 143,
771    "background-color": 222,
772    "background-image": 201,
773    "background-origin": 142,
774    "background-size": 25,
775    "border": 121,
776    "border-bottom": 121,
777    "border-bottom-color": 121,
778    "border-bottom-left-radius": 50,
779    "border-bottom-right-radius": 50,
780    "border-bottom-style": 114,
781    "border-bottom-width": 120,
782    "border-collapse": 3,
783    "border-left": 95,
784    "border-left-color": 95,
785    "border-left-style": 89,
786    "border-left-width": 94,
787    "border-radius": 50,
788    "border-right": 93,
789    "border-right-color": 93,
790    "border-right-style": 88,
791    "border-right-width": 93,
792    "border-top": 111,
793    "border-top-color": 111,
794    "border-top-left-radius": 49,
795    "border-top-right-radius": 49,
796    "border-top-style": 104,
797    "border-top-width": 109,
798    "bottom": 16,
799    "box-shadow": 25,
800    "box-sizing": 2,
801    "clear": 23,
802    "color": 237,
803    "cursor": 34,
804    "direction": 4,
805    "display": 210,
806    "fill": 2,
807    "filter": 1,
808    "float": 105,
809    "font": 174,
810    "font-family": 25,
811    "font-size": 174,
812    "font-style": 9,
813    "font-weight": 89,
814    "height": 161,
815    "left": 54,
816    "letter-spacing": 3,
817    "line-height": 75,
818    "list-style": 17,
819    "list-style-image": 8,
820    "list-style-position": 8,
821    "list-style-type": 17,
822    "margin": 241,
823    "margin-bottom": 226,
824    "margin-left": 225,
825    "margin-right": 213,
826    "margin-top": 241,
827    "max-height": 5,
828    "max-width": 11,
829    "min-height": 9,
830    "min-width": 6,
831    "opacity": 24,
832    "outline": 10,
833    "outline-color": 10,
834    "outline-style": 10,
835    "outline-width": 10,
836    "overflow": 57,
837    "overflow-x": 56,
838    "overflow-y": 57,
839    "padding": 216,
840    "padding-bottom": 208,
841    "padding-left": 216,
842    "padding-right": 206,
843    "padding-top": 216,
844    "position": 136,
845    "resize": 1,
846    "right": 29,
847    "stroke": 1,
848    "stroke-width": 1,
849    "table-layout": 1,
850    "text-align": 66,
851    "text-decoration": 53,
852    "text-indent": 9,
853    "text-overflow": 8,
854    "text-shadow": 19,
855    "text-transform": 5,
856    "top": 71,
857    "transform": 1,
858    "unicode-bidi": 1,
859    "vertical-align": 37,
860    "visibility": 11,
861    "white-space": 24,
862    "width": 255,
863    "word-wrap": 6,
864    "z-index": 32,
865    "zoom": 10
866};
867
868
869WebInspector.CSSMetadata.prototype = {
870    /**
871     * @param {string} prefix
872     * @return {!Array.<string>}
873     */
874    startsWith: function(prefix)
875    {
876        var firstIndex = this._firstIndexOfPrefix(prefix);
877        if (firstIndex === -1)
878            return [];
879
880        var results = [];
881        while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix))
882            results.push(this._values[firstIndex++]);
883        return results;
884    },
885
886    /**
887     * @param {!Array.<string>} properties
888     * @return {number}
889     */
890    mostUsedOf: function(properties)
891    {
892        var maxWeight = 0;
893        var index = 0;
894        for (var i = 0; i < properties.length; i++) {
895            var weight = WebInspector.CSSMetadata.Weight[properties[i]];
896            if (!weight)
897                weight = WebInspector.CSSMetadata.Weight[WebInspector.CSSMetadata.canonicalPropertyName(properties[i])];
898            if (weight > maxWeight) {
899                maxWeight = weight;
900                index = i;
901            }
902        }
903        return index;
904    },
905
906    _firstIndexOfPrefix: function(prefix)
907    {
908        if (!this._values.length)
909            return -1;
910        if (!prefix)
911            return 0;
912
913        var maxIndex = this._values.length - 1;
914        var minIndex = 0;
915        var foundIndex;
916
917        do {
918            var middleIndex = (maxIndex + minIndex) >> 1;
919            if (this._values[middleIndex].startsWith(prefix)) {
920                foundIndex = middleIndex;
921                break;
922            }
923            if (this._values[middleIndex] < prefix)
924                minIndex = middleIndex + 1;
925            else
926                maxIndex = middleIndex - 1;
927        } while (minIndex <= maxIndex);
928
929        if (foundIndex === undefined)
930            return -1;
931
932        while (foundIndex && this._values[foundIndex - 1].startsWith(prefix))
933            foundIndex--;
934
935        return foundIndex;
936    },
937
938    /**
939     * @return {!Object.<string, boolean>}
940     */
941    keySet: function()
942    {
943        if (!this._keySet)
944            this._keySet = this._values.keySet();
945        return this._keySet;
946    },
947
948    /**
949     * @param {string} str
950     * @param {string} prefix
951     * @return {string}
952     */
953    next: function(str, prefix)
954    {
955        return this._closest(str, prefix, 1);
956    },
957
958    /**
959     * @param {string} str
960     * @param {string} prefix
961     * @return {string}
962     */
963    previous: function(str, prefix)
964    {
965        return this._closest(str, prefix, -1);
966    },
967
968    /**
969     * @param {string} str
970     * @param {string} prefix
971     * @param {number} shift
972     * @return {string}
973     */
974    _closest: function(str, prefix, shift)
975    {
976        if (!str)
977            return "";
978
979        var index = this._values.indexOf(str);
980        if (index === -1)
981            return "";
982
983        if (!prefix) {
984            index = (index + this._values.length + shift) % this._values.length;
985            return this._values[index];
986        }
987
988        var propertiesWithPrefix = this.startsWith(prefix);
989        var j = propertiesWithPrefix.indexOf(str);
990        j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
991        return propertiesWithPrefix[j];
992    },
993
994    /**
995     * @param {string} shorthand
996     * @return {?Array.<string>}
997     */
998    longhands: function(shorthand)
999    {
1000        return this._longhands[shorthand];
1001    },
1002
1003    /**
1004     * @param {string} longhand
1005     * @return {?Array.<string>}
1006     */
1007    shorthands: function(longhand)
1008    {
1009        return this._shorthands[longhand];
1010    }
1011}
1012
1013WebInspector.CSSMetadata.initializeWithSupportedProperties([]);
1014