blazer 3.4.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +23 -27
  4. data/app/assets/javascripts/blazer/Sortable.js +826 -1162
  5. data/app/assets/javascripts/blazer/ace/ace.js +15775 -13360
  6. data/app/assets/javascripts/blazer/ace/ext-language_tools.js +1411 -668
  7. data/app/assets/javascripts/blazer/ace/mode-sql.js +12 -6
  8. data/app/assets/javascripts/blazer/ace/theme-twilight.js +3 -3
  9. data/app/assets/javascripts/blazer/application.js +94 -52
  10. data/app/assets/javascripts/blazer/chart.umd.js +6 -6
  11. data/app/assets/javascripts/blazer/daterangepicker.js +193 -199
  12. data/app/assets/javascripts/blazer/highlight.min.js +235 -373
  13. data/app/assets/javascripts/blazer/moment-timezone-with-data.js +116 -82
  14. data/app/assets/javascripts/blazer/moment.js +368 -365
  15. data/app/assets/javascripts/blazer/queries.js +68 -58
  16. data/app/assets/javascripts/blazer/routes.js +11 -11
  17. data/app/assets/javascripts/blazer/tablesort.js +42 -0
  18. data/app/assets/javascripts/blazer/tom-select.base.js +4175 -0
  19. data/app/assets/stylesheets/blazer/application.css +114 -5
  20. data/app/assets/stylesheets/blazer/tom-select.css +502 -0
  21. data/app/controllers/blazer/base_controller.rb +1 -1
  22. data/app/controllers/blazer/checks_controller.rb +5 -2
  23. data/app/controllers/blazer/queries_controller.rb +3 -1
  24. data/app/helpers/blazer/base_helper.rb +1 -1
  25. data/app/models/blazer/check.rb +35 -57
  26. data/app/views/blazer/_nav.html.erb +1 -1
  27. data/app/views/blazer/_variables.html.erb +57 -42
  28. data/app/views/blazer/checks/_form.html.erb +20 -16
  29. data/app/views/blazer/checks/index.html.erb +17 -20
  30. data/app/views/blazer/dashboards/_form.html.erb +63 -48
  31. data/app/views/blazer/dashboards/show.html.erb +23 -16
  32. data/app/views/blazer/queries/_caching.html.erb +1 -1
  33. data/app/views/blazer/queries/_chart.html.erb +8 -0
  34. data/app/views/blazer/queries/_form.html.erb +153 -180
  35. data/app/views/blazer/queries/_map.html.erb +8 -0
  36. data/app/views/blazer/queries/docs.html.erb +6 -6
  37. data/app/views/blazer/queries/edit.html.erb +1 -0
  38. data/app/views/blazer/queries/home.html.erb +101 -102
  39. data/app/views/blazer/queries/new.html.erb +1 -0
  40. data/app/views/blazer/queries/run.html.erb +23 -34
  41. data/app/views/blazer/queries/schema.html.erb +20 -20
  42. data/app/views/blazer/queries/show.html.erb +19 -12
  43. data/app/views/blazer/uploads/index.html.erb +10 -10
  44. data/app/views/layouts/blazer/application.html.erb +3 -3
  45. data/lib/blazer/adapters/athena_adapter.rb +12 -6
  46. data/lib/blazer/adapters/clickhouse_adapter.rb +136 -0
  47. data/lib/blazer/adapters/druid_adapter.rb +0 -2
  48. data/lib/blazer/adapters/snowflake2_adapter.rb +198 -0
  49. data/lib/blazer/adapters/soda_adapter.rb +0 -2
  50. data/lib/blazer/adapters/sql_adapter.rb +4 -0
  51. data/lib/blazer/adapters.rb +2 -0
  52. data/lib/blazer/check_types.rb +20 -0
  53. data/lib/blazer/email_notifier.rb +49 -0
  54. data/lib/blazer/result.rb +15 -0
  55. data/lib/blazer/slack_notifier.rb +39 -7
  56. data/lib/blazer/version.rb +1 -1
  57. data/lib/blazer.rb +32 -26
  58. data/lib/generators/blazer/templates/config.yml.tt +0 -2
  59. data/licenses/LICENSE-chart.js.txt +1 -1
  60. metadata +12 -31
  61. data/app/assets/javascripts/blazer/bootstrap.js +0 -2580
  62. data/app/assets/javascripts/blazer/jquery.js +0 -10872
  63. data/app/assets/javascripts/blazer/jquery.stickytableheaders.js +0 -325
  64. data/app/assets/javascripts/blazer/rails-ujs.js +0 -746
  65. data/app/assets/javascripts/blazer/selectize.js +0 -3891
  66. data/app/assets/javascripts/blazer/stupidtable-custom-settings.js +0 -13
  67. data/app/assets/javascripts/blazer/stupidtable.js +0 -281
  68. data/app/assets/javascripts/blazer/vue.global.prod.js +0 -1
  69. data/app/assets/stylesheets/blazer/selectize.css +0 -403
  70. data/licenses/LICENSE-jquery.txt +0 -20
  71. data/licenses/LICENSE-rails-ujs.txt +0 -20
  72. data/licenses/LICENSE-stickytableheaders.txt +0 -20
  73. data/licenses/LICENSE-stupidtable.txt +0 -19
  74. data/licenses/LICENSE-vue.txt +0 -21
  75. /data/licenses/{LICENSE-selectize.txt → LICENSE-tom-select.txt} +0 -0
@@ -80,16 +80,16 @@ function date(dateFormat) {
80
80
  var str = new Date().toLocaleString("en-us", dateFormat);
81
81
  return str.length == 1 ? "0" + str : str;
82
82
  }
83
- var SnippetManager = function () {
84
- this.snippetMap = {};
85
- this.snippetNameMap = {};
86
- };
87
- (function () {
88
- oop.implement(this, EventEmitter);
89
- this.getTokenizer = function () {
90
- return SnippetManager.$tokenizer || this.createTokenizer();
83
+ var SnippetManager = /** @class */ (function () {
84
+ function SnippetManager() {
85
+ this.snippetMap = {};
86
+ this.snippetNameMap = {};
87
+ this.variables = VARIABLES;
88
+ }
89
+ SnippetManager.prototype.getTokenizer = function () {
90
+ return SnippetManager["$tokenizer"] || this.createTokenizer();
91
91
  };
92
- this.createTokenizer = function () {
92
+ SnippetManager.prototype.createTokenizer = function () {
93
93
  function TabstopToken(str) {
94
94
  str = str.substr(1);
95
95
  if (/^\d+$/.test(str))
@@ -110,7 +110,7 @@ var SnippetManager = function () {
110
110
  },
111
111
  next: "formatString"
112
112
  };
113
- SnippetManager.$tokenizer = new Tokenizer({
113
+ SnippetManager["$tokenizer"] = new Tokenizer({
114
114
  start: [
115
115
  { regex: /\\./, onMatch: function (val, state, stack) {
116
116
  var ch = val[1];
@@ -207,14 +207,14 @@ var SnippetManager = function () {
207
207
  { regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "formatString" }
208
208
  ]
209
209
  });
210
- return SnippetManager.$tokenizer;
210
+ return SnippetManager["$tokenizer"];
211
211
  };
212
- this.tokenizeTmSnippet = function (str, startState) {
212
+ SnippetManager.prototype.tokenizeTmSnippet = function (str, startState) {
213
213
  return this.getTokenizer().getLineTokens(str, startState).tokens.map(function (x) {
214
214
  return x.value || x;
215
215
  });
216
216
  };
217
- this.getVariableValue = function (editor, name, indentation) {
217
+ SnippetManager.prototype.getVariableValue = function (editor, name, indentation) {
218
218
  if (/^\d+$/.test(name))
219
219
  return (this.variables.__ || {})[name] || "";
220
220
  if (/^[A-Z]\d+$/.test(name))
@@ -227,8 +227,7 @@ var SnippetManager = function () {
227
227
  value = this.variables[name](editor, name, indentation);
228
228
  return value == null ? "" : value;
229
229
  };
230
- this.variables = VARIABLES;
231
- this.tmStrFormat = function (str, ch, editor) {
230
+ SnippetManager.prototype.tmStrFormat = function (str, ch, editor) {
232
231
  if (!ch.fmt)
233
232
  return str;
234
233
  var flag = ch.flag || "";
@@ -271,14 +270,14 @@ var SnippetManager = function () {
271
270
  });
272
271
  return formatted;
273
272
  };
274
- this.tmFormatFunction = function (str, ch, editor) {
273
+ SnippetManager.prototype.tmFormatFunction = function (str, ch, editor) {
275
274
  if (ch.formatFunction == "upcase")
276
275
  return str.toUpperCase();
277
276
  if (ch.formatFunction == "downcase")
278
277
  return str.toLowerCase();
279
278
  return str;
280
279
  };
281
- this.resolveVariables = function (snippet, editor) {
280
+ SnippetManager.prototype.resolveVariables = function (snippet, editor) {
282
281
  var result = [];
283
282
  var indentation = "";
284
283
  var afterNewLine = true;
@@ -337,131 +336,31 @@ var SnippetManager = function () {
337
336
  }
338
337
  return result;
339
338
  };
340
- this.insertSnippetForSelection = function (editor, snippetText) {
341
- var cursor = editor.getCursorPosition();
342
- var line = editor.session.getLine(cursor.row);
343
- var tabString = editor.session.getTabString();
344
- var indentString = line.match(/^\s*/)[0];
345
- if (cursor.column < indentString.length)
346
- indentString = indentString.slice(0, cursor.column);
347
- snippetText = snippetText.replace(/\r/g, "");
348
- var tokens = this.tokenizeTmSnippet(snippetText);
349
- tokens = this.resolveVariables(tokens, editor);
350
- tokens = tokens.map(function (x) {
351
- if (x == "\n")
352
- return x + indentString;
353
- if (typeof x == "string")
354
- return x.replace(/\t/g, tabString);
355
- return x;
356
- });
357
- var tabstops = [];
358
- tokens.forEach(function (p, i) {
359
- if (typeof p != "object")
360
- return;
361
- var id = p.tabstopId;
362
- var ts = tabstops[id];
363
- if (!ts) {
364
- ts = tabstops[id] = [];
365
- ts.index = id;
366
- ts.value = "";
367
- ts.parents = {};
368
- }
369
- if (ts.indexOf(p) !== -1)
370
- return;
371
- if (p.choices && !ts.choices)
372
- ts.choices = p.choices;
373
- ts.push(p);
374
- var i1 = tokens.indexOf(p, i + 1);
375
- if (i1 === -1)
376
- return;
377
- var value = tokens.slice(i + 1, i1);
378
- var isNested = value.some(function (t) { return typeof t === "object"; });
379
- if (isNested && !ts.value) {
380
- ts.value = value;
381
- }
382
- else if (value.length && (!ts.value || typeof ts.value !== "string")) {
383
- ts.value = value.join("");
384
- }
385
- });
386
- tabstops.forEach(function (ts) { ts.length = 0; });
387
- var expanding = {};
388
- function copyValue(val) {
389
- var copy = [];
390
- for (var i = 0; i < val.length; i++) {
391
- var p = val[i];
392
- if (typeof p == "object") {
393
- if (expanding[p.tabstopId])
394
- continue;
395
- var j = val.lastIndexOf(p, i - 1);
396
- p = copy[j] || { tabstopId: p.tabstopId };
397
- }
398
- copy[i] = p;
399
- }
400
- return copy;
401
- }
402
- for (var i = 0; i < tokens.length; i++) {
403
- var p = tokens[i];
404
- if (typeof p != "object")
405
- continue;
406
- var id = p.tabstopId;
407
- var ts = tabstops[id];
408
- var i1 = tokens.indexOf(p, i + 1);
409
- if (expanding[id]) {
410
- if (expanding[id] === p) {
411
- delete expanding[id];
412
- Object.keys(expanding).forEach(function (parentId) {
413
- ts.parents[parentId] = true;
414
- });
415
- }
416
- continue;
417
- }
418
- expanding[id] = p;
419
- var value = ts.value;
420
- if (typeof value !== "string")
421
- value = copyValue(value);
422
- else if (p.fmt)
423
- value = this.tmStrFormat(value, p, editor);
424
- tokens.splice.apply(tokens, [i + 1, Math.max(0, i1 - i)].concat(value, p));
425
- if (ts.indexOf(p) === -1)
426
- ts.push(p);
427
- }
428
- var row = 0, column = 0;
429
- var text = "";
430
- tokens.forEach(function (t) {
431
- if (typeof t === "string") {
432
- var lines = t.split("\n");
433
- if (lines.length > 1) {
434
- column = lines[lines.length - 1].length;
435
- row += lines.length - 1;
436
- }
437
- else
438
- column += t.length;
439
- text += t;
440
- }
441
- else if (t) {
442
- if (!t.start)
443
- t.start = { row: row, column: column };
444
- else
445
- t.end = { row: row, column: column };
446
- }
447
- });
339
+ SnippetManager.prototype.getDisplayTextForSnippet = function (editor, snippetText) {
340
+ var processedSnippet = processSnippetText.call(this, editor, snippetText);
341
+ return processedSnippet.text;
342
+ };
343
+ SnippetManager.prototype.insertSnippetForSelection = function (editor, snippetText, options) {
344
+ if (options === void 0) { options = {}; }
345
+ var processedSnippet = processSnippetText.call(this, editor, snippetText, options);
448
346
  var range = editor.getSelectionRange();
449
- var end = editor.session.replace(range, text);
347
+ var end = editor.session.replace(range, processedSnippet.text);
450
348
  var tabstopManager = new TabstopManager(editor);
451
349
  var selectionId = editor.inVirtualSelectionMode && editor.selection.index;
452
- tabstopManager.addTabstops(tabstops, range.start, end, selectionId);
350
+ tabstopManager.addTabstops(processedSnippet.tabstops, range.start, end, selectionId);
453
351
  };
454
- this.insertSnippet = function (editor, snippetText) {
352
+ SnippetManager.prototype.insertSnippet = function (editor, snippetText, options) {
353
+ if (options === void 0) { options = {}; }
455
354
  var self = this;
456
355
  if (editor.inVirtualSelectionMode)
457
- return self.insertSnippetForSelection(editor, snippetText);
356
+ return self.insertSnippetForSelection(editor, snippetText, options);
458
357
  editor.forEachSelection(function () {
459
- self.insertSnippetForSelection(editor, snippetText);
358
+ self.insertSnippetForSelection(editor, snippetText, options);
460
359
  }, null, { keepOrder: true });
461
360
  if (editor.tabstopManager)
462
361
  editor.tabstopManager.tabNext();
463
362
  };
464
- this.$getScope = function (editor) {
363
+ SnippetManager.prototype.$getScope = function (editor) {
465
364
  var scope = editor.session.$mode.$id || "";
466
365
  scope = scope.split("/").pop();
467
366
  if (scope === "html" || scope === "php") {
@@ -483,7 +382,7 @@ var SnippetManager = function () {
483
382
  }
484
383
  return scope;
485
384
  };
486
- this.getActiveScopes = function (editor) {
385
+ SnippetManager.prototype.getActiveScopes = function (editor) {
487
386
  var scope = this.$getScope(editor);
488
387
  var scopes = [scope];
489
388
  var snippetMap = this.snippetMap;
@@ -493,7 +392,7 @@ var SnippetManager = function () {
493
392
  scopes.push("_");
494
393
  return scopes;
495
394
  };
496
- this.expandWithTab = function (editor, options) {
395
+ SnippetManager.prototype.expandWithTab = function (editor, options) {
497
396
  var self = this;
498
397
  var result = editor.forEachSelection(function () {
499
398
  return self.expandSnippetForSelection(editor, options);
@@ -502,7 +401,7 @@ var SnippetManager = function () {
502
401
  editor.tabstopManager.tabNext();
503
402
  return result;
504
403
  };
505
- this.expandSnippetForSelection = function (editor, options) {
404
+ SnippetManager.prototype.expandSnippetForSelection = function (editor, options) {
506
405
  var cursor = editor.getCursorPosition();
507
406
  var line = editor.session.getLine(cursor.row);
508
407
  var before = line.substring(0, cursor.column);
@@ -526,7 +425,7 @@ var SnippetManager = function () {
526
425
  this.variables.M__ = this.variables.T__ = null;
527
426
  return true;
528
427
  };
529
- this.findMatchingSnippet = function (snippetList, before, after) {
428
+ SnippetManager.prototype.findMatchingSnippet = function (snippetList, before, after) {
530
429
  for (var i = snippetList.length; i--;) {
531
430
  var s = snippetList[i];
532
431
  if (s.startRe && !s.startRe.test(before))
@@ -542,9 +441,7 @@ var SnippetManager = function () {
542
441
  return s;
543
442
  }
544
443
  };
545
- this.snippetMap = {};
546
- this.snippetNameMap = {};
547
- this.register = function (snippets, scope) {
444
+ SnippetManager.prototype.register = function (snippets, scope) {
548
445
  var snippetMap = this.snippetMap;
549
446
  var snippetNameMap = this.snippetNameMap;
550
447
  var self = this;
@@ -612,7 +509,7 @@ var SnippetManager = function () {
612
509
  }
613
510
  this._signal("registerSnippets", { scope: scope });
614
511
  };
615
- this.unregister = function (snippets, scope) {
512
+ SnippetManager.prototype.unregister = function (snippets, scope) {
616
513
  var snippetMap = this.snippetMap;
617
514
  var snippetNameMap = this.snippetNameMap;
618
515
  function removeSnippet(s) {
@@ -630,9 +527,9 @@ var SnippetManager = function () {
630
527
  else if (Array.isArray(snippets))
631
528
  snippets.forEach(removeSnippet);
632
529
  };
633
- this.parseSnippetFile = function (str) {
530
+ SnippetManager.prototype.parseSnippetFile = function (str) {
634
531
  str = str.replace(/\r/g, "");
635
- var list = [], snippet = {};
532
+ var list = [], /**@type{Snippet}*/ snippet = {};
636
533
  var re = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm;
637
534
  var m;
638
535
  while (m = re.exec(str)) {
@@ -669,7 +566,7 @@ var SnippetManager = function () {
669
566
  }
670
567
  return list;
671
568
  };
672
- this.getSnippetByName = function (name, editor) {
569
+ SnippetManager.prototype.getSnippetByName = function (name, editor) {
673
570
  var snippetMap = this.snippetNameMap;
674
571
  var snippet;
675
572
  this.getActiveScopes(editor).some(function (scope) {
@@ -680,49 +577,168 @@ var SnippetManager = function () {
680
577
  }, this);
681
578
  return snippet;
682
579
  };
683
- }).call(SnippetManager.prototype);
684
- var TabstopManager = function (editor) {
685
- if (editor.tabstopManager)
686
- return editor.tabstopManager;
687
- editor.tabstopManager = this;
688
- this.$onChange = this.onChange.bind(this);
689
- this.$onChangeSelection = lang.delayedCall(this.onChangeSelection.bind(this)).schedule;
690
- this.$onChangeSession = this.onChangeSession.bind(this);
691
- this.$onAfterExec = this.onAfterExec.bind(this);
692
- this.attach(editor);
580
+ return SnippetManager;
581
+ }());
582
+ oop.implement(SnippetManager.prototype, EventEmitter);
583
+ var processSnippetText = function (editor, snippetText, options) {
584
+ if (options === void 0) { options = {}; }
585
+ var cursor = editor.getCursorPosition();
586
+ var line = editor.session.getLine(cursor.row);
587
+ var tabString = editor.session.getTabString();
588
+ var indentString = line.match(/^\s*/)[0];
589
+ if (cursor.column < indentString.length)
590
+ indentString = indentString.slice(0, cursor.column);
591
+ snippetText = snippetText.replace(/\r/g, "");
592
+ var tokens = this.tokenizeTmSnippet(snippetText);
593
+ tokens = this.resolveVariables(tokens, editor);
594
+ tokens = tokens.map(function (x) {
595
+ if (x == "\n" && !options.excludeExtraIndent)
596
+ return x + indentString;
597
+ if (typeof x == "string")
598
+ return x.replace(/\t/g, tabString);
599
+ return x;
600
+ });
601
+ var tabstops = [];
602
+ tokens.forEach(function (p, i) {
603
+ if (typeof p != "object")
604
+ return;
605
+ var id = p.tabstopId;
606
+ var ts = tabstops[id];
607
+ if (!ts) {
608
+ ts = tabstops[id] = [];
609
+ ts.index = id;
610
+ ts.value = "";
611
+ ts.parents = {};
612
+ }
613
+ if (ts.indexOf(p) !== -1)
614
+ return;
615
+ if (p.choices && !ts.choices)
616
+ ts.choices = p.choices;
617
+ ts.push(p);
618
+ var i1 = tokens.indexOf(p, i + 1);
619
+ if (i1 === -1)
620
+ return;
621
+ var value = tokens.slice(i + 1, i1);
622
+ var isNested = value.some(function (t) { return typeof t === "object"; });
623
+ if (isNested && !ts.value) {
624
+ ts.value = value;
625
+ }
626
+ else if (value.length && (!ts.value || typeof ts.value !== "string")) {
627
+ ts.value = value.join("");
628
+ }
629
+ });
630
+ tabstops.forEach(function (ts) { ts.length = 0; });
631
+ var expanding = {};
632
+ function copyValue(val) {
633
+ var copy = [];
634
+ for (var i = 0; i < val.length; i++) {
635
+ var p = val[i];
636
+ if (typeof p == "object") {
637
+ if (expanding[p.tabstopId])
638
+ continue;
639
+ var j = val.lastIndexOf(p, i - 1);
640
+ p = copy[j] || { tabstopId: p.tabstopId };
641
+ }
642
+ copy[i] = p;
643
+ }
644
+ return copy;
645
+ }
646
+ for (var i = 0; i < tokens.length; i++) {
647
+ var p = tokens[i];
648
+ if (typeof p != "object")
649
+ continue;
650
+ var id = p.tabstopId;
651
+ var ts = tabstops[id];
652
+ var i1 = tokens.indexOf(p, i + 1);
653
+ if (expanding[id]) {
654
+ if (expanding[id] === p) {
655
+ delete expanding[id];
656
+ Object.keys(expanding).forEach(function (parentId) {
657
+ ts.parents[parentId] = true;
658
+ });
659
+ }
660
+ continue;
661
+ }
662
+ expanding[id] = p;
663
+ var value = ts.value;
664
+ if (typeof value !== "string")
665
+ value = copyValue(value);
666
+ else if (p.fmt)
667
+ value = this.tmStrFormat(value, p, editor);
668
+ tokens.splice.apply(tokens, [i + 1, Math.max(0, i1 - i)].concat(value, p));
669
+ if (ts.indexOf(p) === -1)
670
+ ts.push(p);
671
+ }
672
+ var row = 0, column = 0;
673
+ var text = "";
674
+ tokens.forEach(function (t) {
675
+ if (typeof t === "string") {
676
+ var lines = t.split("\n");
677
+ if (lines.length > 1) {
678
+ column = lines[lines.length - 1].length;
679
+ row += lines.length - 1;
680
+ }
681
+ else
682
+ column += t.length;
683
+ text += t;
684
+ }
685
+ else if (t) {
686
+ if (!t.start)
687
+ t.start = { row: row, column: column };
688
+ else
689
+ t.end = { row: row, column: column };
690
+ }
691
+ });
692
+ return {
693
+ text: text,
694
+ tabstops: tabstops,
695
+ tokens: tokens
696
+ };
693
697
  };
694
- (function () {
695
- this.attach = function (editor) {
698
+ var TabstopManager = /** @class */ (function () {
699
+ function TabstopManager(editor) {
696
700
  this.index = 0;
697
701
  this.ranges = [];
698
702
  this.tabstops = [];
703
+ if (editor.tabstopManager)
704
+ return editor.tabstopManager;
705
+ editor.tabstopManager = this;
706
+ this.$onChange = this.onChange.bind(this);
707
+ this.$onChangeSelection = lang.delayedCall(this.onChangeSelection.bind(this)).schedule;
708
+ this.$onChangeSession = this.onChangeSession.bind(this);
709
+ this.$onAfterExec = this.onAfterExec.bind(this);
710
+ this.attach(editor);
711
+ }
712
+ TabstopManager.prototype.attach = function (editor) {
699
713
  this.$openTabstops = null;
700
714
  this.selectedTabstop = null;
701
715
  this.editor = editor;
716
+ this.session = editor.session;
702
717
  this.editor.on("change", this.$onChange);
703
718
  this.editor.on("changeSelection", this.$onChangeSelection);
704
719
  this.editor.on("changeSession", this.$onChangeSession);
705
720
  this.editor.commands.on("afterExec", this.$onAfterExec);
706
721
  this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
707
722
  };
708
- this.detach = function () {
723
+ TabstopManager.prototype.detach = function () {
709
724
  this.tabstops.forEach(this.removeTabstopMarkers, this);
710
- this.ranges = null;
711
- this.tabstops = null;
725
+ this.ranges.length = 0;
726
+ this.tabstops.length = 0;
712
727
  this.selectedTabstop = null;
713
- this.editor.removeListener("change", this.$onChange);
714
- this.editor.removeListener("changeSelection", this.$onChangeSelection);
715
- this.editor.removeListener("changeSession", this.$onChangeSession);
716
- this.editor.commands.removeListener("afterExec", this.$onAfterExec);
728
+ this.editor.off("change", this.$onChange);
729
+ this.editor.off("changeSelection", this.$onChangeSelection);
730
+ this.editor.off("changeSession", this.$onChangeSession);
731
+ this.editor.commands.off("afterExec", this.$onAfterExec);
717
732
  this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
718
733
  this.editor.tabstopManager = null;
734
+ this.session = null;
719
735
  this.editor = null;
720
736
  };
721
- this.onChange = function (delta) {
737
+ TabstopManager.prototype.onChange = function (delta) {
722
738
  var isRemove = delta.action[0] == "r";
723
739
  var selectedTabstop = this.selectedTabstop || {};
724
740
  var parents = selectedTabstop.parents || {};
725
- var tabstops = (this.tabstops || []).slice();
741
+ var tabstops = this.tabstops.slice();
726
742
  for (var i = 0; i < tabstops.length; i++) {
727
743
  var ts = tabstops[i];
728
744
  var active = ts == selectedTabstop || parents[ts.index];
@@ -739,16 +755,16 @@ var TabstopManager = function (editor) {
739
755
  }
740
756
  ts.rangeList.$onChange(delta);
741
757
  }
742
- var session = this.editor.session;
758
+ var session = this.session;
743
759
  if (!this.$inChange && isRemove && session.getLength() == 1 && !session.getValue())
744
760
  this.detach();
745
761
  };
746
- this.updateLinkedFields = function () {
762
+ TabstopManager.prototype.updateLinkedFields = function () {
747
763
  var ts = this.selectedTabstop;
748
764
  if (!ts || !ts.hasLinkedRanges || !ts.firstNonLinked)
749
765
  return;
750
766
  this.$inChange = true;
751
- var session = this.editor.session;
767
+ var session = this.session;
752
768
  var text = session.getTextRange(ts.firstNonLinked);
753
769
  for (var i = 0; i < ts.length; i++) {
754
770
  var range = ts[i];
@@ -760,11 +776,11 @@ var TabstopManager = function (editor) {
760
776
  }
761
777
  this.$inChange = false;
762
778
  };
763
- this.onAfterExec = function (e) {
779
+ TabstopManager.prototype.onAfterExec = function (e) {
764
780
  if (e.command && !e.command.readOnly)
765
781
  this.updateLinkedFields();
766
782
  };
767
- this.onChangeSelection = function () {
783
+ TabstopManager.prototype.onChangeSelection = function () {
768
784
  if (!this.editor)
769
785
  return;
770
786
  var lead = this.editor.selection.lead;
@@ -780,20 +796,22 @@ var TabstopManager = function (editor) {
780
796
  }
781
797
  this.detach();
782
798
  };
783
- this.onChangeSession = function () {
799
+ TabstopManager.prototype.onChangeSession = function () {
784
800
  this.detach();
785
801
  };
786
- this.tabNext = function (dir) {
802
+ TabstopManager.prototype.tabNext = function (dir) {
787
803
  var max = this.tabstops.length;
788
804
  var index = this.index + (dir || 1);
789
805
  index = Math.min(Math.max(index, 1), max);
790
806
  if (index == max)
791
807
  index = 0;
792
808
  this.selectTabstop(index);
793
- if (index === 0)
809
+ this.updateTabstopMarkers();
810
+ if (index === 0) {
794
811
  this.detach();
812
+ }
795
813
  };
796
- this.selectTabstop = function (index) {
814
+ TabstopManager.prototype.selectTabstop = function (index) {
797
815
  this.$openTabstops = null;
798
816
  var ts = this.tabstops[this.index];
799
817
  if (ts)
@@ -822,7 +840,7 @@ var TabstopManager = function (editor) {
822
840
  if (this.selectedTabstop && this.selectedTabstop.choices)
823
841
  this.editor.execCommand("startAutocomplete", { matches: this.selectedTabstop.choices });
824
842
  };
825
- this.addTabstops = function (tabstops, start, end) {
843
+ TabstopManager.prototype.addTabstops = function (tabstops, start, end) {
826
844
  var useLink = this.useLink || !this.editor.getOption("enableMultiselect");
827
845
  if (!this.$openTabstops)
828
846
  this.$openTabstops = [];
@@ -836,8 +854,10 @@ var TabstopManager = function (editor) {
836
854
  var i = this.index;
837
855
  var arg = [i + 1, 0];
838
856
  var ranges = this.ranges;
857
+ var snippetId = this.snippetId = (this.snippetId || 0) + 1;
839
858
  tabstops.forEach(function (ts, index) {
840
859
  var dest = this.$openTabstops[index] || ts;
860
+ dest.snippetId = snippetId;
841
861
  for (var i = 0; i < ts.length; i++) {
842
862
  var p = ts[i];
843
863
  var range = Range.fromPoints(p.start, p.end || p.start);
@@ -874,21 +894,35 @@ var TabstopManager = function (editor) {
874
894
  this.tabstops.splice.apply(this.tabstops, arg);
875
895
  }
876
896
  };
877
- this.addTabstopMarkers = function (ts) {
878
- var session = this.editor.session;
897
+ TabstopManager.prototype.addTabstopMarkers = function (ts) {
898
+ var session = this.session;
879
899
  ts.forEach(function (range) {
880
900
  if (!range.markerId)
881
901
  range.markerId = session.addMarker(range, "ace_snippet-marker", "text");
882
902
  });
883
903
  };
884
- this.removeTabstopMarkers = function (ts) {
885
- var session = this.editor.session;
904
+ TabstopManager.prototype.removeTabstopMarkers = function (ts) {
905
+ var session = this.session;
886
906
  ts.forEach(function (range) {
887
907
  session.removeMarker(range.markerId);
888
908
  range.markerId = null;
889
909
  });
890
910
  };
891
- this.removeRange = function (range) {
911
+ TabstopManager.prototype.updateTabstopMarkers = function () {
912
+ if (!this.selectedTabstop)
913
+ return;
914
+ var currentSnippetId = this.selectedTabstop.snippetId;
915
+ if (this.selectedTabstop.index === 0) {
916
+ currentSnippetId--;
917
+ }
918
+ this.tabstops.forEach(function (ts) {
919
+ if (ts.snippetId === currentSnippetId)
920
+ this.addTabstopMarkers(ts);
921
+ else
922
+ this.removeTabstopMarkers(ts);
923
+ }, this);
924
+ };
925
+ TabstopManager.prototype.removeRange = function (range) {
892
926
  var i = range.tabstop.indexOf(range);
893
927
  if (i != -1)
894
928
  range.tabstop.splice(i, 1);
@@ -898,7 +932,7 @@ var TabstopManager = function (editor) {
898
932
  i = range.tabstop.rangeList.ranges.indexOf(range);
899
933
  if (i != -1)
900
934
  range.tabstop.splice(i, 1);
901
- this.editor.session.removeMarker(range.markerId);
935
+ this.session.removeMarker(range.markerId);
902
936
  if (!range.tabstop.length) {
903
937
  i = this.tabstops.indexOf(range.tabstop);
904
938
  if (i != -1)
@@ -907,23 +941,24 @@ var TabstopManager = function (editor) {
907
941
  this.detach();
908
942
  }
909
943
  };
910
- this.keyboardHandler = new HashHandler();
911
- this.keyboardHandler.bindKeys({
912
- "Tab": function (editor) {
913
- if (exports.snippetManager && exports.snippetManager.expandWithTab(editor))
914
- return;
915
- editor.tabstopManager.tabNext(1);
916
- editor.renderer.scrollCursorIntoView();
917
- },
918
- "Shift-Tab": function (editor) {
919
- editor.tabstopManager.tabNext(-1);
920
- editor.renderer.scrollCursorIntoView();
921
- },
922
- "Esc": function (editor) {
923
- editor.tabstopManager.detach();
924
- }
925
- });
926
- }).call(TabstopManager.prototype);
944
+ return TabstopManager;
945
+ }());
946
+ TabstopManager.prototype.keyboardHandler = new HashHandler();
947
+ TabstopManager.prototype.keyboardHandler.bindKeys({
948
+ "Tab": function (editor) {
949
+ if (exports.snippetManager && exports.snippetManager.expandWithTab(editor))
950
+ return;
951
+ editor.tabstopManager.tabNext(1);
952
+ editor.renderer.scrollCursorIntoView();
953
+ },
954
+ "Shift-Tab": function (editor) {
955
+ editor.tabstopManager.tabNext(-1);
956
+ editor.renderer.scrollCursorIntoView();
957
+ },
958
+ "Esc": function (editor) {
959
+ editor.tabstopManager.detach();
960
+ }
961
+ });
927
962
  var movePoint = function (point, diff) {
928
963
  if (point.row == 0)
929
964
  point.column += diff.column;
@@ -948,16 +983,21 @@ var Editor = require("./editor").Editor;
948
983
 
949
984
  });
950
985
 
951
- define("ace/autocomplete/popup",["require","exports","module","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom"], function(require, exports, module){"use strict";
986
+ define("ace/autocomplete/popup",["require","exports","module","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom","ace/config","ace/lib/useragent"], function(require, exports, module){"use strict";
952
987
  var Renderer = require("../virtual_renderer").VirtualRenderer;
953
988
  var Editor = require("../editor").Editor;
954
989
  var Range = require("../range").Range;
955
990
  var event = require("../lib/event");
956
991
  var lang = require("../lib/lang");
957
992
  var dom = require("../lib/dom");
993
+ var nls = require("../config").nls;
994
+ var userAgent = require("./../lib/useragent");
958
995
  var getAriaId = function (index) {
959
996
  return "suggest-aria-id:".concat(index);
960
997
  };
998
+ var popupAriaRole = userAgent.isSafari ? "menu" : "listbox";
999
+ var optionAriaRole = userAgent.isSafari ? "menuitem" : "option";
1000
+ var ariaActiveState = userAgent.isSafari ? "aria-current" : "aria-selected";
961
1001
  var $singleLineEditor = function (el) {
962
1002
  var renderer = new Renderer(el);
963
1003
  renderer.$maxLines = 4;
@@ -970,259 +1010,455 @@ var $singleLineEditor = function (el) {
970
1010
  editor.$highlightTagPending = true;
971
1011
  return editor;
972
1012
  };
973
- var AcePopup = function (parentNode) {
974
- var el = dom.createElement("div");
975
- var popup = new $singleLineEditor(el);
976
- if (parentNode)
977
- parentNode.appendChild(el);
978
- el.style.display = "none";
979
- popup.renderer.content.style.cursor = "default";
980
- popup.renderer.setStyle("ace_autocomplete");
981
- popup.renderer.container.setAttribute("role", "listbox");
982
- popup.renderer.container.setAttribute("aria-label", "Autocomplete suggestions");
983
- popup.setOption("displayIndentGuides", false);
984
- popup.setOption("dragDelay", 150);
985
- var noop = function () { };
986
- popup.focus = noop;
987
- popup.$isFocused = true;
988
- popup.renderer.$cursorLayer.restartTimer = noop;
989
- popup.renderer.$cursorLayer.element.style.opacity = 0;
990
- popup.renderer.$maxLines = 8;
991
- popup.renderer.$keepTextAreaAtCursor = false;
992
- popup.setHighlightActiveLine(false);
993
- popup.session.highlight("");
994
- popup.session.$searchHighlight.clazz = "ace_highlight-marker";
995
- popup.on("mousedown", function (e) {
996
- var pos = e.getDocumentPosition();
997
- popup.selection.moveToPosition(pos);
998
- selectionMarker.start.row = selectionMarker.end.row = pos.row;
999
- e.stop();
1000
- });
1001
- var lastMouseEvent;
1002
- var hoverMarker = new Range(-1, 0, -1, Infinity);
1003
- var selectionMarker = new Range(-1, 0, -1, Infinity);
1004
- selectionMarker.id = popup.session.addMarker(selectionMarker, "ace_active-line", "fullLine");
1005
- popup.setSelectOnHover = function (val) {
1006
- if (!val) {
1007
- hoverMarker.id = popup.session.addMarker(hoverMarker, "ace_line-hover", "fullLine");
1008
- }
1009
- else if (hoverMarker.id) {
1010
- popup.session.removeMarker(hoverMarker.id);
1011
- hoverMarker.id = null;
1012
- }
1013
- };
1014
- popup.setSelectOnHover(false);
1015
- popup.on("mousemove", function (e) {
1016
- if (!lastMouseEvent) {
1013
+ var AcePopup = /** @class */ (function () {
1014
+ function AcePopup(parentNode) {
1015
+ var el = dom.createElement("div");
1016
+ var popup = $singleLineEditor(el);
1017
+ if (parentNode) {
1018
+ parentNode.appendChild(el);
1019
+ }
1020
+ el.style.display = "none";
1021
+ popup.renderer.content.style.cursor = "default";
1022
+ popup.renderer.setStyle("ace_autocomplete");
1023
+ popup.renderer.$textLayer.element.setAttribute("role", popupAriaRole);
1024
+ popup.renderer.$textLayer.element.setAttribute("aria-roledescription", nls("autocomplete.popup.aria-roledescription", "Autocomplete suggestions"));
1025
+ popup.renderer.$textLayer.element.setAttribute("aria-label", nls("autocomplete.popup.aria-label", "Autocomplete suggestions"));
1026
+ popup.renderer.textarea.setAttribute("aria-hidden", "true");
1027
+ popup.setOption("displayIndentGuides", false);
1028
+ popup.setOption("dragDelay", 150);
1029
+ var noop = function () { };
1030
+ popup.focus = noop;
1031
+ popup.$isFocused = true;
1032
+ popup.renderer.$cursorLayer.restartTimer = noop;
1033
+ popup.renderer.$cursorLayer.element.style.opacity = "0";
1034
+ popup.renderer.$maxLines = 8;
1035
+ popup.renderer.$keepTextAreaAtCursor = false;
1036
+ popup.setHighlightActiveLine(false);
1037
+ popup.session.highlight("");
1038
+ popup.session.$searchHighlight.clazz = "ace_highlight-marker";
1039
+ popup.on("mousedown", function (e) {
1040
+ var pos = e.getDocumentPosition();
1041
+ popup.selection.moveToPosition(pos);
1042
+ selectionMarker.start.row = selectionMarker.end.row = pos.row;
1043
+ e.stop();
1044
+ });
1045
+ var lastMouseEvent;
1046
+ var hoverMarker = new Range(-1, 0, -1, Infinity);
1047
+ var selectionMarker = new Range(-1, 0, -1, Infinity);
1048
+ selectionMarker.id = popup.session.addMarker(selectionMarker, "ace_active-line", "fullLine");
1049
+ popup.setSelectOnHover = function (val) {
1050
+ if (!val) {
1051
+ hoverMarker.id = popup.session.addMarker(hoverMarker, "ace_line-hover", "fullLine");
1052
+ }
1053
+ else if (hoverMarker.id) {
1054
+ popup.session.removeMarker(hoverMarker.id);
1055
+ hoverMarker.id = null;
1056
+ }
1057
+ };
1058
+ popup.setSelectOnHover(false);
1059
+ popup.on("mousemove", function (e) {
1060
+ if (!lastMouseEvent) {
1061
+ lastMouseEvent = e;
1062
+ return;
1063
+ }
1064
+ if (lastMouseEvent.x == e.x && lastMouseEvent.y == e.y) {
1065
+ return;
1066
+ }
1017
1067
  lastMouseEvent = e;
1018
- return;
1019
- }
1020
- if (lastMouseEvent.x == e.x && lastMouseEvent.y == e.y) {
1021
- return;
1022
- }
1023
- lastMouseEvent = e;
1024
- lastMouseEvent.scrollTop = popup.renderer.scrollTop;
1025
- var row = lastMouseEvent.getDocumentPosition().row;
1026
- if (hoverMarker.start.row != row) {
1027
- if (!hoverMarker.id)
1028
- popup.setRow(row);
1029
- setHoverMarker(row);
1030
- }
1031
- });
1032
- popup.renderer.on("beforeRender", function () {
1033
- if (lastMouseEvent && hoverMarker.start.row != -1) {
1034
- lastMouseEvent.$pos = null;
1068
+ lastMouseEvent.scrollTop = popup.renderer.scrollTop;
1069
+ popup.isMouseOver = true;
1035
1070
  var row = lastMouseEvent.getDocumentPosition().row;
1036
- if (!hoverMarker.id)
1037
- popup.setRow(row);
1038
- setHoverMarker(row, true);
1039
- }
1040
- });
1041
- popup.renderer.on("afterRender", function () {
1042
- var row = popup.getRow();
1043
- var t = popup.renderer.$textLayer;
1044
- var selected = t.element.childNodes[row - t.config.firstRow];
1045
- var el = document.activeElement; // Active element is textarea of main editor
1046
- if (selected !== t.selectedNode && t.selectedNode) {
1047
- dom.removeCssClass(t.selectedNode, "ace_selected");
1071
+ if (hoverMarker.start.row != row) {
1072
+ if (!hoverMarker.id)
1073
+ popup.setRow(row);
1074
+ setHoverMarker(row);
1075
+ }
1076
+ });
1077
+ popup.renderer.on("beforeRender", function () {
1078
+ if (lastMouseEvent && hoverMarker.start.row != -1) {
1079
+ lastMouseEvent.$pos = null;
1080
+ var row = lastMouseEvent.getDocumentPosition().row;
1081
+ if (!hoverMarker.id)
1082
+ popup.setRow(row);
1083
+ setHoverMarker(row, true);
1084
+ }
1085
+ });
1086
+ popup.renderer.on("afterRender", function () {
1087
+ var t = popup.renderer.$textLayer;
1088
+ for (var row = t.config.firstRow, l = t.config.lastRow; row <= l; row++) {
1089
+ var popupRowElement = /** @type {HTMLElement|null} */ (t.element.childNodes[row - t.config.firstRow]);
1090
+ popupRowElement.setAttribute("role", optionAriaRole);
1091
+ popupRowElement.setAttribute("aria-roledescription", nls("autocomplete.popup.item.aria-roledescription", "item"));
1092
+ popupRowElement.setAttribute("aria-setsize", popup.data.length);
1093
+ popupRowElement.setAttribute("aria-describedby", "doc-tooltip");
1094
+ popupRowElement.setAttribute("aria-posinset", row + 1);
1095
+ var rowData = popup.getData(row);
1096
+ if (rowData) {
1097
+ var ariaLabel = "".concat(rowData.caption || rowData.value).concat(rowData.meta ? ", ".concat(rowData.meta) : '');
1098
+ popupRowElement.setAttribute("aria-label", ariaLabel);
1099
+ }
1100
+ var highlightedSpans = popupRowElement.querySelectorAll(".ace_completion-highlight");
1101
+ highlightedSpans.forEach(function (span) {
1102
+ span.setAttribute("role", "mark");
1103
+ });
1104
+ }
1105
+ });
1106
+ popup.renderer.on("afterRender", function () {
1107
+ var row = popup.getRow();
1108
+ var t = popup.renderer.$textLayer;
1109
+ var selected = /** @type {HTMLElement|null} */ (t.element.childNodes[row - t.config.firstRow]);
1110
+ var el = document.activeElement; // Active element is textarea of main editor
1111
+ if (selected !== popup.selectedNode && popup.selectedNode) {
1112
+ dom.removeCssClass(popup.selectedNode, "ace_selected");
1113
+ popup.selectedNode.removeAttribute(ariaActiveState);
1114
+ popup.selectedNode.removeAttribute("id");
1115
+ }
1048
1116
  el.removeAttribute("aria-activedescendant");
1049
- t.selectedNode.removeAttribute("id");
1050
- }
1051
- t.selectedNode = selected;
1052
- if (selected) {
1053
- dom.addCssClass(selected, "ace_selected");
1054
- var ariaId = getAriaId(row);
1055
- selected.id = ariaId;
1056
- popup.renderer.container.setAttribute("aria-activedescendant", ariaId);
1057
- el.setAttribute("aria-activedescendant", ariaId);
1058
- selected.setAttribute("aria-label", popup.getData(row).value);
1059
- }
1060
- });
1061
- var hideHoverMarker = function () { setHoverMarker(-1); };
1062
- var setHoverMarker = function (row, suppressRedraw) {
1063
- if (row !== hoverMarker.start.row) {
1064
- hoverMarker.start.row = hoverMarker.end.row = row;
1065
- if (!suppressRedraw)
1117
+ popup.selectedNode = selected;
1118
+ if (selected) {
1119
+ var ariaId = getAriaId(row);
1120
+ dom.addCssClass(selected, "ace_selected");
1121
+ selected.id = ariaId;
1122
+ t.element.setAttribute("aria-activedescendant", ariaId);
1123
+ el.setAttribute("aria-activedescendant", ariaId);
1124
+ selected.setAttribute(ariaActiveState, "true");
1125
+ }
1126
+ });
1127
+ var hideHoverMarker = function () { setHoverMarker(-1); };
1128
+ var setHoverMarker = function (row, suppressRedraw) {
1129
+ if (row !== hoverMarker.start.row) {
1130
+ hoverMarker.start.row = hoverMarker.end.row = row;
1131
+ if (!suppressRedraw)
1132
+ popup.session._emit("changeBackMarker");
1133
+ popup._emit("changeHoverMarker");
1134
+ }
1135
+ };
1136
+ popup.getHoveredRow = function () {
1137
+ return hoverMarker.start.row;
1138
+ };
1139
+ event.addListener(popup.container, "mouseout", function () {
1140
+ popup.isMouseOver = false;
1141
+ hideHoverMarker();
1142
+ });
1143
+ popup.on("hide", hideHoverMarker);
1144
+ popup.on("changeSelection", hideHoverMarker);
1145
+ popup.session.doc.getLength = function () {
1146
+ return popup.data.length;
1147
+ };
1148
+ popup.session.doc.getLine = function (i) {
1149
+ var data = popup.data[i];
1150
+ if (typeof data == "string")
1151
+ return data;
1152
+ return (data && data.value) || "";
1153
+ };
1154
+ var bgTokenizer = popup.session.bgTokenizer;
1155
+ bgTokenizer.$tokenizeRow = function (row) {
1156
+ var data = popup.data[row];
1157
+ var tokens = [];
1158
+ if (!data)
1159
+ return tokens;
1160
+ if (typeof data == "string")
1161
+ data = { value: data };
1162
+ var caption = data.caption || data.value || data.name;
1163
+ function addToken(value, className) {
1164
+ value && tokens.push({
1165
+ type: (data.className || "") + (className || ""),
1166
+ value: value
1167
+ });
1168
+ }
1169
+ var lower = caption.toLowerCase();
1170
+ var filterText = (popup.filterText || "").toLowerCase();
1171
+ var lastIndex = 0;
1172
+ var lastI = 0;
1173
+ for (var i = 0; i <= filterText.length; i++) {
1174
+ if (i != lastI && (data.matchMask & (1 << i) || i == filterText.length)) {
1175
+ var sub = filterText.slice(lastI, i);
1176
+ lastI = i;
1177
+ var index = lower.indexOf(sub, lastIndex);
1178
+ if (index == -1)
1179
+ continue;
1180
+ addToken(caption.slice(lastIndex, index), "");
1181
+ lastIndex = index + sub.length;
1182
+ addToken(caption.slice(index, lastIndex), "completion-highlight");
1183
+ }
1184
+ }
1185
+ addToken(caption.slice(lastIndex, caption.length), "");
1186
+ tokens.push({ type: "completion-spacer", value: " " });
1187
+ if (data.meta)
1188
+ tokens.push({ type: "completion-meta", value: data.meta });
1189
+ if (data.message)
1190
+ tokens.push({ type: "completion-message", value: data.message });
1191
+ return tokens;
1192
+ };
1193
+ bgTokenizer.$updateOnChange = noop;
1194
+ bgTokenizer.start = noop;
1195
+ popup.session.$computeWidth = function () {
1196
+ return this.screenWidth = 0;
1197
+ };
1198
+ popup.isOpen = false;
1199
+ popup.isTopdown = false;
1200
+ popup.autoSelect = true;
1201
+ popup.filterText = "";
1202
+ popup.isMouseOver = false;
1203
+ popup.data = [];
1204
+ popup.setData = function (list, filterText) {
1205
+ popup.filterText = filterText || "";
1206
+ popup.setValue(lang.stringRepeat("\n", list.length), -1);
1207
+ popup.data = list || [];
1208
+ popup.setRow(0);
1209
+ };
1210
+ popup.getData = function (row) {
1211
+ return popup.data[row];
1212
+ };
1213
+ popup.getRow = function () {
1214
+ return selectionMarker.start.row;
1215
+ };
1216
+ popup.setRow = function (line) {
1217
+ line = Math.max(this.autoSelect ? 0 : -1, Math.min(this.data.length - 1, line));
1218
+ if (selectionMarker.start.row != line) {
1219
+ popup.selection.clearSelection();
1220
+ selectionMarker.start.row = selectionMarker.end.row = line || 0;
1066
1221
  popup.session._emit("changeBackMarker");
1067
- popup._emit("changeHoverMarker");
1222
+ popup.moveCursorTo(line || 0, 0);
1223
+ if (popup.isOpen)
1224
+ popup._signal("select");
1225
+ }
1226
+ };
1227
+ popup.on("changeSelection", function () {
1228
+ if (popup.isOpen)
1229
+ popup.setRow(popup.selection.lead.row);
1230
+ popup.renderer.scrollCursorIntoView();
1231
+ });
1232
+ popup.hide = function () {
1233
+ this.container.style.display = "none";
1234
+ popup.anchorPos = null;
1235
+ popup.anchor = null;
1236
+ if (popup.isOpen) {
1237
+ popup.isOpen = false;
1238
+ this._signal("hide");
1239
+ }
1240
+ };
1241
+ popup.tryShow = function (pos, lineHeight, anchor, forceShow) {
1242
+ if (!forceShow && popup.isOpen && popup.anchorPos && popup.anchor &&
1243
+ popup.anchorPos.top === pos.top && popup.anchorPos.left === pos.left &&
1244
+ popup.anchor === anchor) {
1245
+ return true;
1246
+ }
1247
+ var el = this.container;
1248
+ var scrollBarSize = this.renderer.scrollBar.width || 10;
1249
+ var screenHeight = window.innerHeight - scrollBarSize;
1250
+ var screenWidth = window.innerWidth - scrollBarSize;
1251
+ var renderer = this.renderer;
1252
+ var maxH = renderer.$maxLines * lineHeight * 1.4;
1253
+ var dims = { top: 0, bottom: 0, left: 0 };
1254
+ var spaceBelow = screenHeight - pos.top - 3 * this.$borderSize - lineHeight;
1255
+ var spaceAbove = pos.top - 3 * this.$borderSize;
1256
+ if (!anchor) {
1257
+ if (spaceAbove <= spaceBelow || spaceBelow >= maxH) {
1258
+ anchor = "bottom";
1259
+ }
1260
+ else {
1261
+ anchor = "top";
1262
+ }
1263
+ }
1264
+ if (anchor === "top") {
1265
+ dims.bottom = pos.top - this.$borderSize;
1266
+ dims.top = dims.bottom - maxH;
1267
+ }
1268
+ else if (anchor === "bottom") {
1269
+ dims.top = pos.top + lineHeight + this.$borderSize;
1270
+ dims.bottom = dims.top + maxH;
1271
+ }
1272
+ var fitsX = dims.top >= 0 && dims.bottom <= screenHeight;
1273
+ if (!forceShow && !fitsX) {
1274
+ return false;
1275
+ }
1276
+ if (!fitsX) {
1277
+ if (anchor === "top") {
1278
+ renderer.$maxPixelHeight = spaceAbove;
1279
+ }
1280
+ else {
1281
+ renderer.$maxPixelHeight = spaceBelow;
1282
+ }
1283
+ }
1284
+ else {
1285
+ renderer.$maxPixelHeight = null;
1286
+ }
1287
+ if (anchor === "top") {
1288
+ el.style.top = "";
1289
+ el.style.bottom = (screenHeight + scrollBarSize - dims.bottom) + "px";
1290
+ popup.isTopdown = false;
1291
+ }
1292
+ else {
1293
+ el.style.top = dims.top + "px";
1294
+ el.style.bottom = "";
1295
+ popup.isTopdown = true;
1296
+ }
1297
+ el.style.display = "";
1298
+ var left = pos.left;
1299
+ if (left + el.offsetWidth > screenWidth)
1300
+ left = screenWidth - el.offsetWidth;
1301
+ el.style.left = left + "px";
1302
+ el.style.right = "";
1303
+ dom.$fixPositionBug(el);
1304
+ if (!popup.isOpen) {
1305
+ popup.isOpen = true;
1306
+ this._signal("show");
1307
+ lastMouseEvent = null;
1308
+ }
1309
+ popup.anchorPos = pos;
1310
+ popup.anchor = anchor;
1311
+ return true;
1312
+ };
1313
+ popup.show = function (pos, lineHeight, topdownOnly) {
1314
+ this.tryShow(pos, lineHeight, topdownOnly ? "bottom" : undefined, true);
1315
+ };
1316
+ popup.goTo = function (where) {
1317
+ var row = this.getRow();
1318
+ var max = this.session.getLength() - 1;
1319
+ switch (where) {
1320
+ case "up":
1321
+ row = row <= 0 ? max : row - 1;
1322
+ break;
1323
+ case "down":
1324
+ row = row >= max ? -1 : row + 1;
1325
+ break;
1326
+ case "start":
1327
+ row = 0;
1328
+ break;
1329
+ case "end":
1330
+ row = max;
1331
+ break;
1332
+ }
1333
+ this.setRow(row);
1334
+ };
1335
+ popup.getTextLeftOffset = function () {
1336
+ return this.$borderSize + this.renderer.$padding + this.$imageSize;
1337
+ };
1338
+ popup.$imageSize = 0;
1339
+ popup.$borderSize = 1;
1340
+ return popup;
1341
+ }
1342
+ return AcePopup;
1343
+ }());
1344
+ dom.importCssString("\n.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #CAD6FA;\n z-index: 1;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #3a674e;\n}\n.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid #abbffe;\n margin-top: -1px;\n background: rgba(233,233,253,0.4);\n position: absolute;\n z-index: 2;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid rgba(109, 150, 13, 0.8);\n background: rgba(58, 103, 78, 0.62);\n}\n.ace_completion-meta {\n opacity: 0.5;\n margin-left: 0.9em;\n}\n.ace_completion-message {\n margin-left: 0.9em;\n color: blue;\n}\n.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #2d69c7;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #93ca12;\n}\n.ace_editor.ace_autocomplete {\n width: 300px;\n z-index: 200000;\n border: 1px lightgray solid;\n position: fixed;\n box-shadow: 2px 3px 5px rgba(0,0,0,.2);\n line-height: 1.4;\n background: #fefefe;\n color: #111;\n}\n.ace_dark.ace_editor.ace_autocomplete {\n border: 1px #484747 solid;\n box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\n line-height: 1.4;\n background: #25282c;\n color: #c1c1c1;\n}\n.ace_autocomplete .ace_text-layer {\n width: calc(100% - 8px);\n}\n.ace_autocomplete .ace_line {\n display: flex;\n align-items: center;\n}\n.ace_autocomplete .ace_line > * {\n min-width: 0;\n flex: 0 0 auto;\n}\n.ace_autocomplete .ace_line .ace_ {\n flex: 0 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ace_autocomplete .ace_completion-spacer {\n flex: 1;\n}\n.ace_autocomplete.ace_loading:after {\n content: \"\";\n position: absolute;\n top: 0px;\n height: 2px;\n width: 8%;\n background: blue;\n z-index: 100;\n animation: ace_progress 3s infinite linear;\n animation-delay: 300ms;\n transform: translateX(-100%) scaleX(1);\n}\n@keyframes ace_progress {\n 0% { transform: translateX(-100%) scaleX(1) }\n 50% { transform: translateX(625%) scaleX(2) } \n 100% { transform: translateX(1500%) scaleX(3) } \n}\n@media (prefers-reduced-motion) {\n .ace_autocomplete.ace_loading:after {\n transform: translateX(625%) scaleX(2);\n animation: none;\n }\n}\n", "autocompletion.css", false);
1345
+ exports.AcePopup = AcePopup;
1346
+ exports.$singleLineEditor = $singleLineEditor;
1347
+ exports.getAriaId = getAriaId;
1348
+
1349
+ });
1350
+
1351
+ define("ace/autocomplete/inline_screenreader",["require","exports","module"], function(require, exports, module){"use strict";
1352
+ var AceInlineScreenReader = /** @class */ (function () {
1353
+ function AceInlineScreenReader(editor) {
1354
+ this.editor = editor;
1355
+ this.screenReaderDiv = document.createElement("div");
1356
+ this.screenReaderDiv.classList.add("ace_screenreader-only");
1357
+ this.editor.container.appendChild(this.screenReaderDiv);
1358
+ }
1359
+ AceInlineScreenReader.prototype.setScreenReaderContent = function (content) {
1360
+ if (!this.popup && this.editor.completer && /**@type{import("../autocomplete").Autocomplete}*/ (this.editor.completer).popup) {
1361
+ this.popup = /**@type{import("../autocomplete").Autocomplete}*/ (this.editor.completer).popup;
1362
+ this.popup.renderer.on("afterRender", function () {
1363
+ var row = this.popup.getRow();
1364
+ var t = this.popup.renderer.$textLayer;
1365
+ var selected = t.element.childNodes[row - t.config.firstRow];
1366
+ if (selected) {
1367
+ var idString = "doc-tooltip ";
1368
+ for (var lineIndex = 0; lineIndex < this._lines.length; lineIndex++) {
1369
+ idString += "ace-inline-screenreader-line-".concat(lineIndex, " ");
1370
+ }
1371
+ selected.setAttribute("aria-describedby", idString);
1372
+ }
1373
+ }.bind(this));
1068
1374
  }
1375
+ while (this.screenReaderDiv.firstChild) {
1376
+ this.screenReaderDiv.removeChild(this.screenReaderDiv.firstChild);
1377
+ }
1378
+ this._lines = content.split(/\r\n|\r|\n/);
1379
+ var codeElement = this.createCodeBlock();
1380
+ this.screenReaderDiv.appendChild(codeElement);
1069
1381
  };
1070
- popup.getHoveredRow = function () {
1071
- return hoverMarker.start.row;
1072
- };
1073
- event.addListener(popup.container, "mouseout", hideHoverMarker);
1074
- popup.on("hide", hideHoverMarker);
1075
- popup.on("changeSelection", hideHoverMarker);
1076
- popup.session.doc.getLength = function () {
1077
- return popup.data.length;
1382
+ AceInlineScreenReader.prototype.destroy = function () {
1383
+ this.screenReaderDiv.remove();
1078
1384
  };
1079
- popup.session.doc.getLine = function (i) {
1080
- var data = popup.data[i];
1081
- if (typeof data == "string")
1082
- return data;
1083
- return (data && data.value) || "";
1385
+ AceInlineScreenReader.prototype.createCodeBlock = function () {
1386
+ var container = document.createElement("pre");
1387
+ container.setAttribute("id", "ace-inline-screenreader");
1388
+ for (var lineIndex = 0; lineIndex < this._lines.length; lineIndex++) {
1389
+ var codeElement = document.createElement("code");
1390
+ codeElement.setAttribute("id", "ace-inline-screenreader-line-".concat(lineIndex));
1391
+ var line = document.createTextNode(this._lines[lineIndex]);
1392
+ codeElement.appendChild(line);
1393
+ container.appendChild(codeElement);
1394
+ }
1395
+ return container;
1084
1396
  };
1085
- var bgTokenizer = popup.session.bgTokenizer;
1086
- bgTokenizer.$tokenizeRow = function (row) {
1087
- var data = popup.data[row];
1088
- var tokens = [];
1089
- if (!data)
1090
- return tokens;
1091
- if (typeof data == "string")
1092
- data = { value: data };
1093
- var caption = data.caption || data.value || data.name;
1094
- function addToken(value, className) {
1095
- value && tokens.push({
1096
- type: (data.className || "") + (className || ""),
1097
- value: value
1098
- });
1397
+ return AceInlineScreenReader;
1398
+ }());
1399
+ exports.AceInlineScreenReader = AceInlineScreenReader;
1400
+
1401
+ });
1402
+
1403
+ define("ace/autocomplete/inline",["require","exports","module","ace/snippets","ace/autocomplete/inline_screenreader"], function(require, exports, module){"use strict";
1404
+ var snippetManager = require("../snippets").snippetManager;
1405
+ var AceInlineScreenReader = require("./inline_screenreader").AceInlineScreenReader;
1406
+ var AceInline = /** @class */ (function () {
1407
+ function AceInline() {
1408
+ this.editor = null;
1409
+ }
1410
+ AceInline.prototype.show = function (editor, completion, prefix) {
1411
+ prefix = prefix || "";
1412
+ if (editor && this.editor && this.editor !== editor) {
1413
+ this.hide();
1414
+ this.editor = null;
1415
+ this.inlineScreenReader = null;
1416
+ }
1417
+ if (!editor || !completion) {
1418
+ return false;
1099
1419
  }
1100
- var lower = caption.toLowerCase();
1101
- var filterText = (popup.filterText || "").toLowerCase();
1102
- var lastIndex = 0;
1103
- var lastI = 0;
1104
- for (var i = 0; i <= filterText.length; i++) {
1105
- if (i != lastI && (data.matchMask & (1 << i) || i == filterText.length)) {
1106
- var sub = filterText.slice(lastI, i);
1107
- lastI = i;
1108
- var index = lower.indexOf(sub, lastIndex);
1109
- if (index == -1)
1110
- continue;
1111
- addToken(caption.slice(lastIndex, index), "");
1112
- lastIndex = index + sub.length;
1113
- addToken(caption.slice(index, lastIndex), "completion-highlight");
1114
- }
1115
- }
1116
- addToken(caption.slice(lastIndex, caption.length), "");
1117
- if (data.meta)
1118
- tokens.push({ type: "completion-meta", value: data.meta });
1119
- if (data.message)
1120
- tokens.push({ type: "completion-message", value: data.message });
1121
- return tokens;
1122
- };
1123
- bgTokenizer.$updateOnChange = noop;
1124
- bgTokenizer.start = noop;
1125
- popup.session.$computeWidth = function () {
1126
- return this.screenWidth = 0;
1127
- };
1128
- popup.isOpen = false;
1129
- popup.isTopdown = false;
1130
- popup.autoSelect = true;
1131
- popup.filterText = "";
1132
- popup.data = [];
1133
- popup.setData = function (list, filterText) {
1134
- popup.filterText = filterText || "";
1135
- popup.setValue(lang.stringRepeat("\n", list.length), -1);
1136
- popup.data = list || [];
1137
- popup.setRow(0);
1138
- };
1139
- popup.getData = function (row) {
1140
- return popup.data[row];
1141
- };
1142
- popup.getRow = function () {
1143
- return selectionMarker.start.row;
1144
- };
1145
- popup.setRow = function (line) {
1146
- line = Math.max(this.autoSelect ? 0 : -1, Math.min(this.data.length, line));
1147
- if (selectionMarker.start.row != line) {
1148
- popup.selection.clearSelection();
1149
- selectionMarker.start.row = selectionMarker.end.row = line || 0;
1150
- popup.session._emit("changeBackMarker");
1151
- popup.moveCursorTo(line || 0, 0);
1152
- if (popup.isOpen)
1153
- popup._signal("select");
1420
+ if (!this.inlineScreenReader) {
1421
+ this.inlineScreenReader = new AceInlineScreenReader(editor);
1154
1422
  }
1155
- };
1156
- popup.on("changeSelection", function () {
1157
- if (popup.isOpen)
1158
- popup.setRow(popup.selection.lead.row);
1159
- popup.renderer.scrollCursorIntoView();
1160
- });
1161
- popup.hide = function () {
1162
- this.container.style.display = "none";
1163
- this._signal("hide");
1164
- popup.isOpen = false;
1165
- };
1166
- popup.show = function (pos, lineHeight, topdownOnly) {
1167
- var el = this.container;
1168
- var screenHeight = window.innerHeight;
1169
- var screenWidth = window.innerWidth;
1170
- var renderer = this.renderer;
1171
- var maxH = renderer.$maxLines * lineHeight * 1.4;
1172
- var top = pos.top + this.$borderSize;
1173
- var allowTopdown = top > screenHeight / 2 && !topdownOnly;
1174
- if (allowTopdown && top + lineHeight + maxH > screenHeight) {
1175
- renderer.$maxPixelHeight = top - 2 * this.$borderSize;
1176
- el.style.top = "";
1177
- el.style.bottom = screenHeight - top + "px";
1178
- popup.isTopdown = false;
1423
+ var displayText = completion.snippet ? snippetManager.getDisplayTextForSnippet(editor, completion.snippet) : completion.value;
1424
+ if (completion.hideInlinePreview || !displayText || !displayText.startsWith(prefix)) {
1425
+ return false;
1426
+ }
1427
+ this.editor = editor;
1428
+ this.inlineScreenReader.setScreenReaderContent(displayText);
1429
+ displayText = displayText.slice(prefix.length);
1430
+ if (displayText === "") {
1431
+ editor.removeGhostText();
1179
1432
  }
1180
1433
  else {
1181
- top += lineHeight;
1182
- renderer.$maxPixelHeight = screenHeight - top - 0.2 * lineHeight;
1183
- el.style.top = top + "px";
1184
- el.style.bottom = "";
1185
- popup.isTopdown = true;
1186
- }
1187
- el.style.display = "";
1188
- var left = pos.left;
1189
- if (left + el.offsetWidth > screenWidth)
1190
- left = screenWidth - el.offsetWidth;
1191
- el.style.left = left + "px";
1192
- this._signal("show");
1193
- lastMouseEvent = null;
1194
- popup.isOpen = true;
1195
- };
1196
- popup.goTo = function (where) {
1197
- var row = this.getRow();
1198
- var max = this.session.getLength() - 1;
1199
- switch (where) {
1200
- case "up":
1201
- row = row <= 0 ? max : row - 1;
1202
- break;
1203
- case "down":
1204
- row = row >= max ? -1 : row + 1;
1205
- break;
1206
- case "start":
1207
- row = 0;
1208
- break;
1209
- case "end":
1210
- row = max;
1211
- break;
1434
+ editor.setGhostText(displayText);
1435
+ }
1436
+ return true;
1437
+ };
1438
+ AceInline.prototype.isOpen = function () {
1439
+ if (!this.editor) {
1440
+ return false;
1212
1441
  }
1213
- this.setRow(row);
1442
+ return !!this.editor.renderer.$ghostText;
1214
1443
  };
1215
- popup.getTextLeftOffset = function () {
1216
- return this.$borderSize + this.renderer.$padding + this.$imageSize;
1444
+ AceInline.prototype.hide = function () {
1445
+ if (!this.editor) {
1446
+ return false;
1447
+ }
1448
+ this.editor.removeGhostText();
1449
+ return true;
1217
1450
  };
1218
- popup.$imageSize = 0;
1219
- popup.$borderSize = 1;
1220
- return popup;
1221
- };
1222
- dom.importCssString("\n.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #CAD6FA;\n z-index: 1;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #3a674e;\n}\n.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid #abbffe;\n margin-top: -1px;\n background: rgba(233,233,253,0.4);\n position: absolute;\n z-index: 2;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid rgba(109, 150, 13, 0.8);\n background: rgba(58, 103, 78, 0.62);\n}\n.ace_completion-meta {\n opacity: 0.5;\n margin: 0.9em;\n}\n.ace_completion-message {\n color: blue;\n}\n.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #2d69c7;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #93ca12;\n}\n.ace_editor.ace_autocomplete {\n width: 300px;\n z-index: 200000;\n border: 1px lightgray solid;\n position: fixed;\n box-shadow: 2px 3px 5px rgba(0,0,0,.2);\n line-height: 1.4;\n background: #fefefe;\n color: #111;\n}\n.ace_dark.ace_editor.ace_autocomplete {\n border: 1px #484747 solid;\n box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\n line-height: 1.4;\n background: #25282c;\n color: #c1c1c1;\n}", "autocompletion.css", false);
1223
- exports.AcePopup = AcePopup;
1224
- exports.$singleLineEditor = $singleLineEditor;
1225
- exports.getAriaId = getAriaId;
1451
+ AceInline.prototype.destroy = function () {
1452
+ this.hide();
1453
+ this.editor = null;
1454
+ if (this.inlineScreenReader) {
1455
+ this.inlineScreenReader.destroy();
1456
+ this.inlineScreenReader = null;
1457
+ }
1458
+ };
1459
+ return AceInline;
1460
+ }());
1461
+ exports.AceInline = AceInline;
1226
1462
 
1227
1463
  });
1228
1464
 
@@ -1277,93 +1513,292 @@ exports.getCompletionPrefix = function (editor) {
1277
1513
  }.bind(this));
1278
1514
  return prefix || this.retrievePrecedingIdentifier(line, pos.column);
1279
1515
  };
1516
+ exports.triggerAutocomplete = function (editor, previousChar) {
1517
+ var previousChar = previousChar == null
1518
+ ? editor.session.getPrecedingCharacter()
1519
+ : previousChar;
1520
+ return editor.completers.some(function (completer) {
1521
+ if (completer.triggerCharacters && Array.isArray(completer.triggerCharacters)) {
1522
+ return completer.triggerCharacters.includes(previousChar);
1523
+ }
1524
+ });
1525
+ };
1280
1526
 
1281
1527
  });
1282
1528
 
1283
- define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/lang","ace/lib/dom","ace/snippets","ace/config"], function(require, exports, module){"use strict";
1529
+ define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/inline","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/lang","ace/lib/dom","ace/snippets","ace/config","ace/lib/event","ace/lib/scroll"], function(require, exports, module){"use strict";
1284
1530
  var HashHandler = require("./keyboard/hash_handler").HashHandler;
1285
1531
  var AcePopup = require("./autocomplete/popup").AcePopup;
1532
+ var AceInline = require("./autocomplete/inline").AceInline;
1286
1533
  var getAriaId = require("./autocomplete/popup").getAriaId;
1287
1534
  var util = require("./autocomplete/util");
1288
1535
  var lang = require("./lib/lang");
1289
1536
  var dom = require("./lib/dom");
1290
1537
  var snippetManager = require("./snippets").snippetManager;
1291
1538
  var config = require("./config");
1292
- var Autocomplete = function () {
1293
- this.autoInsert = false;
1294
- this.autoSelect = true;
1295
- this.exactMatch = false;
1296
- this.gatherCompletionsId = 0;
1297
- this.keyboardHandler = new HashHandler();
1298
- this.keyboardHandler.bindKeys(this.commands);
1299
- this.blurListener = this.blurListener.bind(this);
1300
- this.changeListener = this.changeListener.bind(this);
1301
- this.mousedownListener = this.mousedownListener.bind(this);
1302
- this.mousewheelListener = this.mousewheelListener.bind(this);
1303
- this.changeTimer = lang.delayedCall(function () {
1304
- this.updateCompletions(true);
1305
- }.bind(this));
1306
- this.tooltipTimer = lang.delayedCall(this.updateDocTooltip.bind(this), 50);
1539
+ var event = require("./lib/event");
1540
+ var preventParentScroll = require("./lib/scroll").preventParentScroll;
1541
+ var destroyCompleter = function (e, editor) {
1542
+ editor.completer && editor.completer.destroy();
1307
1543
  };
1308
- (function () {
1309
- this.$init = function () {
1310
- this.popup = new AcePopup(document.body || document.documentElement);
1544
+ var Autocomplete = /** @class */ (function () {
1545
+ function Autocomplete() {
1546
+ this.autoInsert = false;
1547
+ this.autoSelect = true;
1548
+ this.autoShown = false;
1549
+ this.exactMatch = false;
1550
+ this.inlineEnabled = false;
1551
+ this.keyboardHandler = new HashHandler();
1552
+ this.keyboardHandler.bindKeys(this.commands);
1553
+ this.parentNode = null;
1554
+ this.setSelectOnHover = false;
1555
+ this.hasSeen = new Set();
1556
+ this.showLoadingState = false;
1557
+ this.stickySelectionDelay = 500;
1558
+ this.blurListener = this.blurListener.bind(this);
1559
+ this.changeListener = this.changeListener.bind(this);
1560
+ this.mousedownListener = this.mousedownListener.bind(this);
1561
+ this.mousewheelListener = this.mousewheelListener.bind(this);
1562
+ this.onLayoutChange = this.onLayoutChange.bind(this);
1563
+ this.changeTimer = lang.delayedCall(function () {
1564
+ this.updateCompletions(true);
1565
+ }.bind(this));
1566
+ this.tooltipTimer = lang.delayedCall(this.updateDocTooltip.bind(this), 50);
1567
+ this.popupTimer = lang.delayedCall(this.$updatePopupPosition.bind(this), 50);
1568
+ this.stickySelectionTimer = lang.delayedCall(function () {
1569
+ this.stickySelection = true;
1570
+ }.bind(this), this.stickySelectionDelay);
1571
+ this.$firstOpenTimer = lang.delayedCall(/**@this{Autocomplete}*/ function () {
1572
+ var initialPosition = this.completionProvider && this.completionProvider.initialPosition;
1573
+ if (this.autoShown || (this.popup && this.popup.isOpen) || !initialPosition || this.editor.completers.length === 0)
1574
+ return;
1575
+ this.completions = new FilteredList(Autocomplete.completionsForLoading);
1576
+ this.openPopup(this.editor, initialPosition.prefix, false);
1577
+ this.popup.renderer.setStyle("ace_loading", true);
1578
+ }.bind(this), this.stickySelectionDelay);
1579
+ }
1580
+ Object.defineProperty(Autocomplete, "completionsForLoading", {
1581
+ get: function () {
1582
+ return [{
1583
+ caption: config.nls("autocomplete.loading", "Loading..."),
1584
+ value: ""
1585
+ }];
1586
+ },
1587
+ enumerable: false,
1588
+ configurable: true
1589
+ });
1590
+ Autocomplete.prototype.$init = function () {
1591
+ this.popup = new AcePopup(this.parentNode || document.body || document.documentElement);
1311
1592
  this.popup.on("click", function (e) {
1312
1593
  this.insertMatch();
1313
1594
  e.stop();
1314
1595
  }.bind(this));
1315
1596
  this.popup.focus = this.editor.focus.bind(this.editor);
1316
- this.popup.on("show", this.tooltipTimer.bind(null, null));
1317
- this.popup.on("select", this.tooltipTimer.bind(null, null));
1597
+ this.popup.on("show", this.$onPopupShow.bind(this));
1598
+ this.popup.on("hide", this.$onHidePopup.bind(this));
1599
+ this.popup.on("select", this.$onPopupChange.bind(this));
1600
+ event.addListener(this.popup.container, "mouseout", this.mouseOutListener.bind(this));
1318
1601
  this.popup.on("changeHoverMarker", this.tooltipTimer.bind(null, null));
1602
+ this.popup.renderer.on("afterRender", this.$onPopupRender.bind(this));
1319
1603
  return this.popup;
1320
1604
  };
1321
- this.getPopup = function () {
1605
+ Autocomplete.prototype.$initInline = function () {
1606
+ if (!this.inlineEnabled || this.inlineRenderer)
1607
+ return;
1608
+ this.inlineRenderer = new AceInline();
1609
+ return this.inlineRenderer;
1610
+ };
1611
+ Autocomplete.prototype.getPopup = function () {
1322
1612
  return this.popup || this.$init();
1323
1613
  };
1324
- this.openPopup = function (editor, prefix, keepPopupPosition) {
1614
+ Autocomplete.prototype.$onHidePopup = function () {
1615
+ if (this.inlineRenderer) {
1616
+ this.inlineRenderer.hide();
1617
+ }
1618
+ this.hideDocTooltip();
1619
+ this.stickySelectionTimer.cancel();
1620
+ this.popupTimer.cancel();
1621
+ this.stickySelection = false;
1622
+ };
1623
+ Autocomplete.prototype.$seen = function (completion) {
1624
+ if (!this.hasSeen.has(completion) && completion && completion.completer && completion.completer.onSeen && typeof completion.completer.onSeen === "function") {
1625
+ completion.completer.onSeen(this.editor, completion);
1626
+ this.hasSeen.add(completion);
1627
+ }
1628
+ };
1629
+ Autocomplete.prototype.$onPopupChange = function (hide) {
1630
+ if (this.inlineRenderer && this.inlineEnabled) {
1631
+ var completion = hide ? null : this.popup.getData(this.popup.getRow());
1632
+ this.$updateGhostText(completion);
1633
+ if (this.popup.isMouseOver && this.setSelectOnHover) {
1634
+ this.tooltipTimer.call(null, null);
1635
+ return;
1636
+ }
1637
+ this.popupTimer.schedule();
1638
+ this.tooltipTimer.schedule();
1639
+ }
1640
+ else {
1641
+ this.popupTimer.call(null, null);
1642
+ this.tooltipTimer.call(null, null);
1643
+ }
1644
+ };
1645
+ Autocomplete.prototype.$updateGhostText = function (completion) {
1646
+ var row = this.base.row;
1647
+ var column = this.base.column;
1648
+ var cursorColumn = this.editor.getCursorPosition().column;
1649
+ var prefix = this.editor.session.getLine(row).slice(column, cursorColumn);
1650
+ if (!this.inlineRenderer.show(this.editor, completion, prefix)) {
1651
+ this.inlineRenderer.hide();
1652
+ }
1653
+ else {
1654
+ this.$seen(completion);
1655
+ }
1656
+ };
1657
+ Autocomplete.prototype.$onPopupRender = function () {
1658
+ var inlineEnabled = this.inlineRenderer && this.inlineEnabled;
1659
+ if (this.completions && this.completions.filtered && this.completions.filtered.length > 0) {
1660
+ for (var i = this.popup.getFirstVisibleRow(); i <= this.popup.getLastVisibleRow(); i++) {
1661
+ var completion = this.popup.getData(i);
1662
+ if (completion && (!inlineEnabled || completion.hideInlinePreview)) {
1663
+ this.$seen(completion);
1664
+ }
1665
+ }
1666
+ }
1667
+ };
1668
+ Autocomplete.prototype.$onPopupShow = function (hide) {
1669
+ this.$onPopupChange(hide);
1670
+ this.stickySelection = false;
1671
+ if (this.stickySelectionDelay >= 0)
1672
+ this.stickySelectionTimer.schedule(this.stickySelectionDelay);
1673
+ };
1674
+ Autocomplete.prototype.observeLayoutChanges = function () {
1675
+ if (this.$elements || !this.editor)
1676
+ return;
1677
+ window.addEventListener("resize", this.onLayoutChange, { passive: true });
1678
+ window.addEventListener("wheel", this.mousewheelListener);
1679
+ var el = this.editor.container.parentNode;
1680
+ var elements = [];
1681
+ while (el) {
1682
+ elements.push(el);
1683
+ el.addEventListener("scroll", this.onLayoutChange, { passive: true });
1684
+ el = el.parentNode;
1685
+ }
1686
+ this.$elements = elements;
1687
+ };
1688
+ Autocomplete.prototype.unObserveLayoutChanges = function () {
1689
+ var _this = this;
1690
+ window.removeEventListener("resize", this.onLayoutChange, { passive: true });
1691
+ window.removeEventListener("wheel", this.mousewheelListener);
1692
+ this.$elements && this.$elements.forEach(function (el) {
1693
+ el.removeEventListener("scroll", _this.onLayoutChange, { passive: true });
1694
+ });
1695
+ this.$elements = null;
1696
+ };
1697
+ Autocomplete.prototype.onLayoutChange = function () {
1698
+ if (!this.popup.isOpen)
1699
+ return this.unObserveLayoutChanges();
1700
+ this.$updatePopupPosition();
1701
+ this.updateDocTooltip();
1702
+ };
1703
+ Autocomplete.prototype.$updatePopupPosition = function () {
1704
+ var editor = this.editor;
1705
+ var renderer = editor.renderer;
1706
+ var lineHeight = renderer.layerConfig.lineHeight;
1707
+ var pos = renderer.$cursorLayer.getPixelPosition(this.base, true);
1708
+ pos.left -= this.popup.getTextLeftOffset();
1709
+ var rect = editor.container.getBoundingClientRect();
1710
+ pos.top += rect.top - renderer.layerConfig.offset;
1711
+ pos.left += rect.left - editor.renderer.scrollLeft;
1712
+ pos.left += renderer.gutterWidth;
1713
+ var posGhostText = {
1714
+ top: pos.top,
1715
+ left: pos.left
1716
+ };
1717
+ if (renderer.$ghostText && renderer.$ghostTextWidget) {
1718
+ if (this.base.row === renderer.$ghostText.position.row) {
1719
+ posGhostText.top += renderer.$ghostTextWidget.el.offsetHeight;
1720
+ }
1721
+ }
1722
+ var editorContainerBottom = editor.container.getBoundingClientRect().bottom - lineHeight;
1723
+ var lowestPosition = editorContainerBottom < posGhostText.top ?
1724
+ { top: editorContainerBottom, left: posGhostText.left } :
1725
+ posGhostText;
1726
+ if (this.popup.tryShow(lowestPosition, lineHeight, "bottom")) {
1727
+ return;
1728
+ }
1729
+ if (this.popup.tryShow(pos, lineHeight, "top")) {
1730
+ return;
1731
+ }
1732
+ this.popup.show(pos, lineHeight);
1733
+ };
1734
+ Autocomplete.prototype.openPopup = function (editor, prefix, keepPopupPosition) {
1735
+ this.$firstOpenTimer.cancel();
1325
1736
  if (!this.popup)
1326
1737
  this.$init();
1738
+ if (this.inlineEnabled && !this.inlineRenderer)
1739
+ this.$initInline();
1327
1740
  this.popup.autoSelect = this.autoSelect;
1741
+ this.popup.setSelectOnHover(this.setSelectOnHover);
1742
+ var oldRow = this.popup.getRow();
1743
+ var previousSelectedItem = this.popup.data[oldRow];
1328
1744
  this.popup.setData(this.completions.filtered, this.completions.filterText);
1329
- this.editor.textInput.setAriaOptions({ activeDescendant: getAriaId(this.popup.getRow()) });
1745
+ if (this.editor.textInput.setAriaOptions) {
1746
+ this.editor.textInput.setAriaOptions({
1747
+ activeDescendant: getAriaId(this.popup.getRow()),
1748
+ inline: this.inlineEnabled
1749
+ });
1750
+ }
1330
1751
  editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
1331
- var renderer = editor.renderer;
1332
- this.popup.setRow(this.autoSelect ? 0 : -1);
1752
+ var newRow;
1753
+ if (this.stickySelection)
1754
+ newRow = this.popup.data.indexOf(previousSelectedItem);
1755
+ if (!newRow || newRow === -1)
1756
+ newRow = 0;
1757
+ this.popup.setRow(this.autoSelect ? newRow : -1);
1758
+ if (newRow === oldRow && previousSelectedItem !== this.completions.filtered[newRow])
1759
+ this.$onPopupChange();
1760
+ var inlineEnabled = this.inlineRenderer && this.inlineEnabled;
1761
+ if (newRow === oldRow && inlineEnabled) {
1762
+ var completion = this.popup.getData(this.popup.getRow());
1763
+ this.$updateGhostText(completion);
1764
+ }
1333
1765
  if (!keepPopupPosition) {
1334
1766
  this.popup.setTheme(editor.getTheme());
1335
1767
  this.popup.setFontSize(editor.getFontSize());
1336
- var lineHeight = renderer.layerConfig.lineHeight;
1337
- var pos = renderer.$cursorLayer.getPixelPosition(this.base, true);
1338
- pos.left -= this.popup.getTextLeftOffset();
1339
- var rect = editor.container.getBoundingClientRect();
1340
- pos.top += rect.top - renderer.layerConfig.offset;
1341
- pos.left += rect.left - editor.renderer.scrollLeft;
1342
- pos.left += renderer.gutterWidth;
1343
- this.popup.show(pos, lineHeight);
1344
- }
1345
- else if (keepPopupPosition && !prefix) {
1346
- this.detach();
1768
+ this.$updatePopupPosition();
1769
+ if (this.tooltipNode) {
1770
+ this.updateDocTooltip();
1771
+ }
1347
1772
  }
1348
1773
  this.changeTimer.cancel();
1774
+ this.observeLayoutChanges();
1349
1775
  };
1350
- this.detach = function () {
1351
- this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
1352
- this.editor.off("changeSelection", this.changeListener);
1353
- this.editor.off("blur", this.blurListener);
1354
- this.editor.off("mousedown", this.mousedownListener);
1355
- this.editor.off("mousewheel", this.mousewheelListener);
1776
+ Autocomplete.prototype.detach = function () {
1777
+ if (this.editor) {
1778
+ this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
1779
+ this.editor.off("changeSelection", this.changeListener);
1780
+ this.editor.off("blur", this.blurListener);
1781
+ this.editor.off("mousedown", this.mousedownListener);
1782
+ this.editor.off("mousewheel", this.mousewheelListener);
1783
+ }
1784
+ this.$firstOpenTimer.cancel();
1356
1785
  this.changeTimer.cancel();
1357
1786
  this.hideDocTooltip();
1358
- this.gatherCompletionsId += 1;
1787
+ if (this.completionProvider) {
1788
+ this.completionProvider.detach();
1789
+ }
1359
1790
  if (this.popup && this.popup.isOpen)
1360
1791
  this.popup.hide();
1792
+ if (this.popup && this.popup.renderer) {
1793
+ this.popup.renderer.off("afterRender", this.$onPopupRender);
1794
+ }
1361
1795
  if (this.base)
1362
1796
  this.base.detach();
1363
1797
  this.activated = false;
1364
- this.completions = this.base = null;
1798
+ this.completionProvider = this.completions = this.base = null;
1799
+ this.unObserveLayoutChanges();
1365
1800
  };
1366
- this.changeListener = function (e) {
1801
+ Autocomplete.prototype.changeListener = function (e) {
1367
1802
  var cursor = this.editor.selection.lead;
1368
1803
  if (cursor.row != this.base.row || cursor.column < this.base.column) {
1369
1804
  this.detach();
@@ -1373,7 +1808,7 @@ var Autocomplete = function () {
1373
1808
  else
1374
1809
  this.detach();
1375
1810
  };
1376
- this.blurListener = function (e) {
1811
+ Autocomplete.prototype.blurListener = function (e) {
1377
1812
  var el = document.activeElement;
1378
1813
  var text = this.editor.textInput.getElement();
1379
1814
  var fromTooltip = e.relatedTarget && this.tooltipNode && this.tooltipNode.contains(e.relatedTarget);
@@ -1383,84 +1818,34 @@ var Autocomplete = function () {
1383
1818
  this.detach();
1384
1819
  }
1385
1820
  };
1386
- this.mousedownListener = function (e) {
1821
+ Autocomplete.prototype.mousedownListener = function (e) {
1387
1822
  this.detach();
1388
1823
  };
1389
- this.mousewheelListener = function (e) {
1390
- this.detach();
1824
+ Autocomplete.prototype.mousewheelListener = function (e) {
1825
+ if (this.popup && !this.popup.isMouseOver)
1826
+ this.detach();
1391
1827
  };
1392
- this.goTo = function (where) {
1828
+ Autocomplete.prototype.mouseOutListener = function (e) {
1829
+ if (this.popup.isOpen)
1830
+ this.$updatePopupPosition();
1831
+ };
1832
+ Autocomplete.prototype.goTo = function (where) {
1393
1833
  this.popup.goTo(where);
1394
1834
  };
1395
- this.insertMatch = function (data, options) {
1835
+ Autocomplete.prototype.insertMatch = function (data, options) {
1396
1836
  if (!data)
1397
1837
  data = this.popup.getData(this.popup.getRow());
1398
1838
  if (!data)
1399
1839
  return false;
1840
+ if (data.value === "") // Explicitly given nothing to insert, e.g. "No suggestion state"
1841
+ return this.detach();
1400
1842
  var completions = this.completions;
1401
- this.editor.startOperation({ command: { name: "insertMatch" } });
1402
- if (data.completer && data.completer.insertMatch) {
1403
- data.completer.insertMatch(this.editor, data);
1404
- }
1405
- else {
1406
- if (!completions)
1407
- return false;
1408
- if (completions.filterText) {
1409
- var ranges = this.editor.selection.getAllRanges();
1410
- for (var i = 0, range; range = ranges[i]; i++) {
1411
- range.start.column -= completions.filterText.length;
1412
- this.editor.session.remove(range);
1413
- }
1414
- }
1415
- if (data.snippet)
1416
- snippetManager.insertSnippet(this.editor, data.snippet);
1417
- else
1418
- this.editor.execCommand("insertstring", data.value || data);
1419
- }
1843
+ var result = this.getCompletionProvider().insertMatch(this.editor, data, completions.filterText, options);
1420
1844
  if (this.completions == completions)
1421
1845
  this.detach();
1422
- this.editor.endOperation();
1423
- };
1424
- this.commands = {
1425
- "Up": function (editor) { editor.completer.goTo("up"); },
1426
- "Down": function (editor) { editor.completer.goTo("down"); },
1427
- "Ctrl-Up|Ctrl-Home": function (editor) { editor.completer.goTo("start"); },
1428
- "Ctrl-Down|Ctrl-End": function (editor) { editor.completer.goTo("end"); },
1429
- "Esc": function (editor) { editor.completer.detach(); },
1430
- "Return": function (editor) { return editor.completer.insertMatch(); },
1431
- "Shift-Return": function (editor) { editor.completer.insertMatch(null, { deleteSuffix: true }); },
1432
- "Tab": function (editor) {
1433
- var result = editor.completer.insertMatch();
1434
- if (!result && !editor.tabstopManager)
1435
- editor.completer.goTo("down");
1436
- else
1437
- return result;
1438
- },
1439
- "PageUp": function (editor) { editor.completer.popup.gotoPageUp(); },
1440
- "PageDown": function (editor) { editor.completer.popup.gotoPageDown(); }
1441
- };
1442
- this.gatherCompletions = function (editor, callback) {
1443
- var session = editor.getSession();
1444
- var pos = editor.getCursorPosition();
1445
- var prefix = util.getCompletionPrefix(editor);
1446
- this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);
1447
- this.base.$insertRight = true;
1448
- var matches = [];
1449
- var total = editor.completers.length;
1450
- editor.completers.forEach(function (completer, i) {
1451
- completer.getCompletions(editor, session, pos, prefix, function (err, results) {
1452
- if (!err && results)
1453
- matches = matches.concat(results);
1454
- callback(null, {
1455
- prefix: util.getCompletionPrefix(editor),
1456
- matches: matches,
1457
- finished: (--total === 0)
1458
- });
1459
- });
1460
- });
1461
- return true;
1846
+ return result;
1462
1847
  };
1463
- this.showPopup = function (editor, options) {
1848
+ Autocomplete.prototype.showPopup = function (editor, options) {
1464
1849
  if (this.editor)
1465
1850
  this.detach();
1466
1851
  this.activated = true;
@@ -1476,7 +1861,15 @@ var Autocomplete = function () {
1476
1861
  editor.on("mousewheel", this.mousewheelListener);
1477
1862
  this.updateCompletions(false, options);
1478
1863
  };
1479
- this.updateCompletions = function (keepPopupPosition, options) {
1864
+ Autocomplete.prototype.getCompletionProvider = function (initialPosition) {
1865
+ if (!this.completionProvider)
1866
+ this.completionProvider = new CompletionProvider(initialPosition);
1867
+ return this.completionProvider;
1868
+ };
1869
+ Autocomplete.prototype.gatherCompletions = function (editor, callback) {
1870
+ return this.getCompletionProvider().gatherCompletions(editor, callback);
1871
+ };
1872
+ Autocomplete.prototype.updateCompletions = function (keepPopupPosition, options) {
1480
1873
  if (keepPopupPosition && this.base && this.completions) {
1481
1874
  var pos = this.editor.getCursorPosition();
1482
1875
  var prefix = this.editor.session.getTextRange({ start: this.base, end: pos });
@@ -1497,67 +1890,80 @@ var Autocomplete = function () {
1497
1890
  this.base = this.editor.session.doc.createAnchor(pos.row, pos.column);
1498
1891
  this.base.$insertRight = true;
1499
1892
  this.completions = new FilteredList(options.matches);
1893
+ this.getCompletionProvider().completions = this.completions;
1500
1894
  return this.openPopup(this.editor, "", keepPopupPosition);
1501
1895
  }
1502
- var _id = this.gatherCompletionsId;
1503
- var detachIfFinished = function (results) {
1504
- if (!results.finished)
1505
- return;
1506
- return this.detach();
1507
- }.bind(this);
1508
- var processResults = function (results) {
1509
- var prefix = results.prefix;
1510
- var matches = results.matches;
1511
- this.completions = new FilteredList(matches);
1512
- if (this.exactMatch)
1513
- this.completions.exactMatch = true;
1514
- this.completions.setFilter(prefix);
1515
- var filtered = this.completions.filtered;
1516
- if (!filtered.length)
1517
- return detachIfFinished(results);
1518
- if (filtered.length == 1 && filtered[0].value == prefix && !filtered[0].snippet)
1519
- return detachIfFinished(results);
1520
- if (this.autoInsert && filtered.length == 1 && results.finished)
1521
- return this.insertMatch(filtered[0]);
1522
- this.openPopup(this.editor, prefix, keepPopupPosition);
1523
- }.bind(this);
1524
- var isImmediate = true;
1525
- var immediateResults = null;
1526
- this.gatherCompletions(this.editor, function (err, results) {
1527
- var prefix = results.prefix;
1528
- var matches = results && results.matches;
1529
- if (!matches || !matches.length)
1530
- return detachIfFinished(results);
1531
- if (prefix.indexOf(results.prefix) !== 0 || _id != this.gatherCompletionsId)
1532
- return;
1533
- if (isImmediate) {
1534
- immediateResults = results;
1535
- return;
1896
+ var session = this.editor.getSession();
1897
+ var pos = this.editor.getCursorPosition();
1898
+ var prefix = util.getCompletionPrefix(this.editor);
1899
+ this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);
1900
+ this.base.$insertRight = true;
1901
+ var completionOptions = {
1902
+ exactMatch: this.exactMatch,
1903
+ ignoreCaption: this.ignoreCaption
1904
+ };
1905
+ this.getCompletionProvider({
1906
+ prefix: prefix,
1907
+ pos: pos
1908
+ }).provideCompletions(this.editor, completionOptions,
1909
+ function (err, completions, finished) {
1910
+ var filtered = completions.filtered;
1911
+ var prefix = util.getCompletionPrefix(this.editor);
1912
+ this.$firstOpenTimer.cancel();
1913
+ if (finished) {
1914
+ if (!filtered.length) {
1915
+ var emptyMessage = !this.autoShown && this.emptyMessage;
1916
+ if (typeof emptyMessage == "function")
1917
+ emptyMessage = this.emptyMessage(prefix);
1918
+ if (emptyMessage) {
1919
+ var completionsForEmpty = [{
1920
+ caption: emptyMessage,
1921
+ value: ""
1922
+ }
1923
+ ];
1924
+ this.completions = new FilteredList(completionsForEmpty);
1925
+ this.openPopup(this.editor, prefix, keepPopupPosition);
1926
+ this.popup.renderer.setStyle("ace_loading", false);
1927
+ this.popup.renderer.setStyle("ace_empty-message", true);
1928
+ return;
1929
+ }
1930
+ return this.detach();
1931
+ }
1932
+ if (filtered.length == 1 && filtered[0].value == prefix
1933
+ && !filtered[0].snippet)
1934
+ return this.detach();
1935
+ if (this.autoInsert && !this.autoShown && filtered.length == 1)
1936
+ return this.insertMatch(filtered[0]);
1536
1937
  }
1537
- processResults(results);
1938
+ this.completions = !finished && this.showLoadingState ?
1939
+ new FilteredList(Autocomplete.completionsForLoading.concat(filtered), completions.filterText) :
1940
+ completions;
1941
+ this.openPopup(this.editor, prefix, keepPopupPosition);
1942
+ this.popup.renderer.setStyle("ace_empty-message", false);
1943
+ this.popup.renderer.setStyle("ace_loading", !finished);
1538
1944
  }.bind(this));
1539
- isImmediate = false;
1540
- if (immediateResults) {
1541
- var results = immediateResults;
1542
- immediateResults = null;
1543
- processResults(results);
1945
+ if (this.showLoadingState && !this.autoShown && !(this.popup && this.popup.isOpen)) {
1946
+ this.$firstOpenTimer.delay(this.stickySelectionDelay / 2);
1544
1947
  }
1545
1948
  };
1546
- this.cancelContextMenu = function () {
1949
+ Autocomplete.prototype.cancelContextMenu = function () {
1547
1950
  this.editor.$mouseHandler.cancelContextMenu();
1548
1951
  };
1549
- this.updateDocTooltip = function () {
1952
+ Autocomplete.prototype.updateDocTooltip = function () {
1550
1953
  var popup = this.popup;
1551
- var all = popup.data;
1954
+ var all = this.completions && this.completions.filtered;
1552
1955
  var selected = all && (all[popup.getHoveredRow()] || all[popup.getRow()]);
1553
1956
  var doc = null;
1554
1957
  if (!selected || !this.editor || !this.popup.isOpen)
1555
1958
  return this.hideDocTooltip();
1556
- this.editor.completers.some(function (completer) {
1557
- if (completer.getDocTooltip)
1959
+ var completersLength = this.editor.completers.length;
1960
+ for (var i = 0; i < completersLength; i++) {
1961
+ var completer = this.editor.completers[i];
1962
+ if (completer.getDocTooltip && selected.completerId === completer.id) {
1558
1963
  doc = completer.getDocTooltip(selected);
1559
- return doc;
1560
- });
1964
+ break;
1965
+ }
1966
+ }
1561
1967
  if (!doc && typeof selected != "string")
1562
1968
  doc = selected;
1563
1969
  if (typeof doc == "string")
@@ -1566,16 +1972,22 @@ var Autocomplete = function () {
1566
1972
  return this.hideDocTooltip();
1567
1973
  this.showDocTooltip(doc);
1568
1974
  };
1569
- this.showDocTooltip = function (item) {
1975
+ Autocomplete.prototype.showDocTooltip = function (item) {
1570
1976
  if (!this.tooltipNode) {
1571
1977
  this.tooltipNode = dom.createElement("div");
1572
- this.tooltipNode.className = "ace_tooltip ace_doc-tooltip";
1573
- this.tooltipNode.style.margin = 0;
1978
+ this.tooltipNode.style.margin = "0";
1574
1979
  this.tooltipNode.style.pointerEvents = "auto";
1980
+ this.tooltipNode.style.overscrollBehavior = "contain";
1575
1981
  this.tooltipNode.tabIndex = -1;
1576
1982
  this.tooltipNode.onblur = this.blurListener.bind(this);
1577
1983
  this.tooltipNode.onclick = this.onTooltipClick.bind(this);
1984
+ this.tooltipNode.id = "doc-tooltip";
1985
+ this.tooltipNode.setAttribute("role", "tooltip");
1986
+ this.tooltipNode.addEventListener("wheel", preventParentScroll);
1578
1987
  }
1988
+ var theme = this.editor.renderer.theme;
1989
+ this.tooltipNode.className = "ace_tooltip ace_doc-tooltip " +
1990
+ (theme.isDark ? "ace_dark " : "") + (theme.cssClass || "");
1579
1991
  var tooltipNode = this.tooltipNode;
1580
1992
  if (item.docHTML) {
1581
1993
  tooltipNode.innerHTML = item.docHTML;
@@ -1584,38 +1996,57 @@ var Autocomplete = function () {
1584
1996
  tooltipNode.textContent = item.docText;
1585
1997
  }
1586
1998
  if (!tooltipNode.parentNode)
1587
- document.body.appendChild(tooltipNode);
1999
+ this.popup.container.appendChild(this.tooltipNode);
1588
2000
  var popup = this.popup;
1589
2001
  var rect = popup.container.getBoundingClientRect();
1590
- tooltipNode.style.top = popup.container.style.top;
1591
- tooltipNode.style.bottom = popup.container.style.bottom;
1592
- tooltipNode.style.display = "block";
1593
- if (window.innerWidth - rect.right < 320) {
1594
- if (rect.left < 320) {
1595
- if (popup.isTopdown) {
1596
- tooltipNode.style.top = rect.bottom + "px";
1597
- tooltipNode.style.left = rect.left + "px";
1598
- tooltipNode.style.right = "";
1599
- tooltipNode.style.bottom = "";
1600
- }
1601
- else {
1602
- tooltipNode.style.top = popup.container.offsetTop - tooltipNode.offsetHeight + "px";
1603
- tooltipNode.style.left = rect.left + "px";
1604
- tooltipNode.style.right = "";
1605
- tooltipNode.style.bottom = "";
1606
- }
2002
+ var targetWidth = 400;
2003
+ var targetHeight = 300;
2004
+ var scrollBarSize = popup.renderer.scrollBar.width || 10;
2005
+ var leftSize = rect.left;
2006
+ var rightSize = window.innerWidth - rect.right - scrollBarSize;
2007
+ var topSize = popup.isTopdown ? window.innerHeight - scrollBarSize - rect.bottom : rect.top;
2008
+ var scores = [
2009
+ Math.min(rightSize / targetWidth, 1),
2010
+ Math.min(leftSize / targetWidth, 1),
2011
+ Math.min(topSize / targetHeight, 1) * 0.9,
2012
+ ];
2013
+ var max = Math.max.apply(Math, scores);
2014
+ var tooltipStyle = tooltipNode.style;
2015
+ tooltipStyle.display = "block";
2016
+ if (max == scores[0] || scores[0] >= 1) {
2017
+ tooltipStyle.left = (rect.right + 1) + "px";
2018
+ tooltipStyle.right = "";
2019
+ tooltipStyle.maxWidth = targetWidth * max + "px";
2020
+ tooltipStyle.top = rect.top + "px";
2021
+ tooltipStyle.bottom = "";
2022
+ tooltipStyle.maxHeight = Math.min(window.innerHeight - scrollBarSize - rect.top, targetHeight) + "px";
2023
+ }
2024
+ else if (max == scores[1] || scores[1] >= 1) {
2025
+ tooltipStyle.right = window.innerWidth - rect.left + "px";
2026
+ tooltipStyle.left = "";
2027
+ tooltipStyle.maxWidth = targetWidth * max + "px";
2028
+ tooltipStyle.top = rect.top + "px";
2029
+ tooltipStyle.bottom = "";
2030
+ tooltipStyle.maxHeight = Math.min(window.innerHeight - scrollBarSize - rect.top, targetHeight) + "px";
2031
+ }
2032
+ else if (max == scores[2]) {
2033
+ tooltipStyle.left = rect.left + "px";
2034
+ tooltipStyle.right = "";
2035
+ tooltipStyle.maxWidth = Math.min(targetWidth, window.innerWidth - rect.left) + "px";
2036
+ if (popup.isTopdown) {
2037
+ tooltipStyle.top = rect.bottom + "px";
2038
+ tooltipStyle.bottom = "";
2039
+ tooltipStyle.maxHeight = Math.min(window.innerHeight - scrollBarSize - rect.bottom, targetHeight) + "px";
1607
2040
  }
1608
2041
  else {
1609
- tooltipNode.style.right = window.innerWidth - rect.left + "px";
1610
- tooltipNode.style.left = "";
2042
+ tooltipStyle.top = "";
2043
+ tooltipStyle.bottom = (window.innerHeight - rect.top) + "px";
2044
+ tooltipStyle.maxHeight = Math.min(rect.top, targetHeight) + "px";
1611
2045
  }
1612
2046
  }
1613
- else {
1614
- tooltipNode.style.left = (rect.right + 1) + "px";
1615
- tooltipNode.style.right = "";
1616
- }
2047
+ dom.$fixPositionBug(tooltipNode);
1617
2048
  };
1618
- this.hideDocTooltip = function () {
2049
+ Autocomplete.prototype.hideDocTooltip = function () {
1619
2050
  this.tooltipTimer.cancel();
1620
2051
  if (!this.tooltipNode)
1621
2052
  return;
@@ -1626,7 +2057,7 @@ var Autocomplete = function () {
1626
2057
  if (el.parentNode)
1627
2058
  el.parentNode.removeChild(el);
1628
2059
  };
1629
- this.onTooltipClick = function (e) {
2060
+ Autocomplete.prototype.onTooltipClick = function (e) {
1630
2061
  var a = e.target;
1631
2062
  while (a && a != this.tooltipNode) {
1632
2063
  if (a.nodeName == "A" && a.href) {
@@ -1637,7 +2068,7 @@ var Autocomplete = function () {
1637
2068
  a = a.parentNode;
1638
2069
  }
1639
2070
  };
1640
- this.destroy = function () {
2071
+ Autocomplete.prototype.destroy = function () {
1641
2072
  this.detach();
1642
2073
  if (this.popup) {
1643
2074
  this.popup.destroy();
@@ -1645,27 +2076,56 @@ var Autocomplete = function () {
1645
2076
  if (el && el.parentNode)
1646
2077
  el.parentNode.removeChild(el);
1647
2078
  }
1648
- if (this.editor && this.editor.completer == this)
1649
- this.editor.completer == null;
1650
- this.popup = null;
2079
+ if (this.editor && this.editor.completer == this) {
2080
+ this.editor.off("destroy", destroyCompleter);
2081
+ this.editor.completer = null;
2082
+ }
2083
+ this.inlineRenderer = this.popup = this.editor = null;
1651
2084
  };
1652
- }).call(Autocomplete.prototype);
1653
- Autocomplete.for = function (editor) {
1654
- if (editor.completer) {
1655
- return editor.completer;
1656
- }
1657
- if (config.get("sharedPopups")) {
1658
- if (!Autocomplete.$shared)
1659
- Autocomplete.$sharedInstance = new Autocomplete();
1660
- editor.completer = Autocomplete.$sharedInstance;
1661
- }
1662
- else {
1663
- editor.completer = new Autocomplete();
1664
- editor.once("destroy", function (e, editor) {
2085
+ Autocomplete.for = function (editor) {
2086
+ if (editor.completer instanceof Autocomplete) {
2087
+ return editor.completer;
2088
+ }
2089
+ if (editor.completer) {
1665
2090
  editor.completer.destroy();
1666
- });
1667
- }
1668
- return editor.completer;
2091
+ editor.completer = null;
2092
+ }
2093
+ if (config.get("sharedPopups")) {
2094
+ if (!Autocomplete["$sharedInstance"])
2095
+ Autocomplete["$sharedInstance"] = new Autocomplete();
2096
+ editor.completer = Autocomplete["$sharedInstance"];
2097
+ }
2098
+ else {
2099
+ editor.completer = new Autocomplete();
2100
+ editor.once("destroy", destroyCompleter);
2101
+ }
2102
+ return editor.completer;
2103
+ };
2104
+ return Autocomplete;
2105
+ }());
2106
+ Autocomplete.prototype.commands = {
2107
+ "Up": function (editor) { editor.completer.goTo("up"); },
2108
+ "Down": function (editor) { editor.completer.goTo("down"); },
2109
+ "Ctrl-Up|Ctrl-Home": function (editor) { editor.completer.goTo("start"); },
2110
+ "Ctrl-Down|Ctrl-End": function (editor) { editor.completer.goTo("end"); },
2111
+ "Esc": function (editor) { editor.completer.detach(); },
2112
+ "Return": function (editor) { return editor.completer.insertMatch(); },
2113
+ "Shift-Return": function (editor) { editor.completer.insertMatch(null, { deleteSuffix: true }); },
2114
+ "Tab": function (editor) {
2115
+ var result = editor.completer.insertMatch();
2116
+ if (!result && !editor.tabstopManager)
2117
+ editor.completer.goTo("down");
2118
+ else
2119
+ return result;
2120
+ },
2121
+ "Backspace": function (editor) {
2122
+ editor.execCommand("backspace");
2123
+ var prefix = util.getCompletionPrefix(editor);
2124
+ if (!prefix && editor.completer)
2125
+ editor.completer.detach();
2126
+ },
2127
+ "PageUp": function (editor) { editor.completer.popup.gotoPageUp(); },
2128
+ "PageDown": function (editor) { editor.completer.popup.gotoPageDown(); }
1669
2129
  };
1670
2130
  Autocomplete.startCommand = {
1671
2131
  name: "startAutocomplete",
@@ -1673,19 +2133,156 @@ Autocomplete.startCommand = {
1673
2133
  var completer = Autocomplete.for(editor);
1674
2134
  completer.autoInsert = false;
1675
2135
  completer.autoSelect = true;
2136
+ completer.autoShown = false;
1676
2137
  completer.showPopup(editor, options);
1677
2138
  completer.cancelContextMenu();
1678
2139
  },
1679
2140
  bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
1680
2141
  };
1681
- var FilteredList = function (array, filterText) {
1682
- this.all = array;
1683
- this.filtered = array;
1684
- this.filterText = filterText || "";
1685
- this.exactMatch = false;
1686
- };
1687
- (function () {
1688
- this.setFilter = function (str) {
2142
+ var CompletionProvider = /** @class */ (function () {
2143
+ function CompletionProvider(initialPosition) {
2144
+ this.initialPosition = initialPosition;
2145
+ this.active = true;
2146
+ }
2147
+ CompletionProvider.prototype.insertByIndex = function (editor, index, options) {
2148
+ if (!this.completions || !this.completions.filtered) {
2149
+ return false;
2150
+ }
2151
+ return this.insertMatch(editor, this.completions.filtered[index], options);
2152
+ };
2153
+ CompletionProvider.prototype.insertMatch = function (editor, data, options) {
2154
+ if (!data)
2155
+ return false;
2156
+ editor.startOperation({ command: { name: "insertMatch" } });
2157
+ if (data.completer && data.completer.insertMatch) {
2158
+ data.completer.insertMatch(editor, data);
2159
+ }
2160
+ else {
2161
+ if (!this.completions)
2162
+ return false;
2163
+ var replaceBefore = this.completions.filterText.length;
2164
+ var replaceAfter = 0;
2165
+ if (data.range && data.range.start.row === data.range.end.row) {
2166
+ replaceBefore -= this.initialPosition.prefix.length;
2167
+ replaceBefore += this.initialPosition.pos.column - data.range.start.column;
2168
+ replaceAfter += data.range.end.column - this.initialPosition.pos.column;
2169
+ }
2170
+ if (replaceBefore || replaceAfter) {
2171
+ var ranges;
2172
+ if (editor.selection.getAllRanges) {
2173
+ ranges = editor.selection.getAllRanges();
2174
+ }
2175
+ else {
2176
+ ranges = [editor.getSelectionRange()];
2177
+ }
2178
+ for (var i = 0, range; range = ranges[i]; i++) {
2179
+ range.start.column -= replaceBefore;
2180
+ range.end.column += replaceAfter;
2181
+ editor.session.remove(range);
2182
+ }
2183
+ }
2184
+ if (data.snippet) {
2185
+ snippetManager.insertSnippet(editor, data.snippet);
2186
+ }
2187
+ else {
2188
+ this.$insertString(editor, data);
2189
+ }
2190
+ if (data.completer && data.completer.onInsert && typeof data.completer.onInsert == "function") {
2191
+ data.completer.onInsert(editor, data);
2192
+ }
2193
+ if (data.command && data.command === "startAutocomplete") {
2194
+ editor.execCommand(data.command);
2195
+ }
2196
+ }
2197
+ editor.endOperation();
2198
+ return true;
2199
+ };
2200
+ CompletionProvider.prototype.$insertString = function (editor, data) {
2201
+ var text = data.value || data;
2202
+ editor.execCommand("insertstring", text);
2203
+ };
2204
+ CompletionProvider.prototype.gatherCompletions = function (editor, callback) {
2205
+ var session = editor.getSession();
2206
+ var pos = editor.getCursorPosition();
2207
+ var prefix = util.getCompletionPrefix(editor);
2208
+ var matches = [];
2209
+ this.completers = editor.completers;
2210
+ var total = editor.completers.length;
2211
+ editor.completers.forEach(function (completer, i) {
2212
+ completer.getCompletions(editor, session, pos, prefix, function (err, results) {
2213
+ if (completer.hideInlinePreview)
2214
+ results = results.map(function (result) {
2215
+ return Object.assign(result, { hideInlinePreview: completer.hideInlinePreview });
2216
+ });
2217
+ if (!err && results)
2218
+ matches = matches.concat(results);
2219
+ callback(null, {
2220
+ prefix: util.getCompletionPrefix(editor),
2221
+ matches: matches,
2222
+ finished: (--total === 0)
2223
+ });
2224
+ });
2225
+ });
2226
+ return true;
2227
+ };
2228
+ CompletionProvider.prototype.provideCompletions = function (editor, options, callback) {
2229
+ var processResults = function (results) {
2230
+ var prefix = results.prefix;
2231
+ var matches = results.matches;
2232
+ this.completions = new FilteredList(matches);
2233
+ if (options.exactMatch)
2234
+ this.completions.exactMatch = true;
2235
+ if (options.ignoreCaption)
2236
+ this.completions.ignoreCaption = true;
2237
+ this.completions.setFilter(prefix);
2238
+ if (results.finished || this.completions.filtered.length)
2239
+ callback(null, this.completions, results.finished);
2240
+ }.bind(this);
2241
+ var isImmediate = true;
2242
+ var immediateResults = null;
2243
+ this.gatherCompletions(editor, function (err, results) {
2244
+ if (!this.active) {
2245
+ return;
2246
+ }
2247
+ if (err) {
2248
+ callback(err, [], true);
2249
+ this.detach();
2250
+ }
2251
+ var prefix = results.prefix;
2252
+ if (prefix.indexOf(results.prefix) !== 0)
2253
+ return;
2254
+ if (isImmediate) {
2255
+ immediateResults = results;
2256
+ return;
2257
+ }
2258
+ processResults(results);
2259
+ }.bind(this));
2260
+ isImmediate = false;
2261
+ if (immediateResults) {
2262
+ var results = immediateResults;
2263
+ immediateResults = null;
2264
+ processResults(results);
2265
+ }
2266
+ };
2267
+ CompletionProvider.prototype.detach = function () {
2268
+ this.active = false;
2269
+ this.completers && this.completers.forEach(function (completer) {
2270
+ if (typeof completer.cancel === "function") {
2271
+ completer.cancel();
2272
+ }
2273
+ });
2274
+ };
2275
+ return CompletionProvider;
2276
+ }());
2277
+ var FilteredList = /** @class */ (function () {
2278
+ function FilteredList(array, filterText) {
2279
+ this.all = array;
2280
+ this.filtered = array;
2281
+ this.filterText = filterText || "";
2282
+ this.exactMatch = false;
2283
+ this.ignoreCaption = false;
2284
+ }
2285
+ FilteredList.prototype.setFilter = function (str) {
1689
2286
  if (str.length > this.filterText && str.lastIndexOf(this.filterText, 0) === 0)
1690
2287
  var matches = this.filtered;
1691
2288
  else
@@ -1706,12 +2303,17 @@ var FilteredList = function (array, filterText) {
1706
2303
  });
1707
2304
  this.filtered = matches;
1708
2305
  };
1709
- this.filterCompletions = function (items, needle) {
2306
+ FilteredList.prototype.filterCompletions = function (items, needle) {
1710
2307
  var results = [];
1711
2308
  var upper = needle.toUpperCase();
1712
2309
  var lower = needle.toLowerCase();
1713
2310
  loop: for (var i = 0, item; item = items[i]; i++) {
1714
- var caption = item.caption || item.value || item.snippet;
2311
+ if (item.skipFilter) {
2312
+ item.$score = item.score;
2313
+ results.push(item);
2314
+ continue;
2315
+ }
2316
+ var caption = (!this.ignoreCaption && item.caption) || item.value || item.snippet;
1715
2317
  if (!caption)
1716
2318
  continue;
1717
2319
  var lastIndex = -1;
@@ -1752,16 +2354,99 @@ var FilteredList = function (array, filterText) {
1752
2354
  }
1753
2355
  return results;
1754
2356
  };
1755
- }).call(FilteredList.prototype);
2357
+ return FilteredList;
2358
+ }());
1756
2359
  exports.Autocomplete = Autocomplete;
2360
+ exports.CompletionProvider = CompletionProvider;
1757
2361
  exports.FilteredList = FilteredList;
1758
2362
 
1759
2363
  });
1760
2364
 
2365
+ define("ace/marker_group",["require","exports","module"], function(require, exports, module){"use strict";
2366
+ var MarkerGroup = /** @class */ (function () {
2367
+ function MarkerGroup(session, options) {
2368
+ if (options)
2369
+ this.markerType = options.markerType;
2370
+ this.markers = [];
2371
+ this.session = session;
2372
+ session.addDynamicMarker(this);
2373
+ }
2374
+ MarkerGroup.prototype.getMarkerAtPosition = function (pos) {
2375
+ return this.markers.find(function (marker) {
2376
+ return marker.range.contains(pos.row, pos.column);
2377
+ });
2378
+ };
2379
+ MarkerGroup.prototype.markersComparator = function (a, b) {
2380
+ return a.range.start.row - b.range.start.row;
2381
+ };
2382
+ MarkerGroup.prototype.setMarkers = function (markers) {
2383
+ this.markers = markers.sort(this.markersComparator).slice(0, this.MAX_MARKERS);
2384
+ this.session._signal("changeBackMarker");
2385
+ };
2386
+ MarkerGroup.prototype.update = function (html, markerLayer, session, config) {
2387
+ if (!this.markers || !this.markers.length)
2388
+ return;
2389
+ var visibleRangeStartRow = config.firstRow, visibleRangeEndRow = config.lastRow;
2390
+ var foldLine;
2391
+ var markersOnOneLine = 0;
2392
+ var lastRow = 0;
2393
+ for (var i = 0; i < this.markers.length; i++) {
2394
+ var marker = this.markers[i];
2395
+ if (marker.range.end.row < visibleRangeStartRow)
2396
+ continue;
2397
+ if (marker.range.start.row > visibleRangeEndRow)
2398
+ continue;
2399
+ if (marker.range.start.row === lastRow) {
2400
+ markersOnOneLine++;
2401
+ }
2402
+ else {
2403
+ lastRow = marker.range.start.row;
2404
+ markersOnOneLine = 0;
2405
+ }
2406
+ if (markersOnOneLine > 200) {
2407
+ continue;
2408
+ }
2409
+ var markerVisibleRange = marker.range.clipRows(visibleRangeStartRow, visibleRangeEndRow);
2410
+ if (markerVisibleRange.start.row === markerVisibleRange.end.row
2411
+ && markerVisibleRange.start.column === markerVisibleRange.end.column) {
2412
+ continue; // visible range is empty
2413
+ }
2414
+ var screenRange = markerVisibleRange.toScreenRange(session);
2415
+ if (screenRange.isEmpty()) {
2416
+ foldLine = session.getNextFoldLine(markerVisibleRange.end.row, foldLine);
2417
+ if (foldLine && foldLine.end.row > markerVisibleRange.end.row) {
2418
+ visibleRangeStartRow = foldLine.end.row;
2419
+ }
2420
+ continue;
2421
+ }
2422
+ if (this.markerType === "fullLine") {
2423
+ markerLayer.drawFullLineMarker(html, screenRange, marker.className, config);
2424
+ }
2425
+ else if (screenRange.isMultiLine()) {
2426
+ if (this.markerType === "line")
2427
+ markerLayer.drawMultiLineMarker(html, screenRange, marker.className, config);
2428
+ else
2429
+ markerLayer.drawTextMarker(html, screenRange, marker.className, config);
2430
+ }
2431
+ else {
2432
+ markerLayer.drawSingleLineMarker(html, screenRange, marker.className + " ace_br15", config);
2433
+ }
2434
+ }
2435
+ };
2436
+ return MarkerGroup;
2437
+ }());
2438
+ MarkerGroup.prototype.MAX_MARKERS = 10000;
2439
+ exports.MarkerGroup = MarkerGroup;
2440
+
2441
+ });
2442
+
1761
2443
  define("ace/autocomplete/text_completer",["require","exports","module","ace/range"], function(require, exports, module){var Range = require("../range").Range;
1762
2444
  var splitRegex = /[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;
1763
2445
  function getWordIndex(doc, pos) {
1764
- var textBefore = doc.getTextRange(Range.fromPoints({ row: 0, column: 0 }, pos));
2446
+ var textBefore = doc.getTextRange(Range.fromPoints({
2447
+ row: 0,
2448
+ column: 0
2449
+ }, pos));
1765
2450
  return textBefore.split(splitRegex).length - 1;
1766
2451
  }
1767
2452
  function wordDistance(doc, pos) {
@@ -1783,6 +2468,7 @@ function wordDistance(doc, pos) {
1783
2468
  });
1784
2469
  return wordScores;
1785
2470
  }
2471
+ exports.id = "textCompleter";
1786
2472
  exports.getCompletions = function (editor, session, pos, prefix, callback) {
1787
2473
  var wordScore = wordDistance(session, pos);
1788
2474
  var wordList = Object.keys(wordScore);
@@ -1798,12 +2484,38 @@ exports.getCompletions = function (editor, session, pos, prefix, callback) {
1798
2484
 
1799
2485
  });
1800
2486
 
1801
- define("ace/ext/language_tools",["require","exports","module","ace/snippets","ace/autocomplete","ace/config","ace/lib/lang","ace/autocomplete/util","ace/autocomplete/text_completer","ace/editor","ace/config"], function(require, exports, module){"use strict";
2487
+ define("ace/ext/language_tools",["require","exports","module","ace/snippets","ace/autocomplete","ace/config","ace/lib/lang","ace/autocomplete/util","ace/marker_group","ace/autocomplete/text_completer","ace/editor","ace/config"], function(require, exports, module){/**
2488
+ * ## Language Tools extension for Ace Editor
2489
+ *
2490
+ * Provides autocompletion, snippets, and language intelligence features for the Ace code editor.
2491
+ * This extension integrates multiple completion providers including keyword completion, snippet expansion,
2492
+ * and text-based completion to enhance the coding experience with contextual suggestions and automated code generation.
2493
+ *
2494
+ * **Configuration Options:**
2495
+ * - `enableBasicAutocompletion`: Enable/disable basic completion functionality
2496
+ * - `enableLiveAutocompletion`: Enable/disable real-time completion suggestions
2497
+ * - `enableSnippets`: Enable/disable snippet expansion with Tab key
2498
+ * - `liveAutocompletionDelay`: Delay before showing live completion popup
2499
+ * - `liveAutocompletionThreshold`: Minimum prefix length to trigger completion
2500
+ *
2501
+ * **Usage:**
2502
+ * ```javascript
2503
+ * editor.setOptions({
2504
+ * enableBasicAutocompletion: true,
2505
+ * enableLiveAutocompletion: true,
2506
+ * enableSnippets: true
2507
+ * });
2508
+ * ```
2509
+ *
2510
+ * @module
2511
+ */
2512
+ "use strict";
1802
2513
  var snippetManager = require("../snippets").snippetManager;
1803
2514
  var Autocomplete = require("../autocomplete").Autocomplete;
1804
2515
  var config = require("../config");
1805
2516
  var lang = require("../lib/lang");
1806
2517
  var util = require("../autocomplete/util");
2518
+ var MarkerGroup = require("../marker_group").MarkerGroup;
1807
2519
  var textCompleter = require("../autocomplete/text_completer");
1808
2520
  var keyWordCompleter = {
1809
2521
  getCompletions: function (editor, session, pos, prefix, callback) {
@@ -1812,8 +2524,13 @@ var keyWordCompleter = {
1812
2524
  }
1813
2525
  var state = editor.session.getState(pos.row);
1814
2526
  var completions = session.$mode.getCompletions(state, session, pos, prefix);
2527
+ completions = completions.map(function (el) {
2528
+ el.completerId = keyWordCompleter.id;
2529
+ return el;
2530
+ });
1815
2531
  callback(null, completions);
1816
- }
2532
+ },
2533
+ id: "keywordCompleter"
1817
2534
  };
1818
2535
  var transformSnippetTooltip = function (str) {
1819
2536
  var record = {};
@@ -1844,20 +2561,21 @@ var snippetCompleter = {
1844
2561
  caption: caption,
1845
2562
  snippet: s.content,
1846
2563
  meta: s.tabTrigger && !s.name ? s.tabTrigger + "\u21E5 " : "snippet",
1847
- type: "snippet"
2564
+ completerId: snippetCompleter.id
1848
2565
  });
1849
2566
  }
1850
2567
  }, this);
1851
2568
  callback(null, completions);
1852
2569
  },
1853
2570
  getDocTooltip: function (item) {
1854
- if (item.type == "snippet" && !item.docHTML) {
2571
+ if (item.snippet && !item.docHTML) {
1855
2572
  item.docHTML = [
1856
2573
  "<b>", lang.escapeHTML(item.caption), "</b>", "<hr></hr>",
1857
2574
  lang.escapeHTML(transformSnippetTooltip(item.snippet))
1858
2575
  ].join("");
1859
2576
  }
1860
- }
2577
+ },
2578
+ id: "snippetCompleter"
1861
2579
  };
1862
2580
  var completers = [snippetCompleter, textCompleter, keyWordCompleter];
1863
2581
  exports.setCompleters = function (val) {
@@ -1918,20 +2636,38 @@ var doLiveAutocomplete = function (e) {
1918
2636
  if (hasCompleter && !util.getCompletionPrefix(editor))
1919
2637
  editor.completer.detach();
1920
2638
  }
1921
- else if (e.command.name === "insertstring") {
1922
- var prefix = util.getCompletionPrefix(editor);
1923
- if (prefix && !hasCompleter) {
1924
- var completer = Autocomplete.for(editor);
1925
- completer.autoInsert = false;
1926
- completer.showPopup(editor);
2639
+ else if (e.command.name === "insertstring" && !hasCompleter) {
2640
+ lastExecEvent = e;
2641
+ var delay = e.editor.$liveAutocompletionDelay;
2642
+ if (delay) {
2643
+ liveAutocompleteTimer.delay(delay);
2644
+ }
2645
+ else {
2646
+ showLiveAutocomplete(e);
1927
2647
  }
1928
2648
  }
1929
2649
  };
2650
+ var lastExecEvent;
2651
+ var liveAutocompleteTimer = lang.delayedCall(function () {
2652
+ showLiveAutocomplete(lastExecEvent);
2653
+ }, 0);
2654
+ var showLiveAutocomplete = function (e) {
2655
+ var editor = e.editor;
2656
+ var prefix = util.getCompletionPrefix(editor);
2657
+ var previousChar = e.args;
2658
+ var triggerAutocomplete = util.triggerAutocomplete(editor, previousChar);
2659
+ if (prefix && prefix.length >= editor.$liveAutocompletionThreshold || triggerAutocomplete) {
2660
+ var completer = Autocomplete.for(editor);
2661
+ completer.autoShown = true;
2662
+ completer.showPopup(editor);
2663
+ }
2664
+ };
1930
2665
  var Editor = require("../editor").Editor;
1931
2666
  require("../config").defineOptions(Editor.prototype, "editor", {
1932
2667
  enableBasicAutocompletion: {
1933
2668
  set: function (val) {
1934
2669
  if (val) {
2670
+ Autocomplete.for(this);
1935
2671
  if (!this.completers)
1936
2672
  this.completers = Array.isArray(val) ? val : completers;
1937
2673
  this.commands.addCommand(Autocomplete.startCommand);
@@ -1950,11 +2686,17 @@ require("../config").defineOptions(Editor.prototype, "editor", {
1950
2686
  this.commands.on('afterExec', doLiveAutocomplete);
1951
2687
  }
1952
2688
  else {
1953
- this.commands.removeListener('afterExec', doLiveAutocomplete);
2689
+ this.commands.off('afterExec', doLiveAutocomplete);
1954
2690
  }
1955
2691
  },
1956
2692
  value: false
1957
2693
  },
2694
+ liveAutocompletionDelay: {
2695
+ initialValue: 0
2696
+ },
2697
+ liveAutocompletionThreshold: {
2698
+ initialValue: 0
2699
+ },
1958
2700
  enableSnippets: {
1959
2701
  set: function (val) {
1960
2702
  if (val) {
@@ -1970,6 +2712,7 @@ require("../config").defineOptions(Editor.prototype, "editor", {
1970
2712
  value: false
1971
2713
  }
1972
2714
  });
2715
+ exports.MarkerGroup = MarkerGroup;
1973
2716
 
1974
2717
  }); (function() {
1975
2718
  window.require(["ace/ext/language_tools"], function(m) {