Move webkit.css to opensource to support resultsdbpy's frontend
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / External / CodeMirror / css.js
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5   if (typeof exports == "object" && typeof module == "object") // CommonJS
6     mod(require("../../lib/codemirror"));
7   else if (typeof define == "function" && define.amd) // AMD
8     define(["../../lib/codemirror"], mod);
9   else // Plain browser env
10     mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("css", function(config, parserConfig) {
15   var inline = parserConfig.inline
16   if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
17
18   var indentUnit = config.indentUnit,
19       tokenHooks = parserConfig.tokenHooks,
20       documentTypes = parserConfig.documentTypes || {},
21       mediaTypes = parserConfig.mediaTypes || {},
22       mediaFeatures = parserConfig.mediaFeatures || {},
23       mediaValueKeywords = parserConfig.mediaValueKeywords || {},
24       propertyKeywords = parserConfig.propertyKeywords || {},
25       nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
26       fontProperties = parserConfig.fontProperties || {},
27       counterDescriptors = parserConfig.counterDescriptors || {},
28       colorKeywords = parserConfig.colorKeywords || {},
29       valueKeywords = parserConfig.valueKeywords || {},
30       allowNested = parserConfig.allowNested,
31       supportsAtComponent = parserConfig.supportsAtComponent === true;
32
33   var type, override;
34   function ret(style, tp) { type = tp; return style; }
35
36   // Tokenizers
37
38   function tokenBase(stream, state) {
39     var ch = stream.next();
40     if (tokenHooks[ch]) {
41       var result = tokenHooks[ch](stream, state);
42       if (result !== false) return result;
43     }
44     if (ch == "@") {
45       stream.eatWhile(/[\w\\\-]/);
46       return ret("def", stream.current());
47     } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
48       return ret(null, "compare");
49     } else if (ch == "\"" || ch == "'") {
50       state.tokenize = tokenString(ch);
51       return state.tokenize(stream, state);
52     } else if (ch == "#") {
53       stream.eatWhile(/[\w\\\-]/);
54       return ret("atom", "hash");
55     } else if (ch == "!") {
56       stream.match(/^\s*\w*/);
57       return ret("keyword", "important");
58     } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
59       stream.eatWhile(/[\w.%]/);
60       return ret("number", "unit");
61     } else if (ch === "-") {
62       if (/[\d.]/.test(stream.peek())) {
63         stream.eatWhile(/[\w.%]/);
64         return ret("number", "unit");
65       } else if (stream.match(/^-[\w\\\-]+/)) {
66         stream.eatWhile(/[\w\\\-]/);
67         if (stream.match(/^\s*:/, false))
68           return ret("variable-2", "variable-definition");
69         return ret("variable-2", "variable");
70       } else if (stream.match(/^\w+-/)) {
71         return ret("meta", "meta");
72       }
73     } else if (/[,+>*\/]/.test(ch)) {
74       return ret(null, "select-op");
75     } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
76       return ret("qualifier", "qualifier");
77     } else if (/[:;{}\[\]\(\)]/.test(ch)) {
78       return ret(null, ch);
79     } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
80                (ch == "d" && stream.match("omain(")) ||
81                (ch == "r" && stream.match("egexp("))) {
82       stream.backUp(1);
83       state.tokenize = tokenParenthesized;
84       return ret("property", "word");
85     } else if (/[\w\\\-]/.test(ch)) {
86       stream.eatWhile(/[\w\\\-]/);
87       return ret("property", "word");
88     } else {
89       return ret(null, null);
90     }
91   }
92
93   function tokenString(quote) {
94     return function(stream, state) {
95       var escaped = false, ch;
96       while ((ch = stream.next()) != null) {
97         if (ch == quote && !escaped) {
98           if (quote == ")") stream.backUp(1);
99           break;
100         }
101         escaped = !escaped && ch == "\\";
102       }
103       if (ch == quote || !escaped && quote != ")") state.tokenize = null;
104       return ret("string", "string");
105     };
106   }
107
108   function tokenParenthesized(stream, state) {
109     stream.next(); // Must be '('
110     if (!stream.match(/\s*[\"\')]/, false))
111       state.tokenize = tokenString(")");
112     else
113       state.tokenize = null;
114     return ret(null, "(");
115   }
116
117   // Context management
118
119   function Context(type, indent, prev) {
120     this.type = type;
121     this.indent = indent;
122     this.prev = prev;
123   }
124
125   function pushContext(state, stream, type, indent) {
126     state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
127     return type;
128   }
129
130   function popContext(state) {
131     if (state.context.prev)
132       state.context = state.context.prev;
133     return state.context.type;
134   }
135
136   function pass(type, stream, state) {
137     return states[state.context.type](type, stream, state);
138   }
139   function popAndPass(type, stream, state, n) {
140     for (var i = n || 1; i > 0; i--)
141       state.context = state.context.prev;
142     return pass(type, stream, state);
143   }
144
145   // Parser
146
147   function wordAsValue(stream) {
148     var word = stream.current().toLowerCase();
149     if (valueKeywords.hasOwnProperty(word))
150       override = "atom";
151     else if (colorKeywords.hasOwnProperty(word))
152       override = "keyword";
153     else
154       override = "variable";
155   }
156
157   var states = {};
158
159   states.top = function(type, stream, state) {
160     if (type == "{") {
161       return pushContext(state, stream, "block");
162     } else if (type == "}" && state.context.prev) {
163       return popContext(state);
164     } else if (supportsAtComponent && /@component/.test(type)) {
165       return pushContext(state, stream, "atComponentBlock");
166     } else if (/^@(-moz-)?document$/.test(type)) {
167       return pushContext(state, stream, "documentTypes");
168     } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
169       return pushContext(state, stream, "atBlock");
170     } else if (/^@(font-face|counter-style)/.test(type)) {
171       state.stateArg = type;
172       return "restricted_atBlock_before";
173     } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
174       return "keyframes";
175     } else if (type && type.charAt(0) == "@") {
176       return pushContext(state, stream, "at");
177     } else if (type == "hash") {
178       override = "builtin";
179     } else if (type == "word") {
180       override = "tag";
181     } else if (type == "variable-definition") {
182       return "maybeprop";
183     } else if (type == "interpolation") {
184       return pushContext(state, stream, "interpolation");
185     } else if (type == ":") {
186       return "pseudo";
187     } else if (allowNested && type == "(") {
188       return pushContext(state, stream, "parens");
189     }
190     return state.context.type;
191   };
192
193   states.block = function(type, stream, state) {
194     if (type == "word") {
195       var word = stream.current().toLowerCase();
196       if (propertyKeywords.hasOwnProperty(word)) {
197         override = "property";
198         return "maybeprop";
199       } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
200         override = "string-2";
201         return "maybeprop";
202       } else if (allowNested) {
203         override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
204         return "block";
205       } else {
206         override += " error";
207         return "maybeprop";
208       }
209     } else if (type == "meta") {
210       return "block";
211     } else if (!allowNested && (type == "hash" || type == "qualifier")) {
212       override = "error";
213       return "block";
214     } else {
215       return states.top(type, stream, state);
216     }
217   };
218
219   states.maybeprop = function(type, stream, state) {
220     if (type == ":") return pushContext(state, stream, "prop");
221     return pass(type, stream, state);
222   };
223
224   states.prop = function(type, stream, state) {
225     if (type == ";") return popContext(state);
226     if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
227     if (type == "}" || type == "{") return popAndPass(type, stream, state);
228     if (type == "(") return pushContext(state, stream, "parens");
229
230     if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
231       override += " error";
232     } else if (type == "word") {
233       wordAsValue(stream);
234     } else if (type == "interpolation") {
235       return pushContext(state, stream, "interpolation");
236     }
237     return "prop";
238   };
239
240   states.propBlock = function(type, _stream, state) {
241     if (type == "}") return popContext(state);
242     if (type == "word") { override = "property"; return "maybeprop"; }
243     return state.context.type;
244   };
245
246   states.parens = function(type, stream, state) {
247     if (type == "{" || type == "}") return popAndPass(type, stream, state);
248     if (type == ")") return popContext(state);
249     if (type == "(") return pushContext(state, stream, "parens");
250     if (type == "interpolation") return pushContext(state, stream, "interpolation");
251     if (type == "word") wordAsValue(stream);
252     return "parens";
253   };
254
255   states.pseudo = function(type, stream, state) {
256     if (type == "word") {
257       override = "variable-3";
258       return state.context.type;
259     }
260     return pass(type, stream, state);
261   };
262
263   states.documentTypes = function(type, stream, state) {
264     if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
265       override = "tag";
266       return state.context.type;
267     } else {
268       return states.atBlock(type, stream, state);
269     }
270   };
271
272   states.atBlock = function(type, stream, state) {
273     if (type == "(") return pushContext(state, stream, "atBlock_parens");
274     if (type == "}" || type == ";") return popAndPass(type, stream, state);
275     if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
276
277     if (type == "interpolation") return pushContext(state, stream, "interpolation");
278
279     if (type == "word") {
280       var word = stream.current().toLowerCase();
281       if (word == "only" || word == "not" || word == "and" || word == "or")
282         override = "keyword";
283       else if (mediaTypes.hasOwnProperty(word))
284         override = "attribute";
285       else if (mediaFeatures.hasOwnProperty(word))
286         override = "property";
287       else if (mediaValueKeywords.hasOwnProperty(word))
288         override = "keyword";
289       else if (propertyKeywords.hasOwnProperty(word))
290         override = "property";
291       else if (nonStandardPropertyKeywords.hasOwnProperty(word))
292         override = "string-2";
293       else if (valueKeywords.hasOwnProperty(word))
294         override = "atom";
295       else if (colorKeywords.hasOwnProperty(word))
296         override = "keyword";
297       else
298         override = "error";
299     }
300     return state.context.type;
301   };
302
303   states.atComponentBlock = function(type, stream, state) {
304     if (type == "}")
305       return popAndPass(type, stream, state);
306     if (type == "{")
307       return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
308     if (type == "word")
309       override = "error";
310     return state.context.type;
311   };
312
313   states.atBlock_parens = function(type, stream, state) {
314     if (type == ")") return popContext(state);
315     if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
316     return states.atBlock(type, stream, state);
317   };
318
319   states.restricted_atBlock_before = function(type, stream, state) {
320     if (type == "{")
321       return pushContext(state, stream, "restricted_atBlock");
322     if (type == "word" && state.stateArg == "@counter-style") {
323       override = "variable";
324       return "restricted_atBlock_before";
325     }
326     return pass(type, stream, state);
327   };
328
329   states.restricted_atBlock = function(type, stream, state) {
330     if (type == "}") {
331       state.stateArg = null;
332       return popContext(state);
333     }
334     if (type == "word") {
335       if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
336           (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
337         override = "error";
338       else
339         override = "property";
340       return "maybeprop";
341     }
342     return "restricted_atBlock";
343   };
344
345   states.keyframes = function(type, stream, state) {
346     if (type == "word") { override = "variable"; return "keyframes"; }
347     if (type == "{") return pushContext(state, stream, "top");
348     return pass(type, stream, state);
349   };
350
351   states.at = function(type, stream, state) {
352     if (type == ";") return popContext(state);
353     if (type == "{" || type == "}") return popAndPass(type, stream, state);
354     if (type == "word") override = "tag";
355     else if (type == "hash") override = "builtin";
356     return "at";
357   };
358
359   states.interpolation = function(type, stream, state) {
360     if (type == "}") return popContext(state);
361     if (type == "{" || type == ";") return popAndPass(type, stream, state);
362     if (type == "word") override = "variable";
363     else if (type != "variable" && type != "(" && type != ")") override = "error";
364     return "interpolation";
365   };
366
367   return {
368     startState: function(base) {
369       return {tokenize: null,
370               state: inline ? "block" : "top",
371               stateArg: null,
372               context: new Context(inline ? "block" : "top", base || 0, null)};
373     },
374
375     token: function(stream, state) {
376       if (!state.tokenize && stream.eatSpace()) return null;
377       var style = (state.tokenize || tokenBase)(stream, state);
378       if (style && typeof style == "object") {
379         type = style[1];
380         style = style[0];
381       }
382       override = style;
383       state.state = states[state.state](type, stream, state);
384       return override;
385     },
386
387     indent: function(state, textAfter) {
388       var cx = state.context, ch = textAfter && textAfter.charAt(0);
389       var indent = cx.indent;
390       if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
391       if (cx.prev) {
392         if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
393                           cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
394           // Resume indentation from parent context.
395           cx = cx.prev;
396           indent = cx.indent;
397         } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
398             ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
399           // Dedent relative to current context.
400           indent = Math.max(0, cx.indent - indentUnit);
401           cx = cx.prev;
402         }
403       }
404       return indent;
405     },
406
407     electricChars: "}",
408     blockCommentStart: "/*",
409     blockCommentEnd: "*/",
410     fold: "brace"
411   };
412 });
413
414   function keySet(array) {
415     var keys = {};
416     for (var i = 0; i < array.length; ++i) {
417       keys[array[i].toLowerCase()] = true;
418     }
419     return keys;
420   }
421
422   var documentTypes_ = [
423     "domain", "regexp", "url", "url-prefix"
424   ], documentTypes = keySet(documentTypes_);
425
426   var mediaTypes_ = [
427     "all", "aural", "braille", "handheld", "print", "projection", "screen",
428     "tty", "tv", "embossed"
429   ], mediaTypes = keySet(mediaTypes_);
430
431   var mediaFeatures_ = [
432     "width", "min-width", "max-width", "height", "min-height", "max-height",
433     "device-width", "min-device-width", "max-device-width", "device-height",
434     "min-device-height", "max-device-height", "aspect-ratio",
435     "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
436     "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
437     "max-color", "color-index", "min-color-index", "max-color-index",
438     "monochrome", "min-monochrome", "max-monochrome", "resolution",
439     "min-resolution", "max-resolution", "scan", "grid", "orientation",
440     "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
441     "pointer", "any-pointer", "hover", "any-hover"
442   ], mediaFeatures = keySet(mediaFeatures_);
443
444   var mediaValueKeywords_ = [
445     "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
446     "interlace", "progressive"
447   ], mediaValueKeywords = keySet(mediaValueKeywords_);
448
449   var propertyKeywords_ = [
450     "align-content", "align-items", "align-self", "alignment-adjust",
451     "alignment-baseline", "anchor-point", "animation", "animation-delay",
452     "animation-direction", "animation-duration", "animation-fill-mode",
453     "animation-iteration-count", "animation-name", "animation-play-state",
454     "animation-timing-function", "appearance", "azimuth", "backface-visibility",
455     "background", "background-attachment", "background-blend-mode", "background-clip",
456     "background-color", "background-image", "background-origin", "background-position",
457     "background-repeat", "background-size", "baseline-shift", "binding",
458     "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
459     "bookmark-target", "border", "border-bottom", "border-bottom-color",
460     "border-bottom-left-radius", "border-bottom-right-radius",
461     "border-bottom-style", "border-bottom-width", "border-collapse",
462     "border-color", "border-image", "border-image-outset",
463     "border-image-repeat", "border-image-slice", "border-image-source",
464     "border-image-width", "border-left", "border-left-color",
465     "border-left-style", "border-left-width", "border-radius", "border-right",
466     "border-right-color", "border-right-style", "border-right-width",
467     "border-spacing", "border-style", "border-top", "border-top-color",
468     "border-top-left-radius", "border-top-right-radius", "border-top-style",
469     "border-top-width", "border-width", "bottom", "box-decoration-break",
470     "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
471     "caption-side", "clear", "clip", "color", "color-profile", "column-count",
472     "column-fill", "column-gap", "column-rule", "column-rule-color",
473     "column-rule-style", "column-rule-width", "column-span", "column-width",
474     "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
475     "cue-after", "cue-before", "cursor", "direction", "display",
476     "dominant-baseline", "drop-initial-after-adjust",
477     "drop-initial-after-align", "drop-initial-before-adjust",
478     "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
479     "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
480     "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
481     "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
482     "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
483     "font-stretch", "font-style", "font-synthesis", "font-variant",
484     "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
485     "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
486     "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
487     "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
488     "grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
489     "grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
490     "grid-template-rows", "hanging-punctuation", "height", "hyphens",
491     "icon", "image-orientation", "image-rendering", "image-resolution",
492     "inline-box-align", "justify-content", "left", "letter-spacing",
493     "line-break", "line-height", "line-stacking", "line-stacking-ruby",
494     "line-stacking-shift", "line-stacking-strategy", "list-style",
495     "list-style-image", "list-style-position", "list-style-type", "margin",
496     "margin-bottom", "margin-left", "margin-right", "margin-top",
497     "marks", "marquee-direction", "marquee-loop",
498     "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
499     "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
500     "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
501     "opacity", "order", "orphans", "outline",
502     "outline-color", "outline-offset", "outline-style", "outline-width",
503     "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
504     "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
505     "page", "page-break-after", "page-break-before", "page-break-inside",
506     "page-policy", "pause", "pause-after", "pause-before", "perspective",
507     "perspective-origin", "pitch", "pitch-range", "play-during", "position",
508     "presentation-level", "punctuation-trim", "quotes", "region-break-after",
509     "region-break-before", "region-break-inside", "region-fragment",
510     "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
511     "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
512     "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
513     "shape-outside", "size", "speak", "speak-as", "speak-header",
514     "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
515     "tab-size", "table-layout", "target", "target-name", "target-new",
516     "target-position", "text-align", "text-align-last", "text-decoration",
517     "text-decoration-color", "text-decoration-line", "text-decoration-skip",
518     "text-decoration-style", "text-emphasis", "text-emphasis-color",
519     "text-emphasis-position", "text-emphasis-style", "text-height",
520     "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
521     "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
522     "text-wrap", "top", "transform", "transform-box", "transform-origin", "transform-style",
523     "transition", "transition-delay", "transition-duration",
524     "transition-property", "transition-timing-function", "unicode-bidi",
525     "user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
526     "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
527     "voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
528     "word-spacing", "word-wrap", "z-index",
529     // SVG-specific
530     "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
531     "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
532     "color-interpolation", "color-interpolation-filters",
533     "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
534     "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
535     "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
536     "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
537     "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
538     "glyph-orientation-vertical", "text-anchor", "writing-mode"
539   ], propertyKeywords = keySet(propertyKeywords_);
540
541   var nonStandardPropertyKeywords_ = [
542     "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
543     "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
544     "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
545     "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
546     "searchfield-results-decoration", "zoom"
547   ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
548
549   var fontProperties_ = [
550     "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
551     "font-stretch", "font-weight", "font-style"
552   ], fontProperties = keySet(fontProperties_);
553
554   var counterDescriptors_ = [
555     "additive-symbols", "fallback", "negative", "pad", "prefix", "range",
556     "speak-as", "suffix", "symbols", "system"
557   ], counterDescriptors = keySet(counterDescriptors_);
558
559   var colorKeywords_ = [
560     "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
561     "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
562     "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
563     "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
564     "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
565     "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
566     "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
567     "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
568     "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
569     "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
570     "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
571     "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
572     "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
573     "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
574     "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
575     "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
576     "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
577     "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
578     "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
579     "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
580     "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
581     "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
582     "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
583     "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
584     "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
585     "whitesmoke", "yellow", "yellowgreen"
586   ], colorKeywords = keySet(colorKeywords_);
587
588   var valueKeywords_ = [
589     "above", "absolute", "activeborder", "additive", "activecaption", "afar",
590     "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
591     "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
592     "arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
593     "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
594     "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
595     "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
596     "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
597     "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
598     "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
599     "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
600     "col-resize", "collapse", "color", "color-burn", "color-dodge", "color-well", "column", "column-reverse",
601     "compact", "condensed", "contain", "content", "contents",
602     "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
603     "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
604     "decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
605     "destination-in", "destination-out", "destination-over", "devanagari", "difference",
606     "disc", "discard", "disclosure-closed", "disclosure-open", "document",
607     "dot-dash", "dot-dot-dash",
608     "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
609     "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
610     "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
611     "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
612     "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
613     "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
614     "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
615     "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
616     "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
617     "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "flow-root", "footnotes",
618     "forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
619     "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
620     "help", "hidden", "hide", "higher", "highlight", "highlighttext",
621     "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
622     "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
623     "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
624     "inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
625     "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
626     "katakana", "katakana-iroha", "keep-all", "khmer",
627     "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
628     "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
629     "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "list-button", "listitem",
630     "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
631     "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
632     "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
633     "media-controls-background", "media-current-time-display",
634     "media-fullscreen-button", "media-mute-button", "media-play-button",
635     "media-return-to-realtime-button", "media-rewind-button",
636     "media-seek-back-button", "media-seek-forward-button", "media-slider",
637     "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
638     "media-volume-slider-container", "media-volume-sliderthumb", "medium",
639     "menu", "menulist", "menulist-button", "menulist-text",
640     "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
641     "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
642     "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
643     "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
644     "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
645     "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
646     "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
647     "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
648     "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
649     "progress", "push-button", "radial-gradient", "radio", "read-only",
650     "read-write", "read-write-plaintext-only", "rectangle", "region",
651     "relative", "repeat", "repeating-linear-gradient",
652     "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
653     "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
654     "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
655     "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
656     "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
657     "searchfield-cancel-button", "searchfield-decoration",
658     "searchfield-results-button", "searchfield-results-decoration",
659     "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
660     "simp-chinese-formal", "simp-chinese-informal", "single",
661     "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
662     "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
663     "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
664     "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
665     "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
666     "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
667     "table-caption", "table-cell", "table-column", "table-column-group",
668     "table-footer-group", "table-header-group", "table-row", "table-row-group",
669     "tamil",
670     "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
671     "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
672     "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
673     "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
674     "trad-chinese-formal", "trad-chinese-informal", "transform",
675     "translate", "translate3d", "translateX", "translateY", "translateZ",
676     "transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
677     "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
678     "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
679     "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
680     "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
681     "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
682     "xx-large", "xx-small"
683   ], valueKeywords = keySet(valueKeywords_);
684
685   var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
686     .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
687     .concat(valueKeywords_);
688   CodeMirror.registerHelper("hintWords", "css", allWords);
689
690   function tokenCComment(stream, state) {
691     var maybeEnd = false, ch;
692     while ((ch = stream.next()) != null) {
693       if (maybeEnd && ch == "/") {
694         state.tokenize = null;
695         break;
696       }
697       maybeEnd = (ch == "*");
698     }
699     return ["comment", "comment"];
700   }
701
702   CodeMirror.defineMIME("text/css", {
703     documentTypes: documentTypes,
704     mediaTypes: mediaTypes,
705     mediaFeatures: mediaFeatures,
706     mediaValueKeywords: mediaValueKeywords,
707     propertyKeywords: propertyKeywords,
708     nonStandardPropertyKeywords: nonStandardPropertyKeywords,
709     fontProperties: fontProperties,
710     counterDescriptors: counterDescriptors,
711     colorKeywords: colorKeywords,
712     valueKeywords: valueKeywords,
713     tokenHooks: {
714       "/": function(stream, state) {
715         if (!stream.eat("*")) return false;
716         state.tokenize = tokenCComment;
717         return tokenCComment(stream, state);
718       }
719     },
720     name: "css"
721   });
722
723   CodeMirror.defineMIME("text/x-scss", {
724     mediaTypes: mediaTypes,
725     mediaFeatures: mediaFeatures,
726     mediaValueKeywords: mediaValueKeywords,
727     propertyKeywords: propertyKeywords,
728     nonStandardPropertyKeywords: nonStandardPropertyKeywords,
729     colorKeywords: colorKeywords,
730     valueKeywords: valueKeywords,
731     fontProperties: fontProperties,
732     allowNested: true,
733     tokenHooks: {
734       "/": function(stream, state) {
735         if (stream.eat("/")) {
736           stream.skipToEnd();
737           return ["comment", "comment"];
738         } else if (stream.eat("*")) {
739           state.tokenize = tokenCComment;
740           return tokenCComment(stream, state);
741         } else {
742           return ["operator", "operator"];
743         }
744       },
745       ":": function(stream) {
746         if (stream.match(/\s*\{/))
747           return [null, "{"];
748         return false;
749       },
750       "$": function(stream) {
751         stream.match(/^[\w-]+/);
752         if (stream.match(/^\s*:/, false))
753           return ["variable-2", "variable-definition"];
754         return ["variable-2", "variable"];
755       },
756       "#": function(stream) {
757         if (!stream.eat("{")) return false;
758         return [null, "interpolation"];
759       }
760     },
761     name: "css",
762     helperType: "scss"
763   });
764
765   CodeMirror.defineMIME("text/x-less", {
766     mediaTypes: mediaTypes,
767     mediaFeatures: mediaFeatures,
768     mediaValueKeywords: mediaValueKeywords,
769     propertyKeywords: propertyKeywords,
770     nonStandardPropertyKeywords: nonStandardPropertyKeywords,
771     colorKeywords: colorKeywords,
772     valueKeywords: valueKeywords,
773     fontProperties: fontProperties,
774     allowNested: true,
775     tokenHooks: {
776       "/": function(stream, state) {
777         if (stream.eat("/")) {
778           stream.skipToEnd();
779           return ["comment", "comment"];
780         } else if (stream.eat("*")) {
781           state.tokenize = tokenCComment;
782           return tokenCComment(stream, state);
783         } else {
784           return ["operator", "operator"];
785         }
786       },
787       "@": function(stream) {
788         if (stream.eat("{")) return [null, "interpolation"];
789         if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
790         stream.eatWhile(/[\w\\\-]/);
791         if (stream.match(/^\s*:/, false))
792           return ["variable-2", "variable-definition"];
793         return ["variable-2", "variable"];
794       },
795       "&": function() {
796         return ["atom", "atom"];
797       }
798     },
799     name: "css",
800     helperType: "less"
801   });
802
803   CodeMirror.defineMIME("text/x-gss", {
804     documentTypes: documentTypes,
805     mediaTypes: mediaTypes,
806     mediaFeatures: mediaFeatures,
807     propertyKeywords: propertyKeywords,
808     nonStandardPropertyKeywords: nonStandardPropertyKeywords,
809     fontProperties: fontProperties,
810     counterDescriptors: counterDescriptors,
811     colorKeywords: colorKeywords,
812     valueKeywords: valueKeywords,
813     supportsAtComponent: true,
814     tokenHooks: {
815       "/": function(stream, state) {
816         if (!stream.eat("*")) return false;
817         state.tokenize = tokenCComment;
818         return tokenCComment(stream, state);
819       }
820     },
821     name: "css",
822     helperType: "gss"
823   });
824
825 });