Passed
Push — master ( 3324e2...2ba76b )
by Ralf
13:44
created

Resources/Public/JavaScript/editormd/lib/codemirror/mode/css/css.js   F

Complexity

Total Complexity 153
Complexity/F 3.56

Size

Lines of Code 763
Function Count 43

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 153
eloc 632
c 0
b 0
f 0
dl 0
loc 763
rs 1.968
mnd 110
bc 110
fnc 43
bpm 2.5581
cpm 3.5581
noi 7

13 Functions

Rating   Name   Duplication   Size   Complexity  
A css.js ➔ pass 0 3 1
A css.js ➔ popAndPass 0 5 2
A css.js ➔ tokenCComment 0 11 3
F css.js ➔ keySet 0 7 85
B css.js ➔ ret 0 1 7
A css.js ➔ tokenSGMLComment 0 9 2
F css.js ➔ tokenBase 0 54 19
A css.js ➔ tokenParenthesized 0 8 2
A css.js ➔ pushContext 0 4 1
A css.js ➔ popContext 0 4 1
A css.js ➔ Context 0 5 1
A css.js ➔ wordAsValue 0 9 3
B css.js ➔ tokenString 0 14 6

How to fix   Complexity   

Complexity

Complex classes like Resources/Public/JavaScript/editormd/lib/codemirror/mode/css/css.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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
0 ignored issues
show
Bug introduced by
The variable define seems to be never declared. If this is a global, consider adding a /** global: define */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
8
    define(["../../lib/codemirror"], mod);
9
  else // Plain browser env
10
    mod(CodeMirror);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
11
})(function(CodeMirror) {
12
"use strict";
13
14
CodeMirror.defineMode("css", function(config, parserConfig) {
15
  if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
16
17
  var indentUnit = config.indentUnit,
18
      tokenHooks = parserConfig.tokenHooks,
19
      documentTypes = parserConfig.documentTypes || {},
20
      mediaTypes = parserConfig.mediaTypes || {},
21
      mediaFeatures = parserConfig.mediaFeatures || {},
22
      propertyKeywords = parserConfig.propertyKeywords || {},
23
      nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
24
      fontProperties = parserConfig.fontProperties || {},
25
      counterDescriptors = parserConfig.counterDescriptors || {},
26
      colorKeywords = parserConfig.colorKeywords || {},
27
      valueKeywords = parserConfig.valueKeywords || {},
28
      allowNested = parserConfig.allowNested;
29
30
  var type, override;
31
  function ret(style, tp) { type = tp; return style; }
32
33
  // Tokenizers
34
35
  function tokenBase(stream, state) {
36
    var ch = stream.next();
37
    if (tokenHooks[ch]) {
38
      var result = tokenHooks[ch](stream, state);
39
      if (result !== false) return result;
40
    }
41
    if (ch == "@") {
42
      stream.eatWhile(/[\w\\\-]/);
43
      return ret("def", stream.current());
44
    } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
45
      return ret(null, "compare");
46
    } else if (ch == "\"" || ch == "'") {
47
      state.tokenize = tokenString(ch);
48
      return state.tokenize(stream, state);
49
    } else if (ch == "#") {
50
      stream.eatWhile(/[\w\\\-]/);
51
      return ret("atom", "hash");
52
    } else if (ch == "!") {
53
      stream.match(/^\s*\w*/);
54
      return ret("keyword", "important");
55
    } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
56
      stream.eatWhile(/[\w.%]/);
57
      return ret("number", "unit");
58
    } else if (ch === "-") {
59
      if (/[\d.]/.test(stream.peek())) {
60
        stream.eatWhile(/[\w.%]/);
61
        return ret("number", "unit");
62
      } else if (stream.match(/^-[\w\\\-]+/)) {
63
        stream.eatWhile(/[\w\\\-]/);
64
        if (stream.match(/^\s*:/, false))
65
          return ret("variable-2", "variable-definition");
66
        return ret("variable-2", "variable");
67
      } else if (stream.match(/^\w+-/)) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if stream.match(^\w+-) is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

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