Вход Регистрация
Файл: engine/skins/mirror/mode/javascript/javascript.js
Строк: 1100
<?php
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// TODO actually recognize syntax of TypeScript constructs

(function(mod) {
  if (
typeof exports == "object" && typeof module == "object"// CommonJS
    
mod(require("../../lib/codemirror"));
  else if (
typeof define == "function" && define.amd// AMD
    
define(["../../lib/codemirror"], mod);
  else 
// Plain browser env
    
mod(CodeMirror);
})(function(
CodeMirror) {
"use strict";

CodeMirror.defineMode("javascript", function(configparserConfig) {
  var 
indentUnit config.indentUnit;
  var 
statementIndent parserConfig.statementIndent;
  var 
jsonldMode parserConfig.jsonld;
  var 
jsonMode parserConfig.json || jsonldMode;
  var 
isTS parserConfig.typescript;

  
// Tokenizer

  
var keywords = function(){
    function 
kw(type) {return {typetypestyle"keyword"};}
    var 
kw("keyword a"), kw("keyword b"), kw("keyword c");
    var 
operator kw("operator"), atom = {type"atom"style"atom"};

    var 
jsKeywords = {
      
"if"kw("if"), "while"A"with"A"else"B"do"B"try"B"finally"B,
      
"return"C"break"C"continue"C"new"C"delete"C"throw"C"debugger"C,
      
"var"kw("var"), "const"kw("var"), "let"kw("var"),
      
"function"kw("function"), "catch"kw("catch"),
      
"for"kw("for"), "switch"kw("switch"), "case"kw("case"), "default"kw("default"),
      
"in"operator"typeof"operator"instanceof"operator,
      
"true"atom"false"atom"null"atom"undefined"atom"NaN"atom"Infinity"atom,
      
"this"kw("this"), "module"kw("module"), "class"kw("class"), "super"kw("atom"),
      
"yield"C"export"kw("export"), "import"kw("import"), "extends"C
    
};

    
// Extend the 'normal' keywords with the TypeScript language extensions
    
if (isTS) {
      var 
type = {type"variable"style"variable-3"};
      var 
tsKeywords = {
        
// object-like things
        
"interface"kw("interface"),
        
"extends"kw("extends"),
        
"constructor"kw("constructor"),

        
// scope modifiers
        
"public"kw("public"),
        
"private"kw("private"),
        
"protected"kw("protected"),
        
"static"kw("static"),

        
// types
        
"string"type"number"type"bool"type"any"type
      
};

      for (var 
attr in tsKeywords) {
        
jsKeywords[attr] = tsKeywords[attr];
      }
    }

    return 
jsKeywords;
  }();

  var 
isOperatorChar = /[+-*&%=<>!?|~^]/;
  var 
isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;

  function readRegexp(stream) {
    var escaped = false, next, inSet = false;
    while ((next = stream.next()) != null) {
      if (!escaped) {
        if (next == "
/" && !inSet) return;
        if (next == "
[") inSet = true;
        else if (inSet && next == "
]") inSet = false;
      }
      escaped = !escaped && next == "
\";
    }
  }

  // Used as scratch variables to communicate multiple values without
  // consing up tons of objects.
  var type, content;
  function ret(tp, style, cont) {
    type = tp; content = cont;
    return style;
  }
  function tokenBase(stream, state) {
    var ch = stream.next();
    if (ch == '"' || ch == "'") {
      state.tokenize = tokenString(ch);
      return state.tokenize(stream, state);
    } else if (ch == "
." && stream.match(/^d+(?:[eE][+-]?d+)?/)) {
      return ret("
number", "number");
    } else if (ch == "
." && stream.match("..")) {
      return ret("
spread", "meta");
    } else if (/[[]{}(),;:.]/.test(ch)) {
      return ret(ch);
    } else if (ch == "
=" && stream.eat(">")) {
      return ret("
=>", "operator");
    } else if (ch == "
0" && stream.eat(/x/i)) {
      stream.eatWhile(/[da-f]/i);
      return ret("
number", "number");
    } else if (/d/.test(ch)) {
      stream.match(/^d*(?:.d*)?(?:[eE][+-]?d+)?/);
      return ret("
number", "number");
    } else if (ch == "
/") {
      if (stream.eat("
*")) {
        state.tokenize = tokenComment;
        return tokenComment(stream, state);
      } else if (stream.eat("
/")) {
        stream.skipToEnd();
        return ret("
comment", "comment");
      } else if (state.lastType == "
operator" || state.lastType == "keyword c" ||
               state.lastType == "
sof" || /^[[{}(,;:]$/.test(state.lastType)) {
        readRegexp(stream);
        stream.eatWhile(/[gimy]/); // 'y' is "
sticky" option in Mozilla
        return ret("
regexp", "string-2");
      } else {
        stream.eatWhile(isOperatorChar);
        return ret("
operator", "operator", stream.current());
      }
    } else if (ch == "
`") {
      state.tokenize = tokenQuasi;
      return tokenQuasi(stream, state);
    } else if (ch == "#") {
      stream.skipToEnd();
      return ret("error", "error");
    } else if (isOperatorChar.test(ch)) {
      stream.eatWhile(isOperatorChar);
      return ret("operator", "operator", stream.current());
    } else {
      stream.eatWhile(/[w
$_]/);
      var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
      return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
                     ret("variable", "variable", word);
    }
  }

  function tokenString(quote) {
    return function(stream, state) {
      var escaped = false, next;
      if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
        state.tokenize = tokenBase;
        return ret("jsonld-keyword", "meta");
      }
      while ((next = stream.next()) != null) {
        if (next == quote && !escaped) break;
        escaped = !escaped && next == "\";
      }
      if (!escaped) state.tokenize = tokenBase;
      return ret("string", "string");
    };
  }

  function tokenComment(stream, state) {
    var maybeEnd = false, ch;
    while (ch = stream.next()) {
      if (ch == "/" && maybeEnd) {
        state.tokenize = tokenBase;
        break;
      }
      maybeEnd = (ch == "*");
    }
    return ret("comment", "comment");
  }

  function tokenQuasi(stream, state) {
    var escaped = false, next;
    while ((next = stream.next()) != null) {
      if (!escaped && (next == "
`" || next == "$" && stream.eat("{"))) {
        state.tokenize = tokenBase;
        break;
      }
      escaped = !escaped && next == "
\";
    }
    return ret("
quasi", "string-2", stream.current());
  }

  var brackets = "
([{}])";
  // This is a crude lookahead trick to try and notice that we're
  // parsing the argument patterns for a fat-arrow function before we
  // actually hit the arrow token. It only works if the arrow is on
  // the same line as the arguments and there's no strange noise
  // (comments) in between. Fallback is to only notice when we hit the
  // arrow, and not declare the arguments as locals for the arrow
  // body.
  function findFatArrow(stream, state) {
    if (state.fatArrowAt) state.fatArrowAt = null;
    var arrow = stream.string.indexOf("
=>", stream.start);
    if (arrow < 0) return;

    var depth = 0, sawSomething = false;
    for (var pos = arrow - 1; pos >= 0; --pos) {
      var ch = stream.string.charAt(pos);
      var bracket = brackets.indexOf(ch);
      if (bracket >= 0 && bracket < 3) {
        if (!depth) { ++pos; break; }
        if (--depth == 0) break;
      } else if (bracket >= 3 && bracket < 6) {
        ++depth;
      } else if (/[
$w]/.test(ch)) {
        sawSomething = true;
      } else if (sawSomething && !depth) {
        ++pos;
        break;
      }
    }
    if (sawSomething && !depth) state.fatArrowAt = pos;
  }

  // Parser

  var atomicTypes = {"
atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};

  function JSLexical(indented, column, type, align, prev, info) {
    this.indented = indented;
    this.column = column;
    this.type = type;
    this.prev = prev;
    this.info = info;
    if (align != null) this.align = align;
  }

  function inScope(state, varname) {
    for (var v = state.localVars; v; v = v.next)
      if (v.name == varname) return true;
    for (var cx = state.context; cx; cx = cx.prev) {
      for (var v = cx.vars; v; v = v.next)
        if (v.name == varname) return true;
    }
  }

  function parseJS(state, style, type, content, stream) {
    var cc = state.cc;
    // Communicate our context to the combinators.
    // (Less wasteful than consing up a hundred closures on every call.)
    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;

    if (!state.lexical.hasOwnProperty("
align"))
      state.lexical.align = true;

    while(true) {
      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
      if (combinator(type, content)) {
        while(cc.length && cc[cc.length - 1].lex)
          cc.pop()();
        if (cx.marked) return cx.marked;
        if (type == "
variable" && inScope(state, content)) return "variable-2";
        return style;
      }
    }
  }

  // Combinator utils

  var cx = {state: null, column: null, marked: null, cc: null};
  function pass() {
    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
  }
  function cont() {
    pass.apply(null, arguments);
    return true;
  }
  function register(varname) {
    function inList(list) {
      for (var v = list; v; v = v.next)
        if (v.name == varname) return true;
      return false;
    }
    var state = cx.state;
    if (state.context) {
      cx.marked = "
def";
      if (inList(state.localVars)) return;
      state.localVars = {name: varname, next: state.localVars};
    } else {
      if (inList(state.globalVars)) return;
      if (parserConfig.globalVars)
        state.globalVars = {name: varname, next: state.globalVars};
    }
  }

  // Combinators

  var defaultVars = {name: "
this", next: {name: "arguments"}};
  function pushcontext() {
    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
    cx.state.localVars = defaultVars;
  }
  function popcontext() {
    cx.state.localVars = cx.state.context.vars;
    cx.state.context = cx.state.context.prev;
  }
  function pushlex(type, info) {
    var result = function() {
      var state = cx.state, indent = state.indented;
      if (state.lexical.type == "
stat") indent = state.lexical.indented;
      else for (var outer = state.lexical; outer && outer.type == "
)" && outer.align; outer = outer.prev)
        indent = outer.indented;
      state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
    };
    result.lex = true;
    return result;
  }
  function poplex() {
    var state = cx.state;
    if (state.lexical.prev) {
      if (state.lexical.type == "
)")
        state.indented = state.lexical.indented;
      state.lexical = state.lexical.prev;
    }
  }
  poplex.lex = true;

  function expect(wanted) {
    function exp(type) {
      if (type == wanted) return cont();
      else if (wanted == "
;") return pass();
      else return cont(exp);
    };
    return exp;
  }

  function statement(type, value) {
    if (type == "
var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
    if (type == "
keyword a") return cont(pushlex("form"), expression, statement, poplex);
    if (type == "
keyword b") return cont(pushlex("form"), statement, poplex);
    if (type == "
{") return cont(pushlex("}"), block, poplex);
    if (type == "
;") return cont();
    if (type == "
if") {
      if (cx.state.lexical.info == "
else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
        cx.state.cc.pop()();
      return cont(pushlex("
form"), expression, statement, poplex, maybeelse);
    }
    if (type == "
function") return cont(functiondef);
    if (type == "
for") return cont(pushlex("form"), forspec, statement, poplex);
    if (type == "
variable") return cont(pushlex("stat"), maybelabel);
    if (type == "
switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
                                      block, poplex, poplex);
    if (type == "
case") return cont(expression, expect(":"));
    if (type == "
default") return cont(expect(":"));
    if (type == "
catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
                                     statement, poplex, popcontext);
    if (type == "
module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
    if (type == "
class") return cont(pushlex("form"), className, poplex);
    if (type == "
export") return cont(pushlex("form"), afterExport, poplex);
    if (type == "
import") return cont(pushlex("form"), afterImport, poplex);
    return pass(pushlex("
stat"), expression, expect(";"), poplex);
  }
  function expression(type) {
    return expressionInner(type, false);
  }
  function expressionNoComma(type) {
    return expressionInner(type, true);
  }
  function expressionInner(type, noComma) {
    if (cx.state.fatArrowAt == cx.stream.start) {
      var body = noComma ? arrowBodyNoComma : arrowBody;
      if (type == "
(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
      else if (type == "
variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
    }

    var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
    if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
    if (type == "
function") return cont(functiondef, maybeop);
    if (type == "
keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
    if (type == "
(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
    if (type == "
operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
    if (type == "
[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
    if (type == "
{") return contCommasep(objprop, "}", null, maybeop);
    if (type == "
quasi") { return pass(quasi, maybeop); }
    return cont();
  }
  function maybeexpression(type) {
    if (type.match(/[;})],]/)) return pass();
    return pass(expression);
  }
  function maybeexpressionNoComma(type) {
    if (type.match(/[;})],]/)) return pass();
    return pass(expressionNoComma);
  }

  function maybeoperatorComma(type, value) {
    if (type == "
,") return cont(expression);
    return maybeoperatorNoComma(type, value, false);
  }
  function maybeoperatorNoComma(type, value, noComma) {
    var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
    var expr = noComma == false ? expression : expressionNoComma;
    if (value == "
=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
    if (type == "
operator") {
      if (/++|--/.test(value)) return cont(me);
      if (value == "
?") return cont(expression, expect(":"), expr);
      return cont(expr);
    }
    if (type == "
quasi") { return pass(quasi, me); }
    if (type == "
;") return;
    if (type == "
(") return contCommasep(expressionNoComma, ")", "call", me);
    if (type == "
.") return cont(property, me);
    if (type == "
[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
  }
  function quasi(type, value) {
    if (type != "
quasi") return pass();
    if (value.slice(value.length - 2) != "
${") return cont(quasi);
    return cont(expression, continueQuasi);
  }
  function continueQuasi(type) {
    if (type == "
}") {
      cx.marked = "
string-2";
      cx.state.tokenize = tokenQuasi;
      return cont(quasi);
    }
  }
  function arrowBody(type) {
    findFatArrow(cx.stream, cx.state);
    if (type == "
{") return pass(statement);
    return pass(expression);
  }
  function arrowBodyNoComma(type) {
    findFatArrow(cx.stream, cx.state);
    if (type == "
{") return pass(statement);
    return pass(expressionNoComma);
  }
  function maybelabel(type) {
    if (type == "
:") return cont(poplex, statement);
    return pass(maybeoperatorComma, expect("
;"), poplex);
  }
  function property(type) {
    if (type == "
variable") {cx.marked = "property"; return cont();}
  }
  function objprop(type, value) {
    if (type == "
variable" || cx.style == "keyword") {
      cx.marked = "
property";
      if (value == "
get" || value == "set") return cont(getterSetter);
      return cont(afterprop);
    } else if (type == "
number" || type == "string") {
      cx.marked = jsonldMode ? "
property" : (cx.style + " property");
      return cont(afterprop);
    } else if (type == "
jsonld-keyword") {
      return cont(afterprop);
    } else if (type == "
[") {
      return cont(expression, expect("
]"), afterprop);
    }
  }
  function getterSetter(type) {
    if (type != "
variable") return pass(afterprop);
    cx.marked = "
property";
    return cont(functiondef);
  }
  function afterprop(type) {
    if (type == "
:") return cont(expressionNoComma);
    if (type == "
(") return pass(functiondef);
  }
  function commasep(what, end) {
    function proceed(type) {
      if (type == "
,") {
        var lex = cx.state.lexical;
        if (lex.info == "
call") lex.pos = (lex.pos || 0) + 1;
        return cont(what, proceed);
      }
      if (type == end) return cont();
      return cont(expect(end));
    }
    return function(type) {
      if (type == end) return cont();
      return pass(what, proceed);
    };
  }
  function contCommasep(what, end, info) {
    for (var i = 3; i < arguments.length; i++)
      cx.cc.push(arguments[i]);
    return cont(pushlex(end, info), commasep(what, end), poplex);
  }
  function block(type) {
    if (type == "
}") return cont();
    return pass(statement, block);
  }
  function maybetype(type) {
    if (isTS && type == "
:") return cont(typedef);
  }
  function typedef(type) {
    if (type == "
variable"){cx.marked = "variable-3"; return cont();}
  }
  function vardef() {
    return pass(pattern, maybetype, maybeAssign, vardefCont);
  }
  function pattern(type, value) {
    if (type == "
variable") { register(value); return cont(); }
    if (type == "
[") return contCommasep(pattern, "]");
    if (type == "
{") return contCommasep(proppattern, "}");
  }
  function proppattern(type, value) {
    if (type == "
variable" && !cx.stream.match(/^s*:/, false)) {
      register(value);
      return cont(maybeAssign);
    }
    if (type == "
variable") cx.marked = "property";
    return cont(expect("
:"), pattern, maybeAssign);
  }
  function maybeAssign(_type, value) {
    if (value == "
=") return cont(expressionNoComma);
  }
  function vardefCont(type) {
    if (type == "
,") return cont(vardef);
  }
  function maybeelse(type, value) {
    if (type == "
keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
  }
  function forspec(type) {
    if (type == "
(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
  }
  function forspec1(type) {
    if (type == "
var") return cont(vardef, expect(";"), forspec2);
    if (type == "
;") return cont(forspec2);
    if (type == "
variable") return cont(formaybeinof);
    return pass(expression, expect("
;"), forspec2);
  }
  function formaybeinof(_type, value) {
    if (value == "
in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
    return cont(maybeoperatorComma, forspec2);
  }
  function forspec2(type, value) {
    if (type == "
;") return cont(forspec3);
    if (value == "
in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
    return pass(expression, expect("
;"), forspec3);
  }
  function forspec3(type) {
    if (type != "
)") cont(expression);
  }
  function functiondef(type, value) {
    if (value == "
*") {cx.marked = "keyword"; return cont(functiondef);}
    if (type == "
variable") {register(value); return cont(functiondef);}
    if (type == "
(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
  }
  function funarg(type) {
    if (type == "
spread") return cont(funarg);
    return pass(pattern, maybetype);
  }
  function className(type, value) {
    if (type == "
variable") {register(value); return cont(classNameAfter);}
  }
  function classNameAfter(type, value) {
    if (value == "
extends") return cont(expression, classNameAfter);
    if (type == "
{") return cont(pushlex("}"), classBody, poplex);
  }
  function classBody(type, value) {
    if (type == "
variable" || cx.style == "keyword") {
      cx.marked = "
property";
      if (value == "
get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
      return cont(functiondef, classBody);
    }
    if (value == "
*") {
      cx.marked = "
keyword";
      return cont(classBody);
    }
    if (type == "
;") return cont(classBody);
    if (type == "
}") return cont();
  }
  function classGetterSetter(type) {
    if (type != "
variable") return pass();
    cx.marked = "
property";
    return cont();
  }
  function afterModule(type, value) {
    if (type == "
string") return cont(statement);
    if (type == "
variable") { register(value); return cont(maybeFrom); }
  }
  function afterExport(_type, value) {
    if (value == "
*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
    if (value == "
default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
    return pass(statement);
  }
  function afterImport(type) {
    if (type == "
string") return cont();
    return pass(importSpec, maybeFrom);
  }
  function importSpec(type, value) {
    if (type == "
{") return contCommasep(importSpec, "}");
    if (type == "
variable") register(value);
    return cont();
  }
  function maybeFrom(_type, value) {
    if (value == "
from") { cx.marked = "keyword"; return cont(expression); }
  }
  function arrayLiteral(type) {
    if (type == "
]") return cont();
    return pass(expressionNoComma, maybeArrayComprehension);
  }
  function maybeArrayComprehension(type) {
    if (type == "
for") return pass(comprehension, expect("]"));
    if (type == "
,") return cont(commasep(expressionNoComma, "]"));
    return pass(commasep(expressionNoComma, "
]"));
  }
  function comprehension(type) {
    if (type == "
for") return cont(forspec, comprehension);
    if (type == "
if") return cont(expression, comprehension);
  }

  // Interface

  return {
    startState: function(basecolumn) {
      var state = {
        tokenize: tokenBase,
        lastType: "
sof",
        cc: [],
        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "
block", false),
        localVars: parserConfig.localVars,
        context: parserConfig.localVars && {vars: parserConfig.localVars},
        indented: 0
      };
      if (parserConfig.globalVars && typeof parserConfig.globalVars == "
object")
        state.globalVars = parserConfig.globalVars;
      return state;
    },

    token: function(stream, state) {
      if (stream.sol()) {
        if (!state.lexical.hasOwnProperty("
align"))
          state.lexical.align = false;
        state.indented = stream.indentation();
        findFatArrow(stream, state);
      }
      if (state.tokenize != tokenComment && stream.eatSpace()) return null;
      var style = state.tokenize(stream, state);
      if (type == "
comment") return style;
      state.lastType = type == "
operator" && (content == "++" || content == "--") ? "incdec" : type;
      return parseJS(state, style, type, content, stream);
    },

    indent: function(state, textAfter) {
      if (state.tokenize == tokenComment) return CodeMirror.Pass;
      if (state.tokenize != tokenBase) return 0;
      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
      // Kludge to prevent 'maybelse' from blocking lexical scope pops
      if (!/^s*elseb/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
        var c = state.cc[i];
        if (c == poplex) lexical = lexical.prev;
        else if (c != maybeelse) break;
      }
      if (lexical.type == "
stat" && firstChar == "}") lexical = lexical.prev;
      if (statementIndent && lexical.type == "
)" && lexical.prev.type == "stat")
        lexical = lexical.prev;
      var type = lexical.type, closing = firstChar == type;

      if (type == "
vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
      else if (type == "
form" && firstChar == "{") return lexical.indented;
      else if (type == "
form") return lexical.indented + indentUnit;
      else if (type == "
stat")
        return lexical.indented + (state.lastType == "
operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
      else if (lexical.info == "
switch" && !closing && parserConfig.doubleIndentSwitch != false)
        return lexical.indented + (/^(?:case|default)b/.test(textAfter) ? indentUnit : 2 * indentUnit);
      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
      else return lexical.indented + (closing ? 0 : indentUnit);
    },

    electricChars: "
:{}",
    blockCommentStart: jsonMode ? null : "
/*",
    blockCommentEnd: jsonMode ? null : "*/
",
    lineComment: jsonMode ? null : "
//",
    
fold"brace",

    
helperTypejsonMode "json" "javascript",
    
jsonldModejsonldMode,
    
jsonModejsonMode
  
};
});

CodeMirror.registerHelper("wordChars""javascript", /[\w$]/);

CodeMirror.defineMIME("text/javascript""javascript");
CodeMirror.defineMIME("text/ecmascript""javascript");
CodeMirror.defineMIME("application/javascript""javascript");
CodeMirror.defineMIME("application/x-javascript""javascript");
CodeMirror.defineMIME("application/ecmascript""javascript");
CodeMirror.defineMIME("application/json", {name"javascript"jsontrue});
CodeMirror.defineMIME("application/x-json", {name"javascript"jsontrue});
CodeMirror.defineMIME("application/ld+json", {name"javascript"jsonldtrue});
CodeMirror.defineMIME("text/typescript", { name"javascript"typescripttrue });
CodeMirror.defineMIME("application/typescript", { name"javascript"typescripttrue });

});
?>
Онлайн: 0
Реклама