Index: Source/devtools/front_end/cm/javascript.js |
diff --git a/Source/devtools/front_end/cm/javascript.js b/Source/devtools/front_end/cm/javascript.js |
index 315674be74c46ca189cf946f8016e5d7b1dfd9ae..341a43d59224f3fa7764c58db34e88de6e6de981 100644 |
--- a/Source/devtools/front_end/cm/javascript.js |
+++ b/Source/devtools/front_end/cm/javascript.js |
@@ -19,6 +19,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
var jsonldMode = parserConfig.jsonld; |
var jsonMode = parserConfig.json || jsonldMode; |
var isTS = parserConfig.typescript; |
+ var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; |
// Tokenizer |
@@ -35,7 +36,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
"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"), |
+ "this": kw("this"), "class": kw("class"), "super": kw("atom"), |
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C |
}; |
@@ -117,7 +118,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
} 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 |
+ stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); |
return ret("regexp", "string-2"); |
} else { |
stream.eatWhile(isOperatorChar); |
@@ -132,8 +133,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
} else if (isOperatorChar.test(ch)) { |
stream.eatWhile(isOperatorChar); |
return ret("operator", "operator", stream.current()); |
- } else { |
- stream.eatWhile(/[\w\$_]/); |
+ } else if (wordRE.test(ch)) { |
+ stream.eatWhile(wordRE); |
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; |
return (known && state.lastType != ".") ? ret(known.type, known.style, word) : |
ret("variable", "variable", word); |
@@ -202,8 +203,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
if (--depth == 0) break; |
} else if (bracket >= 3 && bracket < 6) { |
++depth; |
- } else if (/[$\w]/.test(ch)) { |
+ } else if (wordRE.test(ch)) { |
sawSomething = true; |
+ } else if (/["'\/]/.test(ch)) { |
+ return; |
} else if (sawSomething && !depth) { |
++pos; |
break; |
@@ -298,6 +301,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
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; |
@@ -342,7 +347,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
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); |
@@ -388,7 +392,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
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 == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); |
if (type == "operator") { |
if (/\+\+|--/.test(value)) return cont(me); |
if (value == "?") return cont(expression, expect(":"), expr); |
@@ -414,13 +418,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
} |
function arrowBody(type) { |
findFatArrow(cx.stream, cx.state); |
- if (type == "{") return pass(statement); |
- return pass(expression); |
+ return pass(type == "{" ? statement : expression); |
} |
function arrowBodyNoComma(type) { |
findFatArrow(cx.stream, cx.state); |
- if (type == "{") return pass(statement); |
- return pass(expressionNoComma); |
+ return pass(type == "{" ? statement : expressionNoComma); |
} |
function maybelabel(type) { |
if (type == ":") return cont(poplex, statement); |
@@ -479,8 +481,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
function maybetype(type) { |
if (isTS && type == ":") return cont(typedef); |
} |
+ function maybedefault(_, value) { |
+ if (value == "=") return cont(expressionNoComma); |
+ } |
function typedef(type) { |
- if (type == "variable"){cx.marked = "variable-3"; return cont();} |
+ if (type == "variable") {cx.marked = "variable-3"; return cont();} |
} |
function vardef() { |
return pass(pattern, maybetype, maybeAssign, vardefCont); |
@@ -535,7 +540,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
} |
function funarg(type) { |
if (type == "spread") return cont(funarg); |
- return pass(pattern, maybetype); |
+ return pass(pattern, maybetype, maybedefault); |
} |
function className(type, value) { |
if (type == "variable") {register(value); return cont(classNameAfter);} |
@@ -546,6 +551,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
} |
function classBody(type, value) { |
if (type == "variable" || cx.style == "keyword") { |
+ if (value == "static") { |
+ cx.marked = "keyword"; |
+ return cont(classBody); |
+ } |
cx.marked = "property"; |
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody); |
return cont(functiondef, classBody); |
@@ -562,10 +571,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
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(";")); } |
@@ -578,7 +583,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
function importSpec(type, value) { |
if (type == "{") return contCommasep(importSpec, "}"); |
if (type == "variable") register(value); |
- return cont(); |
+ if (value == "*") cx.marked = "keyword"; |
+ return cont(maybeAs); |
+ } |
+ function maybeAs(_type, value) { |
+ if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } |
} |
function maybeFrom(_type, value) { |
if (value == "from") { cx.marked = "keyword"; return cont(expression); } |
@@ -589,7 +598,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
} |
function maybeArrayComprehension(type) { |
if (type == "for") return pass(comprehension, expect("]")); |
- if (type == ",") return cont(commasep(expressionNoComma, "]")); |
+ if (type == ",") return cont(commasep(maybeexpressionNoComma, "]")); |
return pass(commasep(expressionNoComma, "]")); |
} |
function comprehension(type) { |
@@ -597,6 +606,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
if (type == "if") return cont(expression, comprehension); |
} |
+ function isContinuedStatement(state, textAfter) { |
+ return state.lastType == "operator" || state.lastType == "," || |
+ isOperatorChar.test(textAfter.charAt(0)) || |
+ /[,.]/.test(textAfter.charAt(0)); |
+ } |
+ |
// Interface |
return { |
@@ -648,18 +663,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
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); |
+ return lexical.indented + (isContinuedStatement(state, textAfter) ? 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: ":{}", |
+ electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, |
blockCommentStart: jsonMode ? null : "/*", |
blockCommentEnd: jsonMode ? null : "*/", |
lineComment: jsonMode ? null : "//", |
fold: "brace", |
+ closeBrackets: "()[]{}''\"\"``", |
helperType: jsonMode ? "json" : "javascript", |
jsonldMode: jsonldMode, |
@@ -667,7 +683,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { |
}; |
}); |
-CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/); |
+CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); |
CodeMirror.defineMIME("text/javascript", "javascript"); |
CodeMirror.defineMIME("text/ecmascript", "javascript"); |