| OLD | NEW |
| 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others |
| 2 // Distributed under an MIT license: http://codemirror.net/LICENSE |
| 3 |
| 1 // TODO actually recognize syntax of TypeScript constructs | 4 // TODO actually recognize syntax of TypeScript constructs |
| 2 | 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 |
| 3 CodeMirror.defineMode("javascript", function(config, parserConfig) { | 16 CodeMirror.defineMode("javascript", function(config, parserConfig) { |
| 4 var indentUnit = config.indentUnit; | 17 var indentUnit = config.indentUnit; |
| 5 var statementIndent = parserConfig.statementIndent; | 18 var statementIndent = parserConfig.statementIndent; |
| 6 var jsonMode = parserConfig.json; | 19 var jsonldMode = parserConfig.jsonld; |
| 20 var jsonMode = parserConfig.json || jsonldMode; |
| 7 var isTS = parserConfig.typescript; | 21 var isTS = parserConfig.typescript; |
| 8 | 22 |
| 9 // Tokenizer | 23 // Tokenizer |
| 10 | 24 |
| 11 var keywords = function(){ | 25 var keywords = function(){ |
| 12 function kw(type) {return {type: type, style: "keyword"};} | 26 function kw(type) {return {type: type, style: "keyword"};} |
| 13 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); | 27 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); |
| 14 var operator = kw("operator"), atom = {type: "atom", style: "atom"}; | 28 var operator = kw("operator"), atom = {type: "atom", style: "atom"}; |
| 15 | 29 |
| 16 var jsKeywords = { | 30 var jsKeywords = { |
| 17 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "fina
lly": B, | 31 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "fina
lly": B, |
| 18 "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, | 32 "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
"debugger": C, |
| 19 "var": kw("var"), "const": kw("var"), "let": kw("var"), | 33 "var": kw("var"), "const": kw("var"), "let": kw("var"), |
| 20 "function": kw("function"), "catch": kw("catch"), | 34 "function": kw("function"), "catch": kw("catch"), |
| 21 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": k
w("default"), | 35 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": k
w("default"), |
| 22 "in": operator, "typeof": operator, "instanceof": operator, | 36 "in": operator, "typeof": operator, "instanceof": operator, |
| 23 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom,
"Infinity": atom, | 37 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom,
"Infinity": atom, |
| 24 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super":
kw("atom"), | 38 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super":
kw("atom"), |
| 25 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C | 39 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C |
| 26 }; | 40 }; |
| 27 | 41 |
| 28 // Extend the 'normal' keywords with the TypeScript language extensions | 42 // Extend the 'normal' keywords with the TypeScript language extensions |
| (...skipping 17 matching lines...) Expand all Loading... |
| 46 | 60 |
| 47 for (var attr in tsKeywords) { | 61 for (var attr in tsKeywords) { |
| 48 jsKeywords[attr] = tsKeywords[attr]; | 62 jsKeywords[attr] = tsKeywords[attr]; |
| 49 } | 63 } |
| 50 } | 64 } |
| 51 | 65 |
| 52 return jsKeywords; | 66 return jsKeywords; |
| 53 }(); | 67 }(); |
| 54 | 68 |
| 55 var isOperatorChar = /[+\-*&%=<>!?|~^]/; | 69 var isOperatorChar = /[+\-*&%=<>!?|~^]/; |
| 70 var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|re
verse|index|base|vocab|graph)"/; |
| 56 | 71 |
| 57 function nextUntilUnescaped(stream, end) { | 72 function readRegexp(stream) { |
| 58 var escaped = false, next; | 73 var escaped = false, next, inSet = false; |
| 59 while ((next = stream.next()) != null) { | 74 while ((next = stream.next()) != null) { |
| 60 if (next == end && !escaped) | 75 if (!escaped) { |
| 61 return false; | 76 if (next == "/" && !inSet) return; |
| 77 if (next == "[") inSet = true; |
| 78 else if (inSet && next == "]") inSet = false; |
| 79 } |
| 62 escaped = !escaped && next == "\\"; | 80 escaped = !escaped && next == "\\"; |
| 63 } | 81 } |
| 64 return escaped; | |
| 65 } | 82 } |
| 66 | 83 |
| 67 // Used as scratch variables to communicate multiple values without | 84 // Used as scratch variables to communicate multiple values without |
| 68 // consing up tons of objects. | 85 // consing up tons of objects. |
| 69 var type, content; | 86 var type, content; |
| 70 function ret(tp, style, cont) { | 87 function ret(tp, style, cont) { |
| 71 type = tp; content = cont; | 88 type = tp; content = cont; |
| 72 return style; | 89 return style; |
| 73 } | 90 } |
| 74 function tokenBase(stream, state) { | 91 function tokenBase(stream, state) { |
| 75 var ch = stream.next(); | 92 var ch = stream.next(); |
| 76 if (ch == '"' || ch == "'") { | 93 if (ch == '"' || ch == "'") { |
| 77 state.tokenize = tokenString(ch); | 94 state.tokenize = tokenString(ch); |
| 78 return state.tokenize(stream, state); | 95 return state.tokenize(stream, state); |
| 79 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { | 96 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { |
| 80 return ret("number", "number"); | 97 return ret("number", "number"); |
| 81 } else if (ch == "." && stream.match("..")) { | 98 } else if (ch == "." && stream.match("..")) { |
| 82 return ret("spread", "meta"); | 99 return ret("spread", "meta"); |
| 83 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { | 100 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { |
| 84 return ret(ch); | 101 return ret(ch); |
| 85 } else if (ch == "=" && stream.eat(">")) { | 102 } else if (ch == "=" && stream.eat(">")) { |
| 86 return ret("=>"); | 103 return ret("=>", "operator"); |
| 87 } else if (ch == "0" && stream.eat(/x/i)) { | 104 } else if (ch == "0" && stream.eat(/x/i)) { |
| 88 stream.eatWhile(/[\da-f]/i); | 105 stream.eatWhile(/[\da-f]/i); |
| 89 return ret("number", "number"); | 106 return ret("number", "number"); |
| 90 } else if (/\d/.test(ch)) { | 107 } else if (/\d/.test(ch)) { |
| 91 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); | 108 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); |
| 92 return ret("number", "number"); | 109 return ret("number", "number"); |
| 93 } else if (ch == "/") { | 110 } else if (ch == "/") { |
| 94 if (stream.eat("*")) { | 111 if (stream.eat("*")) { |
| 95 state.tokenize = tokenComment; | 112 state.tokenize = tokenComment; |
| 96 return tokenComment(stream, state); | 113 return tokenComment(stream, state); |
| 97 } else if (stream.eat("/")) { | 114 } else if (stream.eat("/")) { |
| 98 stream.skipToEnd(); | 115 stream.skipToEnd(); |
| 99 return ret("comment", "comment"); | 116 return ret("comment", "comment"); |
| 100 } else if (state.lastType == "operator" || state.lastType == "keyword c" |
| | 117 } else if (state.lastType == "operator" || state.lastType == "keyword c" |
| |
| 101 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType))
{ | 118 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType))
{ |
| 102 nextUntilUnescaped(stream, "/"); | 119 readRegexp(stream); |
| 103 stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla | 120 stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla |
| 104 return ret("regexp", "string-2"); | 121 return ret("regexp", "string-2"); |
| 105 } else { | 122 } else { |
| 106 stream.eatWhile(isOperatorChar); | 123 stream.eatWhile(isOperatorChar); |
| 107 return ret("operator", null, stream.current()); | 124 return ret("operator", "operator", stream.current()); |
| 108 } | 125 } |
| 109 } else if (ch == "`") { | 126 } else if (ch == "`") { |
| 110 state.tokenize = tokenQuasi; | 127 state.tokenize = tokenQuasi; |
| 111 return tokenQuasi(stream, state); | 128 return tokenQuasi(stream, state); |
| 112 } else if (ch == "#") { | 129 } else if (ch == "#") { |
| 113 stream.skipToEnd(); | 130 stream.skipToEnd(); |
| 114 return ret("error", "error"); | 131 return ret("error", "error"); |
| 115 } else if (isOperatorChar.test(ch)) { | 132 } else if (isOperatorChar.test(ch)) { |
| 116 stream.eatWhile(isOperatorChar); | 133 stream.eatWhile(isOperatorChar); |
| 117 return ret("operator", null, stream.current()); | 134 return ret("operator", "operator", stream.current()); |
| 118 } else { | 135 } else { |
| 119 stream.eatWhile(/[\w\$_]/); | 136 stream.eatWhile(/[\w\$_]/); |
| 120 var word = stream.current(), known = keywords.propertyIsEnumerable(word) &
& keywords[word]; | 137 var word = stream.current(), known = keywords.propertyIsEnumerable(word) &
& keywords[word]; |
| 121 return (known && state.lastType != ".") ? ret(known.type, known.style, wor
d) : | 138 return (known && state.lastType != ".") ? ret(known.type, known.style, wor
d) : |
| 122 ret("variable", "variable", word); | 139 ret("variable", "variable", word); |
| 123 } | 140 } |
| 124 } | 141 } |
| 125 | 142 |
| 126 function tokenString(quote) { | 143 function tokenString(quote) { |
| 127 return function(stream, state) { | 144 return function(stream, state) { |
| 128 if (!nextUntilUnescaped(stream, quote)) | 145 var escaped = false, next; |
| 146 if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ |
| 129 state.tokenize = tokenBase; | 147 state.tokenize = tokenBase; |
| 148 return ret("jsonld-keyword", "meta"); |
| 149 } |
| 150 while ((next = stream.next()) != null) { |
| 151 if (next == quote && !escaped) break; |
| 152 escaped = !escaped && next == "\\"; |
| 153 } |
| 154 if (!escaped) state.tokenize = tokenBase; |
| 130 return ret("string", "string"); | 155 return ret("string", "string"); |
| 131 }; | 156 }; |
| 132 } | 157 } |
| 133 | 158 |
| 134 function tokenComment(stream, state) { | 159 function tokenComment(stream, state) { |
| 135 var maybeEnd = false, ch; | 160 var maybeEnd = false, ch; |
| 136 while (ch = stream.next()) { | 161 while (ch = stream.next()) { |
| 137 if (ch == "/" && maybeEnd) { | 162 if (ch == "/" && maybeEnd) { |
| 138 state.tokenize = tokenBase; | 163 state.tokenize = tokenBase; |
| 139 break; | 164 break; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 } else if (sawSomething && !depth) { | 207 } else if (sawSomething && !depth) { |
| 183 ++pos; | 208 ++pos; |
| 184 break; | 209 break; |
| 185 } | 210 } |
| 186 } | 211 } |
| 187 if (sawSomething && !depth) state.fatArrowAt = pos; | 212 if (sawSomething && !depth) state.fatArrowAt = pos; |
| 188 } | 213 } |
| 189 | 214 |
| 190 // Parser | 215 // Parser |
| 191 | 216 |
| 192 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": t
rue, "regexp": true, "this": true}; | 217 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": t
rue, "regexp": true, "this": true, "jsonld-keyword": true}; |
| 193 | 218 |
| 194 function JSLexical(indented, column, type, align, prev, info) { | 219 function JSLexical(indented, column, type, align, prev, info) { |
| 195 this.indented = indented; | 220 this.indented = indented; |
| 196 this.column = column; | 221 this.column = column; |
| 197 this.type = type; | 222 this.type = type; |
| 198 this.prev = prev; | 223 this.prev = prev; |
| 199 this.info = info; | 224 this.info = info; |
| 200 if (align != null) this.align = align; | 225 if (align != null) this.align = align; |
| 201 } | 226 } |
| 202 | 227 |
| 203 function inScope(state, varname) { | 228 function inScope(state, varname) { |
| 204 for (var v = state.localVars; v; v = v.next) | 229 for (var v = state.localVars; v; v = v.next) |
| 205 if (v.name == varname) return true; | 230 if (v.name == varname) return true; |
| 206 for (var cx = state.context; cx; cx = cx.prev) { | 231 for (var cx = state.context; cx; cx = cx.prev) { |
| 207 for (var v = cx.vars; v; v = v.next) | 232 for (var v = cx.vars; v; v = v.next) |
| 208 if (v.name == varname) return true; | 233 if (v.name == varname) return true; |
| 209 } | 234 } |
| 210 } | 235 } |
| 211 | 236 |
| 212 function parseJS(state, style, type, content, stream) { | 237 function parseJS(state, style, type, content, stream) { |
| 213 var cc = state.cc; | 238 var cc = state.cc; |
| 214 // Communicate our context to the combinators. | 239 // Communicate our context to the combinators. |
| 215 // (Less wasteful than consing up a hundred closures on every call.) | 240 // (Less wasteful than consing up a hundred closures on every call.) |
| 216 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; | 241 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style
= style; |
| 217 | 242 |
| 218 if (!state.lexical.hasOwnProperty("align")) | 243 if (!state.lexical.hasOwnProperty("align")) |
| 219 state.lexical.align = true; | 244 state.lexical.align = true; |
| 220 | 245 |
| 221 while(true) { | 246 while(true) { |
| 222 var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; | 247 var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; |
| 223 if (combinator(type, content)) { | 248 if (combinator(type, content)) { |
| 224 while(cc.length && cc[cc.length - 1].lex) | 249 while(cc.length && cc[cc.length - 1].lex) |
| 225 cc.pop()(); | 250 cc.pop()(); |
| 226 if (cx.marked) return cx.marked; | 251 if (cx.marked) return cx.marked; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 var state = cx.state; | 307 var state = cx.state; |
| 283 if (state.lexical.prev) { | 308 if (state.lexical.prev) { |
| 284 if (state.lexical.type == ")") | 309 if (state.lexical.type == ")") |
| 285 state.indented = state.lexical.indented; | 310 state.indented = state.lexical.indented; |
| 286 state.lexical = state.lexical.prev; | 311 state.lexical = state.lexical.prev; |
| 287 } | 312 } |
| 288 } | 313 } |
| 289 poplex.lex = true; | 314 poplex.lex = true; |
| 290 | 315 |
| 291 function expect(wanted) { | 316 function expect(wanted) { |
| 292 return function(type) { | 317 function exp(type) { |
| 293 if (type == wanted) return cont(); | 318 if (type == wanted) return cont(); |
| 294 else if (wanted == ";") return pass(); | 319 else if (wanted == ";") return pass(); |
| 295 else return cont(arguments.callee); | 320 else return cont(exp); |
| 296 }; | 321 }; |
| 322 return exp; |
| 297 } | 323 } |
| 298 | 324 |
| 299 function statement(type, value) { | 325 function statement(type, value) { |
| 300 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expe
ct(";"), poplex); | 326 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expe
ct(";"), poplex); |
| 301 if (type == "keyword a") return cont(pushlex("form"), expression, statement,
poplex); | 327 if (type == "keyword a") return cont(pushlex("form"), expression, statement,
poplex); |
| 302 if (type == "keyword b") return cont(pushlex("form"), statement, poplex); | 328 if (type == "keyword b") return cont(pushlex("form"), statement, poplex); |
| 303 if (type == "{") return cont(pushlex("}"), block, poplex); | 329 if (type == "{") return cont(pushlex("}"), block, poplex); |
| 304 if (type == ";") return cont(); | 330 if (type == ";") return cont(); |
| 305 if (type == "if") return cont(pushlex("form"), expression, statement, poplex
, maybeelse); | 331 if (type == "if") { |
| 332 if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1]
== poplex) |
| 333 cx.state.cc.pop()(); |
| 334 return cont(pushlex("form"), expression, statement, poplex, maybeelse); |
| 335 } |
| 306 if (type == "function") return cont(functiondef); | 336 if (type == "function") return cont(functiondef); |
| 307 if (type == "for") return cont(pushlex("form"), forspec, poplex, statement,
poplex); | 337 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); |
| 308 if (type == "variable") return cont(pushlex("stat"), maybelabel); | 338 if (type == "variable") return cont(pushlex("stat"), maybelabel); |
| 309 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}",
"switch"), expect("{"), | 339 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}",
"switch"), expect("{"), |
| 310 block, poplex, poplex); | 340 block, poplex, poplex); |
| 311 if (type == "case") return cont(expression, expect(":")); | 341 if (type == "case") return cont(expression, expect(":")); |
| 312 if (type == "default") return cont(expect(":")); | 342 if (type == "default") return cont(expect(":")); |
| 313 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("),
funarg, expect(")"), | 343 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("),
funarg, expect(")"), |
| 314 statement, poplex, popcontext); | 344 statement, poplex, popcontext); |
| 315 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule,
popcontext, poplex); | 345 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule,
popcontext, poplex); |
| 316 if (type == "class") return cont(pushlex("form"), className, objlit, poplex)
; | 346 if (type == "class") return cont(pushlex("form"), className, poplex); |
| 317 if (type == "export") return cont(pushlex("form"), afterExport, poplex); | 347 if (type == "export") return cont(pushlex("form"), afterExport, poplex); |
| 318 if (type == "import") return cont(pushlex("form"), afterImport, poplex); | 348 if (type == "import") return cont(pushlex("form"), afterImport, poplex); |
| 319 return pass(pushlex("stat"), expression, expect(";"), poplex); | 349 return pass(pushlex("stat"), expression, expect(";"), poplex); |
| 320 } | 350 } |
| 321 function expression(type) { | 351 function expression(type) { |
| 322 return expressionInner(type, false); | 352 return expressionInner(type, false); |
| 323 } | 353 } |
| 324 function expressionNoComma(type) { | 354 function expressionNoComma(type) { |
| 325 return expressionInner(type, true); | 355 return expressionInner(type, true); |
| 326 } | 356 } |
| 327 function expressionInner(type, noComma) { | 357 function expressionInner(type, noComma) { |
| 328 if (cx.state.fatArrowAt == cx.stream.start) { | 358 if (cx.state.fatArrowAt == cx.stream.start) { |
| 329 var body = noComma ? arrowBodyNoComma : arrowBody; | 359 var body = noComma ? arrowBodyNoComma : arrowBody; |
| 330 if (type == "(") return cont(pushcontext, commasep(pattern, ")"), expect("
=>"), body, popcontext); | 360 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern,
")"), poplex, expect("=>"), body, popcontext); |
| 331 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"
), body, popcontext); | 361 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"
), body, popcontext); |
| 332 } | 362 } |
| 333 | 363 |
| 334 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; | 364 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; |
| 335 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); | 365 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); |
| 336 if (type == "function") return cont(functiondef); | 366 if (type == "function") return cont(functiondef, maybeop); |
| 337 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : mayb
eexpression); | 367 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : mayb
eexpression); |
| 338 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, e
xpect(")"), poplex, maybeop); | 368 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, e
xpect(")"), poplex, maybeop); |
| 339 if (type == "operator" || type == "spread") return cont(noComma ? expression
NoComma : expression); | 369 if (type == "operator" || type == "spread") return cont(noComma ? expression
NoComma : expression); |
| 340 if (type == "[") return cont(pushlex("]"), expressionNoComma, maybeArrayComp
rehension, poplex, maybeop); | 370 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); |
| 341 if (type == "{") return cont(commasep(objprop, "}"), maybeop); | 371 if (type == "{") return contCommasep(objprop, "}", null, maybeop); |
| 372 if (type == "quasi") { return pass(quasi, maybeop); } |
| 342 return cont(); | 373 return cont(); |
| 343 } | 374 } |
| 344 function maybeexpression(type) { | 375 function maybeexpression(type) { |
| 345 if (type.match(/[;\}\)\],]/)) return pass(); | 376 if (type.match(/[;\}\)\],]/)) return pass(); |
| 346 return pass(expression); | 377 return pass(expression); |
| 347 } | 378 } |
| 348 function maybeexpressionNoComma(type) { | 379 function maybeexpressionNoComma(type) { |
| 349 if (type.match(/[;\}\)\],]/)) return pass(); | 380 if (type.match(/[;\}\)\],]/)) return pass(); |
| 350 return pass(expressionNoComma); | 381 return pass(expressionNoComma); |
| 351 } | 382 } |
| 352 | 383 |
| 353 function maybeoperatorComma(type, value) { | 384 function maybeoperatorComma(type, value) { |
| 354 if (type == ",") return cont(expression); | 385 if (type == ",") return cont(expression); |
| 355 return maybeoperatorNoComma(type, value, false); | 386 return maybeoperatorNoComma(type, value, false); |
| 356 } | 387 } |
| 357 function maybeoperatorNoComma(type, value, noComma) { | 388 function maybeoperatorNoComma(type, value, noComma) { |
| 358 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; | 389 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; |
| 359 var expr = noComma == false ? expression : expressionNoComma; | 390 var expr = noComma == false ? expression : expressionNoComma; |
| 360 if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arr
owBody, popcontext); | 391 if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arr
owBody, popcontext); |
| 361 if (type == "operator") { | 392 if (type == "operator") { |
| 362 if (/\+\+|--/.test(value)) return cont(me); | 393 if (/\+\+|--/.test(value)) return cont(me); |
| 363 if (value == "?") return cont(expression, expect(":"), expr); | 394 if (value == "?") return cont(expression, expect(":"), expr); |
| 364 return cont(expr); | 395 return cont(expr); |
| 365 } | 396 } |
| 366 if (type == "quasi") { cx.cc.push(me); return quasi(value); } | 397 if (type == "quasi") { return pass(quasi, me); } |
| 367 if (type == ";") return; | 398 if (type == ";") return; |
| 368 if (type == "(") return cont(commasep(expressionNoComma, ")", "call"), me); | 399 if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); |
| 369 if (type == ".") return cont(property, me); | 400 if (type == ".") return cont(property, me); |
| 370 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), pop
lex, me); | 401 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), pop
lex, me); |
| 371 } | 402 } |
| 372 function quasi(value) { | 403 function quasi(type, value) { |
| 373 if (!value) debugger; | 404 if (type != "quasi") return pass(); |
| 374 if (value.slice(value.length - 2) != "${") return cont(); | 405 if (value.slice(value.length - 2) != "${") return cont(quasi); |
| 375 return cont(expression, continueQuasi); | 406 return cont(expression, continueQuasi); |
| 376 } | 407 } |
| 377 function continueQuasi(type) { | 408 function continueQuasi(type) { |
| 378 if (type == "}") { | 409 if (type == "}") { |
| 379 cx.marked = "string-2"; | 410 cx.marked = "string-2"; |
| 380 cx.state.tokenize = tokenQuasi; | 411 cx.state.tokenize = tokenQuasi; |
| 381 return cont(); | 412 return cont(quasi); |
| 382 } | 413 } |
| 383 } | 414 } |
| 384 function arrowBody(type) { | 415 function arrowBody(type) { |
| 385 findFatArrow(cx.stream, cx.state); | 416 findFatArrow(cx.stream, cx.state); |
| 386 if (type == "{") return pass(statement); | 417 if (type == "{") return pass(statement); |
| 387 return pass(expression); | 418 return pass(expression); |
| 388 } | 419 } |
| 389 function arrowBodyNoComma(type) { | 420 function arrowBodyNoComma(type) { |
| 390 findFatArrow(cx.stream, cx.state); | 421 findFatArrow(cx.stream, cx.state); |
| 391 if (type == "{") return pass(statement); | 422 if (type == "{") return pass(statement); |
| 392 return pass(expressionNoComma); | 423 return pass(expressionNoComma); |
| 393 } | 424 } |
| 394 function maybelabel(type) { | 425 function maybelabel(type) { |
| 395 if (type == ":") return cont(poplex, statement); | 426 if (type == ":") return cont(poplex, statement); |
| 396 return pass(maybeoperatorComma, expect(";"), poplex); | 427 return pass(maybeoperatorComma, expect(";"), poplex); |
| 397 } | 428 } |
| 398 function property(type) { | 429 function property(type) { |
| 399 if (type == "variable") {cx.marked = "property"; return cont();} | 430 if (type == "variable") {cx.marked = "property"; return cont();} |
| 400 } | 431 } |
| 401 function objprop(type, value) { | 432 function objprop(type, value) { |
| 402 if (type == "variable") { | 433 if (type == "variable" || cx.style == "keyword") { |
| 403 cx.marked = "property"; | 434 cx.marked = "property"; |
| 404 if (value == "get" || value == "set") return cont(getterSetter); | 435 if (value == "get" || value == "set") return cont(getterSetter); |
| 436 return cont(afterprop); |
| 405 } else if (type == "number" || type == "string") { | 437 } else if (type == "number" || type == "string") { |
| 406 cx.marked = type + " property"; | 438 cx.marked = jsonldMode ? "property" : (cx.style + " property"); |
| 439 return cont(afterprop); |
| 440 } else if (type == "jsonld-keyword") { |
| 441 return cont(afterprop); |
| 407 } else if (type == "[") { | 442 } else if (type == "[") { |
| 408 return cont(expression, expect("]"), afterprop); | 443 return cont(expression, expect("]"), afterprop); |
| 409 } | 444 } |
| 410 if (atomicTypes.hasOwnProperty(type)) return cont(afterprop); | |
| 411 } | 445 } |
| 412 function getterSetter(type) { | 446 function getterSetter(type) { |
| 413 if (type != "variable") return pass(afterprop); | 447 if (type != "variable") return pass(afterprop); |
| 414 cx.marked = "property"; | 448 cx.marked = "property"; |
| 415 return cont(functiondef); | 449 return cont(functiondef); |
| 416 } | 450 } |
| 417 function afterprop(type) { | 451 function afterprop(type) { |
| 418 if (type == ":") return cont(expressionNoComma); | 452 if (type == ":") return cont(expressionNoComma); |
| 419 if (type == "(") return pass(functiondef); | 453 if (type == "(") return pass(functiondef); |
| 420 } | 454 } |
| 421 function commasep(what, end, info) { | 455 function commasep(what, end) { |
| 422 function proceed(type) { | 456 function proceed(type) { |
| 423 if (type == ",") { | 457 if (type == ",") { |
| 424 var lex = cx.state.lexical; | 458 var lex = cx.state.lexical; |
| 425 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; | 459 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; |
| 426 return cont(what, proceed); | 460 return cont(what, proceed); |
| 427 } | 461 } |
| 428 if (type == end) return cont(); | 462 if (type == end) return cont(); |
| 429 return cont(expect(end)); | 463 return cont(expect(end)); |
| 430 } | 464 } |
| 431 return function(type) { | 465 return function(type) { |
| 432 if (type == end) return cont(); | 466 if (type == end) return cont(); |
| 433 if (info === false) return pass(what, proceed); | 467 return pass(what, proceed); |
| 434 return pass(pushlex(end, info), what, proceed, poplex); | |
| 435 }; | 468 }; |
| 436 } | 469 } |
| 470 function contCommasep(what, end, info) { |
| 471 for (var i = 3; i < arguments.length; i++) |
| 472 cx.cc.push(arguments[i]); |
| 473 return cont(pushlex(end, info), commasep(what, end), poplex); |
| 474 } |
| 437 function block(type) { | 475 function block(type) { |
| 438 if (type == "}") return cont(); | 476 if (type == "}") return cont(); |
| 439 return pass(statement, block); | 477 return pass(statement, block); |
| 440 } | 478 } |
| 441 function maybetype(type) { | 479 function maybetype(type) { |
| 442 if (isTS && type == ":") return cont(typedef); | 480 if (isTS && type == ":") return cont(typedef); |
| 443 } | 481 } |
| 444 function typedef(type) { | 482 function typedef(type) { |
| 445 if (type == "variable"){cx.marked = "variable-3"; return cont();} | 483 if (type == "variable"){cx.marked = "variable-3"; return cont();} |
| 446 } | 484 } |
| 447 function vardef() { | 485 function vardef() { |
| 448 return pass(pattern, maybetype, maybeAssign, vardefCont); | 486 return pass(pattern, maybetype, maybeAssign, vardefCont); |
| 449 } | 487 } |
| 450 function pattern(type, value) { | 488 function pattern(type, value) { |
| 451 if (type == "variable") { register(value); return cont(); } | 489 if (type == "variable") { register(value); return cont(); } |
| 452 if (type == "[") return cont(commasep(pattern, "]")); | 490 if (type == "[") return contCommasep(pattern, "]"); |
| 453 if (type == "{") return cont(commasep(proppattern, "}")); | 491 if (type == "{") return contCommasep(proppattern, "}"); |
| 454 } | 492 } |
| 455 function proppattern(type, value) { | 493 function proppattern(type, value) { |
| 456 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { | 494 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { |
| 457 register(value); | 495 register(value); |
| 458 return cont(maybeAssign); | 496 return cont(maybeAssign); |
| 459 } | 497 } |
| 460 if (type == "variable") cx.marked = "property"; | 498 if (type == "variable") cx.marked = "property"; |
| 461 return cont(expect(":"), pattern, maybeAssign); | 499 return cont(expect(":"), pattern, maybeAssign); |
| 462 } | 500 } |
| 463 function maybeAssign(_type, value) { | 501 function maybeAssign(_type, value) { |
| 464 if (value == "=") return cont(expressionNoComma); | 502 if (value == "=") return cont(expressionNoComma); |
| 465 } | 503 } |
| 466 function vardefCont(type) { | 504 function vardefCont(type) { |
| 467 if (type == ",") return cont(vardef); | 505 if (type == ",") return cont(vardef); |
| 468 } | 506 } |
| 469 function maybeelse(type, value) { | 507 function maybeelse(type, value) { |
| 470 if (type == "keyword b" && value == "else") return cont(pushlex("form"), sta
tement, poplex); | 508 if (type == "keyword b" && value == "else") return cont(pushlex("form", "els
e"), statement, poplex); |
| 471 } | 509 } |
| 472 function forspec(type) { | 510 function forspec(type) { |
| 473 if (type == "(") return cont(pushlex(")"), forspec1, expect(")")); | 511 if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); |
| 474 } | 512 } |
| 475 function forspec1(type) { | 513 function forspec1(type) { |
| 476 if (type == "var") return cont(vardef, expect(";"), forspec2); | 514 if (type == "var") return cont(vardef, expect(";"), forspec2); |
| 477 if (type == ";") return cont(forspec2); | 515 if (type == ";") return cont(forspec2); |
| 478 if (type == "variable") return cont(formaybeinof); | 516 if (type == "variable") return cont(formaybeinof); |
| 479 return pass(expression, expect(";"), forspec2); | 517 return pass(expression, expect(";"), forspec2); |
| 480 } | 518 } |
| 481 function formaybeinof(_type, value) { | 519 function formaybeinof(_type, value) { |
| 482 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp
ression); } | 520 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp
ression); } |
| 483 return cont(maybeoperatorComma, forspec2); | 521 return cont(maybeoperatorComma, forspec2); |
| 484 } | 522 } |
| 485 function forspec2(type, value) { | 523 function forspec2(type, value) { |
| 486 if (type == ";") return cont(forspec3); | 524 if (type == ";") return cont(forspec3); |
| 487 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp
ression); } | 525 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp
ression); } |
| 488 return pass(expression, expect(";"), forspec3); | 526 return pass(expression, expect(";"), forspec3); |
| 489 } | 527 } |
| 490 function forspec3(type) { | 528 function forspec3(type) { |
| 491 if (type != ")") cont(expression); | 529 if (type != ")") cont(expression); |
| 492 } | 530 } |
| 493 function functiondef(type, value) { | 531 function functiondef(type, value) { |
| 494 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} | 532 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} |
| 495 if (type == "variable") {register(value); return cont(functiondef);} | 533 if (type == "variable") {register(value); return cont(functiondef);} |
| 496 if (type == "(") return cont(pushcontext, commasep(funarg, ")"), statement,
popcontext); | 534 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"
), poplex, statement, popcontext); |
| 497 } | 535 } |
| 498 function funarg(type) { | 536 function funarg(type) { |
| 499 if (type == "spread") return cont(funarg); | 537 if (type == "spread") return cont(funarg); |
| 500 return pass(pattern, maybetype); | 538 return pass(pattern, maybetype); |
| 501 } | 539 } |
| 502 function className(type, value) { | 540 function className(type, value) { |
| 503 if (type == "variable") {register(value); return cont(classNameAfter);} | 541 if (type == "variable") {register(value); return cont(classNameAfter);} |
| 504 } | 542 } |
| 505 function classNameAfter(_type, value) { | 543 function classNameAfter(type, value) { |
| 506 if (value == "extends") return cont(expression); | 544 if (value == "extends") return cont(expression, classNameAfter); |
| 545 if (type == "{") return cont(pushlex("}"), classBody, poplex); |
| 507 } | 546 } |
| 508 function objlit(type) { | 547 function classBody(type, value) { |
| 509 if (type == "{") return cont(commasep(objprop, "}")); | 548 if (type == "variable" || cx.style == "keyword") { |
| 549 cx.marked = "property"; |
| 550 if (value == "get" || value == "set") return cont(classGetterSetter, funct
iondef, classBody); |
| 551 return cont(functiondef, classBody); |
| 552 } |
| 553 if (value == "*") { |
| 554 cx.marked = "keyword"; |
| 555 return cont(classBody); |
| 556 } |
| 557 if (type == ";") return cont(classBody); |
| 558 if (type == "}") return cont(); |
| 559 } |
| 560 function classGetterSetter(type) { |
| 561 if (type != "variable") return pass(); |
| 562 cx.marked = "property"; |
| 563 return cont(); |
| 510 } | 564 } |
| 511 function afterModule(type, value) { | 565 function afterModule(type, value) { |
| 512 if (type == "string") return cont(statement); | 566 if (type == "string") return cont(statement); |
| 513 if (type == "variable") { register(value); return cont(maybeFrom); } | 567 if (type == "variable") { register(value); return cont(maybeFrom); } |
| 514 } | 568 } |
| 515 function afterExport(_type, value) { | 569 function afterExport(_type, value) { |
| 516 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";"
)); } | 570 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";"
)); } |
| 517 if (value == "default") { cx.marked = "keyword"; return cont(expression, exp
ect(";")); } | 571 if (value == "default") { cx.marked = "keyword"; return cont(expression, exp
ect(";")); } |
| 518 return pass(statement); | 572 return pass(statement); |
| 519 } | 573 } |
| 520 function afterImport(type) { | 574 function afterImport(type) { |
| 521 if (type == "string") return cont(); | 575 if (type == "string") return cont(); |
| 522 return pass(importSpec, maybeFrom); | 576 return pass(importSpec, maybeFrom); |
| 523 } | 577 } |
| 524 function importSpec(type, value) { | 578 function importSpec(type, value) { |
| 525 if (type == "{") return cont(commasep(importSpec, "}")); | 579 if (type == "{") return contCommasep(importSpec, "}"); |
| 526 if (type == "variable") register(value); | 580 if (type == "variable") register(value); |
| 527 return cont(); | 581 return cont(); |
| 528 } | 582 } |
| 529 function maybeFrom(_type, value) { | 583 function maybeFrom(_type, value) { |
| 530 if (value == "from") { cx.marked = "keyword"; return cont(expression); } | 584 if (value == "from") { cx.marked = "keyword"; return cont(expression); } |
| 531 } | 585 } |
| 586 function arrayLiteral(type) { |
| 587 if (type == "]") return cont(); |
| 588 return pass(expressionNoComma, maybeArrayComprehension); |
| 589 } |
| 532 function maybeArrayComprehension(type) { | 590 function maybeArrayComprehension(type) { |
| 533 if (type == "for") return pass(comprehension); | 591 if (type == "for") return pass(comprehension, expect("]")); |
| 534 if (type == ",") return cont(commasep(expressionNoComma, "]", false)); | 592 if (type == ",") return cont(commasep(expressionNoComma, "]")); |
| 535 return pass(commasep(expressionNoComma, "]", false)); | 593 return pass(commasep(expressionNoComma, "]")); |
| 536 } | 594 } |
| 537 function comprehension(type) { | 595 function comprehension(type) { |
| 538 if (type == "for") return cont(forspec, comprehension); | 596 if (type == "for") return cont(forspec, comprehension); |
| 539 if (type == "if") return cont(expression, comprehension); | 597 if (type == "if") return cont(expression, comprehension); |
| 540 } | 598 } |
| 541 | 599 |
| 542 // Interface | 600 // Interface |
| 543 | 601 |
| 544 return { | 602 return { |
| 545 startState: function(basecolumn) { | 603 startState: function(basecolumn) { |
| 546 var state = { | 604 var state = { |
| 547 tokenize: tokenBase, | 605 tokenize: tokenBase, |
| 548 lastType: "sof", | 606 lastType: "sof", |
| 549 cc: [], | 607 cc: [], |
| 550 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false
), | 608 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false
), |
| 551 localVars: parserConfig.localVars, | 609 localVars: parserConfig.localVars, |
| 552 context: parserConfig.localVars && {vars: parserConfig.localVars}, | 610 context: parserConfig.localVars && {vars: parserConfig.localVars}, |
| 553 indented: 0 | 611 indented: 0 |
| 554 }; | 612 }; |
| 555 if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars; | 613 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") |
| 614 state.globalVars = parserConfig.globalVars; |
| 556 return state; | 615 return state; |
| 557 }, | 616 }, |
| 558 | 617 |
| 559 token: function(stream, state) { | 618 token: function(stream, state) { |
| 560 if (stream.sol()) { | 619 if (stream.sol()) { |
| 561 if (!state.lexical.hasOwnProperty("align")) | 620 if (!state.lexical.hasOwnProperty("align")) |
| 562 state.lexical.align = false; | 621 state.lexical.align = false; |
| 563 state.indented = stream.indentation(); | 622 state.indented = stream.indentation(); |
| 564 findFatArrow(stream, state); | 623 findFatArrow(stream, state); |
| 565 } | 624 } |
| 566 if (state.tokenize != tokenComment && stream.eatSpace()) return null; | 625 if (state.tokenize != tokenComment && stream.eatSpace()) return null; |
| 567 var style = state.tokenize(stream, state); | 626 var style = state.tokenize(stream, state); |
| 568 if (type == "comment") return style; | 627 if (type == "comment") return style; |
| 569 state.lastType = type == "operator" && (content == "++" || content == "--"
) ? "incdec" : type; | 628 state.lastType = type == "operator" && (content == "++" || content == "--"
) ? "incdec" : type; |
| 570 return parseJS(state, style, type, content, stream); | 629 return parseJS(state, style, type, content, stream); |
| 571 }, | 630 }, |
| 572 | 631 |
| 573 indent: function(state, textAfter) { | 632 indent: function(state, textAfter) { |
| 574 if (state.tokenize == tokenComment) return CodeMirror.Pass; | 633 if (state.tokenize == tokenComment) return CodeMirror.Pass; |
| 575 if (state.tokenize != tokenBase) return 0; | 634 if (state.tokenize != tokenBase) return 0; |
| 576 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; | 635 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; |
| 577 // Kludge to prevent 'maybelse' from blocking lexical scope pops | 636 // Kludge to prevent 'maybelse' from blocking lexical scope pops |
| 578 for (var i = state.cc.length - 1; i >= 0; --i) { | 637 if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >=
0; --i) { |
| 579 var c = state.cc[i]; | 638 var c = state.cc[i]; |
| 580 if (c == poplex) lexical = lexical.prev; | 639 if (c == poplex) lexical = lexical.prev; |
| 581 else if (c != maybeelse) break; | 640 else if (c != maybeelse) break; |
| 582 } | 641 } |
| 583 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; | 642 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; |
| 584 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") | 643 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") |
| 585 lexical = lexical.prev; | 644 lexical = lexical.prev; |
| 586 var type = lexical.type, closing = firstChar == type; | 645 var type = lexical.type, closing = firstChar == type; |
| 587 | 646 |
| 588 if (type == "vardef") return lexical.indented + (state.lastType == "operat
or" || state.lastType == "," ? lexical.info + 1 : 0); | 647 if (type == "vardef") return lexical.indented + (state.lastType == "operat
or" || state.lastType == "," ? lexical.info + 1 : 0); |
| 589 else if (type == "form" && firstChar == "{") return lexical.indented; | 648 else if (type == "form" && firstChar == "{") return lexical.indented; |
| 590 else if (type == "form") return lexical.indented + indentUnit; | 649 else if (type == "form") return lexical.indented + indentUnit; |
| 591 else if (type == "stat") | 650 else if (type == "stat") |
| 592 return lexical.indented + (state.lastType == "operator" || state.lastTyp
e == "," ? statementIndent || indentUnit : 0); | 651 return lexical.indented + (state.lastType == "operator" || state.lastTyp
e == "," ? statementIndent || indentUnit : 0); |
| 593 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndent
Switch != false) | 652 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndent
Switch != false) |
| 594 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? inden
tUnit : 2 * indentUnit); | 653 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? inden
tUnit : 2 * indentUnit); |
| 595 else if (lexical.align) return lexical.column + (closing ? 0 : 1); | 654 else if (lexical.align) return lexical.column + (closing ? 0 : 1); |
| 596 else return lexical.indented + (closing ? 0 : indentUnit); | 655 else return lexical.indented + (closing ? 0 : indentUnit); |
| 597 }, | 656 }, |
| 598 | 657 |
| 599 electricChars: ":{}", | 658 electricChars: ":{}", |
| 600 blockCommentStart: jsonMode ? null : "/*", | 659 blockCommentStart: jsonMode ? null : "/*", |
| 601 blockCommentEnd: jsonMode ? null : "*/", | 660 blockCommentEnd: jsonMode ? null : "*/", |
| 602 lineComment: jsonMode ? null : "//", | 661 lineComment: jsonMode ? null : "//", |
| 603 fold: "brace", | 662 fold: "brace", |
| 604 | 663 |
| 605 helperType: jsonMode ? "json" : "javascript", | 664 helperType: jsonMode ? "json" : "javascript", |
| 665 jsonldMode: jsonldMode, |
| 606 jsonMode: jsonMode | 666 jsonMode: jsonMode |
| 607 }; | 667 }; |
| 608 }); | 668 }); |
| 609 | 669 |
| 670 CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/); |
| 671 |
| 610 CodeMirror.defineMIME("text/javascript", "javascript"); | 672 CodeMirror.defineMIME("text/javascript", "javascript"); |
| 611 CodeMirror.defineMIME("text/ecmascript", "javascript"); | 673 CodeMirror.defineMIME("text/ecmascript", "javascript"); |
| 612 CodeMirror.defineMIME("application/javascript", "javascript"); | 674 CodeMirror.defineMIME("application/javascript", "javascript"); |
| 675 CodeMirror.defineMIME("application/x-javascript", "javascript"); |
| 613 CodeMirror.defineMIME("application/ecmascript", "javascript"); | 676 CodeMirror.defineMIME("application/ecmascript", "javascript"); |
| 614 CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); | 677 CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); |
| 615 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); | 678 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); |
| 679 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true})
; |
| 616 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true
}); | 680 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true
}); |
| 617 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript
: true }); | 681 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript
: true }); |
| 682 |
| 683 }); |
| OLD | NEW |