PluginProbe ʕ •ᴥ•ʔ
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel / 1.1.5
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel v1.1.5
trunk 0.9.0 0.9.1 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2.0 1.2.1 1.2.10 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.14 1.4.15 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0
wp-all-export / static / codemirror / javascript.js
wp-all-export / static / codemirror Last commit date
autorefresh.js 8 years ago clike.js 8 years ago codemirror.css 8 years ago codemirror.js 8 years ago htmlmixed.js 8 years ago javascript.js 8 years ago matchbrackets.js 8 years ago php.js 8 years ago xml.js 8 years ago
javascript.js
711 lines
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 // TODO actually recognize syntax of TypeScript constructs
5
6 (function(mod) {
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
12 mod(CodeMirror);
13 })(function(CodeMirror) {
14 "use strict";
15
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]/;
23
24 // Tokenizer
25
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"};
30
31 var jsKeywords = {
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 "async": kw("async"), "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"), "class": kw("class"), "super": kw("atom"),
40 "await": C, "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
41 };
42
43 // Extend the 'normal' keywords with the TypeScript language extensions
44 if (isTS) {
45 var type = {type: "variable", style: "variable-3"};
46 var tsKeywords = {
47 // object-like things
48 "interface": kw("interface"),
49 "extends": kw("extends"),
50 "constructor": kw("constructor"),
51
52 // scope modifiers
53 "public": kw("public"),
54 "private": kw("private"),
55 "protected": kw("protected"),
56 "static": kw("static"),
57
58 // types
59 "string": type, "number": type, "bool": type, "any": type
60 };
61
62 for (var attr in tsKeywords) {
63 jsKeywords[attr] = tsKeywords[attr];
64 }
65 }
66
67 return jsKeywords;
68 }();
69
70 var isOperatorChar = /[+\-*&%=<>!?|~^]/;
71 var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
72
73 function readRegexp(stream) {
74 var escaped = false, next, inSet = false;
75 while ((next = stream.next()) != null) {
76 if (!escaped) {
77 if (next == "/" && !inSet) return;
78 if (next == "[") inSet = true;
79 else if (inSet && next == "]") inSet = false;
80 }
81 escaped = !escaped && next == "\\";
82 }
83 }
84
85 // Used as scratch variables to communicate multiple values without
86 // consing up tons of objects.
87 var type, content;
88 function ret(tp, style, cont) {
89 type = tp; content = cont;
90 return style;
91 }
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)) {
102 return ret(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 (ch == "0" && stream.eat(/o/i)) {
109 stream.eatWhile(/[0-7]/i);
110 return ret("number", "number");
111 } else if (ch == "0" && stream.eat(/b/i)) {
112 stream.eatWhile(/[01]/i);
113 return ret("number", "number");
114 } else if (/\d/.test(ch)) {
115 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
116 return ret("number", "number");
117 } else if (ch == "/") {
118 if (stream.eat("*")) {
119 state.tokenize = tokenComment;
120 return tokenComment(stream, state);
121 } else if (stream.eat("/")) {
122 stream.skipToEnd();
123 return ret("comment", "comment");
124 } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
125 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
126 readRegexp(stream);
127 stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
128 return ret("regexp", "string-2");
129 } else {
130 stream.eatWhile(isOperatorChar);
131 return ret("operator", "operator", stream.current());
132 }
133 } else if (ch == "`") {
134 state.tokenize = tokenQuasi;
135 return tokenQuasi(stream, state);
136 } else if (ch == "#") {
137 stream.skipToEnd();
138 return ret("error", "error");
139 } else if (isOperatorChar.test(ch)) {
140 stream.eatWhile(isOperatorChar);
141 return ret("operator", "operator", stream.current());
142 } else if (wordRE.test(ch)) {
143 stream.eatWhile(wordRE);
144 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
145 return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
146 ret("variable", "variable", word);
147 }
148 }
149
150 function tokenString(quote) {
151 return function(stream, state) {
152 var escaped = false, next;
153 if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
154 state.tokenize = tokenBase;
155 return ret("jsonld-keyword", "meta");
156 }
157 while ((next = stream.next()) != null) {
158 if (next == quote && !escaped) break;
159 escaped = !escaped && next == "\\";
160 }
161 if (!escaped) state.tokenize = tokenBase;
162 return ret("string", "string");
163 };
164 }
165
166 function tokenComment(stream, state) {
167 var maybeEnd = false, ch;
168 while (ch = stream.next()) {
169 if (ch == "/" && maybeEnd) {
170 state.tokenize = tokenBase;
171 break;
172 }
173 maybeEnd = (ch == "*");
174 }
175 return ret("comment", "comment");
176 }
177
178 function tokenQuasi(stream, state) {
179 var escaped = false, next;
180 while ((next = stream.next()) != null) {
181 if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
182 state.tokenize = tokenBase;
183 break;
184 }
185 escaped = !escaped && next == "\\";
186 }
187 return ret("quasi", "string-2", stream.current());
188 }
189
190 var brackets = "([{}])";
191 // This is a crude lookahead trick to try and notice that we're
192 // parsing the argument patterns for a fat-arrow function before we
193 // actually hit the arrow token. It only works if the arrow is on
194 // the same line as the arguments and there's no strange noise
195 // (comments) in between. Fallback is to only notice when we hit the
196 // arrow, and not declare the arguments as locals for the arrow
197 // body.
198 function findFatArrow(stream, state) {
199 if (state.fatArrowAt) state.fatArrowAt = null;
200 var arrow = stream.string.indexOf("=>", stream.start);
201 if (arrow < 0) return;
202
203 var depth = 0, sawSomething = false;
204 for (var pos = arrow - 1; pos >= 0; --pos) {
205 var ch = stream.string.charAt(pos);
206 var bracket = brackets.indexOf(ch);
207 if (bracket >= 0 && bracket < 3) {
208 if (!depth) { ++pos; break; }
209 if (--depth == 0) break;
210 } else if (bracket >= 3 && bracket < 6) {
211 ++depth;
212 } else if (wordRE.test(ch)) {
213 sawSomething = true;
214 } else if (/["'\/]/.test(ch)) {
215 return;
216 } else if (sawSomething && !depth) {
217 ++pos;
218 break;
219 }
220 }
221 if (sawSomething && !depth) state.fatArrowAt = pos;
222 }
223
224 // Parser
225
226 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
227
228 function JSLexical(indented, column, type, align, prev, info) {
229 this.indented = indented;
230 this.column = column;
231 this.type = type;
232 this.prev = prev;
233 this.info = info;
234 if (align != null) this.align = align;
235 }
236
237 function inScope(state, varname) {
238 for (var v = state.localVars; v; v = v.next)
239 if (v.name == varname) return true;
240 for (var cx = state.context; cx; cx = cx.prev) {
241 for (var v = cx.vars; v; v = v.next)
242 if (v.name == varname) return true;
243 }
244 }
245
246 function parseJS(state, style, type, content, stream) {
247 var cc = state.cc;
248 // Communicate our context to the combinators.
249 // (Less wasteful than consing up a hundred closures on every call.)
250 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
251
252 if (!state.lexical.hasOwnProperty("align"))
253 state.lexical.align = true;
254
255 while(true) {
256 var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
257 if (combinator(type, content)) {
258 while(cc.length && cc[cc.length - 1].lex)
259 cc.pop()();
260 if (cx.marked) return cx.marked;
261 if (type == "variable" && inScope(state, content)) return "variable-2";
262 return style;
263 }
264 }
265 }
266
267 // Combinator utils
268
269 var cx = {state: null, column: null, marked: null, cc: null};
270 function pass() {
271 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
272 }
273 function cont() {
274 pass.apply(null, arguments);
275 return true;
276 }
277 function register(varname) {
278 function inList(list) {
279 for (var v = list; v; v = v.next)
280 if (v.name == varname) return true;
281 return false;
282 }
283 var state = cx.state;
284 if (state.context) {
285 cx.marked = "def";
286 if (inList(state.localVars)) return;
287 state.localVars = {name: varname, next: state.localVars};
288 } else {
289 if (inList(state.globalVars)) return;
290 if (parserConfig.globalVars)
291 state.globalVars = {name: varname, next: state.globalVars};
292 }
293 }
294
295 // Combinators
296
297 var defaultVars = {name: "this", next: {name: "arguments"}};
298 function pushcontext() {
299 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
300 cx.state.localVars = defaultVars;
301 }
302 function popcontext() {
303 cx.state.localVars = cx.state.context.vars;
304 cx.state.context = cx.state.context.prev;
305 }
306 function pushlex(type, info) {
307 var result = function() {
308 var state = cx.state, indent = state.indented;
309 if (state.lexical.type == "stat") indent = state.lexical.indented;
310 else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
311 indent = outer.indented;
312 state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
313 };
314 result.lex = true;
315 return result;
316 }
317 function poplex() {
318 var state = cx.state;
319 if (state.lexical.prev) {
320 if (state.lexical.type == ")")
321 state.indented = state.lexical.indented;
322 state.lexical = state.lexical.prev;
323 }
324 }
325 poplex.lex = true;
326
327 function expect(wanted) {
328 function exp(type) {
329 if (type == wanted) return cont();
330 else if (wanted == ";") return pass();
331 else return cont(exp);
332 };
333 return exp;
334 }
335
336 function statement(type, value) {
337 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
338 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
339 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
340 if (type == "{") return cont(pushlex("}"), block, poplex);
341 if (type == ";") return cont();
342 if (type == "if") {
343 if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
344 cx.state.cc.pop()();
345 return cont(pushlex("form"), expression, statement, poplex, maybeelse);
346 }
347 if (type == "function") return cont(functiondef);
348 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
349 if (type == "variable") return cont(pushlex("stat"), maybelabel);
350 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
351 block, poplex, poplex);
352 if (type == "case") return cont(expression, expect(":"));
353 if (type == "default") return cont(expect(":"));
354 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
355 statement, poplex, popcontext);
356 if (type == "class") return cont(pushlex("form"), className, poplex);
357 if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
358 if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
359 return pass(pushlex("stat"), expression, expect(";"), poplex);
360 }
361 function expression(type) {
362 return expressionInner(type, false);
363 }
364 function expressionNoComma(type) {
365 return expressionInner(type, true);
366 }
367 function expressionInner(type, noComma) {
368 if (cx.state.fatArrowAt == cx.stream.start) {
369 var body = noComma ? arrowBodyNoComma : arrowBody;
370 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
371 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
372 }
373
374 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
375 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
376 if (type == "async") return cont(expression);
377 if (type == "function") return cont(functiondef, maybeop);
378 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
379 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
380 if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
381 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
382 if (type == "{") return contCommasep(objprop, "}", null, maybeop);
383 if (type == "quasi") { return pass(quasi, maybeop); }
384 return cont();
385 }
386 function maybeexpression(type) {
387 if (type.match(/[;\}\)\],]/)) return pass();
388 return pass(expression);
389 }
390 function maybeexpressionNoComma(type) {
391 if (type.match(/[;\}\)\],]/)) return pass();
392 return pass(expressionNoComma);
393 }
394
395 function maybeoperatorComma(type, value) {
396 if (type == ",") return cont(expression);
397 return maybeoperatorNoComma(type, value, false);
398 }
399 function maybeoperatorNoComma(type, value, noComma) {
400 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
401 var expr = noComma == false ? expression : expressionNoComma;
402 if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
403 if (type == "operator") {
404 if (/\+\+|--/.test(value)) return cont(me);
405 if (value == "?") return cont(expression, expect(":"), expr);
406 return cont(expr);
407 }
408 if (type == "quasi") { return pass(quasi, me); }
409 if (type == ";") return;
410 if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
411 if (type == ".") return cont(property, me);
412 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
413 }
414 function quasi(type, value) {
415 if (type != "quasi") return pass();
416 if (value.slice(value.length - 2) != "${") return cont(quasi);
417 return cont(expression, continueQuasi);
418 }
419 function continueQuasi(type) {
420 if (type == "}") {
421 cx.marked = "string-2";
422 cx.state.tokenize = tokenQuasi;
423 return cont(quasi);
424 }
425 }
426 function arrowBody(type) {
427 findFatArrow(cx.stream, cx.state);
428 return pass(type == "{" ? statement : expression);
429 }
430 function arrowBodyNoComma(type) {
431 findFatArrow(cx.stream, cx.state);
432 return pass(type == "{" ? statement : expressionNoComma);
433 }
434 function maybelabel(type) {
435 if (type == ":") return cont(poplex, statement);
436 return pass(maybeoperatorComma, expect(";"), poplex);
437 }
438 function property(type) {
439 if (type == "variable") {cx.marked = "property"; return cont();}
440 }
441 function objprop(type, value) {
442 if (type == "async") {
443 return cont(objprop);
444 } else if (type == "variable" || cx.style == "keyword") {
445 cx.marked = "property";
446 if (value == "get" || value == "set") return cont(getterSetter);
447 return cont(afterprop);
448 } else if (type == "number" || type == "string") {
449 cx.marked = jsonldMode ? "property" : (cx.style + " property");
450 return cont(afterprop);
451 } else if (type == "jsonld-keyword") {
452 return cont(afterprop);
453 } else if (type == "[") {
454 return cont(expression, expect("]"), afterprop);
455 }
456 }
457 function getterSetter(type) {
458 if (type != "variable") return pass(afterprop);
459 cx.marked = "property";
460 return cont(functiondef);
461 }
462 function afterprop(type) {
463 if (type == ":") return cont(expressionNoComma);
464 if (type == "(") return pass(functiondef);
465 }
466 function commasep(what, end) {
467 function proceed(type) {
468 if (type == ",") {
469 var lex = cx.state.lexical;
470 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
471 return cont(what, proceed);
472 }
473 if (type == end) return cont();
474 return cont(expect(end));
475 }
476 return function(type) {
477 if (type == end) return cont();
478 return pass(what, proceed);
479 };
480 }
481 function contCommasep(what, end, info) {
482 for (var i = 3; i < arguments.length; i++)
483 cx.cc.push(arguments[i]);
484 return cont(pushlex(end, info), commasep(what, end), poplex);
485 }
486 function block(type) {
487 if (type == "}") return cont();
488 return pass(statement, block);
489 }
490 function maybetype(type) {
491 if (isTS && type == ":") return cont(typedef);
492 }
493 function maybedefault(_, value) {
494 if (value == "=") return cont(expressionNoComma);
495 }
496 function typedef(type) {
497 if (type == "variable") {cx.marked = "variable-3"; return cont();}
498 }
499 function vardef() {
500 return pass(pattern, maybetype, maybeAssign, vardefCont);
501 }
502 function pattern(type, value) {
503 if (type == "variable") { register(value); return cont(); }
504 if (type == "spread") return cont(pattern);
505 if (type == "[") return contCommasep(pattern, "]");
506 if (type == "{") return contCommasep(proppattern, "}");
507 }
508 function proppattern(type, value) {
509 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
510 register(value);
511 return cont(maybeAssign);
512 }
513 if (type == "variable") cx.marked = "property";
514 if (type == "spread") return cont(pattern);
515 return cont(expect(":"), pattern, maybeAssign);
516 }
517 function maybeAssign(_type, value) {
518 if (value == "=") return cont(expressionNoComma);
519 }
520 function vardefCont(type) {
521 if (type == ",") return cont(vardef);
522 }
523 function maybeelse(type, value) {
524 if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
525 }
526 function forspec(type) {
527 if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
528 }
529 function forspec1(type) {
530 if (type == "var") return cont(vardef, expect(";"), forspec2);
531 if (type == ";") return cont(forspec2);
532 if (type == "variable") return cont(formaybeinof);
533 return pass(expression, expect(";"), forspec2);
534 }
535 function formaybeinof(_type, value) {
536 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
537 return cont(maybeoperatorComma, forspec2);
538 }
539 function forspec2(type, value) {
540 if (type == ";") return cont(forspec3);
541 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
542 return pass(expression, expect(";"), forspec3);
543 }
544 function forspec3(type) {
545 if (type != ")") cont(expression);
546 }
547 function functiondef(type, value) {
548 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
549 if (type == "variable") {register(value); return cont(functiondef);}
550 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
551 }
552 function funarg(type) {
553 if (type == "spread") return cont(funarg);
554 return pass(pattern, maybetype, maybedefault);
555 }
556 function className(type, value) {
557 if (type == "variable") {register(value); return cont(classNameAfter);}
558 }
559 function classNameAfter(type, value) {
560 if (value == "extends") return cont(expression, classNameAfter);
561 if (type == "{") return cont(pushlex("}"), classBody, poplex);
562 }
563 function classBody(type, value) {
564 if (type == "variable" || cx.style == "keyword") {
565 if (value == "static") {
566 cx.marked = "keyword";
567 return cont(classBody);
568 }
569 cx.marked = "property";
570 if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
571 return cont(functiondef, classBody);
572 }
573 if (value == "*") {
574 cx.marked = "keyword";
575 return cont(classBody);
576 }
577 if (type == ";") return cont(classBody);
578 if (type == "}") return cont();
579 }
580 function classGetterSetter(type) {
581 if (type != "variable") return pass();
582 cx.marked = "property";
583 return cont();
584 }
585 function afterExport(_type, value) {
586 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
587 if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
588 return pass(statement);
589 }
590 function afterImport(type) {
591 if (type == "string") return cont();
592 return pass(importSpec, maybeFrom);
593 }
594 function importSpec(type, value) {
595 if (type == "{") return contCommasep(importSpec, "}");
596 if (type == "variable") register(value);
597 if (value == "*") cx.marked = "keyword";
598 return cont(maybeAs);
599 }
600 function maybeAs(_type, value) {
601 if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
602 }
603 function maybeFrom(_type, value) {
604 if (value == "from") { cx.marked = "keyword"; return cont(expression); }
605 }
606 function arrayLiteral(type) {
607 if (type == "]") return cont();
608 return pass(expressionNoComma, maybeArrayComprehension);
609 }
610 function maybeArrayComprehension(type) {
611 if (type == "for") return pass(comprehension, expect("]"));
612 if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
613 return pass(commasep(expressionNoComma, "]"));
614 }
615 function comprehension(type) {
616 if (type == "for") return cont(forspec, comprehension);
617 if (type == "if") return cont(expression, comprehension);
618 }
619
620 function isContinuedStatement(state, textAfter) {
621 return state.lastType == "operator" || state.lastType == "," ||
622 isOperatorChar.test(textAfter.charAt(0)) ||
623 /[,.]/.test(textAfter.charAt(0));
624 }
625
626 // Interface
627
628 return {
629 startState: function(basecolumn) {
630 var state = {
631 tokenize: tokenBase,
632 lastType: "sof",
633 cc: [],
634 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
635 localVars: parserConfig.localVars,
636 context: parserConfig.localVars && {vars: parserConfig.localVars},
637 indented: 0
638 };
639 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
640 state.globalVars = parserConfig.globalVars;
641 return state;
642 },
643
644 token: function(stream, state) {
645 if (stream.sol()) {
646 if (!state.lexical.hasOwnProperty("align"))
647 state.lexical.align = false;
648 state.indented = stream.indentation();
649 findFatArrow(stream, state);
650 }
651 if (state.tokenize != tokenComment && stream.eatSpace()) return null;
652 var style = state.tokenize(stream, state);
653 if (type == "comment") return style;
654 state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
655 return parseJS(state, style, type, content, stream);
656 },
657
658 indent: function(state, textAfter) {
659 if (state.tokenize == tokenComment) return CodeMirror.Pass;
660 if (state.tokenize != tokenBase) return 0;
661 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
662 // Kludge to prevent 'maybelse' from blocking lexical scope pops
663 if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
664 var c = state.cc[i];
665 if (c == poplex) lexical = lexical.prev;
666 else if (c != maybeelse) break;
667 }
668 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
669 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
670 lexical = lexical.prev;
671 var type = lexical.type, closing = firstChar == type;
672
673 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
674 else if (type == "form" && firstChar == "{") return lexical.indented;
675 else if (type == "form") return lexical.indented + indentUnit;
676 else if (type == "stat")
677 return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
678 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
679 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
680 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
681 else return lexical.indented + (closing ? 0 : indentUnit);
682 },
683
684 electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
685 blockCommentStart: jsonMode ? null : "/*",
686 blockCommentEnd: jsonMode ? null : "*/",
687 lineComment: jsonMode ? null : "//",
688 fold: "brace",
689 closeBrackets: "()[]{}''\"\"``",
690
691 helperType: jsonMode ? "json" : "javascript",
692 jsonldMode: jsonldMode,
693 jsonMode: jsonMode
694 };
695 });
696
697 CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
698
699 CodeMirror.defineMIME("text/javascript", "javascript");
700 CodeMirror.defineMIME("text/ecmascript", "javascript");
701 CodeMirror.defineMIME("application/javascript", "javascript");
702 CodeMirror.defineMIME("application/x-javascript", "javascript");
703 CodeMirror.defineMIME("application/ecmascript", "javascript");
704 CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
705 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
706 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
707 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
708 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
709
710 });
711