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