Selaa lähdekoodia

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

xuxueli 7 vuotta sitten
vanhempi
commit
5048011fa7

+ 2 - 2
doc/XXL-JOB官方文档.md Näytä tiedosto

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

+ 1 - 1
xxl-job-admin/src/main/resources/static/plugins/codemirror/addon/hint/anyword-hint.js Näytä tiedosto

1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
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
 (function(mod) {
4
 (function(mod) {
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
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 Näytä tiedosto

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

+ 42 - 55
xxl-job-admin/src/main/resources/static/plugins/codemirror/addon/hint/show-hint.js Näytä tiedosto

1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
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
 (function(mod) {
4
 (function(mod) {
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
98
       var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
98
       var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
99
       if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
99
       if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
100
           pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
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
         this.close();
102
         this.close();
103
       } else {
103
       } else {
104
         var self = this;
104
         var self = this;
108
     },
108
     },
109
 
109
 
110
     update: function(first) {
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
     finishUpdate: function(data, first) {
118
     finishUpdate: function(data, first) {
125
       var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
121
       var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
126
       if (this.widget) this.widget.close();
122
       if (this.widget) this.widget.close();
127
 
123
 
128
-      if (data && this.data && isNewCompletion(this.data, data)) return;
129
       this.data = data;
124
       this.data = data;
130
 
125
 
131
       if (data && data.list.length) {
126
       if (data && data.list.length) {
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
   function parseOptions(cm, pos, options) {
137
   function parseOptions(cm, pos, options) {
148
     var editor = cm.options.hintOptions;
138
     var editor = cm.options.hintOptions;
149
     var out = {};
139
     var out = {};
210
     var widget = this, cm = completion.cm;
200
     var widget = this, cm = completion.cm;
211
 
201
 
212
     var hints = this.hints = document.createElement("ul");
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
     this.selectedHint = data.selectedHint || 0;
205
     this.selectedHint = data.selectedHint || 0;
215
 
206
 
216
     var completions = data.list;
207
     var completions = data.list;
233
     var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
224
     var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
234
     (completion.options.container || document.body).appendChild(hints);
225
     (completion.options.container || document.body).appendChild(hints);
235
     var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
226
     var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
227
+    var scrolls = hints.scrollHeight > hints.clientHeight + 1
228
+    var startScroll = cm.getScrollInfo();
229
+
236
     if (overlapY > 0) {
230
     if (overlapY > 0) {
237
       var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
231
       var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
238
       if (curTop - height > 0) { // Fits above cursor
232
       if (curTop - height > 0) { // Fits above cursor
257
       }
251
       }
258
       hints.style.left = (left = pos.left - overlapX) + "px";
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
     cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
257
     cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
262
       moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
258
       moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
274
       cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
270
       cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
275
     }
271
     }
276
 
272
 
277
-    var startScroll = cm.getScrollInfo();
278
     cm.on("scroll", this.onScroll = function() {
273
     cm.on("scroll", this.onScroll = function() {
279
       var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
274
       var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
280
       var newTop = top + startScroll.top - curScroll.top;
275
       var newTop = top + startScroll.top - curScroll.top;
302
       setTimeout(function(){cm.focus();}, 20);
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
     return true;
301
     return true;
307
   }
302
   }
308
 
303
 
339
         i = avoidWrap ? 0  : this.data.list.length - 1;
334
         i = avoidWrap ? 0  : this.data.list.length - 1;
340
       if (this.selectedHint == i) return;
335
       if (this.selectedHint == i) return;
341
       var node = this.hints.childNodes[this.selectedHint];
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
       node = this.hints.childNodes[this.selectedHint = i];
338
       node = this.hints.childNodes[this.selectedHint = i];
344
       node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
339
       node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
345
       if (node.offsetTop < this.hints.scrollTop)
340
       if (node.offsetTop < this.hints.scrollTop)
362
     return result
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
   function resolveAutoHints(cm, pos) {
370
   function resolveAutoHints(cm, pos) {
366
     var helpers = cm.getHelpers(pos, "hint"), words
371
     var helpers = cm.getHelpers(pos, "hint"), words
367
     if (helpers.length) {
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
       resolved.supportsSelection = true
385
       resolved.supportsSelection = true
400
       return resolved
386
       return resolved
401
     } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
387
     } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
412
   });
398
   });
413
 
399
 
414
   CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
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
     } else {
405
     } else {
420
-      var term = "", from = to;
406
+      term = ""
407
+      from = cur
421
     }
408
     }
422
     var found = [];
409
     var found = [];
423
     for (var i = 0; i < options.words.length; i++) {
410
     for (var i = 0; i < options.words.length; i++) {

+ 30 - 22
xxl-job-admin/src/main/resources/static/plugins/codemirror/lib/codemirror.css Näytä tiedosto

5
   font-family: monospace;
5
   font-family: monospace;
6
   height: 300px;
6
   height: 300px;
7
   color: black;
7
   color: black;
8
+  direction: ltr;
8
 }
9
 }
9
 
10
 
10
 /* PADDING */
11
 /* PADDING */
52
 }
53
 }
53
 .cm-fat-cursor .CodeMirror-cursor {
54
 .cm-fat-cursor .CodeMirror-cursor {
54
   width: auto;
55
   width: auto;
55
-  border: 0;
56
+  border: 0 !important;
56
   background: #7e7;
57
   background: #7e7;
57
 }
58
 }
58
 .cm-fat-cursor div.CodeMirror-cursors {
59
 .cm-fat-cursor div.CodeMirror-cursors {
59
   z-index: 1;
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
 .cm-animate-fat-cursor {
68
 .cm-animate-fat-cursor {
63
   width: auto;
69
   width: auto;
64
   border: 0;
70
   border: 0;
88
 
94
 
89
 .cm-tab { display: inline-block; text-decoration: inherit; }
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
 .CodeMirror-ruler {
102
 .CodeMirror-ruler {
92
   border-left: 1px solid #ccc;
103
   border-left: 1px solid #ccc;
104
+  top: 0; bottom: 0;
93
   position: absolute;
105
   position: absolute;
94
 }
106
 }
95
 
107
 
113
 .cm-s-default .cm-property,
125
 .cm-s-default .cm-property,
114
 .cm-s-default .cm-operator {}
126
 .cm-s-default .cm-operator {}
115
 .cm-s-default .cm-variable-2 {color: #05a;}
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
 .cm-s-default .cm-comment {color: #a50;}
129
 .cm-s-default .cm-comment {color: #a50;}
118
 .cm-s-default .cm-string {color: #a11;}
130
 .cm-s-default .cm-string {color: #a11;}
119
 .cm-s-default .cm-string-2 {color: #f50;}
131
 .cm-s-default .cm-string-2 {color: #f50;}
133
 
145
 
134
 /* Default styles for common addons */
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
 .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
150
 .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
139
 .CodeMirror-activeline-background {background: #e8f2ff;}
151
 .CodeMirror-activeline-background {background: #e8f2ff;}
140
 
152
 
200
   display: inline-block;
212
   display: inline-block;
201
   vertical-align: top;
213
   vertical-align: top;
202
   margin-bottom: -30px;
214
   margin-bottom: -30px;
203
-  /* Hack to make IE7 behave */
204
-  *zoom:1;
205
-  *display:inline;
206
 }
215
 }
207
 .CodeMirror-gutter-wrapper {
216
 .CodeMirror-gutter-wrapper {
208
   position: absolute;
217
   position: absolute;
220
   cursor: default;
229
   cursor: default;
221
   z-index: 4;
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
 .CodeMirror-lines {
235
 .CodeMirror-lines {
230
   cursor: text;
236
   cursor: text;
246
   position: relative;
252
   position: relative;
247
   overflow: visible;
253
   overflow: visible;
248
   -webkit-tap-highlight-color: transparent;
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
 .CodeMirror-wrap pre {
258
 .CodeMirror-wrap pre {
253
   word-wrap: break-word;
259
   word-wrap: break-word;
264
 .CodeMirror-linewidget {
270
 .CodeMirror-linewidget {
265
   position: relative;
271
   position: relative;
266
   z-index: 2;
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
 .CodeMirror-widget {}
276
 .CodeMirror-widget {}
271
 
277
 
278
+.CodeMirror-rtl pre { direction: rtl; }
279
+
272
 .CodeMirror-code {
280
 .CodeMirror-code {
273
   outline: none;
281
   outline: none;
274
 }
282
 }
291
   visibility: hidden;
299
   visibility: hidden;
292
 }
300
 }
293
 
301
 
294
-.CodeMirror-cursor { position: absolute; }
302
+.CodeMirror-cursor {
303
+  position: absolute;
304
+  pointer-events: none;
305
+}
295
 .CodeMirror-measure pre { position: static; }
306
 .CodeMirror-measure pre { position: static; }
296
 
307
 
297
 div.CodeMirror-cursors {
308
 div.CodeMirror-cursors {
314
 .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
325
 .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
315
 
326
 
316
 .cm-searching {
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
 /* Used to force a border model for a node */
332
 /* Used to force a border model for a node */
325
 .cm-force-border { padding-right: .1px; }
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 Näytä tiedosto

1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
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
 (function(mod) {
4
 (function(mod) {
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
11
 })(function(CodeMirror) {
11
 })(function(CodeMirror) {
12
 "use strict";
12
 "use strict";
13
 
13
 
14
-function Context(indented, column, type, align, prev) {
14
+function Context(indented, column, type, info, align, prev) {
15
   this.indented = indented;
15
   this.indented = indented;
16
   this.column = column;
16
   this.column = column;
17
   this.type = type;
17
   this.type = type;
18
+  this.info = info;
18
   this.align = align;
19
   this.align = align;
19
   this.prev = prev;
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
   var indent = state.indented;
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
     indent = state.context.indented;
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
 function popContext(state) {
28
 function popContext(state) {
31
   var t = state.context.type;
29
   var t = state.context.type;
34
   return state.context = state.context.prev;
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
 function isTopScope(context) {
41
 function isTopScope(context) {
43
   for (;;) {
42
   for (;;) {
44
     if (!context || context.type == "top") return true;
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
     context = context.prev;
45
     context = context.prev;
47
   }
46
   }
48
 }
47
 }
66
       numberStart = parserConfig.numberStart || /[\d\.]/,
65
       numberStart = parserConfig.numberStart || /[\d\.]/,
67
       number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
66
       number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
68
       isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
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
   var curPunc, isDefKeyword;
73
   var curPunc, isDefKeyword;
72
 
74
 
103
       while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {}
105
       while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {}
104
       return "operator";
106
       return "operator";
105
     }
107
     }
106
-    stream.eatWhile(/[\w\$_\xa1-\uffff]/);
108
+    stream.eatWhile(isIdentifierChar);
107
     if (namespaceSeparator) while (stream.match(namespaceSeparator))
109
     if (namespaceSeparator) while (stream.match(namespaceSeparator))
108
-      stream.eatWhile(/[\w\$_\xa1-\uffff]/);
110
+      stream.eatWhile(isIdentifierChar);
109
 
111
 
110
     var cur = stream.current();
112
     var cur = stream.current();
111
     if (contains(keywords, cur)) {
113
     if (contains(keywords, cur)) {
113
       if (contains(defKeywords, cur)) isDefKeyword = true;
115
       if (contains(defKeywords, cur)) isDefKeyword = true;
114
       return "keyword";
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
       if (contains(blockKeywords, cur)) curPunc = "newstatement";
121
       if (contains(blockKeywords, cur)) curPunc = "newstatement";
119
       return "builtin";
122
       return "builtin";
120
     }
123
     }
147
     return "comment";
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
   // Interface
158
   // Interface
151
 
159
 
152
   return {
160
   return {
153
     startState: function(basecolumn) {
161
     startState: function(basecolumn) {
154
       return {
162
       return {
155
         tokenize: null,
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
         indented: 0,
165
         indented: 0,
158
         startOfLine: true,
166
         startOfLine: true,
159
         prevToken: null
167
         prevToken: null
167
         state.indented = stream.indentation();
175
         state.indented = stream.indentation();
168
         state.startOfLine = true;
176
         state.startOfLine = true;
169
       }
177
       }
170
-      if (stream.eatSpace()) return null;
178
+      if (stream.eatSpace()) { maybeEOL(stream, state); return null; }
171
       curPunc = isDefKeyword = null;
179
       curPunc = isDefKeyword = null;
172
       var style = (state.tokenize || tokenBase)(stream, state);
180
       var style = (state.tokenize || tokenBase)(stream, state);
173
       if (style == "comment" || style == "meta") return style;
181
       if (style == "comment" || style == "meta") return style;
174
       if (ctx.align == null) ctx.align = true;
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
       else if (curPunc == "{") pushContext(state, stream.column(), "}");
186
       else if (curPunc == "{") pushContext(state, stream.column(), "}");
178
       else if (curPunc == "[") pushContext(state, stream.column(), "]");
187
       else if (curPunc == "[") pushContext(state, stream.column(), "]");
179
       else if (curPunc == "(") pushContext(state, stream.column(), ")");
188
       else if (curPunc == "(") pushContext(state, stream.column(), ")");
180
       else if (curPunc == "}") {
189
       else if (curPunc == "}") {
181
-        while (isStatement(ctx.type)) ctx = popContext(state);
190
+        while (ctx.type == "statement") ctx = popContext(state);
182
         if (ctx.type == "}") ctx = popContext(state);
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
       else if (curPunc == ctx.type) popContext(state);
194
       else if (curPunc == ctx.type) popContext(state);
186
       else if (indentStatements &&
195
       else if (indentStatements &&
187
                (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
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
       if (style == "variable" &&
201
       if (style == "variable" &&
198
           ((state.prevToken == "def" ||
202
           ((state.prevToken == "def" ||
199
-            (parserConfig.typeFirstDefinitions && typeBefore(stream, state) &&
203
+            (parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) &&
200
              isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
204
              isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
201
         style = "def";
205
         style = "def";
202
 
206
 
209
 
213
 
210
       state.startOfLine = false;
214
       state.startOfLine = false;
211
       state.prevToken = isDefKeyword ? "def" : style || curPunc;
215
       state.prevToken = isDefKeyword ? "def" : style || curPunc;
216
+      maybeEOL(stream, state);
212
       return style;
217
       return style;
213
     },
218
     },
214
 
219
 
215
     indent: function(state, textAfter) {
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
       var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
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
       if (hooks.indent) {
228
       if (hooks.indent) {
220
-        var hook = hooks.indent(state, ctx, textAfter);
229
+        var hook = hooks.indent(state, ctx, textAfter, indentUnit);
221
         if (typeof hook == "number") return hook
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
       if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
233
       if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
226
         while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
234
         while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
227
         return ctx.indented
235
         return ctx.indented
228
       }
236
       }
229
-      if (isStatement(ctx.type))
237
+      if (ctx.type == "statement")
230
         return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
238
         return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
231
       if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
239
       if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
232
         return ctx.column + (closing ? 0 : 1);
240
         return ctx.column + (closing ? 0 : 1);
240
     electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
248
     electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
241
     blockCommentStart: "/*",
249
     blockCommentStart: "/*",
242
     blockCommentEnd: "*/",
250
     blockCommentEnd: "*/",
251
+    blockCommentContinue: " * ",
243
     lineComment: "//",
252
     lineComment: "//",
244
     fold: "brace"
253
     fold: "brace"
245
   };
254
   };
258
     }
267
     }
259
   }
268
   }
260
   var cKeywords = "auto if break case register continue return default do sizeof " +
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
   function cppHook(stream, state) {
298
   function cppHook(stream, state) {
265
     if (!state.startOfLine) return false
299
     if (!state.startOfLine) return false
277
   }
311
   }
278
 
312
 
279
   function pointerHook(_stream, state) {
313
   function pointerHook(_stream, state) {
280
-    if (state.prevToken == "variable-3") return "variable-3";
314
+    if (state.prevToken == "type") return "type";
281
     return false;
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
   function cpp14Literal(stream) {
326
   function cpp14Literal(stream) {
285
     stream.eatWhile(/[\w\.']/);
327
     stream.eatWhile(/[\w\.']/);
286
     return "number";
328
     return "number";
311
   }
353
   }
312
 
354
 
313
   function cppLooksLikeConstructor(word) {
355
   function cppLooksLikeConstructor(word) {
314
-    var lastTwo = /(\w+)::(\w+)$/.exec(word);
356
+    var lastTwo = /(\w+)::~?(\w+)$/.exec(word);
315
     return lastTwo && lastTwo[1] == lastTwo[2];
357
     return lastTwo && lastTwo[1] == lastTwo[2];
316
   }
358
   }
317
 
359
 
363
   def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
405
   def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
364
     name: "clike",
406
     name: "clike",
365
     keywords: words(cKeywords),
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
     typeFirstDefinitions: true,
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
     modeProps: {fold: ["brace", "include"]}
418
     modeProps: {fold: ["brace", "include"]}
375
   });
419
   });
376
 
420
 
377
   def(["text/x-c++src", "text/x-c++hdr"], {
421
   def(["text/x-c++src", "text/x-c++hdr"], {
378
     name: "clike",
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
                     "static_cast typeid catch operator template typename class friend private " +
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
                     "alignas alignof constexpr decltype nullptr noexcept thread_local final " +
426
                     "alignas alignof constexpr decltype nullptr noexcept thread_local final " +
383
                     "static_assert override"),
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
     typeFirstDefinitions: true,
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
     hooks: {
436
     hooks: {
390
       "#": cppHook,
437
       "#": cppHook,
391
       "*": pointerHook,
438
       "*": pointerHook,
421
                     "do else enum extends final finally float for goto if implements import " +
468
                     "do else enum extends final finally float for goto if implements import " +
422
                     "instanceof interface native new package private protected public " +
469
                     "instanceof interface native new package private protected public " +
423
                     "return static strictfp super switch synchronized this throw throws transient " +
470
                     "return static strictfp super switch synchronized this throw throws transient " +
424
-                    "try volatile while"),
471
+                    "try volatile while @interface"),
425
     types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
472
     types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
426
                  "Integer Long Number Object Short String StringBuffer StringBuilder Void"),
473
                  "Integer Long Number Object Short String StringBuffer StringBuilder Void"),
427
     blockKeywords: words("catch class do else finally for if switch try while"),
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
     typeFirstDefinitions: true,
476
     typeFirstDefinitions: true,
430
     atoms: words("true false null"),
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
     hooks: {
479
     hooks: {
433
       "@": function(stream) {
480
       "@": function(stream) {
481
+        // Don't match the @interface keyword.
482
+        if (stream.match('interface', false)) return false;
483
+
434
         stream.eatWhile(/[\w\$_]/);
484
         stream.eatWhile(/[\w\$_]/);
435
         return "meta";
485
         return "meta";
436
       }
486
       }
479
     return "string";
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
   def("text/x-scala", {
553
   def("text/x-scala", {
483
     name: "clike",
554
     name: "clike",
484
     keywords: words(
555
     keywords: words(
485
-
486
       /* scala */
556
       /* scala */
487
       "abstract case catch class def do else extends final finally for forSome if " +
557
       "abstract case catch class def do else extends final finally for forSome if " +
488
       "implicit import lazy match new null object override package private protected return " +
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
       /* package scala */
561
       /* package scala */
493
       "assert assume require print println printf readLine readBoolean readByte readShort " +
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
     types: words(
565
     types: words(
499
       "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
566
       "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
509
       "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
576
       "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
510
     ),
577
     ),
511
     multiLineStrings: true,
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
     atoms: words("true false null"),
581
     atoms: words("true false null"),
515
     indentStatements: false,
582
     indentStatements: false,
516
     indentSwitch: false,
583
     indentSwitch: false,
584
+    isOperatorChar: /[+\-*&%=<>!?|\/#:@]/,
517
     hooks: {
585
     hooks: {
518
       "@": function(stream) {
586
       "@": function(stream) {
519
         stream.eatWhile(/[\w\$_]/);
587
         stream.eatWhile(/[\w\$_]/);
531
       "=": function(stream, state) {
599
       "=": function(stream, state) {
532
         var cx = state.context
600
         var cx = state.context
533
         if (cx.type == "}" && cx.align && stream.eat(">")) {
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
           return "operator"
603
           return "operator"
536
         } else {
604
         } else {
537
           return false
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
   function tokenKotlinString(tripleString){
618
   function tokenKotlinString(tripleString){
562
     name: "clike",
636
     name: "clike",
563
     keywords: words(
637
     keywords: words(
564
       /*keywords*/
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
       "break continue object if else while do try when !in !is as? " +
641
       "break continue object if else while do try when !in !is as? " +
568
 
642
 
569
       /*soft keywords*/
643
       /*soft keywords*/
570
       "file import where by get set abstract enum open inner override private public internal " +
644
       "file import where by get set abstract enum open inner override private public internal " +
571
       "protected catch finally out final vararg reified dynamic companion constructor init " +
645
       "protected catch finally out final vararg reified dynamic companion constructor init " +
572
       "sealed field property receiver param sparam lateinit data inline noinline tailrec " +
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
     types: words(
649
     types: words(
576
       /* package java.lang */
650
       /* package java.lang */
577
       "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
651
       "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
578
       "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
652
       "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
579
       "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
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
     intendSwitch: false,
658
     intendSwitch: false,
583
     indentStatements: false,
659
     indentStatements: false,
584
     multiLineStrings: true,
660
     multiLineStrings: true,
661
+    number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
585
     blockKeywords: words("catch class do else finally for if where try while enum"),
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
     atoms: words("true false null this"),
664
     atoms: words("true false null this"),
588
     hooks: {
665
     hooks: {
666
+      "@": function(stream) {
667
+        stream.eatWhile(/[\w\$_]/);
668
+        return "meta";
669
+      },
589
       '"': function(stream, state) {
670
       '"': function(stream, state) {
590
         state.tokenize = tokenKotlinString(stream.match('""'));
671
         state.tokenize = tokenKotlinString(stream.match('""'));
591
         return state.tokenize(stream, state);
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
     modeProps: {closeBrackets: {triples: '"'}}
686
     modeProps: {closeBrackets: {triples: '"'}}
655
 
747
 
656
   def("text/x-nesc", {
748
   def("text/x-nesc", {
657
     name: "clike",
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
                     "implementation includes interface module new norace nx_struct nx_union post provides " +
751
                     "implementation includes interface module new norace nx_struct nx_union post provides " +
660
                     "signal task uses abstract extends"),
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
     atoms: words("null true false"),
755
     atoms: words("null true false"),
664
     hooks: {"#": cppHook},
756
     hooks: {"#": cppHook},
665
     modeProps: {fold: ["brace", "include"]}
757
     modeProps: {fold: ["brace", "include"]}
667
 
759
 
668
   def("text/x-objectivec", {
760
   def("text/x-objectivec", {
669
     name: "clike",
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
     hooks: {
778
     hooks: {
675
-      "@": function(stream) {
676
-        stream.eatWhile(/[\w\$]/);
677
-        return "keyword";
678
-      },
679
       "#": cppHook,
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
   def("text/x-squirrel", {
785
   def("text/x-squirrel", {
688
     name: "clike",
786
     name: "clike",
689
     keywords: words("base break clone continue const default delete enum extends function in class" +
787
     keywords: words("base break clone continue const default delete enum extends function in class" +
690
                     " foreach local resume return this throw typeof yield constructor instanceof static"),
788
                     " foreach local resume return this throw typeof yield constructor instanceof static"),
691
-    types: words(cTypes),
789
+    types: cTypes,
692
     blockKeywords: words("case catch class else for foreach if switch try while"),
790
     blockKeywords: words("case catch class else for foreach if switch try while"),
693
     defKeywords: words("function local class"),
791
     defKeywords: words("function local class"),
694
     typeFirstDefinitions: true,
792
     typeFirstDefinitions: true,
766
         return "atom";
864
         return "atom";
767
       },
865
       },
768
       token: function(_stream, state, style) {
866
       token: function(_stream, state, style) {
769
-          if ((style == "variable" || style == "variable-3") &&
867
+          if ((style == "variable" || style == "type") &&
770
               state.prevToken == ".") {
868
               state.prevToken == ".") {
771
             return "variable-2";
869
             return "variable-2";
772
           }
870
           }

+ 220 - 126
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/javascript/javascript.js Näytä tiedosto

1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
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
 (function(mod) {
4
 (function(mod) {
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
11
 })(function(CodeMirror) {
11
 })(function(CodeMirror) {
12
 "use strict";
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
 CodeMirror.defineMode("javascript", function(config, parserConfig) {
14
 CodeMirror.defineMode("javascript", function(config, parserConfig) {
20
   var indentUnit = config.indentUnit;
15
   var indentUnit = config.indentUnit;
21
   var statementIndent = parserConfig.statementIndent;
16
   var statementIndent = parserConfig.statementIndent;
28
 
23
 
29
   var keywords = function(){
24
   var keywords = function(){
30
     function kw(type) {return {type: type, style: "keyword"};}
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
     var operator = kw("operator"), atom = {type: "atom", style: "atom"};
27
     var operator = kw("operator"), atom = {type: "atom", style: "atom"};
33
 
28
 
34
-    var jsKeywords = {
29
+    return {
35
       "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
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
       "function": kw("function"), "catch": kw("catch"),
33
       "function": kw("function"), "catch": kw("catch"),
39
       "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
34
       "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
40
       "in": operator, "typeof": operator, "instanceof": operator,
35
       "in": operator, "typeof": operator, "instanceof": operator,
41
       "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
36
       "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
42
       "this": kw("this"), "class": kw("class"), "super": kw("atom"),
37
       "this": kw("this"), "class": kw("class"), "super": kw("atom"),
43
       "yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
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
   var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
43
   var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
112
       return ret(ch);
75
       return ret(ch);
113
     } else if (ch == "=" && stream.eat(">")) {
76
     } else if (ch == "=" && stream.eat(">")) {
114
       return ret("=>", "operator");
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
       return ret("number", "number");
79
       return ret("number", "number");
124
     } else if (/\d/.test(ch)) {
80
     } else if (/\d/.test(ch)) {
125
-      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
81
+      stream.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/);
126
       return ret("number", "number");
82
       return ret("number", "number");
127
     } else if (ch == "/") {
83
     } else if (ch == "/") {
128
       if (stream.eat("*")) {
84
       if (stream.eat("*")) {
133
         return ret("comment", "comment");
89
         return ret("comment", "comment");
134
       } else if (expressionAllowed(stream, state, 1)) {
90
       } else if (expressionAllowed(stream, state, 1)) {
135
         readRegexp(stream);
91
         readRegexp(stream);
136
-        stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
92
+        stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
137
         return ret("regexp", "string-2");
93
         return ret("regexp", "string-2");
138
       } else {
94
       } else {
139
-        stream.eatWhile(isOperatorChar);
95
+        stream.eat("=");
140
         return ret("operator", "operator", stream.current());
96
         return ret("operator", "operator", stream.current());
141
       }
97
       }
142
     } else if (ch == "`") {
98
     } else if (ch == "`") {
146
       stream.skipToEnd();
102
       stream.skipToEnd();
147
       return ret("error", "error");
103
       return ret("error", "error");
148
     } else if (isOperatorChar.test(ch)) {
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
       return ret("operator", "operator", stream.current());
113
       return ret("operator", "operator", stream.current());
152
     } else if (wordRE.test(ch)) {
114
     } else if (wordRE.test(ch)) {
153
       stream.eatWhile(wordRE);
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
     pass.apply(null, arguments);
258
     pass.apply(null, arguments);
290
     return true;
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
   function register(varname) {
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
     var state = cx.state;
266
     var state = cx.state;
299
     cx.marked = "def";
267
     cx.marked = "def";
300
     if (state.context) {
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
     } else {
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
   // Combinators
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
   function pushcontext() {
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
   function popcontext() {
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
   function pushlex(type, info) {
323
   function pushlex(type, info) {
322
     var result = function() {
324
     var result = function() {
323
       var state = cx.state, indent = state.indented;
325
       var state = cx.state, indent = state.indented;
342
   function expect(wanted) {
344
   function expect(wanted) {
343
     function exp(type) {
345
     function exp(type) {
344
       if (type == wanted) return cont();
346
       if (type == wanted) return cont();
345
-      else if (wanted == ";") return pass();
347
+      else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
346
       else return cont(exp);
348
       else return cont(exp);
347
     };
349
     };
348
     return exp;
350
     return exp;
349
   }
351
   }
350
 
352
 
351
   function statement(type, value) {
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
     if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
355
     if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
354
     if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
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
     if (type == ";") return cont();
360
     if (type == ";") return cont();
357
     if (type == "if") {
361
     if (type == "if") {
358
       if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
362
       if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
361
     }
365
     }
362
     if (type == "function") return cont(functiondef);
366
     if (type == "function") return cont(functiondef);
363
     if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
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
     if (type == "case") return cont(expression, expect(":"));
390
     if (type == "case") return cont(expression, expect(":"));
368
     if (type == "default") return cont(expect(":"));
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
     if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
393
     if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
373
     if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
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
     if (type == "async") return cont(statement)
395
     if (type == "async") return cont(statement)
377
     if (value == "@") return cont(expression, statement)
396
     if (value == "@") return cont(expression, statement)
378
     return pass(pushlex("stat"), expression, expect(";"), poplex);
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
   function parenExpr(type) {
408
   function parenExpr(type) {
387
     if (type != "(") return pass()
409
     if (type != "(") return pass()
388
     return cont(pushlex(")"), expression, expect(")"), poplex)
410
     return cont(pushlex(")"), expression, expect(")"), poplex)
389
   }
411
   }
390
-  function expressionInner(type, noComma) {
412
+  function expressionInner(type, value, noComma) {
391
     if (cx.state.fatArrowAt == cx.stream.start) {
413
     if (cx.state.fatArrowAt == cx.stream.start) {
392
       var body = noComma ? arrowBodyNoComma : arrowBody;
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
       else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
416
       else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
395
     }
417
     }
396
 
418
 
397
     var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
419
     var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
398
     if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
420
     if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
399
     if (type == "function") return cont(functiondef, maybeop);
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
     if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
424
     if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
403
     if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
425
     if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
404
     if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
426
     if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
405
     if (type == "{") return contCommasep(objprop, "}", null, maybeop);
427
     if (type == "{") return contCommasep(objprop, "}", null, maybeop);
406
     if (type == "quasi") return pass(quasi, maybeop);
428
     if (type == "quasi") return pass(quasi, maybeop);
407
     if (type == "new") return cont(maybeTarget(noComma));
429
     if (type == "new") return cont(maybeTarget(noComma));
430
+    if (type == "import") return cont(expression);
408
     return cont();
431
     return cont();
409
   }
432
   }
410
   function maybeexpression(type) {
433
   function maybeexpression(type) {
411
     if (type.match(/[;\}\)\],]/)) return pass();
434
     if (type.match(/[;\}\)\],]/)) return pass();
412
     return pass(expression);
435
     return pass(expression);
413
   }
436
   }
414
-  function maybeexpressionNoComma(type) {
415
-    if (type.match(/[;\}\)\],]/)) return pass();
416
-    return pass(expressionNoComma);
417
-  }
418
 
437
 
419
   function maybeoperatorComma(type, value) {
438
   function maybeoperatorComma(type, value) {
420
     if (type == ",") return cont(expression);
439
     if (type == ",") return cont(expression);
425
     var expr = noComma == false ? expression : expressionNoComma;
444
     var expr = noComma == false ? expression : expressionNoComma;
426
     if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
445
     if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
427
     if (type == "operator") {
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
       if (value == "?") return cont(expression, expect(":"), expr);
450
       if (value == "?") return cont(expression, expect(":"), expr);
430
       return cont(expr);
451
       return cont(expr);
431
     }
452
     }
434
     if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
455
     if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
435
     if (type == ".") return cont(property, me);
456
     if (type == ".") return cont(property, me);
436
     if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
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
   function quasi(type, value) {
465
   function quasi(type, value) {
439
     if (type != "quasi") return pass();
466
     if (type != "quasi") return pass();
458
   function maybeTarget(noComma) {
485
   function maybeTarget(noComma) {
459
     return function(type) {
486
     return function(type) {
460
       if (type == ".") return cont(noComma ? targetNoComma : target);
487
       if (type == ".") return cont(noComma ? targetNoComma : target);
488
+      else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
461
       else return pass(noComma ? expressionNoComma : expression);
489
       else return pass(noComma ? expressionNoComma : expression);
462
     };
490
     };
463
   }
491
   }
481
     } else if (type == "variable" || cx.style == "keyword") {
509
     } else if (type == "variable" || cx.style == "keyword") {
482
       cx.marked = "property";
510
       cx.marked = "property";
483
       if (value == "get" || value == "set") return cont(getterSetter);
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
       return cont(afterprop);
515
       return cont(afterprop);
485
     } else if (type == "number" || type == "string") {
516
     } else if (type == "number" || type == "string") {
486
       cx.marked = jsonldMode ? "property" : (cx.style + " property");
517
       cx.marked = jsonldMode ? "property" : (cx.style + " property");
487
       return cont(afterprop);
518
       return cont(afterprop);
488
     } else if (type == "jsonld-keyword") {
519
     } else if (type == "jsonld-keyword") {
489
       return cont(afterprop);
520
       return cont(afterprop);
490
-    } else if (type == "modifier") {
521
+    } else if (isTS && isModifier(value)) {
522
+      cx.marked = "keyword"
491
       return cont(objprop)
523
       return cont(objprop)
492
     } else if (type == "[") {
524
     } else if (type == "[") {
493
-      return cont(expression, expect("]"), afterprop);
525
+      return cont(expression, maybetype, expect("]"), afterprop);
494
     } else if (type == "spread") {
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
     } else if (type == ":") {
531
     } else if (type == ":") {
497
       return pass(afterprop)
532
       return pass(afterprop)
498
     }
533
     }
539
       if (value == "?") return cont(maybetype);
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
     if (type == "string" || type == "number" || type == "atom") return cont(afterType);
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
     if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
601
     if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
602
+    if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
547
   }
603
   }
548
   function maybeReturnType(type) {
604
   function maybeReturnType(type) {
549
     if (type == "=>") return cont(typeexpr)
605
     if (type == "=>") return cont(typeexpr)
556
       return cont(typeprop)
612
       return cont(typeprop)
557
     } else if (type == ":") {
613
     } else if (type == ":") {
558
       return cont(typeexpr)
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
   function afterType(type, value) {
624
   function afterType(type, value) {
566
     if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
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
     if (type == "[") return cont(expect("]"), afterType)
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
     return pass(pattern, maybetype, maybeAssign, vardefCont);
641
     return pass(pattern, maybetype, maybeAssign, vardefCont);
572
   }
642
   }
573
   function pattern(type, value) {
643
   function pattern(type, value) {
574
-    if (type == "modifier") return cont(pattern)
644
+    if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
575
     if (type == "variable") { register(value); return cont(); }
645
     if (type == "variable") { register(value); return cont(); }
576
     if (type == "spread") return cont(pattern);
646
     if (type == "spread") return cont(pattern);
577
-    if (type == "[") return contCommasep(pattern, "]");
647
+    if (type == "[") return contCommasep(eltpattern, "]");
578
     if (type == "{") return contCommasep(proppattern, "}");
648
     if (type == "{") return contCommasep(proppattern, "}");
579
   }
649
   }
580
   function proppattern(type, value) {
650
   function proppattern(type, value) {
587
     if (type == "}") return pass();
657
     if (type == "}") return pass();
588
     return cont(expect(":"), pattern, maybeAssign);
658
     return cont(expect(":"), pattern, maybeAssign);
589
   }
659
   }
660
+  function eltpattern() {
661
+    return pass(pattern, maybeAssign)
662
+  }
590
   function maybeAssign(_type, value) {
663
   function maybeAssign(_type, value) {
591
     if (value == "=") return cont(expressionNoComma);
664
     if (value == "=") return cont(expressionNoComma);
592
   }
665
   }
596
   function maybeelse(type, value) {
669
   function maybeelse(type, value) {
597
     if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
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
     if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
674
     if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
601
   }
675
   }
602
   function forspec1(type) {
676
   function forspec1(type) {
620
   function functiondef(type, value) {
694
   function functiondef(type, value) {
621
     if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
695
     if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
622
     if (type == "variable") {register(value); return cont(functiondef);}
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
     if (type == "spread") return cont(funarg);
702
     if (type == "spread") return cont(funarg);
703
+    if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
628
     return pass(pattern, maybetype, maybeAssign);
704
     return pass(pattern, maybetype, maybeAssign);
629
   }
705
   }
630
   function classExpression(type, value) {
706
   function classExpression(type, value) {
636
     if (type == "variable") {register(value); return cont(classNameAfter);}
712
     if (type == "variable") {register(value); return cont(classNameAfter);}
637
   }
713
   }
638
   function classNameAfter(type, value) {
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
       return cont(isTS ? typeexpr : expression, classNameAfter);
718
       return cont(isTS ? typeexpr : expression, classNameAfter);
719
+    }
642
     if (type == "{") return cont(pushlex("}"), classBody, poplex);
720
     if (type == "{") return cont(pushlex("}"), classBody, poplex);
643
   }
721
   }
644
   function classBody(type, value) {
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
     if (type == "variable" || cx.style == "keyword") {
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
       cx.marked = "property";
731
       cx.marked = "property";
653
       return cont(isTS ? classfield : functiondef, classBody);
732
       return cont(isTS ? classfield : functiondef, classBody);
654
     }
733
     }
655
     if (type == "[")
734
     if (type == "[")
656
-      return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
735
+      return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
657
     if (value == "*") {
736
     if (value == "*") {
658
       cx.marked = "keyword";
737
       cx.marked = "keyword";
659
       return cont(classBody);
738
       return cont(classBody);
680
   }
759
   }
681
   function afterImport(type) {
760
   function afterImport(type) {
682
     if (type == "string") return cont();
761
     if (type == "string") return cont();
762
+    if (type == "(") return pass(expression);
683
     return pass(importSpec, maybeMoreImports, maybeFrom);
763
     return pass(importSpec, maybeMoreImports, maybeFrom);
684
   }
764
   }
685
   function importSpec(type, value) {
765
   function importSpec(type, value) {
701
     if (type == "]") return cont();
781
     if (type == "]") return cont();
702
     return pass(commasep(expressionNoComma, "]"));
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
   function isContinuedStatement(state, textAfter) {
791
   function isContinuedStatement(state, textAfter) {
706
     return state.lastType == "operator" || state.lastType == "," ||
792
     return state.lastType == "operator" || state.lastType == "," ||
708
       /[,.]/.test(textAfter.charAt(0));
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
   // Interface
803
   // Interface
712
 
804
 
713
   return {
805
   return {
718
         cc: [],
810
         cc: [],
719
         lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
811
         lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
720
         localVars: parserConfig.localVars,
812
         localVars: parserConfig.localVars,
721
-        context: parserConfig.localVars && {vars: parserConfig.localVars},
813
+        context: parserConfig.localVars && new Context(null, null, false),
722
         indented: basecolumn || 0
814
         indented: basecolumn || 0
723
       };
815
       };
724
       if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
816
       if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
759
         lexical = lexical.prev;
851
         lexical = lexical.prev;
760
       var type = lexical.type, closing = firstChar == type;
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
       else if (type == "form" && firstChar == "{") return lexical.indented;
855
       else if (type == "form" && firstChar == "{") return lexical.indented;
764
       else if (type == "form") return lexical.indented + indentUnit;
856
       else if (type == "form") return lexical.indented + indentUnit;
765
       else if (type == "stat")
857
       else if (type == "stat")
773
     electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
865
     electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
774
     blockCommentStart: jsonMode ? null : "/*",
866
     blockCommentStart: jsonMode ? null : "/*",
775
     blockCommentEnd: jsonMode ? null : "*/",
867
     blockCommentEnd: jsonMode ? null : "*/",
868
+    blockCommentContinue: jsonMode ? null : " * ",
776
     lineComment: jsonMode ? null : "//",
869
     lineComment: jsonMode ? null : "//",
777
     fold: "brace",
870
     fold: "brace",
778
     closeBrackets: "()[]{}''\"\"``",
871
     closeBrackets: "()[]{}''\"\"``",
782
     jsonMode: jsonMode,
875
     jsonMode: jsonMode,
783
 
876
 
784
     expressionAllowed: expressionAllowed,
877
     expressionAllowed: expressionAllowed,
878
+
785
     skipExpression: function(state) {
879
     skipExpression: function(state) {
786
       var top = state.cc[state.cc.length - 1]
880
       var top = state.cc[state.cc.length - 1]
787
       if (top == expression || top == expressionNoComma) state.cc.pop()
881
       if (top == expression || top == expressionNoComma) state.cc.pop()

+ 2 - 2
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/php/php.js Näytä tiedosto

1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
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
 (function(mod) {
4
 (function(mod) {
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
151
   };
151
   };
152
 
152
 
153
   CodeMirror.defineMode("php", function(config, parserConfig) {
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
     var phpMode = CodeMirror.getMode(config, phpConfig);
155
     var phpMode = CodeMirror.getMode(config, phpConfig);
156
 
156
 
157
     function dispatch(stream, state) {
157
     function dispatch(stream, state) {

+ 1 - 1
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/powershell/powershell.js Näytä tiedosto

1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
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
 (function(mod) {
4
 (function(mod) {
5
   'use strict';
5
   'use strict';

+ 104 - 35
xxl-job-admin/src/main/resources/static/plugins/codemirror/mode/python/python.js Näytä tiedosto

1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
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
 (function(mod) {
4
 (function(mod) {
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
41
   CodeMirror.defineMode("python", function(conf, parserConf) {
41
   CodeMirror.defineMode("python", function(conf, parserConf) {
42
     var ERRORCLASS = "error";
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
     var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
50
     var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
50
 
51
 
58
     var py3 = !(parserConf.version && Number(parserConf.version) < 3)
59
     var py3 = !(parserConf.version && Number(parserConf.version) < 3)
59
     if (py3) {
60
     if (py3) {
60
       // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
61
       // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
61
-      var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@]/;
62
       var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
62
       var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
63
       myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
63
       myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
64
       myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
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
     } else {
66
     } else {
67
-      var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!]/;
68
       var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
67
       var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
69
       myKeywords = myKeywords.concat(["exec", "print"]);
68
       myKeywords = myKeywords.concat(["exec", "print"]);
70
       myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
69
       myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
77
 
76
 
78
     // tokenizers
77
     // tokenizers
79
     function tokenBase(stream, state) {
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
       // Handle scope changes
81
       // Handle scope changes
82
-      if (stream.sol() && top(state).type == "py") {
82
+      if (sol && top(state).type == "py") {
83
         var scopeOffset = top(state).offset;
83
         var scopeOffset = top(state).offset;
84
         if (stream.eatSpace()) {
84
         if (stream.eatSpace()) {
85
           var lineOffset = stream.indentation();
85
           var lineOffset = stream.indentation();
101
     function tokenBaseInner(stream, state) {
101
     function tokenBaseInner(stream, state) {
102
       if (stream.eatSpace()) return null;
102
       if (stream.eatSpace()) return null;
103
 
103
 
104
-      var ch = stream.peek();
105
-
106
       // Handle Comments
104
       // Handle Comments
107
-      if (ch == "#") {
108
-        stream.skipToEnd();
109
-        return "comment";
110
-      }
105
+      if (stream.match(/^#.*/)) return "comment";
111
 
106
 
112
       // Handle Number Literals
107
       // Handle Number Literals
113
       if (stream.match(/^[0-9\.]/, false)) {
108
       if (stream.match(/^[0-9\.]/, false)) {
147
 
142
 
148
       // Handle Strings
143
       // Handle Strings
149
       if (stream.match(stringPrefixes)) {
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
       if (state.lastToken == "." && stream.match(identifiers))
160
       if (state.lastToken == "." && stream.match(identifiers))
165
         return "property";
161
         return "property";
184
       return ERRORCLASS;
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
     function tokenStringFactory(delimiter) {
254
     function tokenStringFactory(delimiter) {
188
       while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
255
       while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
189
         delimiter = delimiter.substr(1);
256
         delimiter = delimiter.substr(1);
264
       if (current == ":" && !state.lambda && top(state).type == "py")
331
       if (current == ":" && !state.lambda && top(state).type == "py")
265
         pushPyScope(state);
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
       if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
345
       if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
277
         if (state.scopes.length > 1) state.scopes.pop();
346
         if (state.scopes.length > 1) state.scopes.pop();
332
 
401
 
333
   CodeMirror.defineMIME("text/x-cython", {
402
   CodeMirror.defineMIME("text/x-cython", {
334
     name: "python",
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
                           "readonly struct union DEF IF ELIF ELSE")
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 Näytä tiedosto

1
 // CodeMirror, copyright (c) by Marijn Haverbeke and others
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
 (function(mod) {
4
 (function(mod) {
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
5
   if (typeof exports == "object" && typeof module == "object") // CommonJS
14
 CodeMirror.defineMode('shell', function() {
14
 CodeMirror.defineMode('shell', function() {
15
 
15
 
16
   var words = {};
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
   function tokenBase(stream, state) {
39
   function tokenBase(stream, state) {
39
     if (stream.eatSpace()) return null;
40
     if (stream.eatSpace()) return null;
84
   function tokenString(quote, style) {
85
   function tokenString(quote, style) {
85
     var close = quote == "(" ? ")" : quote == "{" ? "}" : quote
86
     var close = quote == "(" ? ")" : quote == "{" ? "}" : quote
86
     return function(stream, state) {
87
     return function(stream, state) {
87
-      var next, end = false, escaped = false;
88
+      var next, escaped = false;
88
       while ((next = stream.next()) != null) {
89
       while ((next = stream.next()) != null) {
89
         if (next === close && !escaped) {
90
         if (next === close && !escaped) {
90
-          end = true;
91
+          state.tokens.shift();
91
           break;
92
           break;
92
-        }
93
-        if (next === '$' && !escaped && quote !== "'") {
93
+        } else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) {
94
           escaped = true;
94
           escaped = true;
95
           stream.backUp(1);
95
           stream.backUp(1);
96
           state.tokens.unshift(tokenDollar);
96
           state.tokens.unshift(tokenDollar);
97
           break;
97
           break;
98
-        }
99
-        if (!escaped && next === quote && quote !== close) {
98
+        } else if (!escaped && quote !== close && next === quote) {
100
           state.tokens.unshift(tokenString(quote, style))
99
           state.tokens.unshift(tokenString(quote, style))
101
           return tokenize(stream, state)
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
         escaped = !escaped && next === '\\';
106
         escaped = !escaped && next === '\\';
104
       }
107
       }
105
-      if (end || !escaped) state.tokens.shift();
106
       return style;
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
   var tokenDollar = function(stream, state) {
120
   var tokenDollar = function(stream, state) {
111
     if (state.tokens.length > 1) stream.eat('$');
121
     if (state.tokens.length > 1) stream.eat('$');
112
     var ch = stream.next()
122
     var ch = stream.next()
135
 });
145
 });
136
 
146
 
137
 CodeMirror.defineMIME('text/x-sh', 'shell');
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