]>
git.immae.eu Git - perso/Immae/Projets/packagist/piedsjaloux-ckeditor-component.git/blob - sources/samples/toolbarconfigurator/lib/codemirror/javascript.js
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
4 // TODO actually recognize syntax of TypeScript constructs
7 if (typeof exports
== "object" && typeof module
== "object") // CommonJS
8 mod(require("../../lib/codemirror"));
9 else if (typeof define
== "function" && define
.amd
) // AMD
10 define(["../../lib/codemirror"], mod
);
11 else // Plain browser env
13 })(function(CodeMirror
) {
16 CodeMirror
.defineMode("javascript", function(config
, parserConfig
) {
17 var indentUnit
= config
.indentUnit
;
18 var statementIndent
= parserConfig
.statementIndent
;
19 var jsonldMode
= parserConfig
.jsonld
;
20 var jsonMode
= parserConfig
.json
|| jsonldMode
;
21 var isTS
= parserConfig
.typescript
;
22 var wordRE
= parserConfig
.wordCharacters
|| /[\w$\xa1-\uffff]/;
26 var keywords = function(){
27 function kw(type
) {return {type: type
, style: "keyword"};}
28 var A
= kw("keyword a"), B
= kw("keyword b"), C
= kw("keyword c");
29 var operator
= kw("operator"), atom
= {type: "atom", style: "atom"};
32 "if": kw("if"), "while": A
, "with": A
, "else": B
, "do": B
, "try": B
, "finally": B
,
33 "return": C
, "break": C
, "continue": C
, "new": C
, "delete": C
, "throw": C
, "debugger": C
,
34 "var": kw("var"), "const": kw("var"), "let": kw("var"),
35 "function": kw("function"), "catch": kw("catch"),
36 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
37 "in": operator
, "typeof": operator
, "instanceof": operator
,
38 "true": atom
, "false": atom
, "null": atom
, "undefined": atom
, "NaN": atom
, "Infinity": atom
,
39 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
40 "yield": C
, "export": kw("export"), "import": kw("import"), "extends": C
43 // Extend the 'normal' keywords with the TypeScript language extensions
45 var type
= {type: "variable", style: "variable-3"};
48 "interface": kw("interface"),
49 "extends": kw("extends"),
50 "constructor": kw("constructor"),
53 "public": kw("public"),
54 "private": kw("private"),
55 "protected": kw("protected"),
56 "static": kw("static"),
59 "string": type
, "number": type
, "bool": type
, "any": type
62 for (var attr
in tsKeywords
) {
63 jsKeywords
[attr
] = tsKeywords
[attr
];
70 var isOperatorChar
= /[+\-*&%=<>!?|~^]/;
71 var isJsonldKeyword
= /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
73 function readRegexp(stream
) {
74 var escaped
= false, next
, inSet
= false;
75 while ((next
= stream
.next()) != null) {
77 if (next
== "/" && !inSet
) return;
78 if (next
== "[") inSet
= true;
79 else if (inSet
&& next
== "]") inSet
= false;
81 escaped
= !escaped
&& next
== "\\";
85 // Used as scratch variables to communicate multiple values without
86 // consing up tons of objects.
88 function ret(tp
, style
, cont
) {
89 type
= tp
; content
= cont
;
92 function tokenBase(stream
, state
) {
93 var ch
= stream
.next();
94 if (ch
== '"' || ch
== "'") {
95 state
.tokenize
= tokenString(ch
);
96 return state
.tokenize(stream
, state
);
97 } else if (ch
== "." && stream
.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
98 return ret("number", "number");
99 } else if (ch
== "." && stream
.match("..")) {
100 return ret("spread", "meta");
101 } else if (/[\[\]{}\(\),;\:\.]/.test(ch
)) {
103 } else if (ch
== "=" && stream
.eat(">")) {
104 return ret("=>", "operator");
105 } else if (ch
== "0" && stream
.eat(/x
/i
)) {
106 stream
.eatWhile(/[\da-f]/i);
107 return ret("number", "number");
108 } else if (/\d/.test(ch
)) {
109 stream
.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
110 return ret("number", "number");
111 } else if (ch
== "/") {
112 if (stream
.eat("*")) {
113 state
.tokenize
= tokenComment
;
114 return tokenComment(stream
, state
);
115 } else if (stream
.eat("/")) {
117 return ret("comment", "comment");
118 } else if (state
.lastType
== "operator" || state
.lastType
== "keyword c" ||
119 state
.lastType
== "sof" || /^[\[{}\(,;:]$/.test(state
.lastType
)) {
121 stream
.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
122 return ret("regexp", "string-2");
124 stream
.eatWhile(isOperatorChar
);
125 return ret("operator", "operator", stream
.current());
127 } else if (ch
== "`") {
128 state
.tokenize
= tokenQuasi
;
129 return tokenQuasi(stream
, state
);
130 } else if (ch
== "#") {
132 return ret("error", "error");
133 } else if (isOperatorChar
.test(ch
)) {
134 stream
.eatWhile(isOperatorChar
);
135 return ret("operator", "operator", stream
.current());
136 } else if (wordRE
.test(ch
)) {
137 stream
.eatWhile(wordRE
);
138 var word
= stream
.current(), known
= keywords
.propertyIsEnumerable(word
) && keywords
[word
];
139 return (known
&& state
.lastType
!= ".") ? ret(known
.type
, known
.style
, word
) :
140 ret("variable", "variable", word
);
144 function tokenString(quote
) {
145 return function(stream
, state
) {
146 var escaped
= false, next
;
147 if (jsonldMode
&& stream
.peek() == "@" && stream
.match(isJsonldKeyword
)){
148 state
.tokenize
= tokenBase
;
149 return ret("jsonld-keyword", "meta");
151 while ((next
= stream
.next()) != null) {
152 if (next
== quote
&& !escaped
) break;
153 escaped
= !escaped
&& next
== "\\";
155 if (!escaped
) state
.tokenize
= tokenBase
;
156 return ret("string", "string");
160 function tokenComment(stream
, state
) {
161 var maybeEnd
= false, ch
;
162 while (ch
= stream
.next()) {
163 if (ch
== "/" && maybeEnd
) {
164 state
.tokenize
= tokenBase
;
167 maybeEnd
= (ch
== "*");
169 return ret("comment", "comment");
172 function tokenQuasi(stream
, state
) {
173 var escaped
= false, next
;
174 while ((next
= stream
.next()) != null) {
175 if (!escaped
&& (next
== "`" || next
== "$" && stream
.eat("{"))) {
176 state
.tokenize
= tokenBase
;
179 escaped
= !escaped
&& next
== "\\";
181 return ret("quasi", "string-2", stream
.current());
184 var brackets
= "([{}])";
185 // This is a crude lookahead trick to try and notice that we're
186 // parsing the argument patterns for a fat-arrow function before we
187 // actually hit the arrow token. It only works if the arrow is on
188 // the same line as the arguments and there's no strange noise
189 // (comments) in between. Fallback is to only notice when we hit the
190 // arrow, and not declare the arguments as locals for the arrow
192 function findFatArrow(stream
, state
) {
193 if (state
.fatArrowAt
) state
.fatArrowAt
= null;
194 var arrow
= stream
.string
.indexOf("=>", stream
.start
);
195 if (arrow
< 0) return;
197 var depth
= 0, sawSomething
= false;
198 for (var pos
= arrow
- 1; pos
>= 0; --pos
) {
199 var ch
= stream
.string
.charAt(pos
);
200 var bracket
= brackets
.indexOf(ch
);
201 if (bracket
>= 0 && bracket
< 3) {
202 if (!depth
) { ++pos
; break; }
203 if (--depth
== 0) break;
204 } else if (bracket
>= 3 && bracket
< 6) {
206 } else if (wordRE
.test(ch
)) {
208 } else if (/["'\/]/.test(ch
)) {
210 } else if (sawSomething
&& !depth
) {
215 if (sawSomething
&& !depth
) state
.fatArrowAt
= pos
;
220 var atomicTypes
= {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
222 function JSLexical(indented
, column
, type
, align
, prev
, info
) {
223 this.indented
= indented
;
224 this.column
= column
;
228 if (align
!= null) this.align
= align
;
231 function inScope(state
, varname
) {
232 for (var v
= state
.localVars
; v
; v
= v
.next
)
233 if (v
.name
== varname
) return true;
234 for (var cx
= state
.context
; cx
; cx
= cx
.prev
) {
235 for (var v
= cx
.vars
; v
; v
= v
.next
)
236 if (v
.name
== varname
) return true;
240 function parseJS(state
, style
, type
, content
, stream
) {
242 // Communicate our context to the combinators.
243 // (Less wasteful than consing up a hundred closures on every call.)
244 cx
.state
= state
; cx
.stream
= stream
; cx
.marked
= null, cx
.cc
= cc
; cx
.style
= style
;
246 if (!state
.lexical
.hasOwnProperty("align"))
247 state
.lexical
.align
= true;
250 var combinator
= cc
.length
? cc
.pop() : jsonMode
? expression : statement
;
251 if (combinator(type
, content
)) {
252 while(cc
.length
&& cc
[cc
.length
- 1].lex
)
254 if (cx
.marked
) return cx
.marked
;
255 if (type
== "variable" && inScope(state
, content
)) return "variable-2";
263 var cx
= {state: null, column: null, marked: null, cc: null};
265 for (var i
= arguments
.length
- 1; i
>= 0; i
--) cx
.cc
.push(arguments
[i
]);
268 pass
.apply(null, arguments
);
271 function register(varname
) {
272 function inList(list
) {
273 for (var v
= list
; v
; v
= v
.next
)
274 if (v
.name
== varname
) return true;
277 var state
= cx
.state
;
280 if (inList(state
.localVars
)) return;
281 state
.localVars
= {name: varname
, next: state
.localVars
};
283 if (inList(state
.globalVars
)) return;
284 if (parserConfig
.globalVars
)
285 state
.globalVars
= {name: varname
, next: state
.globalVars
};
291 var defaultVars
= {name: "this", next: {name: "arguments"}};
292 function pushcontext() {
293 cx
.state
.context
= {prev: cx
.state
.context
, vars: cx
.state
.localVars
};
294 cx
.state
.localVars
= defaultVars
;
296 function popcontext() {
297 cx
.state
.localVars
= cx
.state
.context
.vars
;
298 cx
.state
.context
= cx
.state
.context
.prev
;
300 function pushlex(type
, info
) {
301 var result = function() {
302 var state
= cx
.state
, indent
= state
.indented
;
303 if (state
.lexical
.type
== "stat") indent
= state
.lexical
.indented
;
304 else for (var outer
= state
.lexical
; outer
&& outer
.type
== ")" && outer
.align
; outer
= outer
.prev
)
305 indent
= outer
.indented
;
306 state
.lexical
= new JSLexical(indent
, cx
.stream
.column(), type
, null, state
.lexical
, info
);
312 var state
= cx
.state
;
313 if (state
.lexical
.prev
) {
314 if (state
.lexical
.type
== ")")
315 state
.indented
= state
.lexical
.indented
;
316 state
.lexical
= state
.lexical
.prev
;
321 function expect(wanted
) {
323 if (type
== wanted
) return cont();
324 else if (wanted
== ";") return pass();
325 else return cont(exp
);
330 function statement(type
, value
) {
331 if (type
== "var") return cont(pushlex("vardef", value
.length
), vardef
, expect(";"), poplex
);
332 if (type
== "keyword a") return cont(pushlex("form"), expression
, statement
, poplex
);
333 if (type
== "keyword b") return cont(pushlex("form"), statement
, poplex
);
334 if (type
== "{") return cont(pushlex("}"), block
, poplex
);
335 if (type
== ";") return cont();
337 if (cx
.state
.lexical
.info
== "else" && cx
.state
.cc
[cx
.state
.cc
.length
- 1] == poplex
)
339 return cont(pushlex("form"), expression
, statement
, poplex
, maybeelse
);
341 if (type
== "function") return cont(functiondef
);
342 if (type
== "for") return cont(pushlex("form"), forspec
, statement
, poplex
);
343 if (type
== "variable") return cont(pushlex("stat"), maybelabel
);
344 if (type
== "switch") return cont(pushlex("form"), expression
, pushlex("}", "switch"), expect("{"),
345 block
, poplex
, poplex
);
346 if (type
== "case") return cont(expression
, expect(":"));
347 if (type
== "default") return cont(expect(":"));
348 if (type
== "catch") return cont(pushlex("form"), pushcontext
, expect("("), funarg
, expect(")"),
349 statement
, poplex
, popcontext
);
350 if (type
== "module") return cont(pushlex("form"), pushcontext
, afterModule
, popcontext
, poplex
);
351 if (type
== "class") return cont(pushlex("form"), className
, poplex
);
352 if (type
== "export") return cont(pushlex("form"), afterExport
, poplex
);
353 if (type
== "import") return cont(pushlex("form"), afterImport
, poplex
);
354 return pass(pushlex("stat"), expression
, expect(";"), poplex
);
356 function expression(type
) {
357 return expressionInner(type
, false);
359 function expressionNoComma(type
) {
360 return expressionInner(type
, true);
362 function expressionInner(type
, noComma
) {
363 if (cx
.state
.fatArrowAt
== cx
.stream
.start
) {
364 var body
= noComma
? arrowBodyNoComma : arrowBody
;
365 if (type
== "(") return cont(pushcontext
, pushlex(")"), commasep(pattern
, ")"), poplex
, expect("=>"), body
, popcontext
);
366 else if (type
== "variable") return pass(pushcontext
, pattern
, expect("=>"), body
, popcontext
);
369 var maybeop
= noComma
? maybeoperatorNoComma : maybeoperatorComma
;
370 if (atomicTypes
.hasOwnProperty(type
)) return cont(maybeop
);
371 if (type
== "function") return cont(functiondef
, maybeop
);
372 if (type
== "keyword c") return cont(noComma
? maybeexpressionNoComma : maybeexpression
);
373 if (type
== "(") return cont(pushlex(")"), maybeexpression
, comprehension
, expect(")"), poplex
, maybeop
);
374 if (type
== "operator" || type
== "spread") return cont(noComma
? expressionNoComma : expression
);
375 if (type
== "[") return cont(pushlex("]"), arrayLiteral
, poplex
, maybeop
);
376 if (type
== "{") return contCommasep(objprop
, "}", null, maybeop
);
377 if (type
== "quasi") { return pass(quasi
, maybeop
); }
380 function maybeexpression(type
) {
381 if (type
.match(/[;\}\)\],]/)) return pass();
382 return pass(expression
);
384 function maybeexpressionNoComma(type
) {
385 if (type
.match(/[;\}\)\],]/)) return pass();
386 return pass(expressionNoComma
);
389 function maybeoperatorComma(type
, value
) {
390 if (type
== ",") return cont(expression
);
391 return maybeoperatorNoComma(type
, value
, false);
393 function maybeoperatorNoComma(type
, value
, noComma
) {
394 var me
= noComma
== false ? maybeoperatorComma : maybeoperatorNoComma
;
395 var expr
= noComma
== false ? expression : expressionNoComma
;
396 if (type
== "=>") return cont(pushcontext
, noComma
? arrowBodyNoComma : arrowBody
, popcontext
);
397 if (type
== "operator") {
398 if (/\+\+|--/.test(value
)) return cont(me
);
399 if (value
== "?") return cont(expression
, expect(":"), expr
);
402 if (type
== "quasi") { return pass(quasi
, me
); }
403 if (type
== ";") return;
404 if (type
== "(") return contCommasep(expressionNoComma
, ")", "call", me
);
405 if (type
== ".") return cont(property
, me
);
406 if (type
== "[") return cont(pushlex("]"), maybeexpression
, expect("]"), poplex
, me
);
408 function quasi(type
, value
) {
409 if (type
!= "quasi") return pass();
410 if (value
.slice(value
.length
- 2) != "${") return cont(quasi
);
411 return cont(expression
, continueQuasi
);
413 function continueQuasi(type
) {
415 cx
.marked
= "string-2";
416 cx
.state
.tokenize
= tokenQuasi
;
420 function arrowBody(type
) {
421 findFatArrow(cx
.stream
, cx
.state
);
422 return pass(type
== "{" ? statement : expression
);
424 function arrowBodyNoComma(type
) {
425 findFatArrow(cx
.stream
, cx
.state
);
426 return pass(type
== "{" ? statement : expressionNoComma
);
428 function maybelabel(type
) {
429 if (type
== ":") return cont(poplex
, statement
);
430 return pass(maybeoperatorComma
, expect(";"), poplex
);
432 function property(type
) {
433 if (type
== "variable") {cx
.marked
= "property"; return cont();}
435 function objprop(type
, value
) {
436 if (type
== "variable" || cx
.style
== "keyword") {
437 cx
.marked
= "property";
438 if (value
== "get" || value
== "set") return cont(getterSetter
);
439 return cont(afterprop
);
440 } else if (type
== "number" || type
== "string") {
441 cx
.marked
= jsonldMode
? "property" : (cx
.style
+ " property");
442 return cont(afterprop
);
443 } else if (type
== "jsonld-keyword") {
444 return cont(afterprop
);
445 } else if (type
== "[") {
446 return cont(expression
, expect("]"), afterprop
);
449 function getterSetter(type
) {
450 if (type
!= "variable") return pass(afterprop
);
451 cx
.marked
= "property";
452 return cont(functiondef
);
454 function afterprop(type
) {
455 if (type
== ":") return cont(expressionNoComma
);
456 if (type
== "(") return pass(functiondef
);
458 function commasep(what
, end
) {
459 function proceed(type
) {
461 var lex
= cx
.state
.lexical
;
462 if (lex
.info
== "call") lex
.pos
= (lex
.pos
|| 0) + 1;
463 return cont(what
, proceed
);
465 if (type
== end
) return cont();
466 return cont(expect(end
));
468 return function(type
) {
469 if (type
== end
) return cont();
470 return pass(what
, proceed
);
473 function contCommasep(what
, end
, info
) {
474 for (var i
= 3; i
< arguments
.length
; i
++)
475 cx
.cc
.push(arguments
[i
]);
476 return cont(pushlex(end
, info
), commasep(what
, end
), poplex
);
478 function block(type
) {
479 if (type
== "}") return cont();
480 return pass(statement
, block
);
482 function maybetype(type
) {
483 if (isTS
&& type
== ":") return cont(typedef
);
485 function typedef(type
) {
486 if (type
== "variable"){cx
.marked
= "variable-3"; return cont();}
489 return pass(pattern
, maybetype
, maybeAssign
, vardefCont
);
491 function pattern(type
, value
) {
492 if (type
== "variable") { register(value
); return cont(); }
493 if (type
== "[") return contCommasep(pattern
, "]");
494 if (type
== "{") return contCommasep(proppattern
, "}");
496 function proppattern(type
, value
) {
497 if (type
== "variable" && !cx
.stream
.match(/^\s*:/, false)) {
499 return cont(maybeAssign
);
501 if (type
== "variable") cx
.marked
= "property";
502 return cont(expect(":"), pattern
, maybeAssign
);
504 function maybeAssign(_type
, value
) {
505 if (value
== "=") return cont(expressionNoComma
);
507 function vardefCont(type
) {
508 if (type
== ",") return cont(vardef
);
510 function maybeelse(type
, value
) {
511 if (type
== "keyword b" && value
== "else") return cont(pushlex("form", "else"), statement
, poplex
);
513 function forspec(type
) {
514 if (type
== "(") return cont(pushlex(")"), forspec1
, expect(")"), poplex
);
516 function forspec1(type
) {
517 if (type
== "var") return cont(vardef
, expect(";"), forspec2
);
518 if (type
== ";") return cont(forspec2
);
519 if (type
== "variable") return cont(formaybeinof
);
520 return pass(expression
, expect(";"), forspec2
);
522 function formaybeinof(_type
, value
) {
523 if (value
== "in" || value
== "of") { cx
.marked
= "keyword"; return cont(expression
); }
524 return cont(maybeoperatorComma
, forspec2
);
526 function forspec2(type
, value
) {
527 if (type
== ";") return cont(forspec3
);
528 if (value
== "in" || value
== "of") { cx
.marked
= "keyword"; return cont(expression
); }
529 return pass(expression
, expect(";"), forspec3
);
531 function forspec3(type
) {
532 if (type
!= ")") cont(expression
);
534 function functiondef(type
, value
) {
535 if (value
== "*") {cx
.marked
= "keyword"; return cont(functiondef
);}
536 if (type
== "variable") {register(value
); return cont(functiondef
);}
537 if (type
== "(") return cont(pushcontext
, pushlex(")"), commasep(funarg
, ")"), poplex
, statement
, popcontext
);
539 function funarg(type
) {
540 if (type
== "spread") return cont(funarg
);
541 return pass(pattern
, maybetype
);
543 function className(type
, value
) {
544 if (type
== "variable") {register(value
); return cont(classNameAfter
);}
546 function classNameAfter(type
, value
) {
547 if (value
== "extends") return cont(expression
, classNameAfter
);
548 if (type
== "{") return cont(pushlex("}"), classBody
, poplex
);
550 function classBody(type
, value
) {
551 if (type
== "variable" || cx
.style
== "keyword") {
552 if (value
== "static") {
553 cx
.marked
= "keyword";
554 return cont(classBody
);
556 cx
.marked
= "property";
557 if (value
== "get" || value
== "set") return cont(classGetterSetter
, functiondef
, classBody
);
558 return cont(functiondef
, classBody
);
561 cx
.marked
= "keyword";
562 return cont(classBody
);
564 if (type
== ";") return cont(classBody
);
565 if (type
== "}") return cont();
567 function classGetterSetter(type
) {
568 if (type
!= "variable") return pass();
569 cx
.marked
= "property";
572 function afterModule(type
, value
) {
573 if (type
== "string") return cont(statement
);
574 if (type
== "variable") { register(value
); return cont(maybeFrom
); }
576 function afterExport(_type
, value
) {
577 if (value
== "*") { cx
.marked
= "keyword"; return cont(maybeFrom
, expect(";")); }
578 if (value
== "default") { cx
.marked
= "keyword"; return cont(expression
, expect(";")); }
579 return pass(statement
);
581 function afterImport(type
) {
582 if (type
== "string") return cont();
583 return pass(importSpec
, maybeFrom
);
585 function importSpec(type
, value
) {
586 if (type
== "{") return contCommasep(importSpec
, "}");
587 if (type
== "variable") register(value
);
588 if (value
== "*") cx
.marked
= "keyword";
589 return cont(maybeAs
);
591 function maybeAs(_type
, value
) {
592 if (value
== "as") { cx
.marked
= "keyword"; return cont(importSpec
); }
594 function maybeFrom(_type
, value
) {
595 if (value
== "from") { cx
.marked
= "keyword"; return cont(expression
); }
597 function arrayLiteral(type
) {
598 if (type
== "]") return cont();
599 return pass(expressionNoComma
, maybeArrayComprehension
);
601 function maybeArrayComprehension(type
) {
602 if (type
== "for") return pass(comprehension
, expect("]"));
603 if (type
== ",") return cont(commasep(maybeexpressionNoComma
, "]"));
604 return pass(commasep(expressionNoComma
, "]"));
606 function comprehension(type
) {
607 if (type
== "for") return cont(forspec
, comprehension
);
608 if (type
== "if") return cont(expression
, comprehension
);
611 function isContinuedStatement(state
, textAfter
) {
612 return state
.lastType
== "operator" || state
.lastType
== "," ||
613 isOperatorChar
.test(textAfter
.charAt(0)) ||
614 /[,.]/.test(textAfter
.charAt(0));
620 startState: function(basecolumn
) {
625 lexical: new JSLexical((basecolumn
|| 0) - indentUnit
, 0, "block", false),
626 localVars: parserConfig
.localVars
,
627 context: parserConfig
.localVars
&& {vars: parserConfig
.localVars
},
630 if (parserConfig
.globalVars
&& typeof parserConfig
.globalVars
== "object")
631 state
.globalVars
= parserConfig
.globalVars
;
635 token: function(stream
, state
) {
637 if (!state
.lexical
.hasOwnProperty("align"))
638 state
.lexical
.align
= false;
639 state
.indented
= stream
.indentation();
640 findFatArrow(stream
, state
);
642 if (state
.tokenize
!= tokenComment
&& stream
.eatSpace()) return null;
643 var style
= state
.tokenize(stream
, state
);
644 if (type
== "comment") return style
;
645 state
.lastType
= type
== "operator" && (content
== "++" || content
== "--") ? "incdec" : type
;
646 return parseJS(state
, style
, type
, content
, stream
);
649 indent: function(state
, textAfter
) {
650 if (state
.tokenize
== tokenComment
) return CodeMirror
.Pass
;
651 if (state
.tokenize
!= tokenBase
) return 0;
652 var firstChar
= textAfter
&& textAfter
.charAt(0), lexical
= state
.lexical
;
653 // Kludge to prevent 'maybelse' from blocking lexical scope pops
654 if (!/^\s*else\b/.test(textAfter
)) for (var i
= state
.cc
.length
- 1; i
>= 0; --i
) {
656 if (c
== poplex
) lexical
= lexical
.prev
;
657 else if (c
!= maybeelse
) break;
659 if (lexical
.type
== "stat" && firstChar
== "}") lexical
= lexical
.prev
;
660 if (statementIndent
&& lexical
.type
== ")" && lexical
.prev
.type
== "stat")
661 lexical
= lexical
.prev
;
662 var type
= lexical
.type
, closing
= firstChar
== type
;
664 if (type
== "vardef") return lexical
.indented
+ (state
.lastType
== "operator" || state
.lastType
== "," ? lexical
.info
+ 1 : 0);
665 else if (type
== "form" && firstChar
== "{") return lexical
.indented
;
666 else if (type
== "form") return lexical
.indented
+ indentUnit
;
667 else if (type
== "stat")
668 return lexical
.indented
+ (isContinuedStatement(state
, textAfter
) ? statementIndent
|| indentUnit : 0);
669 else if (lexical
.info
== "switch" && !closing
&& parserConfig
.doubleIndentSwitch
!= false)
670 return lexical
.indented
+ (/^(?:case|default)\b/.test(textAfter
) ? indentUnit : 2 * indentUnit
);
671 else if (lexical
.align
) return lexical
.column
+ (closing
? 0 : 1);
672 else return lexical
.indented
+ (closing
? 0 : indentUnit
);
675 electricInput: /^\s
*(?:case .*?:|default:|\{|\})$/,
676 blockCommentStart: jsonMode
? null : "/*",
677 blockCommentEnd: jsonMode
? null : "*/",
678 lineComment: jsonMode
? null : "//",
680 closeBrackets: "()[]{}''\"\"``",
682 helperType: jsonMode
? "json" : "javascript",
683 jsonldMode: jsonldMode
,
688 CodeMirror
.registerHelper("wordChars", "javascript", /[\w$]/);
690 CodeMirror
.defineMIME("text/javascript", "javascript");
691 CodeMirror
.defineMIME("text/ecmascript", "javascript");
692 CodeMirror
.defineMIME("application/javascript", "javascript");
693 CodeMirror
.defineMIME("application/x-javascript", "javascript");
694 CodeMirror
.defineMIME("application/ecmascript", "javascript");
695 CodeMirror
.defineMIME("application/json", {name: "javascript", json: true});
696 CodeMirror
.defineMIME("application/x-json", {name: "javascript", json: true});
697 CodeMirror
.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
698 CodeMirror
.defineMIME("text/typescript", { name: "javascript", typescript: true });
699 CodeMirror
.defineMIME("application/typescript", { name: "javascript", typescript: true });