PluginProbe
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits / 3.1.2
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits v3.1.2
3.2.2 3.2.3 3.2.1 3.2.0 3.1.9 3.1.8 3.1.7 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.9 trunk 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.3 1.1.4 1.1.5 All 174 releases
master-addons / assets / vendor / ace / ext-language_tools.js

ext-language_tools.js in Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits 3.1.2, at assets/vendor/ace/ext-language_tools.js

2,726 lines 112.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ace.define("ace/snippets",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/editor"], function(require, exports, module){"use strict";
2 var dom = require("./lib/dom");
3 var oop = require("./lib/oop");
4 var EventEmitter = require("./lib/event_emitter").EventEmitter;
5 var lang = require("./lib/lang");
6 var Range = require("./range").Range;
7 var RangeList = require("./range_list").RangeList;
8 var HashHandler = require("./keyboard/hash_handler").HashHandler;
9 var Tokenizer = require("./tokenizer").Tokenizer;
10 var clipboard = require("./clipboard");
11 var VARIABLES = {
12 CURRENT_WORD: function (editor) {
13 return editor.session.getTextRange(editor.session.getWordRange());
14 },
15 SELECTION: function (editor, name, indentation) {
16 var text = editor.session.getTextRange();
17 if (indentation)
18 return text.replace(/\n\r?([ \t]*\S)/g, "\n" + indentation + "$1");
19 return text;
20 },
21 CURRENT_LINE: function (editor) {
22 return editor.session.getLine(editor.getCursorPosition().row);
23 },
24 PREV_LINE: function (editor) {
25 return editor.session.getLine(editor.getCursorPosition().row - 1);
26 },
27 LINE_INDEX: function (editor) {
28 return editor.getCursorPosition().row;
29 },
30 LINE_NUMBER: function (editor) {
31 return editor.getCursorPosition().row + 1;
32 },
33 SOFT_TABS: function (editor) {
34 return editor.session.getUseSoftTabs() ? "YES" : "NO";
35 },
36 TAB_SIZE: function (editor) {
37 return editor.session.getTabSize();
38 },
39 CLIPBOARD: function (editor) {
40 return clipboard.getText && clipboard.getText();
41 },
42 FILENAME: function (editor) {
43 return /[^/\\]*$/.exec(this.FILEPATH(editor))[0];
44 },
45 FILENAME_BASE: function (editor) {
46 return /[^/\\]*$/.exec(this.FILEPATH(editor))[0].replace(/\.[^.]*$/, "");
47 },
48 DIRECTORY: function (editor) {
49 return this.FILEPATH(editor).replace(/[^/\\]*$/, "");
50 },
51 FILEPATH: function (editor) { return "/not implemented.txt"; },
52 WORKSPACE_NAME: function () { return "Unknown"; },
53 FULLNAME: function () { return "Unknown"; },
54 BLOCK_COMMENT_START: function (editor) {
55 var mode = editor.session.$mode || {};
56 return mode.blockComment && mode.blockComment.start || "";
57 },
58 BLOCK_COMMENT_END: function (editor) {
59 var mode = editor.session.$mode || {};
60 return mode.blockComment && mode.blockComment.end || "";
61 },
62 LINE_COMMENT: function (editor) {
63 var mode = editor.session.$mode || {};
64 return mode.lineCommentStart || "";
65 },
66 CURRENT_YEAR: date.bind(null, { year: "numeric" }),
67 CURRENT_YEAR_SHORT: date.bind(null, { year: "2-digit" }),
68 CURRENT_MONTH: date.bind(null, { month: "numeric" }),
69 CURRENT_MONTH_NAME: date.bind(null, { month: "long" }),
70 CURRENT_MONTH_NAME_SHORT: date.bind(null, { month: "short" }),
71 CURRENT_DATE: date.bind(null, { day: "2-digit" }),
72 CURRENT_DAY_NAME: date.bind(null, { weekday: "long" }),
73 CURRENT_DAY_NAME_SHORT: date.bind(null, { weekday: "short" }),
74 CURRENT_HOUR: date.bind(null, { hour: "2-digit", hour12: false }),
75 CURRENT_MINUTE: date.bind(null, { minute: "2-digit" }),
76 CURRENT_SECOND: date.bind(null, { second: "2-digit" })
77 };
78 VARIABLES.SELECTED_TEXT = VARIABLES.SELECTION;
79 function date(dateFormat) {
80 var str = new Date().toLocaleString("en-us", dateFormat);
81 return str.length == 1 ? "0" + str : str;
82 }
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 };
92 SnippetManager.prototype.createTokenizer = function () {
93 function TabstopToken(str) {
94 str = str.substr(1);
95 if (/^\d+$/.test(str))
96 return [{ tabstopId: parseInt(str, 10) }];
97 return [{ text: str }];
98 }
99 function escape(ch) {
100 return "(?:[^\\\\" + ch + "]|\\\\.)";
101 }
102 var formatMatcher = {
103 regex: "/(" + escape("/") + "+)/",
104 onMatch: function (val, state, stack) {
105 var ts = stack[0];
106 ts.fmtString = true;
107 ts.guard = val.slice(1, -1);
108 ts.flag = "";
109 return "";
110 },
111 next: "formatString"
112 };
113 SnippetManager["$tokenizer"] = new Tokenizer({
114 start: [
115 { regex: /\\./, onMatch: function (val, state, stack) {
116 var ch = val[1];
117 if (ch == "}" && stack.length) {
118 val = ch;
119 }
120 else if ("`$\\".indexOf(ch) != -1) {
121 val = ch;
122 }
123 return [val];
124 } },
125 { regex: /}/, onMatch: function (val, state, stack) {
126 return [stack.length ? stack.shift() : val];
127 } },
128 { regex: /\$(?:\d+|\w+)/, onMatch: TabstopToken },
129 { regex: /\$\{[\dA-Z_a-z]+/, onMatch: function (str, state, stack) {
130 var t = TabstopToken(str.substr(1));
131 stack.unshift(t[0]);
132 return t;
133 }, next: "snippetVar" },
134 { regex: /\n/, token: "newline", merge: false }
135 ],
136 snippetVar: [
137 { regex: "\\|" + escape("\\|") + "*\\|", onMatch: function (val, state, stack) {
138 var choices = val.slice(1, -1).replace(/\\[,|\\]|,/g, function (operator) {
139 return operator.length == 2 ? operator[1] : "\x00";
140 }).split("\x00").map(function (value) {
141 return { value: value };
142 });
143 stack[0].choices = choices;
144 return [choices[0]];
145 }, next: "start" },
146 formatMatcher,
147 { regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "start" }
148 ],
149 formatString: [
150 { regex: /:/, onMatch: function (val, state, stack) {
151 if (stack.length && stack[0].expectElse) {
152 stack[0].expectElse = false;
153 stack[0].ifEnd = { elseEnd: stack[0] };
154 return [stack[0].ifEnd];
155 }
156 return ":";
157 } },
158 { regex: /\\./, onMatch: function (val, state, stack) {
159 var ch = val[1];
160 if (ch == "}" && stack.length)
161 val = ch;
162 else if ("`$\\".indexOf(ch) != -1)
163 val = ch;
164 else if (ch == "n")
165 val = "\n";
166 else if (ch == "t")
167 val = "\t";
168 else if ("ulULE".indexOf(ch) != -1)
169 val = { changeCase: ch, local: ch > "a" };
170 return [val];
171 } },
172 { regex: "/\\w*}", onMatch: function (val, state, stack) {
173 var next = stack.shift();
174 if (next)
175 next.flag = val.slice(1, -1);
176 this.next = next && next.tabstopId ? "start" : "";
177 return [next || val];
178 }, next: "start" },
179 { regex: /\$(?:\d+|\w+)/, onMatch: function (val, state, stack) {
180 return [{ text: val.slice(1) }];
181 } },
182 { regex: /\${\w+/, onMatch: function (val, state, stack) {
183 var token = { text: val.slice(2) };
184 stack.unshift(token);
185 return [token];
186 }, next: "formatStringVar" },
187 { regex: /\n/, token: "newline", merge: false },
188 { regex: /}/, onMatch: function (val, state, stack) {
189 var next = stack.shift();
190 this.next = next && next.tabstopId ? "start" : "";
191 return [next || val];
192 }, next: "start" }
193 ],
194 formatStringVar: [
195 { regex: /:\/\w+}/, onMatch: function (val, state, stack) {
196 var ts = stack[0];
197 ts.formatFunction = val.slice(2, -1);
198 return [stack.shift()];
199 }, next: "formatString" },
200 formatMatcher,
201 { regex: /:[\?\-+]?/, onMatch: function (val, state, stack) {
202 if (val[1] == "+")
203 stack[0].ifEnd = stack[0];
204 if (val[1] == "?")
205 stack[0].expectElse = true;
206 }, next: "formatString" },
207 { regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "formatString" }
208 ]
209 });
210 return SnippetManager["$tokenizer"];
211 };
212 SnippetManager.prototype.tokenizeTmSnippet = function (str, startState) {
213 return this.getTokenizer().getLineTokens(str, startState).tokens.map(function (x) {
214 return x.value || x;
215 });
216 };
217 SnippetManager.prototype.getVariableValue = function (editor, name, indentation) {
218 if (/^\d+$/.test(name))
219 return (this.variables.__ || {})[name] || "";
220 if (/^[A-Z]\d+$/.test(name))
221 return (this.variables[name[0] + "__"] || {})[name.substr(1)] || "";
222 name = name.replace(/^TM_/, "");
223 if (!this.variables.hasOwnProperty(name))
224 return "";
225 var value = this.variables[name];
226 if (typeof value == "function")
227 value = this.variables[name](editor, name, indentation);
228 return value == null ? "" : value;
229 };
230 SnippetManager.prototype.tmStrFormat = function (str, ch, editor) {
231 if (!ch.fmt)
232 return str;
233 var flag = ch.flag || "";
234 var re = ch.guard;
235 re = new RegExp(re, flag.replace(/[^gim]/g, ""));
236 var fmtTokens = typeof ch.fmt == "string" ? this.tokenizeTmSnippet(ch.fmt, "formatString") : ch.fmt;
237 var _self = this;
238 var formatted = str.replace(re, function () {
239 var oldArgs = _self.variables.__;
240 _self.variables.__ = [].slice.call(arguments);
241 var fmtParts = _self.resolveVariables(fmtTokens, editor);
242 var gChangeCase = "E";
243 for (var i = 0; i < fmtParts.length; i++) {
244 var ch = fmtParts[i];
245 if (typeof ch == "object") {
246 fmtParts[i] = "";
247 if (ch.changeCase && ch.local) {
248 var next = fmtParts[i + 1];
249 if (next && typeof next == "string") {
250 if (ch.changeCase == "u")
251 fmtParts[i] = next[0].toUpperCase();
252 else
253 fmtParts[i] = next[0].toLowerCase();
254 fmtParts[i + 1] = next.substr(1);
255 }
256 }
257 else if (ch.changeCase) {
258 gChangeCase = ch.changeCase;
259 }
260 }
261 else if (gChangeCase == "U") {
262 fmtParts[i] = ch.toUpperCase();
263 }
264 else if (gChangeCase == "L") {
265 fmtParts[i] = ch.toLowerCase();
266 }
267 }
268 _self.variables.__ = oldArgs;
269 return fmtParts.join("");
270 });
271 return formatted;
272 };
273 SnippetManager.prototype.tmFormatFunction = function (str, ch, editor) {
274 if (ch.formatFunction == "upcase")
275 return str.toUpperCase();
276 if (ch.formatFunction == "downcase")
277 return str.toLowerCase();
278 return str;
279 };
280 SnippetManager.prototype.resolveVariables = function (snippet, editor) {
281 var result = [];
282 var indentation = "";
283 var afterNewLine = true;
284 for (var i = 0; i < snippet.length; i++) {
285 var ch = snippet[i];
286 if (typeof ch == "string") {
287 result.push(ch);
288 if (ch == "\n") {
289 afterNewLine = true;
290 indentation = "";
291 }
292 else if (afterNewLine) {
293 indentation = /^\t*/.exec(ch)[0];
294 afterNewLine = /\S/.test(ch);
295 }
296 continue;
297 }
298 if (!ch)
299 continue;
300 afterNewLine = false;
301 if (ch.fmtString) {
302 var j = snippet.indexOf(ch, i + 1);
303 if (j == -1)
304 j = snippet.length;
305 ch.fmt = snippet.slice(i + 1, j);
306 i = j;
307 }
308 if (ch.text) {
309 var value = this.getVariableValue(editor, ch.text, indentation) + "";
310 if (ch.fmtString)
311 value = this.tmStrFormat(value, ch, editor);
312 if (ch.formatFunction)
313 value = this.tmFormatFunction(value, ch, editor);
314 if (value && !ch.ifEnd) {
315 result.push(value);
316 gotoNext(ch);
317 }
318 else if (!value && ch.ifEnd) {
319 gotoNext(ch.ifEnd);
320 }
321 }
322 else if (ch.elseEnd) {
323 gotoNext(ch.elseEnd);
324 }
325 else if (ch.tabstopId != null) {
326 result.push(ch);
327 }
328 else if (ch.changeCase != null) {
329 result.push(ch);
330 }
331 }
332 function gotoNext(ch) {
333 var i1 = snippet.indexOf(ch, i + 1);
334 if (i1 != -1)
335 i = i1;
336 }
337 return result;
338 };
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);
346 var range = editor.getSelectionRange();
347 var end = editor.session.replace(range, processedSnippet.text);
348 var tabstopManager = new TabstopManager(editor);
349 var selectionId = editor.inVirtualSelectionMode && editor.selection.index;
350 tabstopManager.addTabstops(processedSnippet.tabstops, range.start, end, selectionId);
351 };
352 SnippetManager.prototype.insertSnippet = function (editor, snippetText, options) {
353 if (options === void 0) { options = {}; }
354 var self = this;
355 if (editor.inVirtualSelectionMode)
356 return self.insertSnippetForSelection(editor, snippetText, options);
357 editor.forEachSelection(function () {
358 self.insertSnippetForSelection(editor, snippetText, options);
359 }, null, { keepOrder: true });
360 if (editor.tabstopManager)
361 editor.tabstopManager.tabNext();
362 };
363 SnippetManager.prototype.$getScope = function (editor) {
364 var scope = editor.session.$mode.$id || "";
365 scope = scope.split("/").pop();
366 if (scope === "html" || scope === "php") {
367 if (scope === "php" && !editor.session.$mode.inlinePhp)
368 scope = "html";
369 var c = editor.getCursorPosition();
370 var state = editor.session.getState(c.row);
371 if (typeof state === "object") {
372 state = state[0];
373 }
374 if (state.substring) {
375 if (state.substring(0, 3) == "js-")
376 scope = "javascript";
377 else if (state.substring(0, 4) == "css-")
378 scope = "css";
379 else if (state.substring(0, 4) == "php-")
380 scope = "php";
381 }
382 }
383 return scope;
384 };
385 SnippetManager.prototype.getActiveScopes = function (editor) {
386 var scope = this.$getScope(editor);
387 var scopes = [scope];
388 var snippetMap = this.snippetMap;
389 if (snippetMap[scope] && snippetMap[scope].includeScopes) {
390 scopes.push.apply(scopes, snippetMap[scope].includeScopes);
391 }
392 scopes.push("_");
393 return scopes;
394 };
395 SnippetManager.prototype.expandWithTab = function (editor, options) {
396 var self = this;
397 var result = editor.forEachSelection(function () {
398 return self.expandSnippetForSelection(editor, options);
399 }, null, { keepOrder: true });
400 if (result && editor.tabstopManager)
401 editor.tabstopManager.tabNext();
402 return result;
403 };
404 SnippetManager.prototype.expandSnippetForSelection = function (editor, options) {
405 var cursor = editor.getCursorPosition();
406 var line = editor.session.getLine(cursor.row);
407 var before = line.substring(0, cursor.column);
408 var after = line.substr(cursor.column);
409 var snippetMap = this.snippetMap;
410 var snippet;
411 this.getActiveScopes(editor).some(function (scope) {
412 var snippets = snippetMap[scope];
413 if (snippets)
414 snippet = this.findMatchingSnippet(snippets, before, after);
415 return !!snippet;
416 }, this);
417 if (!snippet)
418 return false;
419 if (options && options.dryRun)
420 return true;
421 editor.session.doc.removeInLine(cursor.row, cursor.column - snippet.replaceBefore.length, cursor.column + snippet.replaceAfter.length);
422 this.variables.M__ = snippet.matchBefore;
423 this.variables.T__ = snippet.matchAfter;
424 this.insertSnippetForSelection(editor, snippet.content);
425 this.variables.M__ = this.variables.T__ = null;
426 return true;
427 };
428 SnippetManager.prototype.findMatchingSnippet = function (snippetList, before, after) {
429 for (var i = snippetList.length; i--;) {
430 var s = snippetList[i];
431 if (s.startRe && !s.startRe.test(before))
432 continue;
433 if (s.endRe && !s.endRe.test(after))
434 continue;
435 if (!s.startRe && !s.endRe)
436 continue;
437 s.matchBefore = s.startRe ? s.startRe.exec(before) : [""];
438 s.matchAfter = s.endRe ? s.endRe.exec(after) : [""];
439 s.replaceBefore = s.triggerRe ? s.triggerRe.exec(before)[0] : "";
440 s.replaceAfter = s.endTriggerRe ? s.endTriggerRe.exec(after)[0] : "";
441 return s;
442 }
443 };
444 SnippetManager.prototype.register = function (snippets, scope) {
445 var snippetMap = this.snippetMap;
446 var snippetNameMap = this.snippetNameMap;
447 var self = this;
448 if (!snippets)
449 snippets = [];
450 function wrapRegexp(src) {
451 if (src && !/^\^?\(.*\)\$?$|^\\b$/.test(src))
452 src = "(?:" + src + ")";
453 return src || "";
454 }
455 function guardedRegexp(re, guard, opening) {
456 re = wrapRegexp(re);
457 guard = wrapRegexp(guard);
458 if (opening) {
459 re = guard + re;
460 if (re && re[re.length - 1] != "$")
461 re = re + "$";
462 }
463 else {
464 re = re + guard;
465 if (re && re[0] != "^")
466 re = "^" + re;
467 }
468 return new RegExp(re);
469 }
470 function addSnippet(s) {
471 if (!s.scope)
472 s.scope = scope || "_";
473 scope = s.scope;
474 if (!snippetMap[scope]) {
475 snippetMap[scope] = [];
476 snippetNameMap[scope] = {};
477 }
478 var map = snippetNameMap[scope];
479 if (s.name) {
480 var old = map[s.name];
481 if (old)
482 self.unregister(old);
483 map[s.name] = s;
484 }
485 snippetMap[scope].push(s);
486 if (s.prefix)
487 s.tabTrigger = s.prefix;
488 if (!s.content && s.body)
489 s.content = Array.isArray(s.body) ? s.body.join("\n") : s.body;
490 if (s.tabTrigger && !s.trigger) {
491 if (!s.guard && /^\w/.test(s.tabTrigger))
492 s.guard = "\\b";
493 s.trigger = lang.escapeRegExp(s.tabTrigger);
494 }
495 if (!s.trigger && !s.guard && !s.endTrigger && !s.endGuard)
496 return;
497 s.startRe = guardedRegexp(s.trigger, s.guard, true);
498 s.triggerRe = new RegExp(s.trigger);
499 s.endRe = guardedRegexp(s.endTrigger, s.endGuard, true);
500 s.endTriggerRe = new RegExp(s.endTrigger);
501 }
502 if (Array.isArray(snippets)) {
503 snippets.forEach(addSnippet);
504 }
505 else {
506 Object.keys(snippets).forEach(function (key) {
507 addSnippet(snippets[key]);
508 });
509 }
510 this._signal("registerSnippets", { scope: scope });
511 };
512 SnippetManager.prototype.unregister = function (snippets, scope) {
513 var snippetMap = this.snippetMap;
514 var snippetNameMap = this.snippetNameMap;
515 function removeSnippet(s) {
516 var nameMap = snippetNameMap[s.scope || scope];
517 if (nameMap && nameMap[s.name]) {
518 delete nameMap[s.name];
519 var map = snippetMap[s.scope || scope];
520 var i = map && map.indexOf(s);
521 if (i >= 0)
522 map.splice(i, 1);
523 }
524 }
525 if (snippets.content)
526 removeSnippet(snippets);
527 else if (Array.isArray(snippets))
528 snippets.forEach(removeSnippet);
529 };
530 SnippetManager.prototype.parseSnippetFile = function (str) {
531 str = str.replace(/\r/g, "");
532 var list = [], /**@type{Snippet}*/ snippet = {};
533 var re = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm;
534 var m;
535 while (m = re.exec(str)) {
536 if (m[1]) {
537 try {
538 snippet = JSON.parse(m[1]);
539 list.push(snippet);
540 }
541 catch (e) { }
542 }
543 if (m[4]) {
544 snippet.content = m[4].replace(/^\t/gm, "");
545 list.push(snippet);
546 snippet = {};
547 }
548 else {
549 var key = m[2], val = m[3];
550 if (key == "regex") {
551 var guardRe = /\/((?:[^\/\\]|\\.)*)|$/g;
552 snippet.guard = guardRe.exec(val)[1];
553 snippet.trigger = guardRe.exec(val)[1];
554 snippet.endTrigger = guardRe.exec(val)[1];
555 snippet.endGuard = guardRe.exec(val)[1];
556 }
557 else if (key == "snippet") {
558 snippet.tabTrigger = val.match(/^\S*/)[0];
559 if (!snippet.name)
560 snippet.name = val;
561 }
562 else if (key) {
563 snippet[key] = val;
564 }
565 }
566 }
567 return list;
568 };
569 SnippetManager.prototype.getSnippetByName = function (name, editor) {
570 var snippetMap = this.snippetNameMap;
571 var snippet;
572 this.getActiveScopes(editor).some(function (scope) {
573 var snippets = snippetMap[scope];
574 if (snippets)
575 snippet = snippets[name];
576 return !!snippet;
577 }, this);
578 return snippet;
579 };
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 };
697 };
698 var TabstopManager = /** @class */ (function () {
699 function TabstopManager(editor) {
700 this.index = 0;
701 this.ranges = [];
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) {
713 this.$openTabstops = null;
714 this.selectedTabstop = null;
715 this.editor = editor;
716 this.session = editor.session;
717 this.editor.on("change", this.$onChange);
718 this.editor.on("changeSelection", this.$onChangeSelection);
719 this.editor.on("changeSession", this.$onChangeSession);
720 this.editor.commands.on("afterExec", this.$onAfterExec);
721 this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
722 };
723 TabstopManager.prototype.detach = function () {
724 this.tabstops.forEach(this.removeTabstopMarkers, this);
725 this.ranges.length = 0;
726 this.tabstops.length = 0;
727 this.selectedTabstop = null;
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);
732 this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
733 this.editor.tabstopManager = null;
734 this.session = null;
735 this.editor = null;
736 };
737 TabstopManager.prototype.onChange = function (delta) {
738 var isRemove = delta.action[0] == "r";
739 var selectedTabstop = this.selectedTabstop || {};
740 var parents = selectedTabstop.parents || {};
741 var tabstops = this.tabstops.slice();
742 for (var i = 0; i < tabstops.length; i++) {
743 var ts = tabstops[i];
744 var active = ts == selectedTabstop || parents[ts.index];
745 ts.rangeList.$bias = active ? 0 : 1;
746 if (delta.action == "remove" && ts !== selectedTabstop) {
747 var parentActive = ts.parents && ts.parents[selectedTabstop.index];
748 var startIndex = ts.rangeList.pointIndex(delta.start, parentActive);
749 startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1;
750 var endIndex = ts.rangeList.pointIndex(delta.end, parentActive);
751 endIndex = endIndex < 0 ? -endIndex - 1 : endIndex - 1;
752 var toRemove = ts.rangeList.ranges.slice(startIndex, endIndex);
753 for (var j = 0; j < toRemove.length; j++)
754 this.removeRange(toRemove[j]);
755 }
756 ts.rangeList.$onChange(delta);
757 }
758 var session = this.session;
759 if (!this.$inChange && isRemove && session.getLength() == 1 && !session.getValue())
760 this.detach();
761 };
762 TabstopManager.prototype.updateLinkedFields = function () {
763 var ts = this.selectedTabstop;
764 if (!ts || !ts.hasLinkedRanges || !ts.firstNonLinked)
765 return;
766 this.$inChange = true;
767 var session = this.session;
768 var text = session.getTextRange(ts.firstNonLinked);
769 for (var i = 0; i < ts.length; i++) {
770 var range = ts[i];
771 if (!range.linked)
772 continue;
773 var original = range.original;
774 var fmt = exports.snippetManager.tmStrFormat(text, original, this.editor);
775 session.replace(range, fmt);
776 }
777 this.$inChange = false;
778 };
779 TabstopManager.prototype.onAfterExec = function (e) {
780 if (e.command && !e.command.readOnly)
781 this.updateLinkedFields();
782 };
783 TabstopManager.prototype.onChangeSelection = function () {
784 if (!this.editor)
785 return;
786 var lead = this.editor.selection.lead;
787 var anchor = this.editor.selection.anchor;
788 var isEmpty = this.editor.selection.isEmpty();
789 for (var i = 0; i < this.ranges.length; i++) {
790 if (this.ranges[i].linked)
791 continue;
792 var containsLead = this.ranges[i].contains(lead.row, lead.column);
793 var containsAnchor = isEmpty || this.ranges[i].contains(anchor.row, anchor.column);
794 if (containsLead && containsAnchor)
795 return;
796 }
797 this.detach();
798 };
799 TabstopManager.prototype.onChangeSession = function () {
800 this.detach();
801 };
802 TabstopManager.prototype.tabNext = function (dir) {
803 var max = this.tabstops.length;
804 var index = this.index + (dir || 1);
805 index = Math.min(Math.max(index, 1), max);
806 if (index == max)
807 index = 0;
808 this.selectTabstop(index);
809 this.updateTabstopMarkers();
810 if (index === 0) {
811 this.detach();
812 }
813 };
814 TabstopManager.prototype.selectTabstop = function (index) {
815 this.$openTabstops = null;
816 var ts = this.tabstops[this.index];
817 if (ts)
818 this.addTabstopMarkers(ts);
819 this.index = index;
820 ts = this.tabstops[this.index];
821 if (!ts || !ts.length)
822 return;
823 this.selectedTabstop = ts;
824 var range = ts.firstNonLinked || ts;
825 if (ts.choices)
826 range.cursor = range.start;
827 if (!this.editor.inVirtualSelectionMode) {
828 var sel = this.editor.multiSelect;
829 sel.toSingleRange(range);
830 for (var i = 0; i < ts.length; i++) {
831 if (ts.hasLinkedRanges && ts[i].linked)
832 continue;
833 sel.addRange(ts[i].clone(), true);
834 }
835 }
836 else {
837 this.editor.selection.fromOrientedRange(range);
838 }
839 this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
840 if (this.selectedTabstop && this.selectedTabstop.choices)
841 this.editor.execCommand("startAutocomplete", { matches: this.selectedTabstop.choices });
842 };
843 TabstopManager.prototype.addTabstops = function (tabstops, start, end) {
844 var useLink = this.useLink || !this.editor.getOption("enableMultiselect");
845 if (!this.$openTabstops)
846 this.$openTabstops = [];
847 if (!tabstops[0]) {
848 var p = Range.fromPoints(end, end);
849 moveRelative(p.start, start);
850 moveRelative(p.end, start);
851 tabstops[0] = [p];
852 tabstops[0].index = 0;
853 }
854 var i = this.index;
855 var arg = [i + 1, 0];
856 var ranges = this.ranges;
857 var snippetId = this.snippetId = (this.snippetId || 0) + 1;
858 tabstops.forEach(function (ts, index) {
859 var dest = this.$openTabstops[index] || ts;
860 dest.snippetId = snippetId;
861 for (var i = 0; i < ts.length; i++) {
862 var p = ts[i];
863 var range = Range.fromPoints(p.start, p.end || p.start);
864 movePoint(range.start, start);
865 movePoint(range.end, start);
866 range.original = p;
867 range.tabstop = dest;
868 ranges.push(range);
869 if (dest != ts)
870 dest.unshift(range);
871 else
872 dest[i] = range;
873 if (p.fmtString || (dest.firstNonLinked && useLink)) {
874 range.linked = true;
875 dest.hasLinkedRanges = true;
876 }
877 else if (!dest.firstNonLinked)
878 dest.firstNonLinked = range;
879 }
880 if (!dest.firstNonLinked)
881 dest.hasLinkedRanges = false;
882 if (dest === ts) {
883 arg.push(dest);
884 this.$openTabstops[index] = dest;
885 }
886 this.addTabstopMarkers(dest);
887 dest.rangeList = dest.rangeList || new RangeList();
888 dest.rangeList.$bias = 0;
889 dest.rangeList.addList(dest);
890 }, this);
891 if (arg.length > 2) {
892 if (this.tabstops.length)
893 arg.push(arg.splice(2, 1)[0]);
894 this.tabstops.splice.apply(this.tabstops, arg);
895 }
896 };
897 TabstopManager.prototype.addTabstopMarkers = function (ts) {
898 var session = this.session;
899 ts.forEach(function (range) {
900 if (!range.markerId)
901 range.markerId = session.addMarker(range, "ace_snippet-marker", "text");
902 });
903 };
904 TabstopManager.prototype.removeTabstopMarkers = function (ts) {
905 var session = this.session;
906 ts.forEach(function (range) {
907 session.removeMarker(range.markerId);
908 range.markerId = null;
909 });
910 };
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) {
926 var i = range.tabstop.indexOf(range);
927 if (i != -1)
928 range.tabstop.splice(i, 1);
929 i = this.ranges.indexOf(range);
930 if (i != -1)
931 this.ranges.splice(i, 1);
932 i = range.tabstop.rangeList.ranges.indexOf(range);
933 if (i != -1)
934 range.tabstop.splice(i, 1);
935 this.session.removeMarker(range.markerId);
936 if (!range.tabstop.length) {
937 i = this.tabstops.indexOf(range.tabstop);
938 if (i != -1)
939 this.tabstops.splice(i, 1);
940 if (!this.tabstops.length)
941 this.detach();
942 }
943 };
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 });
962 var movePoint = function (point, diff) {
963 if (point.row == 0)
964 point.column += diff.column;
965 point.row += diff.row;
966 };
967 var moveRelative = function (point, start) {
968 if (point.row == start.row)
969 point.column -= start.column;
970 point.row -= start.row;
971 };
972 dom.importCssString("\n.ace_snippet-marker {\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n background: rgba(194, 193, 208, 0.09);\n border: 1px dotted rgba(211, 208, 235, 0.62);\n position: absolute;\n}", "snippets.css", false);
973 exports.snippetManager = new SnippetManager();
974 var Editor = require("./editor").Editor;
975 (function () {
976 this.insertSnippet = function (content, options) {
977 return exports.snippetManager.insertSnippet(this, content, options);
978 };
979 this.expandSnippet = function (options) {
980 return exports.snippetManager.expandWithTab(this, options);
981 };
982 }).call(Editor.prototype);
983
984 });
985
986 ace.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";
987 var Renderer = require("../virtual_renderer").VirtualRenderer;
988 var Editor = require("../editor").Editor;
989 var Range = require("../range").Range;
990 var event = require("../lib/event");
991 var lang = require("../lib/lang");
992 var dom = require("../lib/dom");
993 var nls = require("../config").nls;
994 var userAgent = require("./../lib/useragent");
995 var getAriaId = function (index) {
996 return "suggest-aria-id:".concat(index);
997 };
998 var popupAriaRole = userAgent.isSafari ? "menu" : "listbox";
999 var optionAriaRole = userAgent.isSafari ? "menuitem" : "option";
1000 var ariaActiveState = userAgent.isSafari ? "aria-current" : "aria-selected";
1001 var $singleLineEditor = function (el) {
1002 var renderer = new Renderer(el);
1003 renderer.$maxLines = 4;
1004 var editor = new Editor(renderer);
1005 editor.setHighlightActiveLine(false);
1006 editor.setShowPrintMargin(false);
1007 editor.renderer.setShowGutter(false);
1008 editor.renderer.setHighlightGutterLine(false);
1009 editor.$mouseHandler.$focusTimeout = 0;
1010 editor.$highlightTagPending = true;
1011 return editor;
1012 };
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 }
1067 lastMouseEvent = e;
1068 lastMouseEvent.scrollTop = popup.renderer.scrollTop;
1069 popup.isMouseOver = true;
1070 var row = lastMouseEvent.getDocumentPosition().row;
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 }
1116 el.removeAttribute("aria-activedescendant");
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;
1221 popup.session._emit("changeBackMarker");
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 el.style.display = "";
1288 var rootRect = el.offsetParent && el.offsetParent.getBoundingClientRect();
1289 if (anchor === "top") {
1290 el.style.top = "";
1291 el.style.bottom = (screenHeight + scrollBarSize - dims.bottom)
1292 - (rootRect ? screenHeight + scrollBarSize - rootRect.bottom : 0) + "px";
1293 popup.isTopdown = false;
1294 }
1295 else {
1296 el.style.top = (dims.top - (rootRect ? rootRect.top : 0)) + "px";
1297 el.style.bottom = "";
1298 popup.isTopdown = true;
1299 }
1300 var left = pos.left;
1301 if (left + el.offsetWidth > screenWidth)
1302 left = screenWidth - el.offsetWidth;
1303 el.style.left = (left - (rootRect ? rootRect.left : 0)) + "px";
1304 el.style.right = "";
1305 if (!popup.isOpen) {
1306 popup.isOpen = true;
1307 this._signal("show");
1308 lastMouseEvent = null;
1309 }
1310 popup.anchorPos = pos;
1311 popup.anchor = anchor;
1312 return true;
1313 };
1314 popup.show = function (pos, lineHeight, topdownOnly) {
1315 this.tryShow(pos, lineHeight, topdownOnly ? "bottom" : undefined, true);
1316 };
1317 popup.goTo = function (where) {
1318 var row = this.getRow();
1319 var max = this.session.getLength() - 1;
1320 switch (where) {
1321 case "up":
1322 row = row <= 0 ? max : row - 1;
1323 break;
1324 case "down":
1325 row = row >= max ? -1 : row + 1;
1326 break;
1327 case "start":
1328 row = 0;
1329 break;
1330 case "end":
1331 row = max;
1332 break;
1333 }
1334 this.setRow(row);
1335 };
1336 popup.getTextLeftOffset = function () {
1337 return this.$borderSize + this.renderer.$padding + this.$imageSize;
1338 };
1339 popup.$imageSize = 0;
1340 popup.$borderSize = 1;
1341 return popup;
1342 }
1343 return AcePopup;
1344 }());
1345 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: absolute;\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);
1346 exports.AcePopup = AcePopup;
1347 exports.$singleLineEditor = $singleLineEditor;
1348 exports.getAriaId = getAriaId;
1349
1350 });
1351
1352 ace.define("ace/autocomplete/inline_screenreader",["require","exports","module"], function(require, exports, module){"use strict";
1353 var AceInlineScreenReader = /** @class */ (function () {
1354 function AceInlineScreenReader(editor) {
1355 this.editor = editor;
1356 this.screenReaderDiv = document.createElement("div");
1357 this.screenReaderDiv.classList.add("ace_screenreader-only");
1358 this.editor.container.appendChild(this.screenReaderDiv);
1359 }
1360 AceInlineScreenReader.prototype.setScreenReaderContent = function (content) {
1361 if (!this.popup && this.editor.completer && /**@type{import("../autocomplete").Autocomplete}*/ (this.editor.completer).popup) {
1362 this.popup = /**@type{import("../autocomplete").Autocomplete}*/ (this.editor.completer).popup;
1363 this.popup.renderer.on("afterRender", function () {
1364 var row = this.popup.getRow();
1365 var t = this.popup.renderer.$textLayer;
1366 var selected = t.element.childNodes[row - t.config.firstRow];
1367 if (selected) {
1368 var idString = "doc-tooltip ";
1369 for (var lineIndex = 0; lineIndex < this._lines.length; lineIndex++) {
1370 idString += "ace-inline-screenreader-line-".concat(lineIndex, " ");
1371 }
1372 selected.setAttribute("aria-describedby", idString);
1373 }
1374 }.bind(this));
1375 }
1376 while (this.screenReaderDiv.firstChild) {
1377 this.screenReaderDiv.removeChild(this.screenReaderDiv.firstChild);
1378 }
1379 this._lines = content.split(/\r\n|\r|\n/);
1380 var codeElement = this.createCodeBlock();
1381 this.screenReaderDiv.appendChild(codeElement);
1382 };
1383 AceInlineScreenReader.prototype.destroy = function () {
1384 this.screenReaderDiv.remove();
1385 };
1386 AceInlineScreenReader.prototype.createCodeBlock = function () {
1387 var container = document.createElement("pre");
1388 container.setAttribute("id", "ace-inline-screenreader");
1389 for (var lineIndex = 0; lineIndex < this._lines.length; lineIndex++) {
1390 var codeElement = document.createElement("code");
1391 codeElement.setAttribute("id", "ace-inline-screenreader-line-".concat(lineIndex));
1392 var line = document.createTextNode(this._lines[lineIndex]);
1393 codeElement.appendChild(line);
1394 container.appendChild(codeElement);
1395 }
1396 return container;
1397 };
1398 return AceInlineScreenReader;
1399 }());
1400 exports.AceInlineScreenReader = AceInlineScreenReader;
1401
1402 });
1403
1404 ace.define("ace/autocomplete/inline",["require","exports","module","ace/snippets","ace/autocomplete/inline_screenreader"], function(require, exports, module){"use strict";
1405 var snippetManager = require("../snippets").snippetManager;
1406 var AceInlineScreenReader = require("./inline_screenreader").AceInlineScreenReader;
1407 var AceInline = /** @class */ (function () {
1408 function AceInline() {
1409 this.editor = null;
1410 }
1411 AceInline.prototype.show = function (editor, completion, prefix) {
1412 prefix = prefix || "";
1413 if (editor && this.editor && this.editor !== editor) {
1414 this.hide();
1415 this.editor = null;
1416 this.inlineScreenReader = null;
1417 }
1418 if (!editor || !completion) {
1419 return false;
1420 }
1421 if (!this.inlineScreenReader) {
1422 this.inlineScreenReader = new AceInlineScreenReader(editor);
1423 }
1424 var displayText = completion.snippet ? snippetManager.getDisplayTextForSnippet(editor, completion.snippet) : completion.value;
1425 if (completion.hideInlinePreview || !displayText || !displayText.startsWith(prefix)) {
1426 return false;
1427 }
1428 this.editor = editor;
1429 this.inlineScreenReader.setScreenReaderContent(displayText);
1430 displayText = displayText.slice(prefix.length);
1431 if (displayText === "") {
1432 editor.removeGhostText();
1433 }
1434 else {
1435 editor.setGhostText(displayText);
1436 }
1437 return true;
1438 };
1439 AceInline.prototype.isOpen = function () {
1440 if (!this.editor) {
1441 return false;
1442 }
1443 return !!this.editor.renderer.$ghostText;
1444 };
1445 AceInline.prototype.hide = function () {
1446 if (!this.editor) {
1447 return false;
1448 }
1449 this.editor.removeGhostText();
1450 return true;
1451 };
1452 AceInline.prototype.destroy = function () {
1453 this.hide();
1454 this.editor = null;
1455 if (this.inlineScreenReader) {
1456 this.inlineScreenReader.destroy();
1457 this.inlineScreenReader = null;
1458 }
1459 };
1460 return AceInline;
1461 }());
1462 exports.AceInline = AceInline;
1463
1464 });
1465
1466 ace.define("ace/autocomplete/util",["require","exports","module"], function(require, exports, module){"use strict";
1467 exports.parForEach = function (array, fn, callback) {
1468 var completed = 0;
1469 var arLength = array.length;
1470 if (arLength === 0)
1471 callback();
1472 for (var i = 0; i < arLength; i++) {
1473 fn(array[i], function (result, err) {
1474 completed++;
1475 if (completed === arLength)
1476 callback(result, err);
1477 });
1478 }
1479 };
1480 var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/;
1481 exports.retrievePrecedingIdentifier = function (text, pos, regex) {
1482 regex = regex || ID_REGEX;
1483 var buf = [];
1484 for (var i = pos - 1; i >= 0; i--) {
1485 if (regex.test(text[i]))
1486 buf.push(text[i]);
1487 else
1488 break;
1489 }
1490 return buf.reverse().join("");
1491 };
1492 exports.retrieveFollowingIdentifier = function (text, pos, regex) {
1493 regex = regex || ID_REGEX;
1494 var buf = [];
1495 for (var i = pos; i < text.length; i++) {
1496 if (regex.test(text[i]))
1497 buf.push(text[i]);
1498 else
1499 break;
1500 }
1501 return buf;
1502 };
1503 exports.getCompletionPrefix = function (editor) {
1504 var pos = editor.getCursorPosition();
1505 var line = editor.session.getLine(pos.row);
1506 var prefix;
1507 editor.completers.forEach(function (completer) {
1508 if (completer.identifierRegexps) {
1509 completer.identifierRegexps.forEach(function (identifierRegex) {
1510 if (!prefix && identifierRegex)
1511 prefix = this.retrievePrecedingIdentifier(line, pos.column, identifierRegex);
1512 }.bind(this));
1513 }
1514 }.bind(this));
1515 return prefix || this.retrievePrecedingIdentifier(line, pos.column);
1516 };
1517 exports.triggerAutocomplete = function (editor, previousChar) {
1518 var previousChar = previousChar == null
1519 ? editor.session.getPrecedingCharacter()
1520 : previousChar;
1521 return editor.completers.some(function (completer) {
1522 if (completer.triggerCharacters && Array.isArray(completer.triggerCharacters)) {
1523 return completer.triggerCharacters.includes(previousChar);
1524 }
1525 });
1526 };
1527
1528 });
1529
1530 ace.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";
1531 var HashHandler = require("./keyboard/hash_handler").HashHandler;
1532 var AcePopup = require("./autocomplete/popup").AcePopup;
1533 var AceInline = require("./autocomplete/inline").AceInline;
1534 var getAriaId = require("./autocomplete/popup").getAriaId;
1535 var util = require("./autocomplete/util");
1536 var lang = require("./lib/lang");
1537 var dom = require("./lib/dom");
1538 var snippetManager = require("./snippets").snippetManager;
1539 var config = require("./config");
1540 var event = require("./lib/event");
1541 var preventParentScroll = require("./lib/scroll").preventParentScroll;
1542 var destroyCompleter = function (e, editor) {
1543 editor.completer && editor.completer.destroy();
1544 };
1545 var Autocomplete = /** @class */ (function () {
1546 function Autocomplete() {
1547 this.autoInsert = false;
1548 this.autoSelect = true;
1549 this.autoShown = false;
1550 this.exactMatch = false;
1551 this.inlineEnabled = false;
1552 this.keyboardHandler = new HashHandler();
1553 this.keyboardHandler.bindKeys(this.commands);
1554 this.parentNode = null;
1555 this.setSelectOnHover = false;
1556 this.hasSeen = new Set();
1557 this.showLoadingState = false;
1558 this.stickySelectionDelay = 500;
1559 this.blurListener = this.blurListener.bind(this);
1560 this.changeListener = this.changeListener.bind(this);
1561 this.mousedownListener = this.mousedownListener.bind(this);
1562 this.mousewheelListener = this.mousewheelListener.bind(this);
1563 this.onLayoutChange = this.onLayoutChange.bind(this);
1564 this.changeTimer = lang.delayedCall(function () {
1565 this.updateCompletions(true);
1566 }.bind(this));
1567 this.tooltipTimer = lang.delayedCall(this.updateDocTooltip.bind(this), 50);
1568 this.popupTimer = lang.delayedCall(this.$updatePopupPosition.bind(this), 50);
1569 this.stickySelectionTimer = lang.delayedCall(function () {
1570 this.stickySelection = true;
1571 }.bind(this), this.stickySelectionDelay);
1572 this.$firstOpenTimer = lang.delayedCall(/**@this{Autocomplete}*/ function () {
1573 var initialPosition = this.completionProvider && this.completionProvider.initialPosition;
1574 if (this.autoShown || (this.popup && this.popup.isOpen) || !initialPosition || this.editor.completers.length === 0)
1575 return;
1576 this.completions = new FilteredList(Autocomplete.completionsForLoading);
1577 this.openPopup(this.editor, initialPosition.prefix, false);
1578 this.popup.renderer.setStyle("ace_loading", true);
1579 }.bind(this), this.stickySelectionDelay);
1580 }
1581 Object.defineProperty(Autocomplete, "completionsForLoading", {
1582 get: function () {
1583 return [{
1584 caption: config.nls("autocomplete.loading", "Loading..."),
1585 value: ""
1586 }];
1587 },
1588 enumerable: false,
1589 configurable: true
1590 });
1591 Autocomplete.prototype.$init = function () {
1592 this.popup = new AcePopup(this.parentNode || document.body || document.documentElement);
1593 this.popup.on("click", function (e) {
1594 this.insertMatch();
1595 e.stop();
1596 }.bind(this));
1597 this.popup.focus = this.editor.focus.bind(this.editor);
1598 this.popup.on("show", this.$onPopupShow.bind(this));
1599 this.popup.on("hide", this.$onHidePopup.bind(this));
1600 this.popup.on("select", this.$onPopupChange.bind(this));
1601 event.addListener(this.popup.container, "mouseout", this.mouseOutListener.bind(this));
1602 this.popup.on("changeHoverMarker", this.tooltipTimer.bind(null, null));
1603 this.popup.renderer.on("afterRender", this.$onPopupRender.bind(this));
1604 return this.popup;
1605 };
1606 Autocomplete.prototype.$initInline = function () {
1607 if (!this.inlineEnabled || this.inlineRenderer)
1608 return;
1609 this.inlineRenderer = new AceInline();
1610 return this.inlineRenderer;
1611 };
1612 Autocomplete.prototype.getPopup = function () {
1613 return this.popup || this.$init();
1614 };
1615 Autocomplete.prototype.$onHidePopup = function () {
1616 if (this.inlineRenderer) {
1617 this.inlineRenderer.hide();
1618 }
1619 this.hideDocTooltip();
1620 this.stickySelectionTimer.cancel();
1621 this.popupTimer.cancel();
1622 this.stickySelection = false;
1623 };
1624 Autocomplete.prototype.$seen = function (completion) {
1625 if (!this.hasSeen.has(completion) && completion && completion.completer && completion.completer.onSeen && typeof completion.completer.onSeen === "function") {
1626 completion.completer.onSeen(this.editor, completion);
1627 this.hasSeen.add(completion);
1628 }
1629 };
1630 Autocomplete.prototype.$onPopupChange = function (hide) {
1631 if (this.inlineRenderer && this.inlineEnabled) {
1632 var completion = hide ? null : this.popup.getData(this.popup.getRow());
1633 this.$updateGhostText(completion);
1634 if (this.popup.isMouseOver && this.setSelectOnHover) {
1635 this.tooltipTimer.call(null, null);
1636 return;
1637 }
1638 this.popupTimer.schedule();
1639 this.tooltipTimer.schedule();
1640 }
1641 else {
1642 this.popupTimer.call(null, null);
1643 this.tooltipTimer.call(null, null);
1644 }
1645 };
1646 Autocomplete.prototype.$updateGhostText = function (completion) {
1647 var row = this.base.row;
1648 var column = this.base.column;
1649 var cursorColumn = this.editor.getCursorPosition().column;
1650 var prefix = this.editor.session.getLine(row).slice(column, cursorColumn);
1651 if (!this.inlineRenderer.show(this.editor, completion, prefix)) {
1652 this.inlineRenderer.hide();
1653 }
1654 else {
1655 this.$seen(completion);
1656 }
1657 };
1658 Autocomplete.prototype.$onPopupRender = function () {
1659 var inlineEnabled = this.inlineRenderer && this.inlineEnabled;
1660 if (this.completions && this.completions.filtered && this.completions.filtered.length > 0) {
1661 for (var i = this.popup.getFirstVisibleRow(); i <= this.popup.getLastVisibleRow(); i++) {
1662 var completion = this.popup.getData(i);
1663 if (completion && (!inlineEnabled || completion.hideInlinePreview)) {
1664 this.$seen(completion);
1665 }
1666 }
1667 }
1668 };
1669 Autocomplete.prototype.$onPopupShow = function (hide) {
1670 this.$onPopupChange(hide);
1671 this.stickySelection = false;
1672 if (this.stickySelectionDelay >= 0)
1673 this.stickySelectionTimer.schedule(this.stickySelectionDelay);
1674 };
1675 Autocomplete.prototype.observeLayoutChanges = function () {
1676 if (this.$elements || !this.editor)
1677 return;
1678 window.addEventListener("resize", this.onLayoutChange, { passive: true });
1679 window.addEventListener("wheel", this.mousewheelListener);
1680 var el = this.editor.container.parentNode;
1681 var elements = [];
1682 while (el) {
1683 elements.push(el);
1684 el.addEventListener("scroll", this.onLayoutChange, { passive: true });
1685 el = el.parentNode;
1686 }
1687 this.$elements = elements;
1688 };
1689 Autocomplete.prototype.unObserveLayoutChanges = function () {
1690 var _this = this;
1691 window.removeEventListener("resize", this.onLayoutChange, { passive: true });
1692 window.removeEventListener("wheel", this.mousewheelListener);
1693 this.$elements && this.$elements.forEach(function (el) {
1694 el.removeEventListener("scroll", _this.onLayoutChange, { passive: true });
1695 });
1696 this.$elements = null;
1697 };
1698 Autocomplete.prototype.onLayoutChange = function () {
1699 if (!this.popup.isOpen)
1700 return this.unObserveLayoutChanges();
1701 this.$updatePopupPosition();
1702 this.updateDocTooltip();
1703 };
1704 Autocomplete.prototype.$updatePopupPosition = function () {
1705 var editor = this.editor;
1706 var renderer = editor.renderer;
1707 var lineHeight = renderer.layerConfig.lineHeight;
1708 var pos = renderer.$cursorLayer.getPixelPosition(this.base, true);
1709 pos.left -= this.popup.getTextLeftOffset();
1710 var rect = editor.container.getBoundingClientRect();
1711 pos.top += rect.top - renderer.layerConfig.offset;
1712 pos.left += rect.left - editor.renderer.scrollLeft;
1713 pos.left += renderer.gutterWidth;
1714 var posGhostText = {
1715 top: pos.top,
1716 left: pos.left
1717 };
1718 if (renderer.$ghostText && renderer.$ghostTextWidget) {
1719 if (this.base.row === renderer.$ghostText.position.row) {
1720 posGhostText.top += renderer.$ghostTextWidget.el.offsetHeight;
1721 }
1722 }
1723 var editorContainerBottom = editor.container.getBoundingClientRect().bottom - lineHeight;
1724 var lowestPosition = editorContainerBottom < posGhostText.top ?
1725 { top: editorContainerBottom, left: posGhostText.left } :
1726 posGhostText;
1727 if (this.popup.tryShow(lowestPosition, lineHeight, "bottom")) {
1728 return;
1729 }
1730 if (this.popup.tryShow(pos, lineHeight, "top")) {
1731 return;
1732 }
1733 this.popup.show(pos, lineHeight);
1734 };
1735 Autocomplete.prototype.openPopup = function (editor, prefix, keepPopupPosition) {
1736 this.$firstOpenTimer.cancel();
1737 if (!this.popup)
1738 this.$init();
1739 if (this.inlineEnabled && !this.inlineRenderer)
1740 this.$initInline();
1741 this.popup.autoSelect = this.autoSelect;
1742 this.popup.setSelectOnHover(this.setSelectOnHover);
1743 var oldRow = this.popup.getRow();
1744 var previousSelectedItem = this.popup.data[oldRow];
1745 this.popup.setData(this.completions.filtered, this.completions.filterText);
1746 if (this.editor.textInput.setAriaOptions) {
1747 this.editor.textInput.setAriaOptions({
1748 activeDescendant: getAriaId(this.popup.getRow()),
1749 inline: this.inlineEnabled
1750 });
1751 }
1752 editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
1753 var newRow;
1754 if (this.stickySelection)
1755 newRow = this.popup.data.indexOf(previousSelectedItem);
1756 if (!newRow || newRow === -1)
1757 newRow = 0;
1758 this.popup.setRow(this.autoSelect ? newRow : -1);
1759 if (newRow === oldRow && previousSelectedItem !== this.completions.filtered[newRow])
1760 this.$onPopupChange();
1761 var inlineEnabled = this.inlineRenderer && this.inlineEnabled;
1762 if (newRow === oldRow && inlineEnabled) {
1763 var completion = this.popup.getData(this.popup.getRow());
1764 this.$updateGhostText(completion);
1765 }
1766 if (!keepPopupPosition) {
1767 this.popup.setTheme(editor.getTheme());
1768 this.popup.setFontSize(editor.getFontSize());
1769 this.$updatePopupPosition();
1770 if (this.tooltipNode) {
1771 this.updateDocTooltip();
1772 }
1773 }
1774 this.changeTimer.cancel();
1775 this.observeLayoutChanges();
1776 };
1777 Autocomplete.prototype.detach = function () {
1778 if (this.editor) {
1779 this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
1780 this.editor.off("changeSelection", this.changeListener);
1781 this.editor.off("blur", this.blurListener);
1782 this.editor.off("mousedown", this.mousedownListener);
1783 this.editor.off("mousewheel", this.mousewheelListener);
1784 }
1785 this.$firstOpenTimer.cancel();
1786 this.changeTimer.cancel();
1787 this.hideDocTooltip();
1788 if (this.completionProvider) {
1789 this.completionProvider.detach();
1790 }
1791 if (this.popup && this.popup.isOpen)
1792 this.popup.hide();
1793 if (this.popup && this.popup.renderer) {
1794 this.popup.renderer.off("afterRender", this.$onPopupRender);
1795 }
1796 if (this.base)
1797 this.base.detach();
1798 this.activated = false;
1799 this.completionProvider = this.completions = this.base = null;
1800 this.unObserveLayoutChanges();
1801 };
1802 Autocomplete.prototype.changeListener = function (e) {
1803 var cursor = this.editor.selection.lead;
1804 if (cursor.row != this.base.row || cursor.column < this.base.column) {
1805 this.detach();
1806 }
1807 if (this.activated)
1808 this.changeTimer.schedule();
1809 else
1810 this.detach();
1811 };
1812 Autocomplete.prototype.blurListener = function (e) {
1813 var el = document.activeElement;
1814 var text = this.editor.textInput.getElement();
1815 var fromTooltip = e.relatedTarget && this.tooltipNode && this.tooltipNode.contains(e.relatedTarget);
1816 var container = this.popup && this.popup.container;
1817 if (el != text && el.parentNode != container && !fromTooltip
1818 && el != this.tooltipNode && e.relatedTarget != text) {
1819 this.detach();
1820 }
1821 };
1822 Autocomplete.prototype.mousedownListener = function (e) {
1823 this.detach();
1824 };
1825 Autocomplete.prototype.mousewheelListener = function (e) {
1826 if (this.popup && !this.popup.isMouseOver)
1827 this.detach();
1828 };
1829 Autocomplete.prototype.mouseOutListener = function (e) {
1830 if (this.popup.isOpen)
1831 this.$updatePopupPosition();
1832 };
1833 Autocomplete.prototype.goTo = function (where) {
1834 this.popup.goTo(where);
1835 };
1836 Autocomplete.prototype.insertMatch = function (data, options) {
1837 if (!data)
1838 data = this.popup.getData(this.popup.getRow());
1839 if (!data)
1840 return false;
1841 if (data.value === "") // Explicitly given nothing to insert, e.g. "No suggestion state"
1842 return this.detach();
1843 var completions = this.completions;
1844 var result = this.getCompletionProvider().insertMatch(this.editor, data, completions.filterText, options);
1845 if (this.completions == completions)
1846 this.detach();
1847 return result;
1848 };
1849 Autocomplete.prototype.showPopup = function (editor, options) {
1850 if (this.editor)
1851 this.detach();
1852 this.activated = true;
1853 this.editor = editor;
1854 if (editor.completer != this) {
1855 if (editor.completer)
1856 editor.completer.detach();
1857 editor.completer = this;
1858 }
1859 editor.on("changeSelection", this.changeListener);
1860 editor.on("blur", this.blurListener);
1861 editor.on("mousedown", this.mousedownListener);
1862 editor.on("mousewheel", this.mousewheelListener);
1863 this.updateCompletions(false, options);
1864 };
1865 Autocomplete.prototype.getCompletionProvider = function (initialPosition) {
1866 if (!this.completionProvider)
1867 this.completionProvider = new CompletionProvider(initialPosition);
1868 return this.completionProvider;
1869 };
1870 Autocomplete.prototype.gatherCompletions = function (editor, callback) {
1871 return this.getCompletionProvider().gatherCompletions(editor, callback);
1872 };
1873 Autocomplete.prototype.updateCompletions = function (keepPopupPosition, options) {
1874 if (keepPopupPosition && this.base && this.completions) {
1875 var pos = this.editor.getCursorPosition();
1876 var prefix = this.editor.session.getTextRange({ start: this.base, end: pos });
1877 if (prefix == this.completions.filterText)
1878 return;
1879 this.completions.setFilter(prefix);
1880 if (!this.completions.filtered.length)
1881 return this.detach();
1882 if (this.completions.filtered.length == 1
1883 && this.completions.filtered[0].value == prefix
1884 && !this.completions.filtered[0].snippet)
1885 return this.detach();
1886 this.openPopup(this.editor, prefix, keepPopupPosition);
1887 return;
1888 }
1889 if (options && options.matches) {
1890 var pos = this.editor.getSelectionRange().start;
1891 this.base = this.editor.session.doc.createAnchor(pos.row, pos.column);
1892 this.base.$insertRight = true;
1893 this.completions = new FilteredList(options.matches);
1894 this.getCompletionProvider().completions = this.completions;
1895 return this.openPopup(this.editor, "", keepPopupPosition);
1896 }
1897 var session = this.editor.getSession();
1898 var pos = this.editor.getCursorPosition();
1899 var prefix = util.getCompletionPrefix(this.editor);
1900 this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);
1901 this.base.$insertRight = true;
1902 var completionOptions = {
1903 exactMatch: this.exactMatch,
1904 ignoreCaption: this.ignoreCaption
1905 };
1906 this.getCompletionProvider({
1907 prefix: prefix,
1908 pos: pos
1909 }).provideCompletions(this.editor, completionOptions,
1910 function (err, completions, finished) {
1911 var filtered = completions.filtered;
1912 var prefix = util.getCompletionPrefix(this.editor);
1913 this.$firstOpenTimer.cancel();
1914 if (finished) {
1915 if (!filtered.length) {
1916 var emptyMessage = !this.autoShown && this.emptyMessage;
1917 if (typeof emptyMessage == "function")
1918 emptyMessage = this.emptyMessage(prefix);
1919 if (emptyMessage) {
1920 var completionsForEmpty = [{
1921 caption: emptyMessage,
1922 value: ""
1923 }
1924 ];
1925 this.completions = new FilteredList(completionsForEmpty);
1926 this.openPopup(this.editor, prefix, keepPopupPosition);
1927 this.popup.renderer.setStyle("ace_loading", false);
1928 this.popup.renderer.setStyle("ace_empty-message", true);
1929 return;
1930 }
1931 return this.detach();
1932 }
1933 if (filtered.length == 1 && filtered[0].value == prefix
1934 && !filtered[0].snippet)
1935 return this.detach();
1936 if (this.autoInsert && !this.autoShown && filtered.length == 1)
1937 return this.insertMatch(filtered[0]);
1938 }
1939 this.completions = !finished && this.showLoadingState ?
1940 new FilteredList(Autocomplete.completionsForLoading.concat(filtered), completions.filterText) :
1941 completions;
1942 this.openPopup(this.editor, prefix, keepPopupPosition);
1943 this.popup.renderer.setStyle("ace_empty-message", false);
1944 this.popup.renderer.setStyle("ace_loading", !finished);
1945 }.bind(this));
1946 if (this.showLoadingState && !this.autoShown && !(this.popup && this.popup.isOpen)) {
1947 this.$firstOpenTimer.delay(this.stickySelectionDelay / 2);
1948 }
1949 };
1950 Autocomplete.prototype.cancelContextMenu = function () {
1951 this.editor.$mouseHandler.cancelContextMenu();
1952 };
1953 Autocomplete.prototype.updateDocTooltip = function () {
1954 var popup = this.popup;
1955 var all = this.completions && this.completions.filtered;
1956 var selected = all && (all[popup.getHoveredRow()] || all[popup.getRow()]);
1957 var doc = null;
1958 if (!selected || !this.editor || !this.popup.isOpen)
1959 return this.hideDocTooltip();
1960 var completersLength = this.editor.completers.length;
1961 for (var i = 0; i < completersLength; i++) {
1962 var completer = this.editor.completers[i];
1963 if (completer.getDocTooltip && selected.completerId === completer.id) {
1964 doc = completer.getDocTooltip(selected);
1965 break;
1966 }
1967 }
1968 if (!doc && typeof selected != "string")
1969 doc = selected;
1970 if (typeof doc == "string")
1971 doc = { docText: doc };
1972 if (!doc || !(doc.docHTML || doc.docText))
1973 return this.hideDocTooltip();
1974 this.showDocTooltip(doc);
1975 };
1976 Autocomplete.prototype.showDocTooltip = function (item) {
1977 if (!this.tooltipNode) {
1978 this.tooltipNode = dom.createElement("div");
1979 this.tooltipNode.style.margin = "0";
1980 this.tooltipNode.style.pointerEvents = "auto";
1981 this.tooltipNode.style.overscrollBehavior = "contain";
1982 this.tooltipNode.tabIndex = -1;
1983 this.tooltipNode.onblur = this.blurListener.bind(this);
1984 this.tooltipNode.onclick = this.onTooltipClick.bind(this);
1985 this.tooltipNode.id = "doc-tooltip";
1986 this.tooltipNode.setAttribute("role", "tooltip");
1987 this.tooltipNode.addEventListener("wheel", preventParentScroll);
1988 }
1989 var theme = this.editor.renderer.theme;
1990 this.tooltipNode.className = "ace_tooltip ace_doc-tooltip " +
1991 (theme.isDark ? "ace_dark " : "") + (theme.cssClass || "");
1992 var tooltipNode = this.tooltipNode;
1993 if (item.docHTML) {
1994 tooltipNode.innerHTML = item.docHTML;
1995 }
1996 else if (item.docText) {
1997 tooltipNode.textContent = item.docText;
1998 }
1999 if (!tooltipNode.parentNode)
2000 this.popup.container.appendChild(this.tooltipNode);
2001 var popup = this.popup;
2002 var rect = popup.container.getBoundingClientRect();
2003 var targetWidth = 400;
2004 var targetHeight = 300;
2005 var scrollBarSize = popup.renderer.scrollBar.width || 10;
2006 var leftSize = rect.left;
2007 var rightSize = window.innerWidth - rect.right - scrollBarSize;
2008 var topSize = popup.isTopdown ? rect.top : window.innerHeight - scrollBarSize - rect.bottom;
2009 var scores = [
2010 Math.min(rightSize / targetWidth, 1),
2011 Math.min(leftSize / targetWidth, 1),
2012 Math.min(topSize / targetHeight * 0.9),
2013 ];
2014 var max = Math.max.apply(Math, scores);
2015 var tooltipStyle = tooltipNode.style;
2016 tooltipStyle.display = "block";
2017 if (max == scores[0]) {
2018 tooltipStyle.left = (rect.right + 1) + "px";
2019 tooltipStyle.right = "";
2020 tooltipStyle.maxWidth = targetWidth * max + "px";
2021 tooltipStyle.top = rect.top + "px";
2022 tooltipStyle.bottom = "";
2023 tooltipStyle.maxHeight = Math.min(window.innerHeight - scrollBarSize - rect.top, targetHeight) + "px";
2024 }
2025 else if (max == scores[1]) {
2026 tooltipStyle.right = window.innerWidth - rect.left + "px";
2027 tooltipStyle.left = "";
2028 tooltipStyle.maxWidth = targetWidth * max + "px";
2029 tooltipStyle.top = rect.top + "px";
2030 tooltipStyle.bottom = "";
2031 tooltipStyle.maxHeight = Math.min(window.innerHeight - scrollBarSize - rect.top, targetHeight) + "px";
2032 }
2033 else if (max == scores[2]) {
2034 tooltipStyle.left = window.innerWidth - rect.left + "px";
2035 tooltipStyle.maxWidth = Math.min(targetWidth, window.innerWidth) + "px";
2036 if (popup.isTopdown) {
2037 tooltipStyle.top = rect.bottom + "px";
2038 tooltipStyle.left = rect.left + "px";
2039 tooltipStyle.right = "";
2040 tooltipStyle.bottom = "";
2041 tooltipStyle.maxHeight = Math.min(window.innerHeight - scrollBarSize - rect.bottom, targetHeight) + "px";
2042 }
2043 else {
2044 tooltipStyle.top = popup.container.offsetTop - tooltipNode.offsetHeight + "px";
2045 tooltipStyle.left = rect.left + "px";
2046 tooltipStyle.right = "";
2047 tooltipStyle.bottom = "";
2048 tooltipStyle.maxHeight = Math.min(popup.container.offsetTop, targetHeight) + "px";
2049 }
2050 }
2051 };
2052 Autocomplete.prototype.hideDocTooltip = function () {
2053 this.tooltipTimer.cancel();
2054 if (!this.tooltipNode)
2055 return;
2056 var el = this.tooltipNode;
2057 if (!this.editor.isFocused() && document.activeElement == el)
2058 this.editor.focus();
2059 this.tooltipNode = null;
2060 if (el.parentNode)
2061 el.parentNode.removeChild(el);
2062 };
2063 Autocomplete.prototype.onTooltipClick = function (e) {
2064 var a = e.target;
2065 while (a && a != this.tooltipNode) {
2066 if (a.nodeName == "A" && a.href) {
2067 a.rel = "noreferrer";
2068 a.target = "_blank";
2069 break;
2070 }
2071 a = a.parentNode;
2072 }
2073 };
2074 Autocomplete.prototype.destroy = function () {
2075 this.detach();
2076 if (this.popup) {
2077 this.popup.destroy();
2078 var el = this.popup.container;
2079 if (el && el.parentNode)
2080 el.parentNode.removeChild(el);
2081 }
2082 if (this.editor && this.editor.completer == this) {
2083 this.editor.off("destroy", destroyCompleter);
2084 this.editor.completer = null;
2085 }
2086 this.inlineRenderer = this.popup = this.editor = null;
2087 };
2088 Autocomplete.for = function (editor) {
2089 if (editor.completer instanceof Autocomplete) {
2090 return editor.completer;
2091 }
2092 if (editor.completer) {
2093 editor.completer.destroy();
2094 editor.completer = null;
2095 }
2096 if (config.get("sharedPopups")) {
2097 if (!Autocomplete["$sharedInstance"])
2098 Autocomplete["$sharedInstance"] = new Autocomplete();
2099 editor.completer = Autocomplete["$sharedInstance"];
2100 }
2101 else {
2102 editor.completer = new Autocomplete();
2103 editor.once("destroy", destroyCompleter);
2104 }
2105 return editor.completer;
2106 };
2107 return Autocomplete;
2108 }());
2109 Autocomplete.prototype.commands = {
2110 "Up": function (editor) { editor.completer.goTo("up"); },
2111 "Down": function (editor) { editor.completer.goTo("down"); },
2112 "Ctrl-Up|Ctrl-Home": function (editor) { editor.completer.goTo("start"); },
2113 "Ctrl-Down|Ctrl-End": function (editor) { editor.completer.goTo("end"); },
2114 "Esc": function (editor) { editor.completer.detach(); },
2115 "Return": function (editor) { return editor.completer.insertMatch(); },
2116 "Shift-Return": function (editor) { editor.completer.insertMatch(null, { deleteSuffix: true }); },
2117 "Tab": function (editor) {
2118 var result = editor.completer.insertMatch();
2119 if (!result && !editor.tabstopManager)
2120 editor.completer.goTo("down");
2121 else
2122 return result;
2123 },
2124 "Backspace": function (editor) {
2125 editor.execCommand("backspace");
2126 var prefix = util.getCompletionPrefix(editor);
2127 if (!prefix && editor.completer)
2128 editor.completer.detach();
2129 },
2130 "PageUp": function (editor) { editor.completer.popup.gotoPageUp(); },
2131 "PageDown": function (editor) { editor.completer.popup.gotoPageDown(); }
2132 };
2133 Autocomplete.startCommand = {
2134 name: "startAutocomplete",
2135 exec: function (editor, options) {
2136 var completer = Autocomplete.for(editor);
2137 completer.autoInsert = false;
2138 completer.autoSelect = true;
2139 completer.autoShown = false;
2140 completer.showPopup(editor, options);
2141 completer.cancelContextMenu();
2142 },
2143 bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
2144 };
2145 var CompletionProvider = /** @class */ (function () {
2146 function CompletionProvider(initialPosition) {
2147 this.initialPosition = initialPosition;
2148 this.active = true;
2149 }
2150 CompletionProvider.prototype.insertByIndex = function (editor, index, options) {
2151 if (!this.completions || !this.completions.filtered) {
2152 return false;
2153 }
2154 return this.insertMatch(editor, this.completions.filtered[index], options);
2155 };
2156 CompletionProvider.prototype.insertMatch = function (editor, data, options) {
2157 if (!data)
2158 return false;
2159 editor.startOperation({ command: { name: "insertMatch" } });
2160 if (data.completer && data.completer.insertMatch) {
2161 data.completer.insertMatch(editor, data);
2162 }
2163 else {
2164 if (!this.completions)
2165 return false;
2166 var replaceBefore = this.completions.filterText.length;
2167 var replaceAfter = 0;
2168 if (data.range && data.range.start.row === data.range.end.row) {
2169 replaceBefore -= this.initialPosition.prefix.length;
2170 replaceBefore += this.initialPosition.pos.column - data.range.start.column;
2171 replaceAfter += data.range.end.column - this.initialPosition.pos.column;
2172 }
2173 if (replaceBefore || replaceAfter) {
2174 var ranges;
2175 if (editor.selection.getAllRanges) {
2176 ranges = editor.selection.getAllRanges();
2177 }
2178 else {
2179 ranges = [editor.getSelectionRange()];
2180 }
2181 for (var i = 0, range; range = ranges[i]; i++) {
2182 range.start.column -= replaceBefore;
2183 range.end.column += replaceAfter;
2184 editor.session.remove(range);
2185 }
2186 }
2187 if (data.snippet) {
2188 snippetManager.insertSnippet(editor, data.snippet);
2189 }
2190 else {
2191 this.$insertString(editor, data);
2192 }
2193 if (data.completer && data.completer.onInsert && typeof data.completer.onInsert == "function") {
2194 data.completer.onInsert(editor, data);
2195 }
2196 if (data.command && data.command === "startAutocomplete") {
2197 editor.execCommand(data.command);
2198 }
2199 }
2200 editor.endOperation();
2201 return true;
2202 };
2203 CompletionProvider.prototype.$insertString = function (editor, data) {
2204 var text = data.value || data;
2205 editor.execCommand("insertstring", text);
2206 };
2207 CompletionProvider.prototype.gatherCompletions = function (editor, callback) {
2208 var session = editor.getSession();
2209 var pos = editor.getCursorPosition();
2210 var prefix = util.getCompletionPrefix(editor);
2211 var matches = [];
2212 this.completers = editor.completers;
2213 var total = editor.completers.length;
2214 editor.completers.forEach(function (completer, i) {
2215 completer.getCompletions(editor, session, pos, prefix, function (err, results) {
2216 if (completer.hideInlinePreview)
2217 results = results.map(function (result) {
2218 return Object.assign(result, { hideInlinePreview: completer.hideInlinePreview });
2219 });
2220 if (!err && results)
2221 matches = matches.concat(results);
2222 callback(null, {
2223 prefix: util.getCompletionPrefix(editor),
2224 matches: matches,
2225 finished: (--total === 0)
2226 });
2227 });
2228 });
2229 return true;
2230 };
2231 CompletionProvider.prototype.provideCompletions = function (editor, options, callback) {
2232 var processResults = function (results) {
2233 var prefix = results.prefix;
2234 var matches = results.matches;
2235 this.completions = new FilteredList(matches);
2236 if (options.exactMatch)
2237 this.completions.exactMatch = true;
2238 if (options.ignoreCaption)
2239 this.completions.ignoreCaption = true;
2240 this.completions.setFilter(prefix);
2241 if (results.finished || this.completions.filtered.length)
2242 callback(null, this.completions, results.finished);
2243 }.bind(this);
2244 var isImmediate = true;
2245 var immediateResults = null;
2246 this.gatherCompletions(editor, function (err, results) {
2247 if (!this.active) {
2248 return;
2249 }
2250 if (err) {
2251 callback(err, [], true);
2252 this.detach();
2253 }
2254 var prefix = results.prefix;
2255 if (prefix.indexOf(results.prefix) !== 0)
2256 return;
2257 if (isImmediate) {
2258 immediateResults = results;
2259 return;
2260 }
2261 processResults(results);
2262 }.bind(this));
2263 isImmediate = false;
2264 if (immediateResults) {
2265 var results = immediateResults;
2266 immediateResults = null;
2267 processResults(results);
2268 }
2269 };
2270 CompletionProvider.prototype.detach = function () {
2271 this.active = false;
2272 this.completers && this.completers.forEach(function (completer) {
2273 if (typeof completer.cancel === "function") {
2274 completer.cancel();
2275 }
2276 });
2277 };
2278 return CompletionProvider;
2279 }());
2280 var FilteredList = /** @class */ (function () {
2281 function FilteredList(array, filterText) {
2282 this.all = array;
2283 this.filtered = array;
2284 this.filterText = filterText || "";
2285 this.exactMatch = false;
2286 this.ignoreCaption = false;
2287 }
2288 FilteredList.prototype.setFilter = function (str) {
2289 if (str.length > this.filterText && str.lastIndexOf(this.filterText, 0) === 0)
2290 var matches = this.filtered;
2291 else
2292 var matches = this.all;
2293 this.filterText = str;
2294 matches = this.filterCompletions(matches, this.filterText);
2295 matches = matches.sort(function (a, b) {
2296 return b.exactMatch - a.exactMatch || b.$score - a.$score
2297 || (a.caption || a.value).localeCompare(b.caption || b.value);
2298 });
2299 var prev = null;
2300 matches = matches.filter(function (item) {
2301 var caption = item.snippet || item.caption || item.value;
2302 if (caption === prev)
2303 return false;
2304 prev = caption;
2305 return true;
2306 });
2307 this.filtered = matches;
2308 };
2309 FilteredList.prototype.filterCompletions = function (items, needle) {
2310 var results = [];
2311 var upper = needle.toUpperCase();
2312 var lower = needle.toLowerCase();
2313 loop: for (var i = 0, item; item = items[i]; i++) {
2314 if (item.skipFilter) {
2315 item.$score = item.score;
2316 results.push(item);
2317 continue;
2318 }
2319 var caption = (!this.ignoreCaption && item.caption) || item.value || item.snippet;
2320 if (!caption)
2321 continue;
2322 var lastIndex = -1;
2323 var matchMask = 0;
2324 var penalty = 0;
2325 var index, distance;
2326 if (this.exactMatch) {
2327 if (needle !== caption.substr(0, needle.length))
2328 continue loop;
2329 }
2330 else {
2331 var fullMatchIndex = caption.toLowerCase().indexOf(lower);
2332 if (fullMatchIndex > -1) {
2333 penalty = fullMatchIndex;
2334 }
2335 else {
2336 for (var j = 0; j < needle.length; j++) {
2337 var i1 = caption.indexOf(lower[j], lastIndex + 1);
2338 var i2 = caption.indexOf(upper[j], lastIndex + 1);
2339 index = (i1 >= 0) ? ((i2 < 0 || i1 < i2) ? i1 : i2) : i2;
2340 if (index < 0)
2341 continue loop;
2342 distance = index - lastIndex - 1;
2343 if (distance > 0) {
2344 if (lastIndex === -1)
2345 penalty += 10;
2346 penalty += distance;
2347 matchMask = matchMask | (1 << j);
2348 }
2349 lastIndex = index;
2350 }
2351 }
2352 }
2353 item.matchMask = matchMask;
2354 item.exactMatch = penalty ? 0 : 1;
2355 item.$score = (item.score || 0) - penalty;
2356 results.push(item);
2357 }
2358 return results;
2359 };
2360 return FilteredList;
2361 }());
2362 exports.Autocomplete = Autocomplete;
2363 exports.CompletionProvider = CompletionProvider;
2364 exports.FilteredList = FilteredList;
2365
2366 });
2367
2368 ace.define("ace/marker_group",["require","exports","module"], function(require, exports, module){"use strict";
2369 var MarkerGroup = /** @class */ (function () {
2370 function MarkerGroup(session, options) {
2371 if (options)
2372 this.markerType = options.markerType;
2373 this.markers = [];
2374 this.session = session;
2375 session.addDynamicMarker(this);
2376 }
2377 MarkerGroup.prototype.getMarkerAtPosition = function (pos) {
2378 return this.markers.find(function (marker) {
2379 return marker.range.contains(pos.row, pos.column);
2380 });
2381 };
2382 MarkerGroup.prototype.markersComparator = function (a, b) {
2383 return a.range.start.row - b.range.start.row;
2384 };
2385 MarkerGroup.prototype.setMarkers = function (markers) {
2386 this.markers = markers.sort(this.markersComparator).slice(0, this.MAX_MARKERS);
2387 this.session._signal("changeBackMarker");
2388 };
2389 MarkerGroup.prototype.update = function (html, markerLayer, session, config) {
2390 if (!this.markers || !this.markers.length)
2391 return;
2392 var visibleRangeStartRow = config.firstRow, visibleRangeEndRow = config.lastRow;
2393 var foldLine;
2394 var markersOnOneLine = 0;
2395 var lastRow = 0;
2396 for (var i = 0; i < this.markers.length; i++) {
2397 var marker = this.markers[i];
2398 if (marker.range.end.row < visibleRangeStartRow)
2399 continue;
2400 if (marker.range.start.row > visibleRangeEndRow)
2401 continue;
2402 if (marker.range.start.row === lastRow) {
2403 markersOnOneLine++;
2404 }
2405 else {
2406 lastRow = marker.range.start.row;
2407 markersOnOneLine = 0;
2408 }
2409 if (markersOnOneLine > 200) {
2410 continue;
2411 }
2412 var markerVisibleRange = marker.range.clipRows(visibleRangeStartRow, visibleRangeEndRow);
2413 if (markerVisibleRange.start.row === markerVisibleRange.end.row
2414 && markerVisibleRange.start.column === markerVisibleRange.end.column) {
2415 continue; // visible range is empty
2416 }
2417 var screenRange = markerVisibleRange.toScreenRange(session);
2418 if (screenRange.isEmpty()) {
2419 foldLine = session.getNextFoldLine(markerVisibleRange.end.row, foldLine);
2420 if (foldLine && foldLine.end.row > markerVisibleRange.end.row) {
2421 visibleRangeStartRow = foldLine.end.row;
2422 }
2423 continue;
2424 }
2425 if (this.markerType === "fullLine") {
2426 markerLayer.drawFullLineMarker(html, screenRange, marker.className, config);
2427 }
2428 else if (screenRange.isMultiLine()) {
2429 if (this.markerType === "line")
2430 markerLayer.drawMultiLineMarker(html, screenRange, marker.className, config);
2431 else
2432 markerLayer.drawTextMarker(html, screenRange, marker.className, config);
2433 }
2434 else {
2435 markerLayer.drawSingleLineMarker(html, screenRange, marker.className + " ace_br15", config);
2436 }
2437 }
2438 };
2439 return MarkerGroup;
2440 }());
2441 MarkerGroup.prototype.MAX_MARKERS = 10000;
2442 exports.MarkerGroup = MarkerGroup;
2443
2444 });
2445
2446 ace.define("ace/autocomplete/text_completer",["require","exports","module","ace/range"], function(require, exports, module){var Range = require("../range").Range;
2447 var splitRegex = /[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;
2448 function getWordIndex(doc, pos) {
2449 var textBefore = doc.getTextRange(Range.fromPoints({
2450 row: 0,
2451 column: 0
2452 }, pos));
2453 return textBefore.split(splitRegex).length - 1;
2454 }
2455 function wordDistance(doc, pos) {
2456 var prefixPos = getWordIndex(doc, pos);
2457 var words = doc.getValue().split(splitRegex);
2458 var wordScores = Object.create(null);
2459 var currentWord = words[prefixPos];
2460 words.forEach(function (word, idx) {
2461 if (!word || word === currentWord)
2462 return;
2463 var distance = Math.abs(prefixPos - idx);
2464 var score = words.length - distance;
2465 if (wordScores[word]) {
2466 wordScores[word] = Math.max(score, wordScores[word]);
2467 }
2468 else {
2469 wordScores[word] = score;
2470 }
2471 });
2472 return wordScores;
2473 }
2474 exports.getCompletions = function (editor, session, pos, prefix, callback) {
2475 var wordScore = wordDistance(session, pos);
2476 var wordList = Object.keys(wordScore);
2477 callback(null, wordList.map(function (word) {
2478 return {
2479 caption: word,
2480 value: word,
2481 score: wordScore[word],
2482 meta: "local"
2483 };
2484 }));
2485 };
2486
2487 });
2488
2489 ace.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){/**
2490 * ## Language Tools extension for Ace Editor
2491 *
2492 * Provides autocompletion, snippets, and language intelligence features for the Ace code editor.
2493 * This extension integrates multiple completion providers including keyword completion, snippet expansion,
2494 * and text-based completion to enhance the coding experience with contextual suggestions and automated code generation.
2495 *
2496 * **Configuration Options:**
2497 * - `enableBasicAutocompletion`: Enable/disable basic completion functionality
2498 * - `enableLiveAutocompletion`: Enable/disable real-time completion suggestions
2499 * - `enableSnippets`: Enable/disable snippet expansion with Tab key
2500 * - `liveAutocompletionDelay`: Delay before showing live completion popup
2501 * - `liveAutocompletionThreshold`: Minimum prefix length to trigger completion
2502 *
2503 * **Usage:**
2504 * ```javascript
2505 * editor.setOptions({
2506 * enableBasicAutocompletion: true,
2507 * enableLiveAutocompletion: true,
2508 * enableSnippets: true
2509 * });
2510 * ```
2511 *
2512 * @module
2513 */
2514 "use strict";
2515 var snippetManager = require("../snippets").snippetManager;
2516 var Autocomplete = require("../autocomplete").Autocomplete;
2517 var config = require("../config");
2518 var lang = require("../lib/lang");
2519 var util = require("../autocomplete/util");
2520 var MarkerGroup = require("../marker_group").MarkerGroup;
2521 var textCompleter = require("../autocomplete/text_completer");
2522 var keyWordCompleter = {
2523 getCompletions: function (editor, session, pos, prefix, callback) {
2524 if (session.$mode.completer) {
2525 return session.$mode.completer.getCompletions(editor, session, pos, prefix, callback);
2526 }
2527 var state = editor.session.getState(pos.row);
2528 var completions = session.$mode.getCompletions(state, session, pos, prefix);
2529 completions = completions.map(function (el) {
2530 el.completerId = keyWordCompleter.id;
2531 return el;
2532 });
2533 callback(null, completions);
2534 },
2535 id: "keywordCompleter"
2536 };
2537 var transformSnippetTooltip = function (str) {
2538 var record = {};
2539 return str.replace(/\${(\d+)(:(.*?))?}/g, function (_, p1, p2, p3) {
2540 return (record[p1] = p3 || '');
2541 }).replace(/\$(\d+?)/g, function (_, p1) {
2542 return record[p1];
2543 });
2544 };
2545 var snippetCompleter = {
2546 getCompletions: function (editor, session, pos, prefix, callback) {
2547 var scopes = [];
2548 var token = session.getTokenAt(pos.row, pos.column);
2549 if (token && token.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\.xml$/))
2550 scopes.push('html-tag');
2551 else
2552 scopes = snippetManager.getActiveScopes(editor);
2553 var snippetMap = snippetManager.snippetMap;
2554 var completions = [];
2555 scopes.forEach(function (scope) {
2556 var snippets = snippetMap[scope] || [];
2557 for (var i = snippets.length; i--;) {
2558 var s = snippets[i];
2559 var caption = s.name || s.tabTrigger;
2560 if (!caption)
2561 continue;
2562 completions.push({
2563 caption: caption,
2564 snippet: s.content,
2565 meta: s.tabTrigger && !s.name ? s.tabTrigger + "\u21E5 " : "snippet",
2566 completerId: snippetCompleter.id
2567 });
2568 }
2569 }, this);
2570 callback(null, completions);
2571 },
2572 getDocTooltip: function (item) {
2573 if (item.snippet && !item.docHTML) {
2574 item.docHTML = [
2575 "<b>", lang.escapeHTML(item.caption), "</b>", "<hr></hr>",
2576 lang.escapeHTML(transformSnippetTooltip(item.snippet))
2577 ].join("");
2578 }
2579 },
2580 id: "snippetCompleter"
2581 };
2582 var completers = [snippetCompleter, textCompleter, keyWordCompleter];
2583 exports.setCompleters = function (val) {
2584 completers.length = 0;
2585 if (val)
2586 completers.push.apply(completers, val);
2587 };
2588 exports.addCompleter = function (completer) {
2589 completers.push(completer);
2590 };
2591 exports.textCompleter = textCompleter;
2592 exports.keyWordCompleter = keyWordCompleter;
2593 exports.snippetCompleter = snippetCompleter;
2594 var expandSnippet = {
2595 name: "expandSnippet",
2596 exec: function (editor) {
2597 return snippetManager.expandWithTab(editor);
2598 },
2599 bindKey: "Tab"
2600 };
2601 var onChangeMode = function (e, editor) {
2602 loadSnippetsForMode(editor.session.$mode);
2603 };
2604 var loadSnippetsForMode = function (mode) {
2605 if (typeof mode == "string")
2606 mode = config.$modes[mode];
2607 if (!mode)
2608 return;
2609 if (!snippetManager.files)
2610 snippetManager.files = {};
2611 loadSnippetFile(mode.$id, mode.snippetFileId);
2612 if (mode.modes)
2613 mode.modes.forEach(loadSnippetsForMode);
2614 };
2615 var loadSnippetFile = function (id, snippetFilePath) {
2616 if (!snippetFilePath || !id || snippetManager.files[id])
2617 return;
2618 snippetManager.files[id] = {};
2619 config.loadModule(snippetFilePath, function (m) {
2620 if (!m)
2621 return;
2622 snippetManager.files[id] = m;
2623 if (!m.snippets && m.snippetText)
2624 m.snippets = snippetManager.parseSnippetFile(m.snippetText);
2625 snippetManager.register(m.snippets || [], m.scope);
2626 if (m.includeScopes) {
2627 snippetManager.snippetMap[m.scope].includeScopes = m.includeScopes;
2628 m.includeScopes.forEach(function (x) {
2629 loadSnippetsForMode("ace/mode/" + x);
2630 });
2631 }
2632 });
2633 };
2634 var doLiveAutocomplete = function (e) {
2635 var editor = e.editor;
2636 var hasCompleter = editor.completer && editor.completer.activated;
2637 if (e.command.name === "backspace") {
2638 if (hasCompleter && !util.getCompletionPrefix(editor))
2639 editor.completer.detach();
2640 }
2641 else if (e.command.name === "insertstring" && !hasCompleter) {
2642 lastExecEvent = e;
2643 var delay = e.editor.$liveAutocompletionDelay;
2644 if (delay) {
2645 liveAutocompleteTimer.delay(delay);
2646 }
2647 else {
2648 showLiveAutocomplete(e);
2649 }
2650 }
2651 };
2652 var lastExecEvent;
2653 var liveAutocompleteTimer = lang.delayedCall(function () {
2654 showLiveAutocomplete(lastExecEvent);
2655 }, 0);
2656 var showLiveAutocomplete = function (e) {
2657 var editor = e.editor;
2658 var prefix = util.getCompletionPrefix(editor);
2659 var previousChar = e.args;
2660 var triggerAutocomplete = util.triggerAutocomplete(editor, previousChar);
2661 if (prefix && prefix.length >= editor.$liveAutocompletionThreshold || triggerAutocomplete) {
2662 var completer = Autocomplete.for(editor);
2663 completer.autoShown = true;
2664 completer.showPopup(editor);
2665 }
2666 };
2667 var Editor = require("../editor").Editor;
2668 require("../config").defineOptions(Editor.prototype, "editor", {
2669 enableBasicAutocompletion: {
2670 set: function (val) {
2671 if (val) {
2672 Autocomplete.for(this);
2673 if (!this.completers)
2674 this.completers = Array.isArray(val) ? val : completers;
2675 this.commands.addCommand(Autocomplete.startCommand);
2676 }
2677 else {
2678 this.commands.removeCommand(Autocomplete.startCommand);
2679 }
2680 },
2681 value: false
2682 },
2683 enableLiveAutocompletion: {
2684 set: function (val) {
2685 if (val) {
2686 if (!this.completers)
2687 this.completers = Array.isArray(val) ? val : completers;
2688 this.commands.on('afterExec', doLiveAutocomplete);
2689 }
2690 else {
2691 this.commands.off('afterExec', doLiveAutocomplete);
2692 }
2693 },
2694 value: false
2695 },
2696 liveAutocompletionDelay: {
2697 initialValue: 0
2698 },
2699 liveAutocompletionThreshold: {
2700 initialValue: 0
2701 },
2702 enableSnippets: {
2703 set: function (val) {
2704 if (val) {
2705 this.commands.addCommand(expandSnippet);
2706 this.on("changeMode", onChangeMode);
2707 onChangeMode(null, this);
2708 }
2709 else {
2710 this.commands.removeCommand(expandSnippet);
2711 this.off("changeMode", onChangeMode);
2712 }
2713 },
2714 value: false
2715 }
2716 });
2717 exports.MarkerGroup = MarkerGroup;
2718
2719 }); (function() {
2720 ace.require(["ace/ext/language_tools"], function(m) {
2721 if (typeof module == "object" && typeof exports == "object" && module) {
2722 module.exports = m;
2723 }
2724 });
2725 })();
2726