Browse Source

多项UI组件升级到最新版本

xuxueli 6 years ago
parent
commit
5048011fa7

+ 2 - 2
doc/XXL-JOB官方文档.md View File

@@ -1343,7 +1343,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
1343 1343
 - 10、命令行任务:原生提供通用命令行任务Handler(Bean任务,"CommandJobHandler");业务方只需要提供命令行即可;
1344 1344
 - 11、项目依赖升级 groovy 至较新稳定版本;pom清理;
1345 1345
 - 12、子任务失败重试重试逻辑优化,子任务失败时将会按照其预设的失败重试次数主动进行重试
1346
-- 13、多项UI组件升级到最新版本,如:layer/pace/jquery.validate;
1346
+- 13、多项UI组件升级到最新版本,如:layer/pace/jquery.validate/echarts/CodeMirror
1347 1347
 - 14、[迭代中]docker镜像,并且推送docker镜像到中央仓库,更进一步实现产品开箱即用;
1348 1348
 
1349 1349
 
@@ -1366,7 +1366,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
1366 1366
 - 16、Cron TimeZone 自定义;
1367 1367
 - 17、忙碌转移优化,全部机器忙碌时不再直接失败;
1368 1368
 - 18、流程任务等,透传动态参数;
1369
-- 19、任务支持切换执行器;
1369
+- 19、任务支持切换执行器,quartz job group固定
1370 1370
 - 20、任务自动注册;待考虑,因为任务自动注册将会导致任务难以管理控制;
1371 1371
 - 21、批量触发支持,添加参数 "org.quartz.scheduler.batchTriggerAcquisitionMaxCount: 50";
1372 1372
 - 22、失败重试间隔;

+ 1 - 1
xxl-job-admin/src/main/resources/static/plugins/codemirror/addon/hint/anyword-hint.js View File

@@ -1,5 +1,5 @@
1 1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
-// Distributed under an MIT license: http://codemirror.net/LICENSE
2
+// Distributed under an MIT license: https://codemirror.net/LICENSE
3 3
 
4 4
 (function(mod) {
5 5
   if (typeof exports == "object" && typeof module == "object") // CommonJS

+ 0 - 2
xxl-job-admin/src/main/resources/static/plugins/codemirror/addon/hint/show-hint.css View File

@@ -25,8 +25,6 @@
25 25
   margin: 0;
26 26
   padding: 0 4px;
27 27
   border-radius: 2px;
28
-  max-width: 19em;
29
-  overflow: hidden;
30 28
   white-space: pre;
31 29
   color: black;
32 30
   cursor: pointer;

+ 42 - 55
xxl-job-admin/src/main/resources/static/plugins/codemirror/addon/hint/show-hint.js View File

@@ -1,5 +1,5 @@
1 1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
-// Distributed under an MIT license: http://codemirror.net/LICENSE
2
+// Distributed under an MIT license: https://codemirror.net/LICENSE
3 3
 
4 4
 (function(mod) {
5 5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -98,7 +98,7 @@
98 98
       var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
99 99
       if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
100 100
           pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
101
-          (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
101
+          (!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
102 102
         this.close();
103 103
       } else {
104 104
         var self = this;
@@ -108,15 +108,11 @@
108 108
     },
109 109
 
110 110
     update: function(first) {
111
-      if (this.tick == null) return;
112
-      if (!this.options.hint.async) {
113
-        this.finishUpdate(this.options.hint(this.cm, this.options), first);
114
-      } else {
115
-        var myTick = ++this.tick, self = this;
116
-        this.options.hint(this.cm, function(data) {
117
-          if (self.tick == myTick) self.finishUpdate(data, first);
118
-        }, this.options);
119
-      }
111
+      if (this.tick == null) return
112
+      var self = this, myTick = ++this.tick
113
+      fetchHints(this.options.hint, this.cm, this.options, function(data) {
114
+        if (self.tick == myTick) self.finishUpdate(data, first)
115
+      })
120 116
     },
121 117
 
122 118
     finishUpdate: function(data, first) {
@@ -125,7 +121,6 @@
125 121
       var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
126 122
       if (this.widget) this.widget.close();
127 123
 
128
-      if (data && this.data && isNewCompletion(this.data, data)) return;
129 124
       this.data = data;
130 125
 
131 126
       if (data && data.list.length) {
@@ -139,11 +134,6 @@
139 134
     }
140 135
   };
141 136
 
142
-  function isNewCompletion(old, nw) {
143
-    var moved = CodeMirror.cmpPos(nw.from, old.from)
144
-    return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch
145
-  }
146
-
147 137
   function parseOptions(cm, pos, options) {
148 138
     var editor = cm.options.hintOptions;
149 139
     var out = {};
@@ -210,7 +200,8 @@
210 200
     var widget = this, cm = completion.cm;
211 201
 
212 202
     var hints = this.hints = document.createElement("ul");
213
-    hints.className = "CodeMirror-hints";
203
+    var theme = completion.cm.options.theme;
204
+    hints.className = "CodeMirror-hints " + theme;
214 205
     this.selectedHint = data.selectedHint || 0;
215 206
 
216 207
     var completions = data.list;
@@ -233,6 +224,9 @@
233 224
     var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
234 225
     (completion.options.container || document.body).appendChild(hints);
235 226
     var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
227
+    var scrolls = hints.scrollHeight > hints.clientHeight + 1
228
+    var startScroll = cm.getScrollInfo();
229
+
236 230
     if (overlapY > 0) {
237 231
       var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
238 232
       if (curTop - height > 0) { // Fits above cursor
@@ -257,6 +251,8 @@
257 251
       }
258 252
       hints.style.left = (left = pos.left - overlapX) + "px";
259 253
     }
254
+    if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
255
+      node.style.paddingRight = cm.display.nativeBarWidth + "px"
260 256
 
261 257
     cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
262 258
       moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
@@ -274,7 +270,6 @@
274 270
       cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
275 271
     }
276 272
 
277
-    var startScroll = cm.getScrollInfo();
278 273
     cm.on("scroll", this.onScroll = function() {
279 274
       var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
280 275
       var newTop = top + startScroll.top - curScroll.top;
@@ -302,7 +297,7 @@
302 297
       setTimeout(function(){cm.focus();}, 20);
303 298
     });
304 299
 
305
-    CodeMirror.signal(data, "select", completions[0], hints.firstChild);
300
+    CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
306 301
     return true;
307 302
   }
308 303
 
@@ -339,7 +334,7 @@
339 334
         i = avoidWrap ? 0  : this.data.list.length - 1;
340 335
       if (this.selectedHint == i) return;
341 336
       var node = this.hints.childNodes[this.selectedHint];
342
-      node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
337
+      if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
343 338
       node = this.hints.childNodes[this.selectedHint = i];
344 339
       node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
345 340
       if (node.offsetTop < this.hints.scrollTop)
@@ -362,40 +357,31 @@
362 357
     return result
363 358
   }
364 359
 
360
+  function fetchHints(hint, cm, options, callback) {
361
+    if (hint.async) {
362
+      hint(cm, callback, options)
363
+    } else {
364
+      var result = hint(cm, options)
365
+      if (result && result.then) result.then(callback)
366
+      else callback(result)
367
+    }
368
+  }
369
+
365 370
   function resolveAutoHints(cm, pos) {
366 371
     var helpers = cm.getHelpers(pos, "hint"), words
367 372
     if (helpers.length) {
368
-      var async = false, resolved
369
-      for (var i = 0; i < helpers.length; i++) if (helpers[i].async) async = true
370
-      if (async) {
371
-        resolved = function(cm, callback, options) {
372
-          var app = applicableHelpers(cm, helpers)
373
-          function run(i, result) {
374
-            if (i == app.length) return callback(null)
375
-            var helper = app[i]
376
-            if (helper.async) {
377
-              helper(cm, function(result) {
378
-                if (result) callback(result)
379
-                else run(i + 1)
380
-              }, options)
381
-            } else {
382
-              var result = helper(cm, options)
383
-              if (result) callback(result)
384
-              else run(i + 1)
385
-            }
386
-          }
387
-          run(0)
388
-        }
389
-        resolved.async = true
390
-      } else {
391
-        resolved = function(cm, options) {
392
-          var app = applicableHelpers(cm, helpers)
393
-          for (var i = 0; i < app.length; i++) {
394
-            var cur = app[i](cm, options)
395
-            if (cur && cur.list.length) return cur
396
-          }
373
+      var resolved = function(cm, callback, options) {
374
+        var app = applicableHelpers(cm, helpers);
375
+        function run(i) {
376
+          if (i == app.length) return callback(null)
377
+          fetchHints(app[i], cm, options, function(result) {
378
+            if (result && result.list.length > 0) callback(result)
379
+            else run(i + 1)
380
+          })
397 381
         }
382
+        run(0)
398 383
       }
384
+      resolved.async = true
399 385
       resolved.supportsSelection = true
400 386
       return resolved
401 387
     } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
@@ -412,12 +398,13 @@
412 398
   });
413 399
 
414 400
   CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
415
-    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
416
-    var to = CodeMirror.Pos(cur.line, token.end);
417
-    if (token.string && /\w/.test(token.string[token.string.length - 1])) {
418
-      var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
401
+    var cur = cm.getCursor(), token = cm.getTokenAt(cur)
402
+    var term, from = CodeMirror.Pos(cur.line, token.start), to = cur
403
+    if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) {
404
+      term = token.string.substr(0, cur.ch - token.start)
419 405
     } else {
420
-      var term = "", from = to;
406
+      term = ""
407
+      from = cur
421 408
     }
422 409
     var found = [];
423 410
     for (var i = 0; i < options.words.length; i++) {

+ 30 - 22
xxl-job-admin/src/main/resources/static/plugins/codemirror/lib/codemirror.css View File

@@ -5,6 +5,7 @@
5 5
   font-family: monospace;
6 6
   height: 300px;
7 7
   color: black;
8
+  direction: ltr;
8 9
 }
9 10
 
10 11
 /* PADDING */
@@ -52,13 +53,18 @@
52 53
 }
53 54
 .cm-fat-cursor .CodeMirror-cursor {
54 55
   width: auto;
55
-  border: 0;
56
+  border: 0 !important;
56 57
   background: #7e7;
57 58
 }
58 59
 .cm-fat-cursor div.CodeMirror-cursors {
59 60
   z-index: 1;
60 61
 }
61
-
62
+.cm-fat-cursor-mark {
63
+  background-color: rgba(20, 255, 20, 0.5);
64
+  -webkit-animation: blink 1.06s steps(1) infinite;
65
+  -moz-animation: blink 1.06s steps(1) infinite;
66
+  animation: blink 1.06s steps(1) infinite;
67
+}
62 68
 .cm-animate-fat-cursor {
63 69
   width: auto;
64 70
   border: 0;
@@ -88,8 +94,14 @@
88 94
 
89 95
 .cm-tab { display: inline-block; text-decoration: inherit; }
90 96
 
97
+.CodeMirror-rulers {
98
+  position: absolute;
99
+  left: 0; right: 0; top: -50px; bottom: -20px;
100
+  overflow: hidden;
101
+}
91 102
 .CodeMirror-ruler {
92 103
   border-left: 1px solid #ccc;
104
+  top: 0; bottom: 0;
93 105
   position: absolute;
94 106
 }
95 107
 
@@ -113,7 +125,7 @@
113 125
 .cm-s-default .cm-property,
114 126
 .cm-s-default .cm-operator {}
115 127
 .cm-s-default .cm-variable-2 {color: #05a;}
116
-.cm-s-default .cm-variable-3 {color: #085;}
128
+.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
117 129
 .cm-s-default .cm-comment {color: #a50;}
118 130
 .cm-s-default .cm-string {color: #a11;}
119 131
 .cm-s-default .cm-string-2 {color: #f50;}
@@ -133,8 +145,8 @@
133 145
 
134 146
 /* Default styles for common addons */
135 147
 
136
-div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
137
-div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
148
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
149
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
138 150
 .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
139 151
 .CodeMirror-activeline-background {background: #e8f2ff;}
140 152
 
@@ -200,9 +212,6 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
200 212
   display: inline-block;
201 213
   vertical-align: top;
202 214
   margin-bottom: -30px;
203
-  /* Hack to make IE7 behave */
204
-  *zoom:1;
205
-  *display:inline;
206 215
 }
207 216
 .CodeMirror-gutter-wrapper {
208 217
   position: absolute;
@@ -220,11 +229,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
220 229
   cursor: default;
221 230
   z-index: 4;
222 231
 }
223
-.CodeMirror-gutter-wrapper {
224
-  -webkit-user-select: none;
225
-  -moz-user-select: none;
226
-  user-select: none;
227
-}
232
+.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
233
+.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
228 234
 
229 235
 .CodeMirror-lines {
230 236
   cursor: text;
@@ -246,8 +252,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
246 252
   position: relative;
247 253
   overflow: visible;
248 254
   -webkit-tap-highlight-color: transparent;
249
-  -webkit-font-variant-ligatures: none;
250
-  font-variant-ligatures: none;
255
+  -webkit-font-variant-ligatures: contextual;
256
+  font-variant-ligatures: contextual;
251 257
 }
252 258
 .CodeMirror-wrap pre {
253 259
   word-wrap: break-word;
@@ -264,11 +270,13 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
264 270
 .CodeMirror-linewidget {
265 271
   position: relative;
266 272
   z-index: 2;
267
-  overflow: auto;
273
+  padding: 0.1px; /* Force widget margins to stay inside of the container */
268 274
 }
269 275
 
270 276
 .CodeMirror-widget {}
271 277
 
278
+.CodeMirror-rtl pre { direction: rtl; }
279
+
272 280
 .CodeMirror-code {
273 281
   outline: none;
274 282
 }
@@ -291,7 +299,10 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
291 299
   visibility: hidden;
292 300
 }
293 301
 
294
-.CodeMirror-cursor { position: absolute; }
302
+.CodeMirror-cursor {
303
+  position: absolute;
304
+  pointer-events: none;
305
+}
295 306
 .CodeMirror-measure pre { position: static; }
296 307
 
297 308
 div.CodeMirror-cursors {
@@ -314,13 +325,10 @@ div.CodeMirror-dragcursors {
314 325
 .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
315 326
 
316 327
 .cm-searching {
317
-  background: #ffa;
318
-  background: rgba(255, 255, 0, .4);
328
+  background-color: #ffa;
329
+  background-color: rgba(255, 255, 0, .4);
319 330
 }
320 331
 
321
-/* IE7 hack to prevent it from returning funny offsetTops on the spans */
322
-.CodeMirror span { *vertical-align: text-bottom; }
323
-
324 332
 /* Used to force a border model for a node */
325 333
 .cm-force-border { padding-right: .1px; }
326 334
 

File diff suppressed because it is too large
+ 8107 - 7304
xxl-job-admin/src/main/resources/static/plugins/codemirror/lib/codemirror.js


+ 186 - 88
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/clike/clike.js View File

@@ -1,5 +1,5 @@
1 1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
-// Distributed under an MIT license: http://codemirror.net/LICENSE
2
+// Distributed under an MIT license: https://codemirror.net/LICENSE
3 3
 
4 4
 (function(mod) {
5 5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -11,21 +11,19 @@
11 11
 })(function(CodeMirror) {
12 12
 "use strict";
13 13
 
14
-function Context(indented, column, type, align, prev) {
14
+function Context(indented, column, type, info, align, prev) {
15 15
   this.indented = indented;
16 16
   this.column = column;
17 17
   this.type = type;
18
+  this.info = info;
18 19
   this.align = align;
19 20
   this.prev = prev;
20 21
 }
21
-function isStatement(type) {
22
-  return type == "statement" || type == "switchstatement" || type == "namespace";
23
-}
24
-function pushContext(state, col, type) {
22
+function pushContext(state, col, type, info) {
25 23
   var indent = state.indented;
26
-  if (state.context && isStatement(state.context.type) && !isStatement(type))
24
+  if (state.context && state.context.type == "statement" && type != "statement")
27 25
     indent = state.context.indented;
28
-  return state.context = new Context(indent, col, type, null, state.context);
26
+  return state.context = new Context(indent, col, type, info, null, state.context);
29 27
 }
30 28
 function popContext(state) {
31 29
   var t = state.context.type;
@@ -34,15 +32,16 @@ function popContext(state) {
34 32
   return state.context = state.context.prev;
35 33
 }
36 34
 
37
-function typeBefore(stream, state) {
38
-  if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
39
-  if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true;
35
+function typeBefore(stream, state, pos) {
36
+  if (state.prevToken == "variable" || state.prevToken == "type") return true;
37
+  if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true;
38
+  if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true;
40 39
 }
41 40
 
42 41
 function isTopScope(context) {
43 42
   for (;;) {
44 43
     if (!context || context.type == "top") return true;
45
-    if (context.type == "}" && context.prev.type != "namespace") return false;
44
+    if (context.type == "}" && context.prev.info != "namespace") return false;
46 45
     context = context.prev;
47 46
   }
48 47
 }
@@ -66,7 +65,10 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
66 65
       numberStart = parserConfig.numberStart || /[\d\.]/,
67 66
       number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
68 67
       isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
69
-      endStatement = parserConfig.endStatement || /^[;:,]$/;
68
+      isIdentifierChar = parserConfig.isIdentifierChar || /[\w\$_\xa1-\uffff]/,
69
+      // An optional function that takes a {string} token and returns true if it
70
+      // should be treated as a builtin.
71
+      isReservedIdentifier = parserConfig.isReservedIdentifier || false;
70 72
 
71 73
   var curPunc, isDefKeyword;
72 74
 
@@ -103,9 +105,9 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
103 105
       while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {}
104 106
       return "operator";
105 107
     }
106
-    stream.eatWhile(/[\w\$_\xa1-\uffff]/);
108
+    stream.eatWhile(isIdentifierChar);
107 109
     if (namespaceSeparator) while (stream.match(namespaceSeparator))
108
-      stream.eatWhile(/[\w\$_\xa1-\uffff]/);
110
+      stream.eatWhile(isIdentifierChar);
109 111
 
110 112
     var cur = stream.current();
111 113
     if (contains(keywords, cur)) {
@@ -113,8 +115,9 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
113 115
       if (contains(defKeywords, cur)) isDefKeyword = true;
114 116
       return "keyword";
115 117
     }
116
-    if (contains(types, cur)) return "variable-3";
117
-    if (contains(builtin, cur)) {
118
+    if (contains(types, cur)) return "type";
119
+    if (contains(builtin, cur)
120
+        || (isReservedIdentifier && isReservedIdentifier(cur))) {
118 121
       if (contains(blockKeywords, cur)) curPunc = "newstatement";
119 122
       return "builtin";
120 123
     }
@@ -147,13 +150,18 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
147 150
     return "comment";
148 151
   }
149 152
 
153
+  function maybeEOL(stream, state) {
154
+    if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context))
155
+      state.typeAtEndOfLine = typeBefore(stream, state, stream.pos)
156
+  }
157
+
150 158
   // Interface
151 159
 
152 160
   return {
153 161
     startState: function(basecolumn) {
154 162
       return {
155 163
         tokenize: null,
156
-        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
164
+        context: new Context((basecolumn || 0) - indentUnit, 0, "top", null, false),
157 165
         indented: 0,
158 166
         startOfLine: true,
159 167
         prevToken: null
@@ -167,36 +175,32 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
167 175
         state.indented = stream.indentation();
168 176
         state.startOfLine = true;
169 177
       }
170
-      if (stream.eatSpace()) return null;
178
+      if (stream.eatSpace()) { maybeEOL(stream, state); return null; }
171 179
       curPunc = isDefKeyword = null;
172 180
       var style = (state.tokenize || tokenBase)(stream, state);
173 181
       if (style == "comment" || style == "meta") return style;
174 182
       if (ctx.align == null) ctx.align = true;
175 183
 
176
-      if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state);
184
+      if (curPunc == ";" || curPunc == ":" || (curPunc == "," && stream.match(/^\s*(?:\/\/.*)?$/, false)))
185
+        while (state.context.type == "statement") popContext(state);
177 186
       else if (curPunc == "{") pushContext(state, stream.column(), "}");
178 187
       else if (curPunc == "[") pushContext(state, stream.column(), "]");
179 188
       else if (curPunc == "(") pushContext(state, stream.column(), ")");
180 189
       else if (curPunc == "}") {
181
-        while (isStatement(ctx.type)) ctx = popContext(state);
190
+        while (ctx.type == "statement") ctx = popContext(state);
182 191
         if (ctx.type == "}") ctx = popContext(state);
183
-        while (isStatement(ctx.type)) ctx = popContext(state);
192
+        while (ctx.type == "statement") ctx = popContext(state);
184 193
       }
185 194
       else if (curPunc == ctx.type) popContext(state);
186 195
       else if (indentStatements &&
187 196
                (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
188
-                (isStatement(ctx.type) && curPunc == "newstatement"))) {
189
-        var type = "statement";
190
-        if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch")
191
-          type = "switchstatement";
192
-        else if (style == "keyword" && stream.current() == "namespace")
193
-          type = "namespace";
194
-        pushContext(state, stream.column(), type);
197
+                (ctx.type == "statement" && curPunc == "newstatement"))) {
198
+        pushContext(state, stream.column(), "statement", stream.current());
195 199
       }
196 200
 
197 201
       if (style == "variable" &&
198 202
           ((state.prevToken == "def" ||
199
-            (parserConfig.typeFirstDefinitions && typeBefore(stream, state) &&
203
+            (parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) &&
200 204
              isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
201 205
         style = "def";
202 206
 
@@ -209,24 +213,28 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
209 213
 
210 214
       state.startOfLine = false;
211 215
       state.prevToken = isDefKeyword ? "def" : style || curPunc;
216
+      maybeEOL(stream, state);
212 217
       return style;
213 218
     },
214 219
 
215 220
     indent: function(state, textAfter) {
216
-      if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
221
+      if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
217 222
       var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
218
-      if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
223
+      var closing = firstChar == ctx.type;
224
+      if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
225
+      if (parserConfig.dontIndentStatements)
226
+        while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
227
+          ctx = ctx.prev
219 228
       if (hooks.indent) {
220
-        var hook = hooks.indent(state, ctx, textAfter);
229
+        var hook = hooks.indent(state, ctx, textAfter, indentUnit);
221 230
         if (typeof hook == "number") return hook
222 231
       }
223
-      var closing = firstChar == ctx.type;
224
-      var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
232
+      var switchBlock = ctx.prev && ctx.prev.info == "switch";
225 233
       if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
226 234
         while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
227 235
         return ctx.indented
228 236
       }
229
-      if (isStatement(ctx.type))
237
+      if (ctx.type == "statement")
230 238
         return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
231 239
       if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
232 240
         return ctx.column + (closing ? 0 : 1);
@@ -240,6 +248,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
240 248
     electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
241 249
     blockCommentStart: "/*",
242 250
     blockCommentEnd: "*/",
251
+    blockCommentContinue: " * ",
243 252
     lineComment: "//",
244 253
     fold: "brace"
245 254
   };
@@ -258,8 +267,33 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
258 267
     }
259 268
   }
260 269
   var cKeywords = "auto if break case register continue return default do sizeof " +
261
-    "static else struct switch extern typedef union for goto while enum const volatile";
262
-  var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
270
+    "static else struct switch extern typedef union for goto while enum const " +
271
+    "volatile inline restrict asm fortran";
272
+
273
+  // Do not use this. Use the cTypes function below. This is global just to avoid
274
+  // excessive calls when cTypes is being called multiple times during a parse.
275
+  var basicCTypes = words("int long char short double float unsigned signed " +
276
+    "void bool");
277
+
278
+  // Do not use this. Use the objCTypes function below. This is global just to avoid
279
+  // excessive calls when objCTypes is being called multiple times during a parse.
280
+  var basicObjCTypes = words("SEL instancetype id Class Protocol BOOL");
281
+
282
+  // Returns true if identifier is a "C" type.
283
+  // C type is defined as those that are reserved by the compiler (basicTypes),
284
+  // and those that end in _t (Reserved by POSIX for types)
285
+  // http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html
286
+  function cTypes(identifier) {
287
+    return contains(basicCTypes, identifier) || /.+_t/.test(identifier);
288
+  }
289
+
290
+  // Returns true if identifier is a "Objective C" type.
291
+  function objCTypes(identifier) {
292
+    return cTypes(identifier) || contains(basicObjCTypes, identifier);
293
+  }
294
+
295
+  var cBlockKeywords = "case do else for if switch while struct enum union";
296
+  var cDefKeywords = "struct enum union";
263 297
 
264 298
   function cppHook(stream, state) {
265 299
     if (!state.startOfLine) return false
@@ -277,10 +311,18 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
277 311
   }
278 312
 
279 313
   function pointerHook(_stream, state) {
280
-    if (state.prevToken == "variable-3") return "variable-3";
314
+    if (state.prevToken == "type") return "type";
281 315
     return false;
282 316
   }
283 317
 
318
+  // For C and C++ (and ObjC): identifiers starting with __
319
+  // or _ followed by a capital letter are reserved for the compiler.
320
+  function cIsReservedIdentifier(token) {
321
+    if (!token || token.length < 2) return false;
322
+    if (token[0] != '_') return false;
323
+    return (token[1] == '_') || (token[1] !== token[1].toLowerCase());
324
+  }
325
+
284 326
   function cpp14Literal(stream) {
285 327
     stream.eatWhile(/[\w\.']/);
286 328
     return "number";
@@ -311,7 +353,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
311 353
   }
312 354
 
313 355
   function cppLooksLikeConstructor(word) {
314
-    var lastTwo = /(\w+)::(\w+)$/.exec(word);
356
+    var lastTwo = /(\w+)::~?(\w+)$/.exec(word);
315 357
     return lastTwo && lastTwo[1] == lastTwo[2];
316 358
   }
317 359
 
@@ -363,29 +405,34 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
363 405
   def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
364 406
     name: "clike",
365 407
     keywords: words(cKeywords),
366
-    types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " +
367
-                 "int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " +
368
-                 "uint32_t uint64_t"),
369
-    blockKeywords: words("case do else for if switch while struct"),
370
-    defKeywords: words("struct"),
408
+    types: cTypes,
409
+    blockKeywords: words(cBlockKeywords),
410
+    defKeywords: words(cDefKeywords),
371 411
     typeFirstDefinitions: true,
372
-    atoms: words("null true false"),
373
-    hooks: {"#": cppHook, "*": pointerHook},
412
+    atoms: words("NULL true false"),
413
+    isReservedIdentifier: cIsReservedIdentifier,
414
+    hooks: {
415
+      "#": cppHook,
416
+      "*": pointerHook,
417
+    },
374 418
     modeProps: {fold: ["brace", "include"]}
375 419
   });
376 420
 
377 421
   def(["text/x-c++src", "text/x-c++hdr"], {
378 422
     name: "clike",
379
-    keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " +
423
+    keywords: words(cKeywords + " dynamic_cast namespace reinterpret_cast try explicit new " +
380 424
                     "static_cast typeid catch operator template typename class friend private " +
381
-                    "this using const_cast inline public throw virtual delete mutable protected " +
425
+                    "this using const_cast public throw virtual delete mutable protected " +
382 426
                     "alignas alignof constexpr decltype nullptr noexcept thread_local final " +
383 427
                     "static_assert override"),
384
-    types: words(cTypes + " bool wchar_t"),
385
-    blockKeywords: words("catch class do else finally for if struct switch try while"),
386
-    defKeywords: words("class namespace struct enum union"),
428
+    types: cTypes,
429
+    blockKeywords: words(cBlockKeywords +" class try catch finally"),
430
+    defKeywords: words(cDefKeywords + " class namespace"),
387 431
     typeFirstDefinitions: true,
388
-    atoms: words("true false null"),
432
+    atoms: words("true false NULL"),
433
+    dontIndentStatements: /^template$/,
434
+    isIdentifierChar: /[\w\$_~\xa1-\uffff]/,
435
+    isReservedIdentifier: cIsReservedIdentifier,
389 436
     hooks: {
390 437
       "#": cppHook,
391 438
       "*": pointerHook,
@@ -421,16 +468,19 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
421 468
                     "do else enum extends final finally float for goto if implements import " +
422 469
                     "instanceof interface native new package private protected public " +
423 470
                     "return static strictfp super switch synchronized this throw throws transient " +
424
-                    "try volatile while"),
471
+                    "try volatile while @interface"),
425 472
     types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
426 473
                  "Integer Long Number Object Short String StringBuffer StringBuilder Void"),
427 474
     blockKeywords: words("catch class do else finally for if switch try while"),
428
-    defKeywords: words("class interface package enum"),
475
+    defKeywords: words("class interface enum @interface"),
429 476
     typeFirstDefinitions: true,
430 477
     atoms: words("true false null"),
431
-    endStatement: /^[;:]$/,
478
+    number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
432 479
     hooks: {
433 480
       "@": function(stream) {
481
+        // Don't match the @interface keyword.
482
+        if (stream.match('interface', false)) return false;
483
+
434 484
         stream.eatWhile(/[\w\$_]/);
435 485
         return "meta";
436 486
       }
@@ -479,21 +529,38 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
479 529
     return "string";
480 530
   }
481 531
 
532
+  function tokenNestedComment(depth) {
533
+    return function (stream, state) {
534
+      var ch
535
+      while (ch = stream.next()) {
536
+        if (ch == "*" && stream.eat("/")) {
537
+          if (depth == 1) {
538
+            state.tokenize = null
539
+            break
540
+          } else {
541
+            state.tokenize = tokenNestedComment(depth - 1)
542
+            return state.tokenize(stream, state)
543
+          }
544
+        } else if (ch == "/" && stream.eat("*")) {
545
+          state.tokenize = tokenNestedComment(depth + 1)
546
+          return state.tokenize(stream, state)
547
+        }
548
+      }
549
+      return "comment"
550
+    }
551
+  }
552
+
482 553
   def("text/x-scala", {
483 554
     name: "clike",
484 555
     keywords: words(
485
-
486 556
       /* scala */
487 557
       "abstract case catch class def do else extends final finally for forSome if " +
488 558
       "implicit import lazy match new null object override package private protected return " +
489
-      "sealed super this throw trait try type val var while with yield _ : = => <- <: " +
490
-      "<% >: # @ " +
559
+      "sealed super this throw trait try type val var while with yield _ " +
491 560
 
492 561
       /* package scala */
493 562
       "assert assume require print println printf readLine readBoolean readByte readShort " +
494
-      "readChar readInt readLong readFloat readDouble " +
495
-
496
-      ":: #:: "
563
+      "readChar readInt readLong readFloat readDouble"
497 564
     ),
498 565
     types: words(
499 566
       "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
@@ -509,11 +576,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
509 576
       "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
510 577
     ),
511 578
     multiLineStrings: true,
512
-    blockKeywords: words("catch class do else finally for forSome if match switch try while"),
513
-    defKeywords: words("class def object package trait type val var"),
579
+    blockKeywords: words("catch class enum do else finally for forSome if match switch try while"),
580
+    defKeywords: words("class enum def object package trait type val var"),
514 581
     atoms: words("true false null"),
515 582
     indentStatements: false,
516 583
     indentSwitch: false,
584
+    isOperatorChar: /[+\-*&%=<>!?|\/#:@]/,
517 585
     hooks: {
518 586
       "@": function(stream) {
519 587
         stream.eatWhile(/[\w\$_]/);
@@ -531,14 +599,20 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
531 599
       "=": function(stream, state) {
532 600
         var cx = state.context
533 601
         if (cx.type == "}" && cx.align && stream.eat(">")) {
534
-          state.context = new Context(cx.indented, cx.column, cx.type, null, cx.prev)
602
+          state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev)
535 603
           return "operator"
536 604
         } else {
537 605
           return false
538 606
         }
607
+      },
608
+
609
+      "/": function(stream, state) {
610
+        if (!stream.eat("*")) return false
611
+        state.tokenize = tokenNestedComment(1)
612
+        return state.tokenize(stream, state)
539 613
       }
540 614
     },
541
-    modeProps: {closeBrackets: {triples: '"'}}
615
+    modeProps: {closeBrackets: {pairs: '()[]{}""', triples: '"'}}
542 616
   });
543 617
 
544 618
   function tokenKotlinString(tripleString){
@@ -562,33 +636,51 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
562 636
     name: "clike",
563 637
     keywords: words(
564 638
       /*keywords*/
565
-      "package as typealias class interface this super val " +
566
-      "var fun for is in This throw return " +
639
+      "package as typealias class interface this super val operator " +
640
+      "var fun for is in This throw return annotation " +
567 641
       "break continue object if else while do try when !in !is as? " +
568 642
 
569 643
       /*soft keywords*/
570 644
       "file import where by get set abstract enum open inner override private public internal " +
571 645
       "protected catch finally out final vararg reified dynamic companion constructor init " +
572 646
       "sealed field property receiver param sparam lateinit data inline noinline tailrec " +
573
-      "external annotation crossinline const operator infix"
647
+      "external annotation crossinline const operator infix suspend actual expect setparam"
574 648
     ),
575 649
     types: words(
576 650
       /* package java.lang */
577 651
       "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
578 652
       "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
579 653
       "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
580
-      "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
654
+      "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray " +
655
+      "ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy " +
656
+      "LazyThreadSafetyMode LongArray Nothing ShortArray Unit"
581 657
     ),
582 658
     intendSwitch: false,
583 659
     indentStatements: false,
584 660
     multiLineStrings: true,
661
+    number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
585 662
     blockKeywords: words("catch class do else finally for if where try while enum"),
586
-    defKeywords: words("class val var object package interface fun"),
663
+    defKeywords: words("class val var object interface fun"),
587 664
     atoms: words("true false null this"),
588 665
     hooks: {
666
+      "@": function(stream) {
667
+        stream.eatWhile(/[\w\$_]/);
668
+        return "meta";
669
+      },
589 670
       '"': function(stream, state) {
590 671
         state.tokenize = tokenKotlinString(stream.match('""'));
591 672
         return state.tokenize(stream, state);
673
+      },
674
+      indent: function(state, ctx, textAfter, indentUnit) {
675
+        var firstChar = textAfter && textAfter.charAt(0);
676
+        if ((state.prevToken == "}" || state.prevToken == ")") && textAfter == "")
677
+          return state.indented;
678
+        if (state.prevToken == "operator" && textAfter != "}" ||
679
+          state.prevToken == "variable" && firstChar == "." ||
680
+          (state.prevToken == "}" || state.prevToken == ")") && firstChar == ".")
681
+          return indentUnit * 2 + ctx.indented;
682
+        if (ctx.align && ctx.type == "}")
683
+          return ctx.indented + (state.context.type == (textAfter || "").charAt(0) ? 0 : indentUnit);
592 684
       }
593 685
     },
594 686
     modeProps: {closeBrackets: {triples: '"'}}
@@ -655,11 +747,11 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
655 747
 
656 748
   def("text/x-nesc", {
657 749
     name: "clike",
658
-    keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
750
+    keywords: words(cKeywords + " as atomic async call command component components configuration event generic " +
659 751
                     "implementation includes interface module new norace nx_struct nx_union post provides " +
660 752
                     "signal task uses abstract extends"),
661
-    types: words(cTypes),
662
-    blockKeywords: words("case do else for if switch while struct"),
753
+    types: cTypes,
754
+    blockKeywords: words(cBlockKeywords),
663 755
     atoms: words("null true false"),
664 756
     hooks: {"#": cppHook},
665 757
     modeProps: {fold: ["brace", "include"]}
@@ -667,28 +759,34 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
667 759
 
668 760
   def("text/x-objectivec", {
669 761
     name: "clike",
670
-    keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
671
-                    "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
672
-    types: words(cTypes),
673
-    atoms: words("YES NO NULL NILL ON OFF true false"),
762
+    keywords: words(cKeywords + " bycopy byref in inout oneway out self super atomic nonatomic retain copy " +
763
+                    "readwrite readonly strong weak assign typeof nullable nonnull null_resettable _cmd " +
764
+                    "@interface @implementation @end @protocol @encode @property @synthesize @dynamic @class " +
765
+                    "@public @package @private @protected @required @optional @try @catch @finally @import " +
766
+                    "@selector @encode @defs @synchronized @autoreleasepool @compatibility_alias @available"),
767
+    types: objCTypes,
768
+    builtin: words("FOUNDATION_EXPORT FOUNDATION_EXTERN NS_INLINE NS_FORMAT_FUNCTION NS_RETURNS_RETAINED " +
769
+                   "NS_ERROR_ENUM NS_RETURNS_NOT_RETAINED NS_RETURNS_INNER_POINTER NS_DESIGNATED_INITIALIZER " +
770
+                   "NS_ENUM NS_OPTIONS NS_REQUIRES_NIL_TERMINATION NS_ASSUME_NONNULL_BEGIN " +
771
+                   "NS_ASSUME_NONNULL_END NS_SWIFT_NAME NS_REFINED_FOR_SWIFT"),
772
+    blockKeywords: words(cBlockKeywords + " @synthesize @try @catch @finally @autoreleasepool @synchronized"),
773
+    defKeywords: words(cDefKeywords + " @interface @implementation @protocol @class"),
774
+    dontIndentStatements: /^@.*$/,
775
+    typeFirstDefinitions: true,
776
+    atoms: words("YES NO NULL Nil nil true false nullptr"),
777
+    isReservedIdentifier: cIsReservedIdentifier,
674 778
     hooks: {
675
-      "@": function(stream) {
676
-        stream.eatWhile(/[\w\$]/);
677
-        return "keyword";
678
-      },
679 779
       "#": cppHook,
680
-      indent: function(_state, ctx, textAfter) {
681
-        if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented
682
-      }
780
+      "*": pointerHook,
683 781
     },
684
-    modeProps: {fold: "brace"}
782
+    modeProps: {fold: ["brace", "include"]}
685 783
   });
686 784
 
687 785
   def("text/x-squirrel", {
688 786
     name: "clike",
689 787
     keywords: words("base break clone continue const default delete enum extends function in class" +
690 788
                     " foreach local resume return this throw typeof yield constructor instanceof static"),
691
-    types: words(cTypes),
789
+    types: cTypes,
692 790
     blockKeywords: words("case catch class else for foreach if switch try while"),
693 791
     defKeywords: words("function local class"),
694 792
     typeFirstDefinitions: true,
@@ -766,7 +864,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
766 864
         return "atom";
767 865
       },
768 866
       token: function(_stream, state, style) {
769
-          if ((style == "variable" || style == "variable-3") &&
867
+          if ((style == "variable" || style == "type") &&
770 868
               state.prevToken == ".") {
771 869
             return "variable-2";
772 870
           }

+ 220 - 126
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/javascript/javascript.js View File

@@ -1,5 +1,5 @@
1 1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
-// Distributed under an MIT license: http://codemirror.net/LICENSE
2
+// Distributed under an MIT license: https://codemirror.net/LICENSE
3 3
 
4 4
 (function(mod) {
5 5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -11,11 +11,6 @@
11 11
 })(function(CodeMirror) {
12 12
 "use strict";
13 13
 
14
-function expressionAllowed(stream, state, backUp) {
15
-  return /^(?:operator|sof|keyword c|case|new|export|default|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
16
-    (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
17
-}
18
-
19 14
 CodeMirror.defineMode("javascript", function(config, parserConfig) {
20 15
   var indentUnit = config.indentUnit;
21 16
   var statementIndent = parserConfig.statementIndent;
@@ -28,53 +23,21 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
28 23
 
29 24
   var keywords = function(){
30 25
     function kw(type) {return {type: type, style: "keyword"};}
31
-    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
26
+    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
32 27
     var operator = kw("operator"), atom = {type: "atom", style: "atom"};
33 28
 
34
-    var jsKeywords = {
29
+    return {
35 30
       "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
36
-      "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
37
-      "var": kw("var"), "const": kw("var"), "let": kw("var"),
31
+      "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
32
+      "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
38 33
       "function": kw("function"), "catch": kw("catch"),
39 34
       "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
40 35
       "in": operator, "typeof": operator, "instanceof": operator,
41 36
       "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
42 37
       "this": kw("this"), "class": kw("class"), "super": kw("atom"),
43 38
       "yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
44
-      "await": C, "async": kw("async")
39
+      "await": C
45 40
     };
46
-
47
-    // Extend the 'normal' keywords with the TypeScript language extensions
48
-    if (isTS) {
49
-      var type = {type: "variable", style: "variable-3"};
50
-      var tsKeywords = {
51
-        // object-like things
52
-        "interface": kw("class"),
53
-        "implements": C,
54
-        "namespace": C,
55
-        "module": kw("module"),
56
-        "enum": kw("module"),
57
-        "type": kw("type"),
58
-
59
-        // scope modifiers
60
-        "public": kw("modifier"),
61
-        "private": kw("modifier"),
62
-        "protected": kw("modifier"),
63
-        "abstract": kw("modifier"),
64
-
65
-        // operators
66
-        "as": operator,
67
-
68
-        // types
69
-        "string": type, "number": type, "boolean": type, "any": type
70
-      };
71
-
72
-      for (var attr in tsKeywords) {
73
-        jsKeywords[attr] = tsKeywords[attr];
74
-      }
75
-    }
76
-
77
-    return jsKeywords;
78 41
   }();
79 42
 
80 43
   var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
@@ -112,17 +75,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
112 75
       return ret(ch);
113 76
     } else if (ch == "=" && stream.eat(">")) {
114 77
       return ret("=>", "operator");
115
-    } else if (ch == "0" && stream.eat(/x/i)) {
116
-      stream.eatWhile(/[\da-f]/i);
117
-      return ret("number", "number");
118
-    } else if (ch == "0" && stream.eat(/o/i)) {
119
-      stream.eatWhile(/[0-7]/i);
120
-      return ret("number", "number");
121
-    } else if (ch == "0" && stream.eat(/b/i)) {
122
-      stream.eatWhile(/[01]/i);
78
+    } else if (ch == "0" && stream.match(/^(?:x[\da-f]+|o[0-7]+|b[01]+)n?/i)) {
123 79
       return ret("number", "number");
124 80
     } else if (/\d/.test(ch)) {
125
-      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
81
+      stream.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/);
126 82
       return ret("number", "number");
127 83
     } else if (ch == "/") {
128 84
       if (stream.eat("*")) {
@@ -133,10 +89,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
133 89
         return ret("comment", "comment");
134 90
       } else if (expressionAllowed(stream, state, 1)) {
135 91
         readRegexp(stream);
136
-        stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
92
+        stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
137 93
         return ret("regexp", "string-2");
138 94
       } else {
139
-        stream.eatWhile(isOperatorChar);
95
+        stream.eat("=");
140 96
         return ret("operator", "operator", stream.current());
141 97
       }
142 98
     } else if (ch == "`") {
@@ -146,14 +102,27 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
146 102
       stream.skipToEnd();
147 103
       return ret("error", "error");
148 104
     } else if (isOperatorChar.test(ch)) {
149
-      if (ch != ">" || !state.lexical || state.lexical.type != ">")
150
-        stream.eatWhile(isOperatorChar);
105
+      if (ch != ">" || !state.lexical || state.lexical.type != ">") {
106
+        if (stream.eat("=")) {
107
+          if (ch == "!" || ch == "=") stream.eat("=")
108
+        } else if (/[<>*+\-]/.test(ch)) {
109
+          stream.eat(ch)
110
+          if (ch == ">") stream.eat(ch)
111
+        }
112
+      }
151 113
       return ret("operator", "operator", stream.current());
152 114
     } else if (wordRE.test(ch)) {
153 115
       stream.eatWhile(wordRE);
154
-      var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
155
-      return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
156
-                     ret("variable", "variable", word);
116
+      var word = stream.current()
117
+      if (state.lastType != ".") {
118
+        if (keywords.propertyIsEnumerable(word)) {
119
+          var kw = keywords[word]
120
+          return ret(kw.type, kw.style, word)
121
+        }
122
+        if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/, false))
123
+          return ret("async", "keyword", word)
124
+      }
125
+      return ret("variable", "variable", word)
157 126
     }
158 127
   }
159 128
 
@@ -289,35 +258,68 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
289 258
     pass.apply(null, arguments);
290 259
     return true;
291 260
   }
261
+  function inList(name, list) {
262
+    for (var v = list; v; v = v.next) if (v.name == name) return true
263
+    return false;
264
+  }
292 265
   function register(varname) {
293
-    function inList(list) {
294
-      for (var v = list; v; v = v.next)
295
-        if (v.name == varname) return true;
296
-      return false;
297
-    }
298 266
     var state = cx.state;
299 267
     cx.marked = "def";
300 268
     if (state.context) {
301
-      if (inList(state.localVars)) return;
302
-      state.localVars = {name: varname, next: state.localVars};
269
+      if (state.lexical.info == "var" && state.context && state.context.block) {
270
+        // FIXME function decls are also not block scoped
271
+        var newContext = registerVarScoped(varname, state.context)
272
+        if (newContext != null) {
273
+          state.context = newContext
274
+          return
275
+        }
276
+      } else if (!inList(varname, state.localVars)) {
277
+        state.localVars = new Var(varname, state.localVars)
278
+        return
279
+      }
280
+    }
281
+    // Fall through means this is global
282
+    if (parserConfig.globalVars && !inList(varname, state.globalVars))
283
+      state.globalVars = new Var(varname, state.globalVars)
284
+  }
285
+  function registerVarScoped(varname, context) {
286
+    if (!context) {
287
+      return null
288
+    } else if (context.block) {
289
+      var inner = registerVarScoped(varname, context.prev)
290
+      if (!inner) return null
291
+      if (inner == context.prev) return context
292
+      return new Context(inner, context.vars, true)
293
+    } else if (inList(varname, context.vars)) {
294
+      return context
303 295
     } else {
304
-      if (inList(state.globalVars)) return;
305
-      if (parserConfig.globalVars)
306
-        state.globalVars = {name: varname, next: state.globalVars};
296
+      return new Context(context.prev, new Var(varname, context.vars), false)
307 297
     }
308 298
   }
309 299
 
300
+  function isModifier(name) {
301
+    return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly"
302
+  }
303
+
310 304
   // Combinators
311 305
 
312
-  var defaultVars = {name: "this", next: {name: "arguments"}};
306
+  function Context(prev, vars, block) { this.prev = prev; this.vars = vars; this.block = block }
307
+  function Var(name, next) { this.name = name; this.next = next }
308
+
309
+  var defaultVars = new Var("this", new Var("arguments", null))
313 310
   function pushcontext() {
314
-    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
315
-    cx.state.localVars = defaultVars;
311
+    cx.state.context = new Context(cx.state.context, cx.state.localVars, false)
312
+    cx.state.localVars = defaultVars
313
+  }
314
+  function pushblockcontext() {
315
+    cx.state.context = new Context(cx.state.context, cx.state.localVars, true)
316
+    cx.state.localVars = null
316 317
   }
317 318
   function popcontext() {
318
-    cx.state.localVars = cx.state.context.vars;
319
-    cx.state.context = cx.state.context.prev;
319
+    cx.state.localVars = cx.state.context.vars
320
+    cx.state.context = cx.state.context.prev
320 321
   }
322
+  popcontext.lex = true
321 323
   function pushlex(type, info) {
322 324
     var result = function() {
323 325
       var state = cx.state, indent = state.indented;
@@ -342,17 +344,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
342 344
   function expect(wanted) {
343 345
     function exp(type) {
344 346
       if (type == wanted) return cont();
345
-      else if (wanted == ";") return pass();
347
+      else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
346 348
       else return cont(exp);
347 349
     };
348 350
     return exp;
349 351
   }
350 352
 
351 353
   function statement(type, value) {
352
-    if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
354
+    if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex);
353 355
     if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
354 356
     if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
355
-    if (type == "{") return cont(pushlex("}"), block, poplex);
357
+    if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
358
+    if (type == "debugger") return cont(expect(";"));
359
+    if (type == "{") return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext);
356 360
     if (type == ";") return cont();
357 361
     if (type == "if") {
358 362
       if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
@@ -361,60 +365,75 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
361 365
     }
362 366
     if (type == "function") return cont(functiondef);
363 367
     if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
364
-    if (type == "variable") return cont(pushlex("stat"), maybelabel);
365
-    if (type == "switch") return cont(pushlex("form"), parenExpr, pushlex("}", "switch"), expect("{"),
366
-                                      block, poplex, poplex);
368
+    if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), className, poplex); }
369
+    if (type == "variable") {
370
+      if (isTS && value == "declare") {
371
+        cx.marked = "keyword"
372
+        return cont(statement)
373
+      } else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) {
374
+        cx.marked = "keyword"
375
+        if (value == "enum") return cont(enumdef);
376
+        else if (value == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
377
+        else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
378
+      } else if (isTS && value == "namespace") {
379
+        cx.marked = "keyword"
380
+        return cont(pushlex("form"), expression, block, poplex)
381
+      } else if (isTS && value == "abstract") {
382
+        cx.marked = "keyword"
383
+        return cont(statement)
384
+      } else {
385
+        return cont(pushlex("stat"), maybelabel);
386
+      }
387
+    }
388
+    if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext,
389
+                                      block, poplex, poplex, popcontext);
367 390
     if (type == "case") return cont(expression, expect(":"));
368 391
     if (type == "default") return cont(expect(":"));
369
-    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
370
-                                     statement, poplex, popcontext);
371
-    if (type == "class") return cont(pushlex("form"), className, poplex);
392
+    if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext);
372 393
     if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
373 394
     if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
374
-    if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
375
-    if (type == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
376 395
     if (type == "async") return cont(statement)
377 396
     if (value == "@") return cont(expression, statement)
378 397
     return pass(pushlex("stat"), expression, expect(";"), poplex);
379 398
   }
380
-  function expression(type) {
381
-    return expressionInner(type, false);
399
+  function maybeCatchBinding(type) {
400
+    if (type == "(") return cont(funarg, expect(")"))
401
+  }
402
+  function expression(type, value) {
403
+    return expressionInner(type, value, false);
382 404
   }
383
-  function expressionNoComma(type) {
384
-    return expressionInner(type, true);
405
+  function expressionNoComma(type, value) {
406
+    return expressionInner(type, value, true);
385 407
   }
386 408
   function parenExpr(type) {
387 409
     if (type != "(") return pass()
388 410
     return cont(pushlex(")"), expression, expect(")"), poplex)
389 411
   }
390
-  function expressionInner(type, noComma) {
412
+  function expressionInner(type, value, noComma) {
391 413
     if (cx.state.fatArrowAt == cx.stream.start) {
392 414
       var body = noComma ? arrowBodyNoComma : arrowBody;
393
-      if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
415
+      if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
394 416
       else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
395 417
     }
396 418
 
397 419
     var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
398 420
     if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
399 421
     if (type == "function") return cont(functiondef, maybeop);
400
-    if (type == "class") return cont(pushlex("form"), classExpression, poplex);
401
-    if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
422
+    if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
423
+    if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
402 424
     if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
403 425
     if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
404 426
     if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
405 427
     if (type == "{") return contCommasep(objprop, "}", null, maybeop);
406 428
     if (type == "quasi") return pass(quasi, maybeop);
407 429
     if (type == "new") return cont(maybeTarget(noComma));
430
+    if (type == "import") return cont(expression);
408 431
     return cont();
409 432
   }
410 433
   function maybeexpression(type) {
411 434
     if (type.match(/[;\}\)\],]/)) return pass();
412 435
     return pass(expression);
413 436
   }
414
-  function maybeexpressionNoComma(type) {
415
-    if (type.match(/[;\}\)\],]/)) return pass();
416
-    return pass(expressionNoComma);
417
-  }
418 437
 
419 438
   function maybeoperatorComma(type, value) {
420 439
     if (type == ",") return cont(expression);
@@ -425,7 +444,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
425 444
     var expr = noComma == false ? expression : expressionNoComma;
426 445
     if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
427 446
     if (type == "operator") {
428
-      if (/\+\+|--/.test(value)) return cont(me);
447
+      if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
448
+      if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false))
449
+        return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
429 450
       if (value == "?") return cont(expression, expect(":"), expr);
430 451
       return cont(expr);
431 452
     }
@@ -434,6 +455,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
434 455
     if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
435 456
     if (type == ".") return cont(property, me);
436 457
     if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
458
+    if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
459
+    if (type == "regexp") {
460
+      cx.state.lastType = cx.marked = "operator"
461
+      cx.stream.backUp(cx.stream.pos - cx.stream.start - 1)
462
+      return cont(expr)
463
+    }
437 464
   }
438 465
   function quasi(type, value) {
439 466
     if (type != "quasi") return pass();
@@ -458,6 +485,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
458 485
   function maybeTarget(noComma) {
459 486
     return function(type) {
460 487
       if (type == ".") return cont(noComma ? targetNoComma : target);
488
+      else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
461 489
       else return pass(noComma ? expressionNoComma : expression);
462 490
     };
463 491
   }
@@ -481,18 +509,25 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
481 509
     } else if (type == "variable" || cx.style == "keyword") {
482 510
       cx.marked = "property";
483 511
       if (value == "get" || value == "set") return cont(getterSetter);
512
+      var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params
513
+      if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
514
+        cx.state.fatArrowAt = cx.stream.pos + m[0].length
484 515
       return cont(afterprop);
485 516
     } else if (type == "number" || type == "string") {
486 517
       cx.marked = jsonldMode ? "property" : (cx.style + " property");
487 518
       return cont(afterprop);
488 519
     } else if (type == "jsonld-keyword") {
489 520
       return cont(afterprop);
490
-    } else if (type == "modifier") {
521
+    } else if (isTS && isModifier(value)) {
522
+      cx.marked = "keyword"
491 523
       return cont(objprop)
492 524
     } else if (type == "[") {
493
-      return cont(expression, expect("]"), afterprop);
525
+      return cont(expression, maybetype, expect("]"), afterprop);
494 526
     } else if (type == "spread") {
495
-      return cont(expression);
527
+      return cont(expressionNoComma, afterprop);
528
+    } else if (value == "*") {
529
+      cx.marked = "keyword";
530
+      return cont(objprop);
496 531
     } else if (type == ":") {
497 532
       return pass(afterprop)
498 533
     }
@@ -539,11 +574,32 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
539 574
       if (value == "?") return cont(maybetype);
540 575
     }
541 576
   }
542
-  function typeexpr(type) {
543
-    if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);}
577
+  function mayberettype(type) {
578
+    if (isTS && type == ":") {
579
+      if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr)
580
+      else return cont(typeexpr)
581
+    }
582
+  }
583
+  function isKW(_, value) {
584
+    if (value == "is") {
585
+      cx.marked = "keyword"
586
+      return cont()
587
+    }
588
+  }
589
+  function typeexpr(type, value) {
590
+    if (value == "keyof" || value == "typeof") {
591
+      cx.marked = "keyword"
592
+      return cont(value == "keyof" ? typeexpr : expressionNoComma)
593
+    }
594
+    if (type == "variable" || value == "void") {
595
+      cx.marked = "type"
596
+      return cont(afterType)
597
+    }
544 598
     if (type == "string" || type == "number" || type == "atom") return cont(afterType);
545
-    if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex)
599
+    if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
600
+    if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
546 601
     if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
602
+    if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
547 603
   }
548 604
   function maybeReturnType(type) {
549 605
     if (type == "=>") return cont(typeexpr)
@@ -556,25 +612,39 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
556 612
       return cont(typeprop)
557 613
     } else if (type == ":") {
558 614
       return cont(typeexpr)
615
+    } else if (type == "[") {
616
+      return cont(expression, maybetype, expect("]"), typeprop)
559 617
     }
560 618
   }
561
-  function typearg(type) {
562
-    if (type == "variable") return cont(typearg)
563
-    else if (type == ":") return cont(typeexpr)
619
+  function typearg(type, value) {
620
+    if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg)
621
+    if (type == ":") return cont(typeexpr)
622
+    return pass(typeexpr)
564 623
   }
565 624
   function afterType(type, value) {
566 625
     if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
567
-    if (value == "|" || type == ".") return cont(typeexpr)
626
+    if (value == "|" || type == "." || value == "&") return cont(typeexpr)
568 627
     if (type == "[") return cont(expect("]"), afterType)
628
+    if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
629
+  }
630
+  function maybeTypeArgs(_, value) {
631
+    if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
569 632
   }
570
-  function vardef() {
633
+  function typeparam() {
634
+    return pass(typeexpr, maybeTypeDefault)
635
+  }
636
+  function maybeTypeDefault(_, value) {
637
+    if (value == "=") return cont(typeexpr)
638
+  }
639
+  function vardef(_, value) {
640
+    if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)}
571 641
     return pass(pattern, maybetype, maybeAssign, vardefCont);
572 642
   }
573 643
   function pattern(type, value) {
574
-    if (type == "modifier") return cont(pattern)
644
+    if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
575 645
     if (type == "variable") { register(value); return cont(); }
576 646
     if (type == "spread") return cont(pattern);
577
-    if (type == "[") return contCommasep(pattern, "]");
647
+    if (type == "[") return contCommasep(eltpattern, "]");
578 648
     if (type == "{") return contCommasep(proppattern, "}");
579 649
   }
580 650
   function proppattern(type, value) {
@@ -587,6 +657,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
587 657
     if (type == "}") return pass();
588 658
     return cont(expect(":"), pattern, maybeAssign);
589 659
   }
660
+  function eltpattern() {
661
+    return pass(pattern, maybeAssign)
662
+  }
590 663
   function maybeAssign(_type, value) {
591 664
     if (value == "=") return cont(expressionNoComma);
592 665
   }
@@ -596,7 +669,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
596 669
   function maybeelse(type, value) {
597 670
     if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
598 671
   }
599
-  function forspec(type) {
672
+  function forspec(type, value) {
673
+    if (value == "await") return cont(forspec);
600 674
     if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
601 675
   }
602 676
   function forspec1(type) {
@@ -620,11 +694,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
620 694
   function functiondef(type, value) {
621 695
     if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
622 696
     if (type == "variable") {register(value); return cont(functiondef);}
623
-    if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext);
624
-    if (isTS && value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, functiondef)
697
+    if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
698
+    if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
625 699
   }
626
-  function funarg(type) {
700
+  function funarg(type, value) {
701
+    if (value == "@") cont(expression, funarg)
627 702
     if (type == "spread") return cont(funarg);
703
+    if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
628 704
     return pass(pattern, maybetype, maybeAssign);
629 705
   }
630 706
   function classExpression(type, value) {
@@ -636,24 +712,27 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
636 712
     if (type == "variable") {register(value); return cont(classNameAfter);}
637 713
   }
638 714
   function classNameAfter(type, value) {
639
-    if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, classNameAfter)
640
-    if (value == "extends" || value == "implements" || (isTS && type == ","))
715
+    if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
716
+    if (value == "extends" || value == "implements" || (isTS && type == ",")) {
717
+      if (value == "implements") cx.marked = "keyword";
641 718
       return cont(isTS ? typeexpr : expression, classNameAfter);
719
+    }
642 720
     if (type == "{") return cont(pushlex("}"), classBody, poplex);
643 721
   }
644 722
   function classBody(type, value) {
723
+    if (type == "async" ||
724
+        (type == "variable" &&
725
+         (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
726
+         cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
727
+      cx.marked = "keyword";
728
+      return cont(classBody);
729
+    }
645 730
     if (type == "variable" || cx.style == "keyword") {
646
-      if ((value == "async" || value == "static" || value == "get" || value == "set" ||
647
-           (isTS && (value == "public" || value == "private" || value == "protected" || value == "readonly" || value == "abstract"))) &&
648
-          cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) {
649
-        cx.marked = "keyword";
650
-        return cont(classBody);
651
-      }
652 731
       cx.marked = "property";
653 732
       return cont(isTS ? classfield : functiondef, classBody);
654 733
     }
655 734
     if (type == "[")
656
-      return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
735
+      return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
657 736
     if (value == "*") {
658 737
       cx.marked = "keyword";
659 738
       return cont(classBody);
@@ -680,6 +759,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
680 759
   }
681 760
   function afterImport(type) {
682 761
     if (type == "string") return cont();
762
+    if (type == "(") return pass(expression);
683 763
     return pass(importSpec, maybeMoreImports, maybeFrom);
684 764
   }
685 765
   function importSpec(type, value) {
@@ -701,6 +781,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
701 781
     if (type == "]") return cont();
702 782
     return pass(commasep(expressionNoComma, "]"));
703 783
   }
784
+  function enumdef() {
785
+    return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex)
786
+  }
787
+  function enummember() {
788
+    return pass(pattern, maybeAssign);
789
+  }
704 790
 
705 791
   function isContinuedStatement(state, textAfter) {
706 792
     return state.lastType == "operator" || state.lastType == "," ||
@@ -708,6 +794,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
708 794
       /[,.]/.test(textAfter.charAt(0));
709 795
   }
710 796
 
797
+  function expressionAllowed(stream, state, backUp) {
798
+    return state.tokenize == tokenBase &&
799
+      /^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
800
+      (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
801
+  }
802
+
711 803
   // Interface
712 804
 
713 805
   return {
@@ -718,7 +810,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
718 810
         cc: [],
719 811
         lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
720 812
         localVars: parserConfig.localVars,
721
-        context: parserConfig.localVars && {vars: parserConfig.localVars},
813
+        context: parserConfig.localVars && new Context(null, null, false),
722 814
         indented: basecolumn || 0
723 815
       };
724 816
       if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
@@ -759,7 +851,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
759 851
         lexical = lexical.prev;
760 852
       var type = lexical.type, closing = firstChar == type;
761 853
 
762
-      if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
854
+      if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0);
763 855
       else if (type == "form" && firstChar == "{") return lexical.indented;
764 856
       else if (type == "form") return lexical.indented + indentUnit;
765 857
       else if (type == "stat")
@@ -773,6 +865,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
773 865
     electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
774 866
     blockCommentStart: jsonMode ? null : "/*",
775 867
     blockCommentEnd: jsonMode ? null : "*/",
868
+    blockCommentContinue: jsonMode ? null : " * ",
776 869
     lineComment: jsonMode ? null : "//",
777 870
     fold: "brace",
778 871
     closeBrackets: "()[]{}''\"\"``",
@@ -782,6 +875,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
782 875
     jsonMode: jsonMode,
783 876
 
784 877
     expressionAllowed: expressionAllowed,
878
+
785 879
     skipExpression: function(state) {
786 880
       var top = state.cc[state.cc.length - 1]
787 881
       if (top == expression || top == expressionNoComma) state.cc.pop()

+ 2 - 2
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/php/php.js View File

@@ -1,5 +1,5 @@
1 1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
-// Distributed under an MIT license: http://codemirror.net/LICENSE
2
+// Distributed under an MIT license: https://codemirror.net/LICENSE
3 3
 
4 4
 (function(mod) {
5 5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -151,7 +151,7 @@
151 151
   };
152 152
 
153 153
   CodeMirror.defineMode("php", function(config, parserConfig) {
154
-    var htmlMode = CodeMirror.getMode(config, "text/html");
154
+    var htmlMode = CodeMirror.getMode(config, (parserConfig && parserConfig.htmlMode) || "text/html");
155 155
     var phpMode = CodeMirror.getMode(config, phpConfig);
156 156
 
157 157
     function dispatch(stream, state) {

+ 1 - 1
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/powershell/powershell.js View File

@@ -1,5 +1,5 @@
1 1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
-// Distributed under an MIT license: http://codemirror.net/LICENSE
2
+// Distributed under an MIT license: https://codemirror.net/LICENSE
3 3
 
4 4
 (function(mod) {
5 5
   'use strict';

+ 104 - 35
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/python/python.js View File

@@ -1,5 +1,5 @@
1 1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
-// Distributed under an MIT license: http://codemirror.net/LICENSE
2
+// Distributed under an MIT license: https://codemirror.net/LICENSE
3 3
 
4 4
 (function(mod) {
5 5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -41,10 +41,11 @@
41 41
   CodeMirror.defineMode("python", function(conf, parserConf) {
42 42
     var ERRORCLASS = "error";
43 43
 
44
-    var singleDelimiters = parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
45
-    var doubleOperators = parserConf.doubleOperators || /^([!<>]==|<>|<<|>>|\/\/|\*\*)/;
46
-    var doubleDelimiters = parserConf.doubleDelimiters || /^(\+=|\-=|\*=|%=|\/=|&=|\|=|\^=)/;
47
-    var tripleDelimiters = parserConf.tripleDelimiters || /^(\/\/=|>>=|<<=|\*\*=)/;
44
+    var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.\\]/;
45
+    //               (Backwards-compatiblity with old, cumbersome config system)
46
+    var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters,
47
+                     parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@])/]
48
+    for (var i = 0; i < operators.length; i++) if (!operators[i]) operators.splice(i--, 1)
48 49
 
49 50
     var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
50 51
 
@@ -58,13 +59,11 @@
58 59
     var py3 = !(parserConf.version && Number(parserConf.version) < 3)
59 60
     if (py3) {
60 61
       // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
61
-      var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@]/;
62 62
       var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
63 63
       myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
64 64
       myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
65
-      var stringPrefixes = new RegExp("^(([rbuf]|(br))?('{3}|\"{3}|['\"]))", "i");
65
+      var stringPrefixes = new RegExp("^(([rbuf]|(br)|(fr))?('{3}|\"{3}|['\"]))", "i");
66 66
     } else {
67
-      var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!]/;
68 67
       var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
69 68
       myKeywords = myKeywords.concat(["exec", "print"]);
70 69
       myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
@@ -77,9 +76,10 @@
77 76
 
78 77
     // tokenizers
79 78
     function tokenBase(stream, state) {
80
-      if (stream.sol()) state.indent = stream.indentation()
79
+      var sol = stream.sol() && state.lastToken != "\\"
80
+      if (sol) state.indent = stream.indentation()
81 81
       // Handle scope changes
82
-      if (stream.sol() && top(state).type == "py") {
82
+      if (sol && top(state).type == "py") {
83 83
         var scopeOffset = top(state).offset;
84 84
         if (stream.eatSpace()) {
85 85
           var lineOffset = stream.indentation();
@@ -101,13 +101,8 @@
101 101
     function tokenBaseInner(stream, state) {
102 102
       if (stream.eatSpace()) return null;
103 103
 
104
-      var ch = stream.peek();
105
-
106 104
       // Handle Comments
107
-      if (ch == "#") {
108
-        stream.skipToEnd();
109
-        return "comment";
110
-      }
105
+      if (stream.match(/^#.*/)) return "comment";
111 106
 
112 107
       // Handle Number Literals
113 108
       if (stream.match(/^[0-9\.]/, false)) {
@@ -147,19 +142,20 @@
147 142
 
148 143
       // Handle Strings
149 144
       if (stream.match(stringPrefixes)) {
150
-        state.tokenize = tokenStringFactory(stream.current());
151
-        return state.tokenize(stream, state);
145
+        var isFmtString = stream.current().toLowerCase().indexOf('f') !== -1;
146
+        if (!isFmtString) {
147
+          state.tokenize = tokenStringFactory(stream.current());
148
+          return state.tokenize(stream, state);
149
+        } else {
150
+          state.tokenize = formatStringFactory(stream.current(), state.tokenize);
151
+          return state.tokenize(stream, state);
152
+        }
152 153
       }
153 154
 
154
-      // Handle operators and Delimiters
155
-      if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
156
-        return "punctuation";
157
-
158
-      if (stream.match(doubleOperators) || stream.match(singleOperators))
159
-        return "operator";
155
+      for (var i = 0; i < operators.length; i++)
156
+        if (stream.match(operators[i])) return "operator"
160 157
 
161
-      if (stream.match(singleDelimiters))
162
-        return "punctuation";
158
+      if (stream.match(delimiters)) return "punctuation";
163 159
 
164 160
       if (state.lastToken == "." && stream.match(identifiers))
165 161
         return "property";
@@ -184,6 +180,77 @@
184 180
       return ERRORCLASS;
185 181
     }
186 182
 
183
+    function formatStringFactory(delimiter, tokenOuter) {
184
+      while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
185
+        delimiter = delimiter.substr(1);
186
+
187
+      var singleline = delimiter.length == 1;
188
+      var OUTCLASS = "string";
189
+
190
+      function tokenFString(stream, state) {
191
+        // inside f-str Expression
192
+        if (stream.match(delimiter)) {
193
+          // expression ends pre-maturally, but very common in editing
194
+          // Could show error to remind users to close brace here
195
+          state.tokenize = tokenString
196
+          return OUTCLASS;
197
+        } else if (stream.match('{')) {
198
+          // starting brace, if not eaten below
199
+          return "punctuation";
200
+        } else if (stream.match('}')) {
201
+          // return to regular inside string state
202
+          state.tokenize = tokenString
203
+          return "punctuation";
204
+        } else {
205
+          // use tokenBaseInner to parse the expression
206
+          return tokenBaseInner(stream, state);
207
+        }
208
+      }
209
+
210
+      function tokenString(stream, state) {
211
+        while (!stream.eol()) {
212
+          stream.eatWhile(/[^'"\{\}\\]/);
213
+          if (stream.eat("\\")) {
214
+            stream.next();
215
+            if (singleline && stream.eol())
216
+              return OUTCLASS;
217
+          } else if (stream.match(delimiter)) {
218
+            state.tokenize = tokenOuter;
219
+            return OUTCLASS;
220
+          } else if (stream.match('{{')) {
221
+            // ignore {{ in f-str
222
+            return OUTCLASS;
223
+          } else if (stream.match('{', false)) {
224
+            // switch to nested mode
225
+            state.tokenize = tokenFString
226
+            if (stream.current()) {
227
+              return OUTCLASS;
228
+            } else {
229
+              // need to return something, so eat the starting {
230
+              stream.next();
231
+              return "punctuation";
232
+            }
233
+          } else if (stream.match('}}')) {
234
+            return OUTCLASS;
235
+          } else if (stream.match('}')) {
236
+            // single } in f-string is an error
237
+            return ERRORCLASS;
238
+          } else {
239
+            stream.eat(/['"]/);
240
+          }
241
+        }
242
+        if (singleline) {
243
+          if (parserConf.singleLineStringErrors)
244
+            return ERRORCLASS;
245
+          else
246
+            state.tokenize = tokenOuter;
247
+        }
248
+        return OUTCLASS;
249
+      }
250
+      tokenString.isString = true;
251
+      return tokenString;
252
+    }
253
+
187 254
     function tokenStringFactory(delimiter) {
188 255
       while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
189 256
         delimiter = delimiter.substr(1);
@@ -264,14 +331,16 @@
264 331
       if (current == ":" && !state.lambda && top(state).type == "py")
265 332
         pushPyScope(state);
266 333
 
267
-      var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
268
-      if (delimiter_index != -1)
269
-        pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
334
+      if (current.length == 1 && !/string|comment/.test(style)) {
335
+        var delimiter_index = "[({".indexOf(current);
336
+        if (delimiter_index != -1)
337
+          pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
270 338
 
271
-      delimiter_index = "])}".indexOf(current);
272
-      if (delimiter_index != -1) {
273
-        if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
274
-        else return ERRORCLASS;
339
+        delimiter_index = "])}".indexOf(current);
340
+        if (delimiter_index != -1) {
341
+          if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
342
+          else return ERRORCLASS;
343
+        }
275 344
       }
276 345
       if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
277 346
         if (state.scopes.length > 1) state.scopes.pop();
@@ -332,8 +401,8 @@
332 401
 
333 402
   CodeMirror.defineMIME("text/x-cython", {
334 403
     name: "python",
335
-    extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
336
-                          "extern gil include nogil property public"+
404
+    extra_keywords: words("by cdef cimport cpdef ctypedef enum except "+
405
+                          "extern gil include nogil property public "+
337 406
                           "readonly struct union DEF IF ELIF ELSE")
338 407
   });
339 408
 

+ 36 - 23
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/shell/shell.js View File

@@ -1,5 +1,5 @@
1 1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
-// Distributed under an MIT license: http://codemirror.net/LICENSE
2
+// Distributed under an MIT license: https://codemirror.net/LICENSE
3 3
 
4 4
 (function(mod) {
5 5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -14,26 +14,27 @@
14 14
 CodeMirror.defineMode('shell', function() {
15 15
 
16 16
   var words = {};
17
-  function define(style, string) {
18
-    var split = string.split(' ');
19
-    for(var i = 0; i < split.length; i++) {
20
-      words[split[i]] = style;
17
+  function define(style, dict) {
18
+    for(var i = 0; i < dict.length; i++) {
19
+      words[dict[i]] = style;
21 20
     }
22 21
   };
23 22
 
24
-  // Atoms
25
-  define('atom', 'true false');
23
+  var commonAtoms = ["true", "false"];
24
+  var commonKeywords = ["if", "then", "do", "else", "elif", "while", "until", "for", "in", "esac", "fi",
25
+    "fin", "fil", "done", "exit", "set", "unset", "export", "function"];
26
+  var commonCommands = ["ab", "awk", "bash", "beep", "cat", "cc", "cd", "chown", "chmod", "chroot", "clear",
27
+    "cp", "curl", "cut", "diff", "echo", "find", "gawk", "gcc", "get", "git", "grep", "hg", "kill", "killall",
28
+    "ln", "ls", "make", "mkdir", "openssl", "mv", "nc", "nl", "node", "npm", "ping", "ps", "restart", "rm",
29
+    "rmdir", "sed", "service", "sh", "shopt", "shred", "source", "sort", "sleep", "ssh", "start", "stop",
30
+    "su", "sudo", "svn", "tee", "telnet", "top", "touch", "vi", "vim", "wall", "wc", "wget", "who", "write",
31
+    "yes", "zsh"];
26 32
 
27
-  // Keywords
28
-  define('keyword', 'if then do else elif while until for in esac fi fin ' +
29
-    'fil done exit set unset export function');
33
+  CodeMirror.registerHelper("hintWords", "shell", commonAtoms.concat(commonKeywords, commonCommands));
30 34
 
31
-  // Commands
32
-  define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' +
33
-    'curl cut diff echo find gawk gcc get git grep kill killall ln ls make ' +
34
-    'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' +
35
-    'shopt shred source sort sleep ssh start stop su sudo tee telnet top ' +
36
-    'touch vi vim wall wc wget who write yes zsh');
35
+  define('atom', commonAtoms);
36
+  define('keyword', commonKeywords);
37
+  define('builtin', commonCommands);
37 38
 
38 39
   function tokenBase(stream, state) {
39 40
     if (stream.eatSpace()) return null;
@@ -84,29 +85,38 @@ CodeMirror.defineMode('shell', function() {
84 85
   function tokenString(quote, style) {
85 86
     var close = quote == "(" ? ")" : quote == "{" ? "}" : quote
86 87
     return function(stream, state) {
87
-      var next, end = false, escaped = false;
88
+      var next, escaped = false;
88 89
       while ((next = stream.next()) != null) {
89 90
         if (next === close && !escaped) {
90
-          end = true;
91
+          state.tokens.shift();
91 92
           break;
92
-        }
93
-        if (next === '$' && !escaped && quote !== "'") {
93
+        } else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) {
94 94
           escaped = true;
95 95
           stream.backUp(1);
96 96
           state.tokens.unshift(tokenDollar);
97 97
           break;
98
-        }
99
-        if (!escaped && next === quote && quote !== close) {
98
+        } else if (!escaped && quote !== close && next === quote) {
100 99
           state.tokens.unshift(tokenString(quote, style))
101 100
           return tokenize(stream, state)
101
+        } else if (!escaped && /['"]/.test(next) && !/['"]/.test(quote)) {
102
+          state.tokens.unshift(tokenStringStart(next, "string"));
103
+          stream.backUp(1);
104
+          break;
102 105
         }
103 106
         escaped = !escaped && next === '\\';
104 107
       }
105
-      if (end || !escaped) state.tokens.shift();
106 108
       return style;
107 109
     };
108 110
   };
109 111
 
112
+  function tokenStringStart(quote, style) {
113
+    return function(stream, state) {
114
+      state.tokens[0] = tokenString(quote, style)
115
+      stream.next()
116
+      return tokenize(stream, state)
117
+    }
118
+  }
119
+
110 120
   var tokenDollar = function(stream, state) {
111 121
     if (state.tokens.length > 1) stream.eat('$');
112 122
     var ch = stream.next()
@@ -135,5 +145,8 @@ CodeMirror.defineMode('shell', function() {
135 145
 });
136 146
 
137 147
 CodeMirror.defineMIME('text/x-sh', 'shell');
148
+// Apache uses a slightly different Media Type for Shell scripts
149
+// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
150
+CodeMirror.defineMIME('application/x-sh', 'shell');
138 151
 
139 152
 });

File diff suppressed because it is too large
+ 22 - 29
xxl-job-admin/src/main/resources/static/plugins/echarts/echarts.common.min.js