openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

css.js (37677B)


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