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