Home | History | Annotate | Download | only in sdk
      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  */
     37 WebInspector.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  */
     71 WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata([]);
     72 
     73 /**
     74  * @param {string} propertyName
     75  * @return {boolean}
     76  */
     77 WebInspector.CSSMetadata.isColorAwareProperty = function(propertyName)
     78 {
     79     return WebInspector.CSSMetadata._colorAwareProperties[propertyName] === true;
     80 }
     81 
     82 /**
     83  * @return {!Object.<string, boolean>}
     84  */
     85 WebInspector.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.
     93 WebInspector.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.
    103 WebInspector.CSSMetadata.NonStandardInheritedProperties = [
    104     "-webkit-font-smoothing"
    105 ].keySet();
    106 
    107 /**
    108  * @param {string} name
    109  * @return {string}
    110  */
    111 WebInspector.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  */
    127 WebInspector.CSSMetadata.isPropertyInherited = function(propertyName)
    128 {
    129     return !!(WebInspector.CSSMetadata.InheritedProperties[WebInspector.CSSMetadata.canonicalPropertyName(propertyName)]
    130             || WebInspector.CSSMetadata.NonStandardInheritedProperties[propertyName.toLowerCase()]);
    131 }
    132 
    133 WebInspector.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 
    154 WebInspector.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 
    162 WebInspector.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  */
    708 WebInspector.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  */
    723 WebInspector.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 
    734 WebInspector.CSSMetadata.initializeWithSupportedProperties = function(properties)
    735 {
    736     WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata(properties);
    737 }
    738 
    739 /**
    740  * @return {!Object.<string, boolean>}
    741  */
    742 WebInspector.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
    750 WebInspector.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 
    869 WebInspector.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 
   1013 WebInspector.CSSMetadata.initializeWithSupportedProperties([]);
   1014