Home | History | Annotate | Download | only in cm
      1 CodeMirror.defineMode("css", function(config, parserConfig) {
      2   "use strict";
      3 
      4   if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
      5 
      6   var indentUnit = config.indentUnit || config.tabSize || 2,
      7       hooks = parserConfig.hooks || {},
      8       atMediaTypes = parserConfig.atMediaTypes || {},
      9       atMediaFeatures = parserConfig.atMediaFeatures || {},
     10       propertyKeywords = parserConfig.propertyKeywords || {},
     11       colorKeywords = parserConfig.colorKeywords || {},
     12       valueKeywords = parserConfig.valueKeywords || {},
     13       allowNested = !!parserConfig.allowNested,
     14       type = null;
     15 
     16   function ret(style, tp) { type = tp; return style; }
     17 
     18   function tokenBase(stream, state) {
     19     var ch = stream.next();
     20     if (hooks[ch]) {
     21       // result[0] is style and result[1] is type
     22       var result = hooks[ch](stream, state);
     23       if (result !== false) return result;
     24     }
     25     if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
     26     else if (ch == "=") ret(null, "compare");
     27     else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
     28     else if (ch == "\"" || ch == "'") {
     29       state.tokenize = tokenString(ch);
     30       return state.tokenize(stream, state);
     31     }
     32     else if (ch == "#") {
     33       stream.eatWhile(/[\w\\\-]/);
     34       return ret("atom", "hash");
     35     }
     36     else if (ch == "!") {
     37       stream.match(/^\s*\w*/);
     38       return ret("keyword", "important");
     39     }
     40     else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
     41       stream.eatWhile(/[\w.%]/);
     42       return ret("number", "unit");
     43     }
     44     else if (ch === "-") {
     45       if (/\d/.test(stream.peek())) {
     46         stream.eatWhile(/[\w.%]/);
     47         return ret("number", "unit");
     48       } else if (stream.match(/^[^-]+-/)) {
     49         return ret("meta", "meta");
     50       }
     51     }
     52     else if (/[,+>*\/]/.test(ch)) {
     53       return ret(null, "select-op");
     54     }
     55     else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
     56       return ret("qualifier", "qualifier");
     57     }
     58     else if (ch == ":") {
     59       return ret("operator", ch);
     60     }
     61     else if (/[;{}\[\]\(\)]/.test(ch)) {
     62       return ret(null, ch);
     63     }
     64     else if (ch == "u" && stream.match("rl(")) {
     65       stream.backUp(1);
     66       state.tokenize = tokenParenthesized;
     67       return ret("property", "variable");
     68     }
     69     else {
     70       stream.eatWhile(/[\w\\\-]/);
     71       return ret("property", "variable");
     72     }
     73   }
     74 
     75   function tokenString(quote, nonInclusive) {
     76     return function(stream, state) {
     77       var escaped = false, ch;
     78       while ((ch = stream.next()) != null) {
     79         if (ch == quote && !escaped)
     80           break;
     81         escaped = !escaped && ch == "\\";
     82       }
     83       if (!escaped) {
     84         if (nonInclusive) stream.backUp(1);
     85         state.tokenize = tokenBase;
     86       }
     87       return ret("string", "string");
     88     };
     89   }
     90 
     91   function tokenParenthesized(stream, state) {
     92     stream.next(); // Must be '('
     93     if (!stream.match(/\s*[\"\']/, false))
     94       state.tokenize = tokenString(")", true);
     95     else
     96       state.tokenize = tokenBase;
     97     return ret(null, "(");
     98   }
     99 
    100   return {
    101     startState: function(base) {
    102       return {tokenize: tokenBase,
    103               baseIndent: base || 0,
    104               stack: [],
    105               lastToken: null};
    106     },
    107 
    108     token: function(stream, state) {
    109 
    110       // Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
    111       //
    112       // rule** or **ruleset:
    113       // A selector + braces combo, or an at-rule.
    114       //
    115       // declaration block:
    116       // A sequence of declarations.
    117       //
    118       // declaration:
    119       // A property + colon + value combo.
    120       //
    121       // property value:
    122       // The entire value of a property.
    123       //
    124       // component value:
    125       // A single piece of a property value. Like the 5px in
    126       // text-shadow: 0 0 5px blue;. Can also refer to things that are
    127       // multiple terms, like the 1-4 terms that make up the background-size
    128       // portion of the background shorthand.
    129       //
    130       // term:
    131       // The basic unit of author-facing CSS, like a single number (5),
    132       // dimension (5px), string ("foo"), or function. Officially defined
    133       //  by the CSS 2.1 grammar (look for the 'term' production)
    134       //
    135       //
    136       // simple selector:
    137       // A single atomic selector, like a type selector, an attr selector, a
    138       // class selector, etc.
    139       //
    140       // compound selector:
    141       // One or more simple selectors without a combinator. div.example is
    142       // compound, div > .example is not.
    143       //
    144       // complex selector:
    145       // One or more compound selectors chained with combinators.
    146       //
    147       // combinator:
    148       // The parts of selectors that express relationships. There are four
    149       // currently - the space (descendant combinator), the greater-than
    150       // bracket (child combinator), the plus sign (next sibling combinator),
    151       // and the tilda (following sibling combinator).
    152       //
    153       // sequence of selectors:
    154       // One or more of the named type of selector chained with commas.
    155 
    156       state.tokenize = state.tokenize || tokenBase;
    157       if (state.tokenize == tokenBase && stream.eatSpace()) return null;
    158       var style = state.tokenize(stream, state);
    159       if (style && typeof style != "string") style = ret(style[0], style[1]);
    160 
    161       // Changing style returned based on context
    162       var context = state.stack[state.stack.length-1];
    163       if (style == "variable") {
    164         if (type == "variable-definition") state.stack.push("propertyValue");
    165         return state.lastToken = "variable-2";
    166       } else if (style == "property") {
    167         var word = stream.current().toLowerCase();
    168         if (context == "propertyValue") {
    169           if (valueKeywords.hasOwnProperty(word)) {
    170             style = "string-2";
    171           } else if (colorKeywords.hasOwnProperty(word)) {
    172             style = "keyword";
    173           } else {
    174             style = "variable-2";
    175           }
    176         } else if (context == "rule") {
    177           if (!propertyKeywords.hasOwnProperty(word)) {
    178             style += " error";
    179           }
    180         } else if (context == "block") {
    181           // if a value is present in both property, value, or color, the order
    182           // of preference is property -> color -> value
    183           if (propertyKeywords.hasOwnProperty(word)) {
    184             style = "property";
    185           } else if (colorKeywords.hasOwnProperty(word)) {
    186             style = "keyword";
    187           } else if (valueKeywords.hasOwnProperty(word)) {
    188             style = "string-2";
    189           } else {
    190             style = "tag";
    191           }
    192         } else if (!context || context == "@media{") {
    193           style = "tag";
    194         } else if (context == "@media") {
    195           if (atMediaTypes[stream.current()]) {
    196             style = "attribute"; // Known attribute
    197           } else if (/^(only|not)$/.test(word)) {
    198             style = "keyword";
    199           } else if (word == "and") {
    200             style = "error"; // "and" is only allowed in @mediaType
    201           } else if (atMediaFeatures.hasOwnProperty(word)) {
    202             style = "error"; // Known property, should be in @mediaType(
    203           } else {
    204             // Unknown, expecting keyword or attribute, assuming attribute
    205             style = "attribute error";
    206           }
    207         } else if (context == "@mediaType") {
    208           if (atMediaTypes.hasOwnProperty(word)) {
    209             style = "attribute";
    210           } else if (word == "and") {
    211             style = "operator";
    212           } else if (/^(only|not)$/.test(word)) {
    213             style = "error"; // Only allowed in @media
    214           } else {
    215             // Unknown attribute or property, but expecting property (preceded
    216             // by "and"). Should be in parentheses
    217             style = "error";
    218           }
    219         } else if (context == "@mediaType(") {
    220           if (propertyKeywords.hasOwnProperty(word)) {
    221             // do nothing, remains "property"
    222           } else if (atMediaTypes.hasOwnProperty(word)) {
    223             style = "error"; // Known property, should be in parentheses
    224           } else if (word == "and") {
    225             style = "operator";
    226           } else if (/^(only|not)$/.test(word)) {
    227             style = "error"; // Only allowed in @media
    228           } else {
    229             style += " error";
    230           }
    231         } else if (context == "@import") {
    232           style = "tag";
    233         } else {
    234           style = "error";
    235         }
    236       } else if (style == "atom") {
    237         if(!context || context == "@media{" || context == "block") {
    238           style = "builtin";
    239         } else if (context == "propertyValue") {
    240           if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
    241             style += " error";
    242           }
    243         } else {
    244           style = "error";
    245         }
    246       } else if (context == "@media" && type == "{") {
    247         style = "error";
    248       }
    249 
    250       // Push/pop context stack
    251       if (type == "{") {
    252         if (context == "@media" || context == "@mediaType") {
    253           state.stack[state.stack.length-1] = "@media{";
    254         }
    255         else {
    256           var newContext = allowNested ? "block" : "rule";
    257           state.stack.push(newContext);
    258         }
    259       }
    260       else if (type == "}") {
    261         if (context == "interpolation") style = "operator";
    262         // Pop off end of array until { is reached
    263         while(state.stack.length){
    264           var removed = state.stack.pop();
    265           if(removed.indexOf("{") > -1 || removed == "block" || removed == "rule"){
    266             break;
    267           }
    268         }
    269       }
    270       else if (type == "interpolation") state.stack.push("interpolation");
    271       else if (type == "@media") state.stack.push("@media");
    272       else if (type == "@import") state.stack.push("@import");
    273       else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
    274         state.stack[state.stack.length-1] = "@mediaType";
    275       else if (context == "@mediaType" && stream.current() == ",")
    276         state.stack[state.stack.length-1] = "@media";
    277       else if (type == "(") {
    278         if (context == "@media" || context == "@mediaType") {
    279           // Make sure @mediaType is used to avoid error on {
    280           state.stack[state.stack.length-1] = "@mediaType";
    281           state.stack.push("@mediaType(");
    282         }
    283         else state.stack.push("(");
    284       }
    285       else if (type == ")") {
    286         // Pop off end of array until ( is reached
    287         while(state.stack.length){
    288           var removed = state.stack.pop();
    289           if(removed.indexOf("(") > -1){
    290             break;
    291           }
    292         }
    293       }
    294       else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
    295       else if (context == "propertyValue" && type == ";") state.stack.pop();
    296       else if (context == "@import" && type == ";") state.stack.pop();
    297 
    298       return state.lastToken = style;
    299     },
    300 
    301     indent: function(state, textAfter) {
    302       var n = state.stack.length;
    303       if (/^\}/.test(textAfter))
    304         n -= state.stack[n-1] == "propertyValue" ? 2 : 1;
    305       return state.baseIndent + n * indentUnit;
    306     },
    307 
    308     electricChars: "}",
    309     blockCommentStart: "/*",
    310     blockCommentEnd: "*/",
    311     fold: "brace"
    312   };
    313 });
    314 
    315 (function() {
    316   function keySet(array) {
    317     var keys = {};
    318     for (var i = 0; i < array.length; ++i) {
    319       keys[array[i]] = true;
    320     }
    321     return keys;
    322   }
    323 
    324   var atMediaTypes = keySet([
    325     "all", "aural", "braille", "handheld", "print", "projection", "screen",
    326     "tty", "tv", "embossed"
    327   ]);
    328 
    329   var atMediaFeatures = keySet([
    330     "width", "min-width", "max-width", "height", "min-height", "max-height",
    331     "device-width", "min-device-width", "max-device-width", "device-height",
    332     "min-device-height", "max-device-height", "aspect-ratio",
    333     "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
    334     "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
    335     "max-color", "color-index", "min-color-index", "max-color-index",
    336     "monochrome", "min-monochrome", "max-monochrome", "resolution",
    337     "min-resolution", "max-resolution", "scan", "grid"
    338   ]);
    339 
    340   var propertyKeywords = keySet([
    341     "align-content", "align-items", "align-self", "alignment-adjust",
    342     "alignment-baseline", "anchor-point", "animation", "animation-delay",
    343     "animation-direction", "animation-duration", "animation-iteration-count",
    344     "animation-name", "animation-play-state", "animation-timing-function",
    345     "appearance", "azimuth", "backface-visibility", "background",
    346     "background-attachment", "background-clip", "background-color",
    347     "background-image", "background-origin", "background-position",
    348     "background-repeat", "background-size", "baseline-shift", "binding",
    349     "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
    350     "bookmark-target", "border", "border-bottom", "border-bottom-color",
    351     "border-bottom-left-radius", "border-bottom-right-radius",
    352     "border-bottom-style", "border-bottom-width", "border-collapse",
    353     "border-color", "border-image", "border-image-outset",
    354     "border-image-repeat", "border-image-slice", "border-image-source",
    355     "border-image-width", "border-left", "border-left-color",
    356     "border-left-style", "border-left-width", "border-radius", "border-right",
    357     "border-right-color", "border-right-style", "border-right-width",
    358     "border-spacing", "border-style", "border-top", "border-top-color",
    359     "border-top-left-radius", "border-top-right-radius", "border-top-style",
    360     "border-top-width", "border-width", "bottom", "box-decoration-break",
    361     "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
    362     "caption-side", "clear", "clip", "color", "color-profile", "column-count",
    363     "column-fill", "column-gap", "column-rule", "column-rule-color",
    364     "column-rule-style", "column-rule-width", "column-span", "column-width",
    365     "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
    366     "cue-after", "cue-before", "cursor", "direction", "display",
    367     "dominant-baseline", "drop-initial-after-adjust",
    368     "drop-initial-after-align", "drop-initial-before-adjust",
    369     "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
    370     "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
    371     "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
    372     "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
    373     "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
    374     "font-stretch", "font-style", "font-synthesis", "font-variant",
    375     "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
    376     "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
    377     "font-weight", "grid-cell", "grid-column", "grid-column-align",
    378     "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow",
    379     "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span",
    380     "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens",
    381     "icon", "image-orientation", "image-rendering", "image-resolution",
    382     "inline-box-align", "justify-content", "left", "letter-spacing",
    383     "line-break", "line-height", "line-stacking", "line-stacking-ruby",
    384     "line-stacking-shift", "line-stacking-strategy", "list-style",
    385     "list-style-image", "list-style-position", "list-style-type", "margin",
    386     "margin-bottom", "margin-left", "margin-right", "margin-top",
    387     "marker-offset", "marks", "marquee-direction", "marquee-loop",
    388     "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
    389     "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
    390     "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
    391     "outline-color", "outline-offset", "outline-style", "outline-width",
    392     "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
    393     "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
    394     "page", "page-break-after", "page-break-before", "page-break-inside",
    395     "page-policy", "pause", "pause-after", "pause-before", "perspective",
    396     "perspective-origin", "pitch", "pitch-range", "play-during", "position",
    397     "presentation-level", "punctuation-trim", "quotes", "region-break-after",
    398     "region-break-before", "region-break-inside", "region-fragment",
    399     "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
    400     "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
    401     "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size",
    402     "speak", "speak-as", "speak-header",
    403     "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
    404     "tab-size", "table-layout", "target", "target-name", "target-new",
    405     "target-position", "text-align", "text-align-last", "text-decoration",
    406     "text-decoration-color", "text-decoration-line", "text-decoration-skip",
    407     "text-decoration-style", "text-emphasis", "text-emphasis-color",
    408     "text-emphasis-position", "text-emphasis-style", "text-height",
    409     "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
    410     "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
    411     "text-wrap", "top", "transform", "transform-origin", "transform-style",
    412     "transition", "transition-delay", "transition-duration",
    413     "transition-property", "transition-timing-function", "unicode-bidi",
    414     "vertical-align", "visibility", "voice-balance", "voice-duration",
    415     "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
    416     "voice-volume", "volume", "white-space", "widows", "width", "word-break",
    417     "word-spacing", "word-wrap", "z-index", "zoom",
    418     // SVG-specific
    419     "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
    420     "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
    421     "color-interpolation", "color-interpolation-filters", "color-profile",
    422     "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
    423     "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
    424     "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
    425     "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
    426     "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
    427     "glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode"
    428   ]);
    429 
    430   var colorKeywords = keySet([
    431     "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
    432     "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
    433     "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
    434     "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
    435     "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
    436     "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
    437     "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
    438     "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
    439     "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
    440     "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
    441     "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
    442     "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
    443     "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
    444     "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
    445     "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
    446     "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
    447     "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
    448     "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
    449     "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
    450     "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
    451     "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
    452     "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon",
    453     "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
    454     "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
    455     "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
    456     "whitesmoke", "yellow", "yellowgreen"
    457   ]);
    458 
    459   var valueKeywords = keySet([
    460     "above", "absolute", "activeborder", "activecaption", "afar",
    461     "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
    462     "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
    463     "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
    464     "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
    465     "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
    466     "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
    467     "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
    468     "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
    469     "cell", "center", "checkbox", "circle", "cjk-earthly-branch",
    470     "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
    471     "col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
    472     "content-box", "context-menu", "continuous", "copy", "cover", "crop",
    473     "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
    474     "decimal-leading-zero", "default", "default-button", "destination-atop",
    475     "destination-in", "destination-out", "destination-over", "devanagari",
    476     "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
    477     "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
    478     "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
    479     "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
    480     "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
    481     "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
    482     "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
    483     "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
    484     "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
    485     "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
    486     "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
    487     "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
    488     "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
    489     "help", "hidden", "hide", "higher", "highlight", "highlighttext",
    490     "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
    491     "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
    492     "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
    493     "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
    494     "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
    495     "landscape", "lao", "large", "larger", "left", "level", "lighter",
    496     "line-through", "linear", "lines", "list-item", "listbox", "listitem",
    497     "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
    498     "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
    499     "lower-roman", "lowercase", "ltr", "malayalam", "match",
    500     "media-controls-background", "media-current-time-display",
    501     "media-fullscreen-button", "media-mute-button", "media-play-button",
    502     "media-return-to-realtime-button", "media-rewind-button",
    503     "media-seek-back-button", "media-seek-forward-button", "media-slider",
    504     "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
    505     "media-volume-slider-container", "media-volume-sliderthumb", "medium",
    506     "menu", "menulist", "menulist-button", "menulist-text",
    507     "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
    508     "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
    509     "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
    510     "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
    511     "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
    512     "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
    513     "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
    514     "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
    515     "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
    516     "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
    517     "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
    518     "ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
    519     "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
    520     "searchfield-cancel-button", "searchfield-decoration",
    521     "searchfield-results-button", "searchfield-results-decoration",
    522     "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
    523     "single", "skip-white-space", "slide", "slider-horizontal",
    524     "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
    525     "small", "small-caps", "small-caption", "smaller", "solid", "somali",
    526     "source-atop", "source-in", "source-out", "source-over", "space", "square",
    527     "square-button", "start", "static", "status-bar", "stretch", "stroke",
    528     "sub", "subpixel-antialiased", "super", "sw-resize", "table",
    529     "table-caption", "table-cell", "table-column", "table-column-group",
    530     "table-footer-group", "table-header-group", "table-row", "table-row-group",
    531     "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
    532     "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
    533     "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
    534     "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
    535     "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
    536     "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
    537     "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
    538     "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
    539     "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
    540     "window", "windowframe", "windowtext", "x-large", "x-small", "xor",
    541     "xx-large", "xx-small"
    542   ]);
    543 
    544   function tokenCComment(stream, state) {
    545     var maybeEnd = false, ch;
    546     while ((ch = stream.next()) != null) {
    547       if (maybeEnd && ch == "/") {
    548         state.tokenize = null;
    549         break;
    550       }
    551       maybeEnd = (ch == "*");
    552     }
    553     return ["comment", "comment"];
    554   }
    555 
    556   CodeMirror.defineMIME("text/css", {
    557     atMediaTypes: atMediaTypes,
    558     atMediaFeatures: atMediaFeatures,
    559     propertyKeywords: propertyKeywords,
    560     colorKeywords: colorKeywords,
    561     valueKeywords: valueKeywords,
    562     hooks: {
    563       "<": function(stream, state) {
    564         function tokenSGMLComment(stream, state) {
    565           var dashes = 0, ch;
    566           while ((ch = stream.next()) != null) {
    567             if (dashes >= 2 && ch == ">") {
    568               state.tokenize = null;
    569               break;
    570             }
    571             dashes = (ch == "-") ? dashes + 1 : 0;
    572           }
    573           return ["comment", "comment"];
    574         }
    575         if (stream.eat("!")) {
    576           state.tokenize = tokenSGMLComment;
    577           return tokenSGMLComment(stream, state);
    578         }
    579       },
    580       "/": function(stream, state) {
    581         if (stream.eat("*")) {
    582           state.tokenize = tokenCComment;
    583           return tokenCComment(stream, state);
    584         }
    585         return false;
    586       }
    587     },
    588     name: "css"
    589   });
    590 
    591   CodeMirror.defineMIME("text/x-scss", {
    592     atMediaTypes: atMediaTypes,
    593     atMediaFeatures: atMediaFeatures,
    594     propertyKeywords: propertyKeywords,
    595     colorKeywords: colorKeywords,
    596     valueKeywords: valueKeywords,
    597     allowNested: true,
    598     hooks: {
    599       ":": function(stream) {
    600         if (stream.match(/\s*{/)) {
    601           return [null, "{"];
    602         }
    603         return false;
    604       },
    605       "$": function(stream) {
    606         stream.match(/^[\w-]+/);
    607         if (stream.peek() == ":") {
    608           return ["variable", "variable-definition"];
    609         }
    610         return ["variable", "variable"];
    611       },
    612       ",": function(stream, state) {
    613         if (state.stack[state.stack.length - 1] == "propertyValue" && stream.match(/^ *\$/, false)) {
    614           return ["operator", ";"];
    615         }
    616       },
    617       "/": function(stream, state) {
    618         if (stream.eat("/")) {
    619           stream.skipToEnd();
    620           return ["comment", "comment"];
    621         } else if (stream.eat("*")) {
    622           state.tokenize = tokenCComment;
    623           return tokenCComment(stream, state);
    624         } else {
    625           return ["operator", "operator"];
    626         }
    627       },
    628       "#": function(stream) {
    629         if (stream.eat("{")) {
    630           return ["operator", "interpolation"];
    631         } else {
    632           stream.eatWhile(/[\w\\\-]/);
    633           return ["atom", "hash"];
    634         }
    635       }
    636     },
    637     name: "css"
    638   });
    639 })();
    640