tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

css.js (37717B)


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