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