blazer_xlsx 3.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +442 -0
  3. data/CONTRIBUTING.md +42 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +1093 -0
  6. data/app/assets/fonts/blazer/glyphicons-halflings-regular.eot +0 -0
  7. data/app/assets/fonts/blazer/glyphicons-halflings-regular.svg +288 -0
  8. data/app/assets/fonts/blazer/glyphicons-halflings-regular.ttf +0 -0
  9. data/app/assets/fonts/blazer/glyphicons-halflings-regular.woff +0 -0
  10. data/app/assets/fonts/blazer/glyphicons-halflings-regular.woff2 +0 -0
  11. data/app/assets/images/blazer/favicon.png +0 -0
  12. data/app/assets/javascripts/blazer/Sortable.js +3709 -0
  13. data/app/assets/javascripts/blazer/ace/ace.js +19630 -0
  14. data/app/assets/javascripts/blazer/ace/ext-language_tools.js +1981 -0
  15. data/app/assets/javascripts/blazer/ace/mode-sql.js +215 -0
  16. data/app/assets/javascripts/blazer/ace/snippets/sql.js +16 -0
  17. data/app/assets/javascripts/blazer/ace/snippets/text.js +9 -0
  18. data/app/assets/javascripts/blazer/ace/theme-twilight.js +18 -0
  19. data/app/assets/javascripts/blazer/ace.js +6 -0
  20. data/app/assets/javascripts/blazer/application.js +84 -0
  21. data/app/assets/javascripts/blazer/bootstrap.js +2580 -0
  22. data/app/assets/javascripts/blazer/chart.umd.js +13 -0
  23. data/app/assets/javascripts/blazer/chartjs-adapter-date-fns.bundle.js +6322 -0
  24. data/app/assets/javascripts/blazer/chartkick.js +2570 -0
  25. data/app/assets/javascripts/blazer/daterangepicker.js +1578 -0
  26. data/app/assets/javascripts/blazer/fuzzysearch.js +24 -0
  27. data/app/assets/javascripts/blazer/highlight.min.js +466 -0
  28. data/app/assets/javascripts/blazer/jquery.js +10872 -0
  29. data/app/assets/javascripts/blazer/jquery.stickytableheaders.js +325 -0
  30. data/app/assets/javascripts/blazer/mapkick.bundle.js +1029 -0
  31. data/app/assets/javascripts/blazer/moment-timezone-with-data.js +1548 -0
  32. data/app/assets/javascripts/blazer/moment.js +5685 -0
  33. data/app/assets/javascripts/blazer/queries.js +130 -0
  34. data/app/assets/javascripts/blazer/rails-ujs.js +746 -0
  35. data/app/assets/javascripts/blazer/routes.js +26 -0
  36. data/app/assets/javascripts/blazer/selectize.js +3891 -0
  37. data/app/assets/javascripts/blazer/stupidtable-custom-settings.js +13 -0
  38. data/app/assets/javascripts/blazer/stupidtable.js +281 -0
  39. data/app/assets/javascripts/blazer/vue.global.prod.js +1 -0
  40. data/app/assets/stylesheets/blazer/application.css +243 -0
  41. data/app/assets/stylesheets/blazer/bootstrap-propshaft.css +10 -0
  42. data/app/assets/stylesheets/blazer/bootstrap-sprockets.css.erb +10 -0
  43. data/app/assets/stylesheets/blazer/bootstrap.css +6828 -0
  44. data/app/assets/stylesheets/blazer/daterangepicker.css +410 -0
  45. data/app/assets/stylesheets/blazer/github.css +125 -0
  46. data/app/assets/stylesheets/blazer/selectize.css +403 -0
  47. data/app/controllers/blazer/base_controller.rb +135 -0
  48. data/app/controllers/blazer/checks_controller.rb +56 -0
  49. data/app/controllers/blazer/dashboards_controller.rb +99 -0
  50. data/app/controllers/blazer/queries_controller.rb +472 -0
  51. data/app/controllers/blazer/uploads_controller.rb +147 -0
  52. data/app/helpers/blazer/base_helper.rb +39 -0
  53. data/app/models/blazer/audit.rb +6 -0
  54. data/app/models/blazer/check.rb +104 -0
  55. data/app/models/blazer/connection.rb +5 -0
  56. data/app/models/blazer/dashboard.rb +17 -0
  57. data/app/models/blazer/dashboard_query.rb +9 -0
  58. data/app/models/blazer/query.rb +42 -0
  59. data/app/models/blazer/record.rb +5 -0
  60. data/app/models/blazer/upload.rb +11 -0
  61. data/app/models/blazer/uploads_connection.rb +7 -0
  62. data/app/views/blazer/_nav.html.erb +18 -0
  63. data/app/views/blazer/_variables.html.erb +127 -0
  64. data/app/views/blazer/check_mailer/failing_checks.html.erb +7 -0
  65. data/app/views/blazer/check_mailer/state_change.html.erb +48 -0
  66. data/app/views/blazer/checks/_form.html.erb +79 -0
  67. data/app/views/blazer/checks/edit.html.erb +3 -0
  68. data/app/views/blazer/checks/index.html.erb +72 -0
  69. data/app/views/blazer/checks/new.html.erb +3 -0
  70. data/app/views/blazer/dashboards/_form.html.erb +82 -0
  71. data/app/views/blazer/dashboards/edit.html.erb +3 -0
  72. data/app/views/blazer/dashboards/new.html.erb +3 -0
  73. data/app/views/blazer/dashboards/show.html.erb +53 -0
  74. data/app/views/blazer/queries/_caching.html.erb +16 -0
  75. data/app/views/blazer/queries/_cohorts.html.erb +48 -0
  76. data/app/views/blazer/queries/_form.html.erb +255 -0
  77. data/app/views/blazer/queries/docs.html.erb +147 -0
  78. data/app/views/blazer/queries/edit.html.erb +2 -0
  79. data/app/views/blazer/queries/home.html.erb +169 -0
  80. data/app/views/blazer/queries/new.html.erb +2 -0
  81. data/app/views/blazer/queries/run.html.erb +183 -0
  82. data/app/views/blazer/queries/schema.html.erb +55 -0
  83. data/app/views/blazer/queries/show.html.erb +72 -0
  84. data/app/views/blazer/uploads/_form.html.erb +27 -0
  85. data/app/views/blazer/uploads/edit.html.erb +3 -0
  86. data/app/views/blazer/uploads/index.html.erb +55 -0
  87. data/app/views/blazer/uploads/new.html.erb +3 -0
  88. data/app/views/layouts/blazer/application.html.erb +25 -0
  89. data/config/routes.rb +25 -0
  90. data/lib/blazer/adapters/athena_adapter.rb +182 -0
  91. data/lib/blazer/adapters/base_adapter.rb +76 -0
  92. data/lib/blazer/adapters/bigquery_adapter.rb +79 -0
  93. data/lib/blazer/adapters/cassandra_adapter.rb +70 -0
  94. data/lib/blazer/adapters/drill_adapter.rb +38 -0
  95. data/lib/blazer/adapters/druid_adapter.rb +102 -0
  96. data/lib/blazer/adapters/elasticsearch_adapter.rb +61 -0
  97. data/lib/blazer/adapters/hive_adapter.rb +55 -0
  98. data/lib/blazer/adapters/ignite_adapter.rb +64 -0
  99. data/lib/blazer/adapters/influxdb_adapter.rb +57 -0
  100. data/lib/blazer/adapters/neo4j_adapter.rb +62 -0
  101. data/lib/blazer/adapters/opensearch_adapter.rb +52 -0
  102. data/lib/blazer/adapters/presto_adapter.rb +54 -0
  103. data/lib/blazer/adapters/salesforce_adapter.rb +50 -0
  104. data/lib/blazer/adapters/snowflake_adapter.rb +82 -0
  105. data/lib/blazer/adapters/soda_adapter.rb +105 -0
  106. data/lib/blazer/adapters/spark_adapter.rb +14 -0
  107. data/lib/blazer/adapters/sql_adapter.rb +353 -0
  108. data/lib/blazer/adapters.rb +17 -0
  109. data/lib/blazer/anomaly_detectors.rb +22 -0
  110. data/lib/blazer/check_mailer.rb +27 -0
  111. data/lib/blazer/data_source.rb +266 -0
  112. data/lib/blazer/engine.rb +42 -0
  113. data/lib/blazer/forecasters.rb +7 -0
  114. data/lib/blazer/result.rb +178 -0
  115. data/lib/blazer/result_cache.rb +71 -0
  116. data/lib/blazer/run_statement.rb +45 -0
  117. data/lib/blazer/run_statement_job.rb +20 -0
  118. data/lib/blazer/slack_notifier.rb +94 -0
  119. data/lib/blazer/statement.rb +77 -0
  120. data/lib/blazer/version.rb +3 -0
  121. data/lib/blazer.rb +282 -0
  122. data/lib/generators/blazer/install_generator.rb +22 -0
  123. data/lib/generators/blazer/templates/config.yml.tt +79 -0
  124. data/lib/generators/blazer/templates/install.rb.tt +47 -0
  125. data/lib/generators/blazer/templates/uploads.rb.tt +10 -0
  126. data/lib/generators/blazer/uploads_generator.rb +18 -0
  127. data/lib/tasks/blazer.rake +20 -0
  128. data/licenses/LICENSE-ace.txt +24 -0
  129. data/licenses/LICENSE-bootstrap.txt +21 -0
  130. data/licenses/LICENSE-chart.js.txt +9 -0
  131. data/licenses/LICENSE-chartjs-adapter-date-fns.txt +9 -0
  132. data/licenses/LICENSE-chartkick.js.txt +22 -0
  133. data/licenses/LICENSE-date-fns.txt +21 -0
  134. data/licenses/LICENSE-daterangepicker.txt +21 -0
  135. data/licenses/LICENSE-fuzzysearch.txt +20 -0
  136. data/licenses/LICENSE-highlight.js.txt +29 -0
  137. data/licenses/LICENSE-jquery.txt +20 -0
  138. data/licenses/LICENSE-kurkle-color.txt +9 -0
  139. data/licenses/LICENSE-mapkick-bundle.txt +1029 -0
  140. data/licenses/LICENSE-moment-timezone.txt +20 -0
  141. data/licenses/LICENSE-moment.txt +22 -0
  142. data/licenses/LICENSE-rails-ujs.txt +20 -0
  143. data/licenses/LICENSE-selectize.txt +202 -0
  144. data/licenses/LICENSE-sortable.txt +21 -0
  145. data/licenses/LICENSE-stickytableheaders.txt +20 -0
  146. data/licenses/LICENSE-stupidtable.txt +19 -0
  147. data/licenses/LICENSE-vue.txt +21 -0
  148. metadata +271 -0
@@ -0,0 +1,1981 @@
1
+ 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 = function () {
84
+ this.snippetMap = {};
85
+ this.snippetNameMap = {};
86
+ };
87
+ (function () {
88
+ oop.implement(this, EventEmitter);
89
+ this.getTokenizer = function () {
90
+ return SnippetManager.$tokenizer || this.createTokenizer();
91
+ };
92
+ this.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
+ this.tokenizeTmSnippet = function (str, startState) {
213
+ return this.getTokenizer().getLineTokens(str, startState).tokens.map(function (x) {
214
+ return x.value || x;
215
+ });
216
+ };
217
+ this.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
+ this.variables = VARIABLES;
231
+ this.tmStrFormat = function (str, ch, editor) {
232
+ if (!ch.fmt)
233
+ return str;
234
+ var flag = ch.flag || "";
235
+ var re = ch.guard;
236
+ re = new RegExp(re, flag.replace(/[^gim]/g, ""));
237
+ var fmtTokens = typeof ch.fmt == "string" ? this.tokenizeTmSnippet(ch.fmt, "formatString") : ch.fmt;
238
+ var _self = this;
239
+ var formatted = str.replace(re, function () {
240
+ var oldArgs = _self.variables.__;
241
+ _self.variables.__ = [].slice.call(arguments);
242
+ var fmtParts = _self.resolveVariables(fmtTokens, editor);
243
+ var gChangeCase = "E";
244
+ for (var i = 0; i < fmtParts.length; i++) {
245
+ var ch = fmtParts[i];
246
+ if (typeof ch == "object") {
247
+ fmtParts[i] = "";
248
+ if (ch.changeCase && ch.local) {
249
+ var next = fmtParts[i + 1];
250
+ if (next && typeof next == "string") {
251
+ if (ch.changeCase == "u")
252
+ fmtParts[i] = next[0].toUpperCase();
253
+ else
254
+ fmtParts[i] = next[0].toLowerCase();
255
+ fmtParts[i + 1] = next.substr(1);
256
+ }
257
+ }
258
+ else if (ch.changeCase) {
259
+ gChangeCase = ch.changeCase;
260
+ }
261
+ }
262
+ else if (gChangeCase == "U") {
263
+ fmtParts[i] = ch.toUpperCase();
264
+ }
265
+ else if (gChangeCase == "L") {
266
+ fmtParts[i] = ch.toLowerCase();
267
+ }
268
+ }
269
+ _self.variables.__ = oldArgs;
270
+ return fmtParts.join("");
271
+ });
272
+ return formatted;
273
+ };
274
+ this.tmFormatFunction = function (str, ch, editor) {
275
+ if (ch.formatFunction == "upcase")
276
+ return str.toUpperCase();
277
+ if (ch.formatFunction == "downcase")
278
+ return str.toLowerCase();
279
+ return str;
280
+ };
281
+ this.resolveVariables = function (snippet, editor) {
282
+ var result = [];
283
+ var indentation = "";
284
+ var afterNewLine = true;
285
+ for (var i = 0; i < snippet.length; i++) {
286
+ var ch = snippet[i];
287
+ if (typeof ch == "string") {
288
+ result.push(ch);
289
+ if (ch == "\n") {
290
+ afterNewLine = true;
291
+ indentation = "";
292
+ }
293
+ else if (afterNewLine) {
294
+ indentation = /^\t*/.exec(ch)[0];
295
+ afterNewLine = /\S/.test(ch);
296
+ }
297
+ continue;
298
+ }
299
+ if (!ch)
300
+ continue;
301
+ afterNewLine = false;
302
+ if (ch.fmtString) {
303
+ var j = snippet.indexOf(ch, i + 1);
304
+ if (j == -1)
305
+ j = snippet.length;
306
+ ch.fmt = snippet.slice(i + 1, j);
307
+ i = j;
308
+ }
309
+ if (ch.text) {
310
+ var value = this.getVariableValue(editor, ch.text, indentation) + "";
311
+ if (ch.fmtString)
312
+ value = this.tmStrFormat(value, ch, editor);
313
+ if (ch.formatFunction)
314
+ value = this.tmFormatFunction(value, ch, editor);
315
+ if (value && !ch.ifEnd) {
316
+ result.push(value);
317
+ gotoNext(ch);
318
+ }
319
+ else if (!value && ch.ifEnd) {
320
+ gotoNext(ch.ifEnd);
321
+ }
322
+ }
323
+ else if (ch.elseEnd) {
324
+ gotoNext(ch.elseEnd);
325
+ }
326
+ else if (ch.tabstopId != null) {
327
+ result.push(ch);
328
+ }
329
+ else if (ch.changeCase != null) {
330
+ result.push(ch);
331
+ }
332
+ }
333
+ function gotoNext(ch) {
334
+ var i1 = snippet.indexOf(ch, i + 1);
335
+ if (i1 != -1)
336
+ i = i1;
337
+ }
338
+ return result;
339
+ };
340
+ this.insertSnippetForSelection = function (editor, snippetText) {
341
+ var cursor = editor.getCursorPosition();
342
+ var line = editor.session.getLine(cursor.row);
343
+ var tabString = editor.session.getTabString();
344
+ var indentString = line.match(/^\s*/)[0];
345
+ if (cursor.column < indentString.length)
346
+ indentString = indentString.slice(0, cursor.column);
347
+ snippetText = snippetText.replace(/\r/g, "");
348
+ var tokens = this.tokenizeTmSnippet(snippetText);
349
+ tokens = this.resolveVariables(tokens, editor);
350
+ tokens = tokens.map(function (x) {
351
+ if (x == "\n")
352
+ return x + indentString;
353
+ if (typeof x == "string")
354
+ return x.replace(/\t/g, tabString);
355
+ return x;
356
+ });
357
+ var tabstops = [];
358
+ tokens.forEach(function (p, i) {
359
+ if (typeof p != "object")
360
+ return;
361
+ var id = p.tabstopId;
362
+ var ts = tabstops[id];
363
+ if (!ts) {
364
+ ts = tabstops[id] = [];
365
+ ts.index = id;
366
+ ts.value = "";
367
+ ts.parents = {};
368
+ }
369
+ if (ts.indexOf(p) !== -1)
370
+ return;
371
+ if (p.choices && !ts.choices)
372
+ ts.choices = p.choices;
373
+ ts.push(p);
374
+ var i1 = tokens.indexOf(p, i + 1);
375
+ if (i1 === -1)
376
+ return;
377
+ var value = tokens.slice(i + 1, i1);
378
+ var isNested = value.some(function (t) { return typeof t === "object"; });
379
+ if (isNested && !ts.value) {
380
+ ts.value = value;
381
+ }
382
+ else if (value.length && (!ts.value || typeof ts.value !== "string")) {
383
+ ts.value = value.join("");
384
+ }
385
+ });
386
+ tabstops.forEach(function (ts) { ts.length = 0; });
387
+ var expanding = {};
388
+ function copyValue(val) {
389
+ var copy = [];
390
+ for (var i = 0; i < val.length; i++) {
391
+ var p = val[i];
392
+ if (typeof p == "object") {
393
+ if (expanding[p.tabstopId])
394
+ continue;
395
+ var j = val.lastIndexOf(p, i - 1);
396
+ p = copy[j] || { tabstopId: p.tabstopId };
397
+ }
398
+ copy[i] = p;
399
+ }
400
+ return copy;
401
+ }
402
+ for (var i = 0; i < tokens.length; i++) {
403
+ var p = tokens[i];
404
+ if (typeof p != "object")
405
+ continue;
406
+ var id = p.tabstopId;
407
+ var ts = tabstops[id];
408
+ var i1 = tokens.indexOf(p, i + 1);
409
+ if (expanding[id]) {
410
+ if (expanding[id] === p) {
411
+ delete expanding[id];
412
+ Object.keys(expanding).forEach(function (parentId) {
413
+ ts.parents[parentId] = true;
414
+ });
415
+ }
416
+ continue;
417
+ }
418
+ expanding[id] = p;
419
+ var value = ts.value;
420
+ if (typeof value !== "string")
421
+ value = copyValue(value);
422
+ else if (p.fmt)
423
+ value = this.tmStrFormat(value, p, editor);
424
+ tokens.splice.apply(tokens, [i + 1, Math.max(0, i1 - i)].concat(value, p));
425
+ if (ts.indexOf(p) === -1)
426
+ ts.push(p);
427
+ }
428
+ var row = 0, column = 0;
429
+ var text = "";
430
+ tokens.forEach(function (t) {
431
+ if (typeof t === "string") {
432
+ var lines = t.split("\n");
433
+ if (lines.length > 1) {
434
+ column = lines[lines.length - 1].length;
435
+ row += lines.length - 1;
436
+ }
437
+ else
438
+ column += t.length;
439
+ text += t;
440
+ }
441
+ else if (t) {
442
+ if (!t.start)
443
+ t.start = { row: row, column: column };
444
+ else
445
+ t.end = { row: row, column: column };
446
+ }
447
+ });
448
+ var range = editor.getSelectionRange();
449
+ var end = editor.session.replace(range, text);
450
+ var tabstopManager = new TabstopManager(editor);
451
+ var selectionId = editor.inVirtualSelectionMode && editor.selection.index;
452
+ tabstopManager.addTabstops(tabstops, range.start, end, selectionId);
453
+ };
454
+ this.insertSnippet = function (editor, snippetText) {
455
+ var self = this;
456
+ if (editor.inVirtualSelectionMode)
457
+ return self.insertSnippetForSelection(editor, snippetText);
458
+ editor.forEachSelection(function () {
459
+ self.insertSnippetForSelection(editor, snippetText);
460
+ }, null, { keepOrder: true });
461
+ if (editor.tabstopManager)
462
+ editor.tabstopManager.tabNext();
463
+ };
464
+ this.$getScope = function (editor) {
465
+ var scope = editor.session.$mode.$id || "";
466
+ scope = scope.split("/").pop();
467
+ if (scope === "html" || scope === "php") {
468
+ if (scope === "php" && !editor.session.$mode.inlinePhp)
469
+ scope = "html";
470
+ var c = editor.getCursorPosition();
471
+ var state = editor.session.getState(c.row);
472
+ if (typeof state === "object") {
473
+ state = state[0];
474
+ }
475
+ if (state.substring) {
476
+ if (state.substring(0, 3) == "js-")
477
+ scope = "javascript";
478
+ else if (state.substring(0, 4) == "css-")
479
+ scope = "css";
480
+ else if (state.substring(0, 4) == "php-")
481
+ scope = "php";
482
+ }
483
+ }
484
+ return scope;
485
+ };
486
+ this.getActiveScopes = function (editor) {
487
+ var scope = this.$getScope(editor);
488
+ var scopes = [scope];
489
+ var snippetMap = this.snippetMap;
490
+ if (snippetMap[scope] && snippetMap[scope].includeScopes) {
491
+ scopes.push.apply(scopes, snippetMap[scope].includeScopes);
492
+ }
493
+ scopes.push("_");
494
+ return scopes;
495
+ };
496
+ this.expandWithTab = function (editor, options) {
497
+ var self = this;
498
+ var result = editor.forEachSelection(function () {
499
+ return self.expandSnippetForSelection(editor, options);
500
+ }, null, { keepOrder: true });
501
+ if (result && editor.tabstopManager)
502
+ editor.tabstopManager.tabNext();
503
+ return result;
504
+ };
505
+ this.expandSnippetForSelection = function (editor, options) {
506
+ var cursor = editor.getCursorPosition();
507
+ var line = editor.session.getLine(cursor.row);
508
+ var before = line.substring(0, cursor.column);
509
+ var after = line.substr(cursor.column);
510
+ var snippetMap = this.snippetMap;
511
+ var snippet;
512
+ this.getActiveScopes(editor).some(function (scope) {
513
+ var snippets = snippetMap[scope];
514
+ if (snippets)
515
+ snippet = this.findMatchingSnippet(snippets, before, after);
516
+ return !!snippet;
517
+ }, this);
518
+ if (!snippet)
519
+ return false;
520
+ if (options && options.dryRun)
521
+ return true;
522
+ editor.session.doc.removeInLine(cursor.row, cursor.column - snippet.replaceBefore.length, cursor.column + snippet.replaceAfter.length);
523
+ this.variables.M__ = snippet.matchBefore;
524
+ this.variables.T__ = snippet.matchAfter;
525
+ this.insertSnippetForSelection(editor, snippet.content);
526
+ this.variables.M__ = this.variables.T__ = null;
527
+ return true;
528
+ };
529
+ this.findMatchingSnippet = function (snippetList, before, after) {
530
+ for (var i = snippetList.length; i--;) {
531
+ var s = snippetList[i];
532
+ if (s.startRe && !s.startRe.test(before))
533
+ continue;
534
+ if (s.endRe && !s.endRe.test(after))
535
+ continue;
536
+ if (!s.startRe && !s.endRe)
537
+ continue;
538
+ s.matchBefore = s.startRe ? s.startRe.exec(before) : [""];
539
+ s.matchAfter = s.endRe ? s.endRe.exec(after) : [""];
540
+ s.replaceBefore = s.triggerRe ? s.triggerRe.exec(before)[0] : "";
541
+ s.replaceAfter = s.endTriggerRe ? s.endTriggerRe.exec(after)[0] : "";
542
+ return s;
543
+ }
544
+ };
545
+ this.snippetMap = {};
546
+ this.snippetNameMap = {};
547
+ this.register = function (snippets, scope) {
548
+ var snippetMap = this.snippetMap;
549
+ var snippetNameMap = this.snippetNameMap;
550
+ var self = this;
551
+ if (!snippets)
552
+ snippets = [];
553
+ function wrapRegexp(src) {
554
+ if (src && !/^\^?\(.*\)\$?$|^\\b$/.test(src))
555
+ src = "(?:" + src + ")";
556
+ return src || "";
557
+ }
558
+ function guardedRegexp(re, guard, opening) {
559
+ re = wrapRegexp(re);
560
+ guard = wrapRegexp(guard);
561
+ if (opening) {
562
+ re = guard + re;
563
+ if (re && re[re.length - 1] != "$")
564
+ re = re + "$";
565
+ }
566
+ else {
567
+ re = re + guard;
568
+ if (re && re[0] != "^")
569
+ re = "^" + re;
570
+ }
571
+ return new RegExp(re);
572
+ }
573
+ function addSnippet(s) {
574
+ if (!s.scope)
575
+ s.scope = scope || "_";
576
+ scope = s.scope;
577
+ if (!snippetMap[scope]) {
578
+ snippetMap[scope] = [];
579
+ snippetNameMap[scope] = {};
580
+ }
581
+ var map = snippetNameMap[scope];
582
+ if (s.name) {
583
+ var old = map[s.name];
584
+ if (old)
585
+ self.unregister(old);
586
+ map[s.name] = s;
587
+ }
588
+ snippetMap[scope].push(s);
589
+ if (s.prefix)
590
+ s.tabTrigger = s.prefix;
591
+ if (!s.content && s.body)
592
+ s.content = Array.isArray(s.body) ? s.body.join("\n") : s.body;
593
+ if (s.tabTrigger && !s.trigger) {
594
+ if (!s.guard && /^\w/.test(s.tabTrigger))
595
+ s.guard = "\\b";
596
+ s.trigger = lang.escapeRegExp(s.tabTrigger);
597
+ }
598
+ if (!s.trigger && !s.guard && !s.endTrigger && !s.endGuard)
599
+ return;
600
+ s.startRe = guardedRegexp(s.trigger, s.guard, true);
601
+ s.triggerRe = new RegExp(s.trigger);
602
+ s.endRe = guardedRegexp(s.endTrigger, s.endGuard, true);
603
+ s.endTriggerRe = new RegExp(s.endTrigger);
604
+ }
605
+ if (Array.isArray(snippets)) {
606
+ snippets.forEach(addSnippet);
607
+ }
608
+ else {
609
+ Object.keys(snippets).forEach(function (key) {
610
+ addSnippet(snippets[key]);
611
+ });
612
+ }
613
+ this._signal("registerSnippets", { scope: scope });
614
+ };
615
+ this.unregister = function (snippets, scope) {
616
+ var snippetMap = this.snippetMap;
617
+ var snippetNameMap = this.snippetNameMap;
618
+ function removeSnippet(s) {
619
+ var nameMap = snippetNameMap[s.scope || scope];
620
+ if (nameMap && nameMap[s.name]) {
621
+ delete nameMap[s.name];
622
+ var map = snippetMap[s.scope || scope];
623
+ var i = map && map.indexOf(s);
624
+ if (i >= 0)
625
+ map.splice(i, 1);
626
+ }
627
+ }
628
+ if (snippets.content)
629
+ removeSnippet(snippets);
630
+ else if (Array.isArray(snippets))
631
+ snippets.forEach(removeSnippet);
632
+ };
633
+ this.parseSnippetFile = function (str) {
634
+ str = str.replace(/\r/g, "");
635
+ var list = [], snippet = {};
636
+ var re = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm;
637
+ var m;
638
+ while (m = re.exec(str)) {
639
+ if (m[1]) {
640
+ try {
641
+ snippet = JSON.parse(m[1]);
642
+ list.push(snippet);
643
+ }
644
+ catch (e) { }
645
+ }
646
+ if (m[4]) {
647
+ snippet.content = m[4].replace(/^\t/gm, "");
648
+ list.push(snippet);
649
+ snippet = {};
650
+ }
651
+ else {
652
+ var key = m[2], val = m[3];
653
+ if (key == "regex") {
654
+ var guardRe = /\/((?:[^\/\\]|\\.)*)|$/g;
655
+ snippet.guard = guardRe.exec(val)[1];
656
+ snippet.trigger = guardRe.exec(val)[1];
657
+ snippet.endTrigger = guardRe.exec(val)[1];
658
+ snippet.endGuard = guardRe.exec(val)[1];
659
+ }
660
+ else if (key == "snippet") {
661
+ snippet.tabTrigger = val.match(/^\S*/)[0];
662
+ if (!snippet.name)
663
+ snippet.name = val;
664
+ }
665
+ else if (key) {
666
+ snippet[key] = val;
667
+ }
668
+ }
669
+ }
670
+ return list;
671
+ };
672
+ this.getSnippetByName = function (name, editor) {
673
+ var snippetMap = this.snippetNameMap;
674
+ var snippet;
675
+ this.getActiveScopes(editor).some(function (scope) {
676
+ var snippets = snippetMap[scope];
677
+ if (snippets)
678
+ snippet = snippets[name];
679
+ return !!snippet;
680
+ }, this);
681
+ return snippet;
682
+ };
683
+ }).call(SnippetManager.prototype);
684
+ var TabstopManager = function (editor) {
685
+ if (editor.tabstopManager)
686
+ return editor.tabstopManager;
687
+ editor.tabstopManager = this;
688
+ this.$onChange = this.onChange.bind(this);
689
+ this.$onChangeSelection = lang.delayedCall(this.onChangeSelection.bind(this)).schedule;
690
+ this.$onChangeSession = this.onChangeSession.bind(this);
691
+ this.$onAfterExec = this.onAfterExec.bind(this);
692
+ this.attach(editor);
693
+ };
694
+ (function () {
695
+ this.attach = function (editor) {
696
+ this.index = 0;
697
+ this.ranges = [];
698
+ this.tabstops = [];
699
+ this.$openTabstops = null;
700
+ this.selectedTabstop = null;
701
+ this.editor = editor;
702
+ this.editor.on("change", this.$onChange);
703
+ this.editor.on("changeSelection", this.$onChangeSelection);
704
+ this.editor.on("changeSession", this.$onChangeSession);
705
+ this.editor.commands.on("afterExec", this.$onAfterExec);
706
+ this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
707
+ };
708
+ this.detach = function () {
709
+ this.tabstops.forEach(this.removeTabstopMarkers, this);
710
+ this.ranges = null;
711
+ this.tabstops = null;
712
+ this.selectedTabstop = null;
713
+ this.editor.removeListener("change", this.$onChange);
714
+ this.editor.removeListener("changeSelection", this.$onChangeSelection);
715
+ this.editor.removeListener("changeSession", this.$onChangeSession);
716
+ this.editor.commands.removeListener("afterExec", this.$onAfterExec);
717
+ this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
718
+ this.editor.tabstopManager = null;
719
+ this.editor = null;
720
+ };
721
+ this.onChange = function (delta) {
722
+ var isRemove = delta.action[0] == "r";
723
+ var selectedTabstop = this.selectedTabstop || {};
724
+ var parents = selectedTabstop.parents || {};
725
+ var tabstops = (this.tabstops || []).slice();
726
+ for (var i = 0; i < tabstops.length; i++) {
727
+ var ts = tabstops[i];
728
+ var active = ts == selectedTabstop || parents[ts.index];
729
+ ts.rangeList.$bias = active ? 0 : 1;
730
+ if (delta.action == "remove" && ts !== selectedTabstop) {
731
+ var parentActive = ts.parents && ts.parents[selectedTabstop.index];
732
+ var startIndex = ts.rangeList.pointIndex(delta.start, parentActive);
733
+ startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1;
734
+ var endIndex = ts.rangeList.pointIndex(delta.end, parentActive);
735
+ endIndex = endIndex < 0 ? -endIndex - 1 : endIndex - 1;
736
+ var toRemove = ts.rangeList.ranges.slice(startIndex, endIndex);
737
+ for (var j = 0; j < toRemove.length; j++)
738
+ this.removeRange(toRemove[j]);
739
+ }
740
+ ts.rangeList.$onChange(delta);
741
+ }
742
+ var session = this.editor.session;
743
+ if (!this.$inChange && isRemove && session.getLength() == 1 && !session.getValue())
744
+ this.detach();
745
+ };
746
+ this.updateLinkedFields = function () {
747
+ var ts = this.selectedTabstop;
748
+ if (!ts || !ts.hasLinkedRanges || !ts.firstNonLinked)
749
+ return;
750
+ this.$inChange = true;
751
+ var session = this.editor.session;
752
+ var text = session.getTextRange(ts.firstNonLinked);
753
+ for (var i = 0; i < ts.length; i++) {
754
+ var range = ts[i];
755
+ if (!range.linked)
756
+ continue;
757
+ var original = range.original;
758
+ var fmt = exports.snippetManager.tmStrFormat(text, original, this.editor);
759
+ session.replace(range, fmt);
760
+ }
761
+ this.$inChange = false;
762
+ };
763
+ this.onAfterExec = function (e) {
764
+ if (e.command && !e.command.readOnly)
765
+ this.updateLinkedFields();
766
+ };
767
+ this.onChangeSelection = function () {
768
+ if (!this.editor)
769
+ return;
770
+ var lead = this.editor.selection.lead;
771
+ var anchor = this.editor.selection.anchor;
772
+ var isEmpty = this.editor.selection.isEmpty();
773
+ for (var i = 0; i < this.ranges.length; i++) {
774
+ if (this.ranges[i].linked)
775
+ continue;
776
+ var containsLead = this.ranges[i].contains(lead.row, lead.column);
777
+ var containsAnchor = isEmpty || this.ranges[i].contains(anchor.row, anchor.column);
778
+ if (containsLead && containsAnchor)
779
+ return;
780
+ }
781
+ this.detach();
782
+ };
783
+ this.onChangeSession = function () {
784
+ this.detach();
785
+ };
786
+ this.tabNext = function (dir) {
787
+ var max = this.tabstops.length;
788
+ var index = this.index + (dir || 1);
789
+ index = Math.min(Math.max(index, 1), max);
790
+ if (index == max)
791
+ index = 0;
792
+ this.selectTabstop(index);
793
+ if (index === 0)
794
+ this.detach();
795
+ };
796
+ this.selectTabstop = function (index) {
797
+ this.$openTabstops = null;
798
+ var ts = this.tabstops[this.index];
799
+ if (ts)
800
+ this.addTabstopMarkers(ts);
801
+ this.index = index;
802
+ ts = this.tabstops[this.index];
803
+ if (!ts || !ts.length)
804
+ return;
805
+ this.selectedTabstop = ts;
806
+ var range = ts.firstNonLinked || ts;
807
+ if (ts.choices)
808
+ range.cursor = range.start;
809
+ if (!this.editor.inVirtualSelectionMode) {
810
+ var sel = this.editor.multiSelect;
811
+ sel.toSingleRange(range);
812
+ for (var i = 0; i < ts.length; i++) {
813
+ if (ts.hasLinkedRanges && ts[i].linked)
814
+ continue;
815
+ sel.addRange(ts[i].clone(), true);
816
+ }
817
+ }
818
+ else {
819
+ this.editor.selection.fromOrientedRange(range);
820
+ }
821
+ this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
822
+ if (this.selectedTabstop && this.selectedTabstop.choices)
823
+ this.editor.execCommand("startAutocomplete", { matches: this.selectedTabstop.choices });
824
+ };
825
+ this.addTabstops = function (tabstops, start, end) {
826
+ var useLink = this.useLink || !this.editor.getOption("enableMultiselect");
827
+ if (!this.$openTabstops)
828
+ this.$openTabstops = [];
829
+ if (!tabstops[0]) {
830
+ var p = Range.fromPoints(end, end);
831
+ moveRelative(p.start, start);
832
+ moveRelative(p.end, start);
833
+ tabstops[0] = [p];
834
+ tabstops[0].index = 0;
835
+ }
836
+ var i = this.index;
837
+ var arg = [i + 1, 0];
838
+ var ranges = this.ranges;
839
+ tabstops.forEach(function (ts, index) {
840
+ var dest = this.$openTabstops[index] || ts;
841
+ for (var i = 0; i < ts.length; i++) {
842
+ var p = ts[i];
843
+ var range = Range.fromPoints(p.start, p.end || p.start);
844
+ movePoint(range.start, start);
845
+ movePoint(range.end, start);
846
+ range.original = p;
847
+ range.tabstop = dest;
848
+ ranges.push(range);
849
+ if (dest != ts)
850
+ dest.unshift(range);
851
+ else
852
+ dest[i] = range;
853
+ if (p.fmtString || (dest.firstNonLinked && useLink)) {
854
+ range.linked = true;
855
+ dest.hasLinkedRanges = true;
856
+ }
857
+ else if (!dest.firstNonLinked)
858
+ dest.firstNonLinked = range;
859
+ }
860
+ if (!dest.firstNonLinked)
861
+ dest.hasLinkedRanges = false;
862
+ if (dest === ts) {
863
+ arg.push(dest);
864
+ this.$openTabstops[index] = dest;
865
+ }
866
+ this.addTabstopMarkers(dest);
867
+ dest.rangeList = dest.rangeList || new RangeList();
868
+ dest.rangeList.$bias = 0;
869
+ dest.rangeList.addList(dest);
870
+ }, this);
871
+ if (arg.length > 2) {
872
+ if (this.tabstops.length)
873
+ arg.push(arg.splice(2, 1)[0]);
874
+ this.tabstops.splice.apply(this.tabstops, arg);
875
+ }
876
+ };
877
+ this.addTabstopMarkers = function (ts) {
878
+ var session = this.editor.session;
879
+ ts.forEach(function (range) {
880
+ if (!range.markerId)
881
+ range.markerId = session.addMarker(range, "ace_snippet-marker", "text");
882
+ });
883
+ };
884
+ this.removeTabstopMarkers = function (ts) {
885
+ var session = this.editor.session;
886
+ ts.forEach(function (range) {
887
+ session.removeMarker(range.markerId);
888
+ range.markerId = null;
889
+ });
890
+ };
891
+ this.removeRange = function (range) {
892
+ var i = range.tabstop.indexOf(range);
893
+ if (i != -1)
894
+ range.tabstop.splice(i, 1);
895
+ i = this.ranges.indexOf(range);
896
+ if (i != -1)
897
+ this.ranges.splice(i, 1);
898
+ i = range.tabstop.rangeList.ranges.indexOf(range);
899
+ if (i != -1)
900
+ range.tabstop.splice(i, 1);
901
+ this.editor.session.removeMarker(range.markerId);
902
+ if (!range.tabstop.length) {
903
+ i = this.tabstops.indexOf(range.tabstop);
904
+ if (i != -1)
905
+ this.tabstops.splice(i, 1);
906
+ if (!this.tabstops.length)
907
+ this.detach();
908
+ }
909
+ };
910
+ this.keyboardHandler = new HashHandler();
911
+ this.keyboardHandler.bindKeys({
912
+ "Tab": function (editor) {
913
+ if (exports.snippetManager && exports.snippetManager.expandWithTab(editor))
914
+ return;
915
+ editor.tabstopManager.tabNext(1);
916
+ editor.renderer.scrollCursorIntoView();
917
+ },
918
+ "Shift-Tab": function (editor) {
919
+ editor.tabstopManager.tabNext(-1);
920
+ editor.renderer.scrollCursorIntoView();
921
+ },
922
+ "Esc": function (editor) {
923
+ editor.tabstopManager.detach();
924
+ }
925
+ });
926
+ }).call(TabstopManager.prototype);
927
+ var movePoint = function (point, diff) {
928
+ if (point.row == 0)
929
+ point.column += diff.column;
930
+ point.row += diff.row;
931
+ };
932
+ var moveRelative = function (point, start) {
933
+ if (point.row == start.row)
934
+ point.column -= start.column;
935
+ point.row -= start.row;
936
+ };
937
+ 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);
938
+ exports.snippetManager = new SnippetManager();
939
+ var Editor = require("./editor").Editor;
940
+ (function () {
941
+ this.insertSnippet = function (content, options) {
942
+ return exports.snippetManager.insertSnippet(this, content, options);
943
+ };
944
+ this.expandSnippet = function (options) {
945
+ return exports.snippetManager.expandWithTab(this, options);
946
+ };
947
+ }).call(Editor.prototype);
948
+
949
+ });
950
+
951
+ define("ace/autocomplete/popup",["require","exports","module","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom"], function(require, exports, module){"use strict";
952
+ var Renderer = require("../virtual_renderer").VirtualRenderer;
953
+ var Editor = require("../editor").Editor;
954
+ var Range = require("../range").Range;
955
+ var event = require("../lib/event");
956
+ var lang = require("../lib/lang");
957
+ var dom = require("../lib/dom");
958
+ var getAriaId = function (index) {
959
+ return "suggest-aria-id:".concat(index);
960
+ };
961
+ var $singleLineEditor = function (el) {
962
+ var renderer = new Renderer(el);
963
+ renderer.$maxLines = 4;
964
+ var editor = new Editor(renderer);
965
+ editor.setHighlightActiveLine(false);
966
+ editor.setShowPrintMargin(false);
967
+ editor.renderer.setShowGutter(false);
968
+ editor.renderer.setHighlightGutterLine(false);
969
+ editor.$mouseHandler.$focusTimeout = 0;
970
+ editor.$highlightTagPending = true;
971
+ return editor;
972
+ };
973
+ var AcePopup = function (parentNode) {
974
+ var el = dom.createElement("div");
975
+ var popup = new $singleLineEditor(el);
976
+ if (parentNode)
977
+ parentNode.appendChild(el);
978
+ el.style.display = "none";
979
+ popup.renderer.content.style.cursor = "default";
980
+ popup.renderer.setStyle("ace_autocomplete");
981
+ popup.renderer.container.setAttribute("role", "listbox");
982
+ popup.renderer.container.setAttribute("aria-label", "Autocomplete suggestions");
983
+ popup.setOption("displayIndentGuides", false);
984
+ popup.setOption("dragDelay", 150);
985
+ var noop = function () { };
986
+ popup.focus = noop;
987
+ popup.$isFocused = true;
988
+ popup.renderer.$cursorLayer.restartTimer = noop;
989
+ popup.renderer.$cursorLayer.element.style.opacity = 0;
990
+ popup.renderer.$maxLines = 8;
991
+ popup.renderer.$keepTextAreaAtCursor = false;
992
+ popup.setHighlightActiveLine(false);
993
+ popup.session.highlight("");
994
+ popup.session.$searchHighlight.clazz = "ace_highlight-marker";
995
+ popup.on("mousedown", function (e) {
996
+ var pos = e.getDocumentPosition();
997
+ popup.selection.moveToPosition(pos);
998
+ selectionMarker.start.row = selectionMarker.end.row = pos.row;
999
+ e.stop();
1000
+ });
1001
+ var lastMouseEvent;
1002
+ var hoverMarker = new Range(-1, 0, -1, Infinity);
1003
+ var selectionMarker = new Range(-1, 0, -1, Infinity);
1004
+ selectionMarker.id = popup.session.addMarker(selectionMarker, "ace_active-line", "fullLine");
1005
+ popup.setSelectOnHover = function (val) {
1006
+ if (!val) {
1007
+ hoverMarker.id = popup.session.addMarker(hoverMarker, "ace_line-hover", "fullLine");
1008
+ }
1009
+ else if (hoverMarker.id) {
1010
+ popup.session.removeMarker(hoverMarker.id);
1011
+ hoverMarker.id = null;
1012
+ }
1013
+ };
1014
+ popup.setSelectOnHover(false);
1015
+ popup.on("mousemove", function (e) {
1016
+ if (!lastMouseEvent) {
1017
+ lastMouseEvent = e;
1018
+ return;
1019
+ }
1020
+ if (lastMouseEvent.x == e.x && lastMouseEvent.y == e.y) {
1021
+ return;
1022
+ }
1023
+ lastMouseEvent = e;
1024
+ lastMouseEvent.scrollTop = popup.renderer.scrollTop;
1025
+ var row = lastMouseEvent.getDocumentPosition().row;
1026
+ if (hoverMarker.start.row != row) {
1027
+ if (!hoverMarker.id)
1028
+ popup.setRow(row);
1029
+ setHoverMarker(row);
1030
+ }
1031
+ });
1032
+ popup.renderer.on("beforeRender", function () {
1033
+ if (lastMouseEvent && hoverMarker.start.row != -1) {
1034
+ lastMouseEvent.$pos = null;
1035
+ var row = lastMouseEvent.getDocumentPosition().row;
1036
+ if (!hoverMarker.id)
1037
+ popup.setRow(row);
1038
+ setHoverMarker(row, true);
1039
+ }
1040
+ });
1041
+ popup.renderer.on("afterRender", function () {
1042
+ var row = popup.getRow();
1043
+ var t = popup.renderer.$textLayer;
1044
+ var selected = t.element.childNodes[row - t.config.firstRow];
1045
+ var el = document.activeElement; // Active element is textarea of main editor
1046
+ if (selected !== t.selectedNode && t.selectedNode) {
1047
+ dom.removeCssClass(t.selectedNode, "ace_selected");
1048
+ el.removeAttribute("aria-activedescendant");
1049
+ t.selectedNode.removeAttribute("id");
1050
+ }
1051
+ t.selectedNode = selected;
1052
+ if (selected) {
1053
+ dom.addCssClass(selected, "ace_selected");
1054
+ var ariaId = getAriaId(row);
1055
+ selected.id = ariaId;
1056
+ popup.renderer.container.setAttribute("aria-activedescendant", ariaId);
1057
+ el.setAttribute("aria-activedescendant", ariaId);
1058
+ selected.setAttribute("aria-label", popup.getData(row).value);
1059
+ }
1060
+ });
1061
+ var hideHoverMarker = function () { setHoverMarker(-1); };
1062
+ var setHoverMarker = function (row, suppressRedraw) {
1063
+ if (row !== hoverMarker.start.row) {
1064
+ hoverMarker.start.row = hoverMarker.end.row = row;
1065
+ if (!suppressRedraw)
1066
+ popup.session._emit("changeBackMarker");
1067
+ popup._emit("changeHoverMarker");
1068
+ }
1069
+ };
1070
+ popup.getHoveredRow = function () {
1071
+ return hoverMarker.start.row;
1072
+ };
1073
+ event.addListener(popup.container, "mouseout", hideHoverMarker);
1074
+ popup.on("hide", hideHoverMarker);
1075
+ popup.on("changeSelection", hideHoverMarker);
1076
+ popup.session.doc.getLength = function () {
1077
+ return popup.data.length;
1078
+ };
1079
+ popup.session.doc.getLine = function (i) {
1080
+ var data = popup.data[i];
1081
+ if (typeof data == "string")
1082
+ return data;
1083
+ return (data && data.value) || "";
1084
+ };
1085
+ var bgTokenizer = popup.session.bgTokenizer;
1086
+ bgTokenizer.$tokenizeRow = function (row) {
1087
+ var data = popup.data[row];
1088
+ var tokens = [];
1089
+ if (!data)
1090
+ return tokens;
1091
+ if (typeof data == "string")
1092
+ data = { value: data };
1093
+ var caption = data.caption || data.value || data.name;
1094
+ function addToken(value, className) {
1095
+ value && tokens.push({
1096
+ type: (data.className || "") + (className || ""),
1097
+ value: value
1098
+ });
1099
+ }
1100
+ var lower = caption.toLowerCase();
1101
+ var filterText = (popup.filterText || "").toLowerCase();
1102
+ var lastIndex = 0;
1103
+ var lastI = 0;
1104
+ for (var i = 0; i <= filterText.length; i++) {
1105
+ if (i != lastI && (data.matchMask & (1 << i) || i == filterText.length)) {
1106
+ var sub = filterText.slice(lastI, i);
1107
+ lastI = i;
1108
+ var index = lower.indexOf(sub, lastIndex);
1109
+ if (index == -1)
1110
+ continue;
1111
+ addToken(caption.slice(lastIndex, index), "");
1112
+ lastIndex = index + sub.length;
1113
+ addToken(caption.slice(index, lastIndex), "completion-highlight");
1114
+ }
1115
+ }
1116
+ addToken(caption.slice(lastIndex, caption.length), "");
1117
+ if (data.meta)
1118
+ tokens.push({ type: "completion-meta", value: data.meta });
1119
+ if (data.message)
1120
+ tokens.push({ type: "completion-message", value: data.message });
1121
+ return tokens;
1122
+ };
1123
+ bgTokenizer.$updateOnChange = noop;
1124
+ bgTokenizer.start = noop;
1125
+ popup.session.$computeWidth = function () {
1126
+ return this.screenWidth = 0;
1127
+ };
1128
+ popup.isOpen = false;
1129
+ popup.isTopdown = false;
1130
+ popup.autoSelect = true;
1131
+ popup.filterText = "";
1132
+ popup.data = [];
1133
+ popup.setData = function (list, filterText) {
1134
+ popup.filterText = filterText || "";
1135
+ popup.setValue(lang.stringRepeat("\n", list.length), -1);
1136
+ popup.data = list || [];
1137
+ popup.setRow(0);
1138
+ };
1139
+ popup.getData = function (row) {
1140
+ return popup.data[row];
1141
+ };
1142
+ popup.getRow = function () {
1143
+ return selectionMarker.start.row;
1144
+ };
1145
+ popup.setRow = function (line) {
1146
+ line = Math.max(this.autoSelect ? 0 : -1, Math.min(this.data.length, line));
1147
+ if (selectionMarker.start.row != line) {
1148
+ popup.selection.clearSelection();
1149
+ selectionMarker.start.row = selectionMarker.end.row = line || 0;
1150
+ popup.session._emit("changeBackMarker");
1151
+ popup.moveCursorTo(line || 0, 0);
1152
+ if (popup.isOpen)
1153
+ popup._signal("select");
1154
+ }
1155
+ };
1156
+ popup.on("changeSelection", function () {
1157
+ if (popup.isOpen)
1158
+ popup.setRow(popup.selection.lead.row);
1159
+ popup.renderer.scrollCursorIntoView();
1160
+ });
1161
+ popup.hide = function () {
1162
+ this.container.style.display = "none";
1163
+ this._signal("hide");
1164
+ popup.isOpen = false;
1165
+ };
1166
+ popup.show = function (pos, lineHeight, topdownOnly) {
1167
+ var el = this.container;
1168
+ var screenHeight = window.innerHeight;
1169
+ var screenWidth = window.innerWidth;
1170
+ var renderer = this.renderer;
1171
+ var maxH = renderer.$maxLines * lineHeight * 1.4;
1172
+ var top = pos.top + this.$borderSize;
1173
+ var allowTopdown = top > screenHeight / 2 && !topdownOnly;
1174
+ if (allowTopdown && top + lineHeight + maxH > screenHeight) {
1175
+ renderer.$maxPixelHeight = top - 2 * this.$borderSize;
1176
+ el.style.top = "";
1177
+ el.style.bottom = screenHeight - top + "px";
1178
+ popup.isTopdown = false;
1179
+ }
1180
+ else {
1181
+ top += lineHeight;
1182
+ renderer.$maxPixelHeight = screenHeight - top - 0.2 * lineHeight;
1183
+ el.style.top = top + "px";
1184
+ el.style.bottom = "";
1185
+ popup.isTopdown = true;
1186
+ }
1187
+ el.style.display = "";
1188
+ var left = pos.left;
1189
+ if (left + el.offsetWidth > screenWidth)
1190
+ left = screenWidth - el.offsetWidth;
1191
+ el.style.left = left + "px";
1192
+ this._signal("show");
1193
+ lastMouseEvent = null;
1194
+ popup.isOpen = true;
1195
+ };
1196
+ popup.goTo = function (where) {
1197
+ var row = this.getRow();
1198
+ var max = this.session.getLength() - 1;
1199
+ switch (where) {
1200
+ case "up":
1201
+ row = row <= 0 ? max : row - 1;
1202
+ break;
1203
+ case "down":
1204
+ row = row >= max ? -1 : row + 1;
1205
+ break;
1206
+ case "start":
1207
+ row = 0;
1208
+ break;
1209
+ case "end":
1210
+ row = max;
1211
+ break;
1212
+ }
1213
+ this.setRow(row);
1214
+ };
1215
+ popup.getTextLeftOffset = function () {
1216
+ return this.$borderSize + this.renderer.$padding + this.$imageSize;
1217
+ };
1218
+ popup.$imageSize = 0;
1219
+ popup.$borderSize = 1;
1220
+ return popup;
1221
+ };
1222
+ dom.importCssString("\n.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #CAD6FA;\n z-index: 1;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #3a674e;\n}\n.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid #abbffe;\n margin-top: -1px;\n background: rgba(233,233,253,0.4);\n position: absolute;\n z-index: 2;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid rgba(109, 150, 13, 0.8);\n background: rgba(58, 103, 78, 0.62);\n}\n.ace_completion-meta {\n opacity: 0.5;\n margin: 0.9em;\n}\n.ace_completion-message {\n color: blue;\n}\n.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #2d69c7;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #93ca12;\n}\n.ace_editor.ace_autocomplete {\n width: 300px;\n z-index: 200000;\n border: 1px lightgray solid;\n position: fixed;\n box-shadow: 2px 3px 5px rgba(0,0,0,.2);\n line-height: 1.4;\n background: #fefefe;\n color: #111;\n}\n.ace_dark.ace_editor.ace_autocomplete {\n border: 1px #484747 solid;\n box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\n line-height: 1.4;\n background: #25282c;\n color: #c1c1c1;\n}", "autocompletion.css", false);
1223
+ exports.AcePopup = AcePopup;
1224
+ exports.$singleLineEditor = $singleLineEditor;
1225
+ exports.getAriaId = getAriaId;
1226
+
1227
+ });
1228
+
1229
+ define("ace/autocomplete/util",["require","exports","module"], function(require, exports, module){"use strict";
1230
+ exports.parForEach = function (array, fn, callback) {
1231
+ var completed = 0;
1232
+ var arLength = array.length;
1233
+ if (arLength === 0)
1234
+ callback();
1235
+ for (var i = 0; i < arLength; i++) {
1236
+ fn(array[i], function (result, err) {
1237
+ completed++;
1238
+ if (completed === arLength)
1239
+ callback(result, err);
1240
+ });
1241
+ }
1242
+ };
1243
+ var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/;
1244
+ exports.retrievePrecedingIdentifier = function (text, pos, regex) {
1245
+ regex = regex || ID_REGEX;
1246
+ var buf = [];
1247
+ for (var i = pos - 1; i >= 0; i--) {
1248
+ if (regex.test(text[i]))
1249
+ buf.push(text[i]);
1250
+ else
1251
+ break;
1252
+ }
1253
+ return buf.reverse().join("");
1254
+ };
1255
+ exports.retrieveFollowingIdentifier = function (text, pos, regex) {
1256
+ regex = regex || ID_REGEX;
1257
+ var buf = [];
1258
+ for (var i = pos; i < text.length; i++) {
1259
+ if (regex.test(text[i]))
1260
+ buf.push(text[i]);
1261
+ else
1262
+ break;
1263
+ }
1264
+ return buf;
1265
+ };
1266
+ exports.getCompletionPrefix = function (editor) {
1267
+ var pos = editor.getCursorPosition();
1268
+ var line = editor.session.getLine(pos.row);
1269
+ var prefix;
1270
+ editor.completers.forEach(function (completer) {
1271
+ if (completer.identifierRegexps) {
1272
+ completer.identifierRegexps.forEach(function (identifierRegex) {
1273
+ if (!prefix && identifierRegex)
1274
+ prefix = this.retrievePrecedingIdentifier(line, pos.column, identifierRegex);
1275
+ }.bind(this));
1276
+ }
1277
+ }.bind(this));
1278
+ return prefix || this.retrievePrecedingIdentifier(line, pos.column);
1279
+ };
1280
+
1281
+ });
1282
+
1283
+ define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/lang","ace/lib/dom","ace/snippets","ace/config"], function(require, exports, module){"use strict";
1284
+ var HashHandler = require("./keyboard/hash_handler").HashHandler;
1285
+ var AcePopup = require("./autocomplete/popup").AcePopup;
1286
+ var getAriaId = require("./autocomplete/popup").getAriaId;
1287
+ var util = require("./autocomplete/util");
1288
+ var lang = require("./lib/lang");
1289
+ var dom = require("./lib/dom");
1290
+ var snippetManager = require("./snippets").snippetManager;
1291
+ var config = require("./config");
1292
+ var Autocomplete = function () {
1293
+ this.autoInsert = false;
1294
+ this.autoSelect = true;
1295
+ this.exactMatch = false;
1296
+ this.gatherCompletionsId = 0;
1297
+ this.keyboardHandler = new HashHandler();
1298
+ this.keyboardHandler.bindKeys(this.commands);
1299
+ this.blurListener = this.blurListener.bind(this);
1300
+ this.changeListener = this.changeListener.bind(this);
1301
+ this.mousedownListener = this.mousedownListener.bind(this);
1302
+ this.mousewheelListener = this.mousewheelListener.bind(this);
1303
+ this.changeTimer = lang.delayedCall(function () {
1304
+ this.updateCompletions(true);
1305
+ }.bind(this));
1306
+ this.tooltipTimer = lang.delayedCall(this.updateDocTooltip.bind(this), 50);
1307
+ };
1308
+ (function () {
1309
+ this.$init = function () {
1310
+ this.popup = new AcePopup(document.body || document.documentElement);
1311
+ this.popup.on("click", function (e) {
1312
+ this.insertMatch();
1313
+ e.stop();
1314
+ }.bind(this));
1315
+ this.popup.focus = this.editor.focus.bind(this.editor);
1316
+ this.popup.on("show", this.tooltipTimer.bind(null, null));
1317
+ this.popup.on("select", this.tooltipTimer.bind(null, null));
1318
+ this.popup.on("changeHoverMarker", this.tooltipTimer.bind(null, null));
1319
+ return this.popup;
1320
+ };
1321
+ this.getPopup = function () {
1322
+ return this.popup || this.$init();
1323
+ };
1324
+ this.openPopup = function (editor, prefix, keepPopupPosition) {
1325
+ if (!this.popup)
1326
+ this.$init();
1327
+ this.popup.autoSelect = this.autoSelect;
1328
+ this.popup.setData(this.completions.filtered, this.completions.filterText);
1329
+ this.editor.textInput.setAriaOptions({ activeDescendant: getAriaId(this.popup.getRow()) });
1330
+ editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
1331
+ var renderer = editor.renderer;
1332
+ this.popup.setRow(this.autoSelect ? 0 : -1);
1333
+ if (!keepPopupPosition) {
1334
+ this.popup.setTheme(editor.getTheme());
1335
+ this.popup.setFontSize(editor.getFontSize());
1336
+ var lineHeight = renderer.layerConfig.lineHeight;
1337
+ var pos = renderer.$cursorLayer.getPixelPosition(this.base, true);
1338
+ pos.left -= this.popup.getTextLeftOffset();
1339
+ var rect = editor.container.getBoundingClientRect();
1340
+ pos.top += rect.top - renderer.layerConfig.offset;
1341
+ pos.left += rect.left - editor.renderer.scrollLeft;
1342
+ pos.left += renderer.gutterWidth;
1343
+ this.popup.show(pos, lineHeight);
1344
+ }
1345
+ else if (keepPopupPosition && !prefix) {
1346
+ this.detach();
1347
+ }
1348
+ this.changeTimer.cancel();
1349
+ };
1350
+ this.detach = function () {
1351
+ this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
1352
+ this.editor.off("changeSelection", this.changeListener);
1353
+ this.editor.off("blur", this.blurListener);
1354
+ this.editor.off("mousedown", this.mousedownListener);
1355
+ this.editor.off("mousewheel", this.mousewheelListener);
1356
+ this.changeTimer.cancel();
1357
+ this.hideDocTooltip();
1358
+ this.gatherCompletionsId += 1;
1359
+ if (this.popup && this.popup.isOpen)
1360
+ this.popup.hide();
1361
+ if (this.base)
1362
+ this.base.detach();
1363
+ this.activated = false;
1364
+ this.completions = this.base = null;
1365
+ };
1366
+ this.changeListener = function (e) {
1367
+ var cursor = this.editor.selection.lead;
1368
+ if (cursor.row != this.base.row || cursor.column < this.base.column) {
1369
+ this.detach();
1370
+ }
1371
+ if (this.activated)
1372
+ this.changeTimer.schedule();
1373
+ else
1374
+ this.detach();
1375
+ };
1376
+ this.blurListener = function (e) {
1377
+ var el = document.activeElement;
1378
+ var text = this.editor.textInput.getElement();
1379
+ var fromTooltip = e.relatedTarget && this.tooltipNode && this.tooltipNode.contains(e.relatedTarget);
1380
+ var container = this.popup && this.popup.container;
1381
+ if (el != text && el.parentNode != container && !fromTooltip
1382
+ && el != this.tooltipNode && e.relatedTarget != text) {
1383
+ this.detach();
1384
+ }
1385
+ };
1386
+ this.mousedownListener = function (e) {
1387
+ this.detach();
1388
+ };
1389
+ this.mousewheelListener = function (e) {
1390
+ this.detach();
1391
+ };
1392
+ this.goTo = function (where) {
1393
+ this.popup.goTo(where);
1394
+ };
1395
+ this.insertMatch = function (data, options) {
1396
+ if (!data)
1397
+ data = this.popup.getData(this.popup.getRow());
1398
+ if (!data)
1399
+ return false;
1400
+ var completions = this.completions;
1401
+ this.editor.startOperation({ command: { name: "insertMatch" } });
1402
+ if (data.completer && data.completer.insertMatch) {
1403
+ data.completer.insertMatch(this.editor, data);
1404
+ }
1405
+ else {
1406
+ if (!completions)
1407
+ return false;
1408
+ if (completions.filterText) {
1409
+ var ranges = this.editor.selection.getAllRanges();
1410
+ for (var i = 0, range; range = ranges[i]; i++) {
1411
+ range.start.column -= completions.filterText.length;
1412
+ this.editor.session.remove(range);
1413
+ }
1414
+ }
1415
+ if (data.snippet)
1416
+ snippetManager.insertSnippet(this.editor, data.snippet);
1417
+ else
1418
+ this.editor.execCommand("insertstring", data.value || data);
1419
+ }
1420
+ if (this.completions == completions)
1421
+ this.detach();
1422
+ this.editor.endOperation();
1423
+ };
1424
+ this.commands = {
1425
+ "Up": function (editor) { editor.completer.goTo("up"); },
1426
+ "Down": function (editor) { editor.completer.goTo("down"); },
1427
+ "Ctrl-Up|Ctrl-Home": function (editor) { editor.completer.goTo("start"); },
1428
+ "Ctrl-Down|Ctrl-End": function (editor) { editor.completer.goTo("end"); },
1429
+ "Esc": function (editor) { editor.completer.detach(); },
1430
+ "Return": function (editor) { return editor.completer.insertMatch(); },
1431
+ "Shift-Return": function (editor) { editor.completer.insertMatch(null, { deleteSuffix: true }); },
1432
+ "Tab": function (editor) {
1433
+ var result = editor.completer.insertMatch();
1434
+ if (!result && !editor.tabstopManager)
1435
+ editor.completer.goTo("down");
1436
+ else
1437
+ return result;
1438
+ },
1439
+ "PageUp": function (editor) { editor.completer.popup.gotoPageUp(); },
1440
+ "PageDown": function (editor) { editor.completer.popup.gotoPageDown(); }
1441
+ };
1442
+ this.gatherCompletions = function (editor, callback) {
1443
+ var session = editor.getSession();
1444
+ var pos = editor.getCursorPosition();
1445
+ var prefix = util.getCompletionPrefix(editor);
1446
+ this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);
1447
+ this.base.$insertRight = true;
1448
+ var matches = [];
1449
+ var total = editor.completers.length;
1450
+ editor.completers.forEach(function (completer, i) {
1451
+ completer.getCompletions(editor, session, pos, prefix, function (err, results) {
1452
+ if (!err && results)
1453
+ matches = matches.concat(results);
1454
+ callback(null, {
1455
+ prefix: util.getCompletionPrefix(editor),
1456
+ matches: matches,
1457
+ finished: (--total === 0)
1458
+ });
1459
+ });
1460
+ });
1461
+ return true;
1462
+ };
1463
+ this.showPopup = function (editor, options) {
1464
+ if (this.editor)
1465
+ this.detach();
1466
+ this.activated = true;
1467
+ this.editor = editor;
1468
+ if (editor.completer != this) {
1469
+ if (editor.completer)
1470
+ editor.completer.detach();
1471
+ editor.completer = this;
1472
+ }
1473
+ editor.on("changeSelection", this.changeListener);
1474
+ editor.on("blur", this.blurListener);
1475
+ editor.on("mousedown", this.mousedownListener);
1476
+ editor.on("mousewheel", this.mousewheelListener);
1477
+ this.updateCompletions(false, options);
1478
+ };
1479
+ this.updateCompletions = function (keepPopupPosition, options) {
1480
+ if (keepPopupPosition && this.base && this.completions) {
1481
+ var pos = this.editor.getCursorPosition();
1482
+ var prefix = this.editor.session.getTextRange({ start: this.base, end: pos });
1483
+ if (prefix == this.completions.filterText)
1484
+ return;
1485
+ this.completions.setFilter(prefix);
1486
+ if (!this.completions.filtered.length)
1487
+ return this.detach();
1488
+ if (this.completions.filtered.length == 1
1489
+ && this.completions.filtered[0].value == prefix
1490
+ && !this.completions.filtered[0].snippet)
1491
+ return this.detach();
1492
+ this.openPopup(this.editor, prefix, keepPopupPosition);
1493
+ return;
1494
+ }
1495
+ if (options && options.matches) {
1496
+ var pos = this.editor.getSelectionRange().start;
1497
+ this.base = this.editor.session.doc.createAnchor(pos.row, pos.column);
1498
+ this.base.$insertRight = true;
1499
+ this.completions = new FilteredList(options.matches);
1500
+ return this.openPopup(this.editor, "", keepPopupPosition);
1501
+ }
1502
+ var _id = this.gatherCompletionsId;
1503
+ var detachIfFinished = function (results) {
1504
+ if (!results.finished)
1505
+ return;
1506
+ return this.detach();
1507
+ }.bind(this);
1508
+ var processResults = function (results) {
1509
+ var prefix = results.prefix;
1510
+ var matches = results.matches;
1511
+ this.completions = new FilteredList(matches);
1512
+ if (this.exactMatch)
1513
+ this.completions.exactMatch = true;
1514
+ this.completions.setFilter(prefix);
1515
+ var filtered = this.completions.filtered;
1516
+ if (!filtered.length)
1517
+ return detachIfFinished(results);
1518
+ if (filtered.length == 1 && filtered[0].value == prefix && !filtered[0].snippet)
1519
+ return detachIfFinished(results);
1520
+ if (this.autoInsert && filtered.length == 1 && results.finished)
1521
+ return this.insertMatch(filtered[0]);
1522
+ this.openPopup(this.editor, prefix, keepPopupPosition);
1523
+ }.bind(this);
1524
+ var isImmediate = true;
1525
+ var immediateResults = null;
1526
+ this.gatherCompletions(this.editor, function (err, results) {
1527
+ var prefix = results.prefix;
1528
+ var matches = results && results.matches;
1529
+ if (!matches || !matches.length)
1530
+ return detachIfFinished(results);
1531
+ if (prefix.indexOf(results.prefix) !== 0 || _id != this.gatherCompletionsId)
1532
+ return;
1533
+ if (isImmediate) {
1534
+ immediateResults = results;
1535
+ return;
1536
+ }
1537
+ processResults(results);
1538
+ }.bind(this));
1539
+ isImmediate = false;
1540
+ if (immediateResults) {
1541
+ var results = immediateResults;
1542
+ immediateResults = null;
1543
+ processResults(results);
1544
+ }
1545
+ };
1546
+ this.cancelContextMenu = function () {
1547
+ this.editor.$mouseHandler.cancelContextMenu();
1548
+ };
1549
+ this.updateDocTooltip = function () {
1550
+ var popup = this.popup;
1551
+ var all = popup.data;
1552
+ var selected = all && (all[popup.getHoveredRow()] || all[popup.getRow()]);
1553
+ var doc = null;
1554
+ if (!selected || !this.editor || !this.popup.isOpen)
1555
+ return this.hideDocTooltip();
1556
+ this.editor.completers.some(function (completer) {
1557
+ if (completer.getDocTooltip)
1558
+ doc = completer.getDocTooltip(selected);
1559
+ return doc;
1560
+ });
1561
+ if (!doc && typeof selected != "string")
1562
+ doc = selected;
1563
+ if (typeof doc == "string")
1564
+ doc = { docText: doc };
1565
+ if (!doc || !(doc.docHTML || doc.docText))
1566
+ return this.hideDocTooltip();
1567
+ this.showDocTooltip(doc);
1568
+ };
1569
+ this.showDocTooltip = function (item) {
1570
+ if (!this.tooltipNode) {
1571
+ this.tooltipNode = dom.createElement("div");
1572
+ this.tooltipNode.className = "ace_tooltip ace_doc-tooltip";
1573
+ this.tooltipNode.style.margin = 0;
1574
+ this.tooltipNode.style.pointerEvents = "auto";
1575
+ this.tooltipNode.tabIndex = -1;
1576
+ this.tooltipNode.onblur = this.blurListener.bind(this);
1577
+ this.tooltipNode.onclick = this.onTooltipClick.bind(this);
1578
+ }
1579
+ var tooltipNode = this.tooltipNode;
1580
+ if (item.docHTML) {
1581
+ tooltipNode.innerHTML = item.docHTML;
1582
+ }
1583
+ else if (item.docText) {
1584
+ tooltipNode.textContent = item.docText;
1585
+ }
1586
+ if (!tooltipNode.parentNode)
1587
+ document.body.appendChild(tooltipNode);
1588
+ var popup = this.popup;
1589
+ var rect = popup.container.getBoundingClientRect();
1590
+ tooltipNode.style.top = popup.container.style.top;
1591
+ tooltipNode.style.bottom = popup.container.style.bottom;
1592
+ tooltipNode.style.display = "block";
1593
+ if (window.innerWidth - rect.right < 320) {
1594
+ if (rect.left < 320) {
1595
+ if (popup.isTopdown) {
1596
+ tooltipNode.style.top = rect.bottom + "px";
1597
+ tooltipNode.style.left = rect.left + "px";
1598
+ tooltipNode.style.right = "";
1599
+ tooltipNode.style.bottom = "";
1600
+ }
1601
+ else {
1602
+ tooltipNode.style.top = popup.container.offsetTop - tooltipNode.offsetHeight + "px";
1603
+ tooltipNode.style.left = rect.left + "px";
1604
+ tooltipNode.style.right = "";
1605
+ tooltipNode.style.bottom = "";
1606
+ }
1607
+ }
1608
+ else {
1609
+ tooltipNode.style.right = window.innerWidth - rect.left + "px";
1610
+ tooltipNode.style.left = "";
1611
+ }
1612
+ }
1613
+ else {
1614
+ tooltipNode.style.left = (rect.right + 1) + "px";
1615
+ tooltipNode.style.right = "";
1616
+ }
1617
+ };
1618
+ this.hideDocTooltip = function () {
1619
+ this.tooltipTimer.cancel();
1620
+ if (!this.tooltipNode)
1621
+ return;
1622
+ var el = this.tooltipNode;
1623
+ if (!this.editor.isFocused() && document.activeElement == el)
1624
+ this.editor.focus();
1625
+ this.tooltipNode = null;
1626
+ if (el.parentNode)
1627
+ el.parentNode.removeChild(el);
1628
+ };
1629
+ this.onTooltipClick = function (e) {
1630
+ var a = e.target;
1631
+ while (a && a != this.tooltipNode) {
1632
+ if (a.nodeName == "A" && a.href) {
1633
+ a.rel = "noreferrer";
1634
+ a.target = "_blank";
1635
+ break;
1636
+ }
1637
+ a = a.parentNode;
1638
+ }
1639
+ };
1640
+ this.destroy = function () {
1641
+ this.detach();
1642
+ if (this.popup) {
1643
+ this.popup.destroy();
1644
+ var el = this.popup.container;
1645
+ if (el && el.parentNode)
1646
+ el.parentNode.removeChild(el);
1647
+ }
1648
+ if (this.editor && this.editor.completer == this)
1649
+ this.editor.completer == null;
1650
+ this.popup = null;
1651
+ };
1652
+ }).call(Autocomplete.prototype);
1653
+ Autocomplete.for = function (editor) {
1654
+ if (editor.completer) {
1655
+ return editor.completer;
1656
+ }
1657
+ if (config.get("sharedPopups")) {
1658
+ if (!Autocomplete.$shared)
1659
+ Autocomplete.$sharedInstance = new Autocomplete();
1660
+ editor.completer = Autocomplete.$sharedInstance;
1661
+ }
1662
+ else {
1663
+ editor.completer = new Autocomplete();
1664
+ editor.once("destroy", function (e, editor) {
1665
+ editor.completer.destroy();
1666
+ });
1667
+ }
1668
+ return editor.completer;
1669
+ };
1670
+ Autocomplete.startCommand = {
1671
+ name: "startAutocomplete",
1672
+ exec: function (editor, options) {
1673
+ var completer = Autocomplete.for(editor);
1674
+ completer.autoInsert = false;
1675
+ completer.autoSelect = true;
1676
+ completer.showPopup(editor, options);
1677
+ completer.cancelContextMenu();
1678
+ },
1679
+ bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
1680
+ };
1681
+ var FilteredList = function (array, filterText) {
1682
+ this.all = array;
1683
+ this.filtered = array;
1684
+ this.filterText = filterText || "";
1685
+ this.exactMatch = false;
1686
+ };
1687
+ (function () {
1688
+ this.setFilter = function (str) {
1689
+ if (str.length > this.filterText && str.lastIndexOf(this.filterText, 0) === 0)
1690
+ var matches = this.filtered;
1691
+ else
1692
+ var matches = this.all;
1693
+ this.filterText = str;
1694
+ matches = this.filterCompletions(matches, this.filterText);
1695
+ matches = matches.sort(function (a, b) {
1696
+ return b.exactMatch - a.exactMatch || b.$score - a.$score
1697
+ || (a.caption || a.value).localeCompare(b.caption || b.value);
1698
+ });
1699
+ var prev = null;
1700
+ matches = matches.filter(function (item) {
1701
+ var caption = item.snippet || item.caption || item.value;
1702
+ if (caption === prev)
1703
+ return false;
1704
+ prev = caption;
1705
+ return true;
1706
+ });
1707
+ this.filtered = matches;
1708
+ };
1709
+ this.filterCompletions = function (items, needle) {
1710
+ var results = [];
1711
+ var upper = needle.toUpperCase();
1712
+ var lower = needle.toLowerCase();
1713
+ loop: for (var i = 0, item; item = items[i]; i++) {
1714
+ var caption = item.caption || item.value || item.snippet;
1715
+ if (!caption)
1716
+ continue;
1717
+ var lastIndex = -1;
1718
+ var matchMask = 0;
1719
+ var penalty = 0;
1720
+ var index, distance;
1721
+ if (this.exactMatch) {
1722
+ if (needle !== caption.substr(0, needle.length))
1723
+ continue loop;
1724
+ }
1725
+ else {
1726
+ var fullMatchIndex = caption.toLowerCase().indexOf(lower);
1727
+ if (fullMatchIndex > -1) {
1728
+ penalty = fullMatchIndex;
1729
+ }
1730
+ else {
1731
+ for (var j = 0; j < needle.length; j++) {
1732
+ var i1 = caption.indexOf(lower[j], lastIndex + 1);
1733
+ var i2 = caption.indexOf(upper[j], lastIndex + 1);
1734
+ index = (i1 >= 0) ? ((i2 < 0 || i1 < i2) ? i1 : i2) : i2;
1735
+ if (index < 0)
1736
+ continue loop;
1737
+ distance = index - lastIndex - 1;
1738
+ if (distance > 0) {
1739
+ if (lastIndex === -1)
1740
+ penalty += 10;
1741
+ penalty += distance;
1742
+ matchMask = matchMask | (1 << j);
1743
+ }
1744
+ lastIndex = index;
1745
+ }
1746
+ }
1747
+ }
1748
+ item.matchMask = matchMask;
1749
+ item.exactMatch = penalty ? 0 : 1;
1750
+ item.$score = (item.score || 0) - penalty;
1751
+ results.push(item);
1752
+ }
1753
+ return results;
1754
+ };
1755
+ }).call(FilteredList.prototype);
1756
+ exports.Autocomplete = Autocomplete;
1757
+ exports.FilteredList = FilteredList;
1758
+
1759
+ });
1760
+
1761
+ define("ace/autocomplete/text_completer",["require","exports","module","ace/range"], function(require, exports, module){var Range = require("../range").Range;
1762
+ var splitRegex = /[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;
1763
+ function getWordIndex(doc, pos) {
1764
+ var textBefore = doc.getTextRange(Range.fromPoints({ row: 0, column: 0 }, pos));
1765
+ return textBefore.split(splitRegex).length - 1;
1766
+ }
1767
+ function wordDistance(doc, pos) {
1768
+ var prefixPos = getWordIndex(doc, pos);
1769
+ var words = doc.getValue().split(splitRegex);
1770
+ var wordScores = Object.create(null);
1771
+ var currentWord = words[prefixPos];
1772
+ words.forEach(function (word, idx) {
1773
+ if (!word || word === currentWord)
1774
+ return;
1775
+ var distance = Math.abs(prefixPos - idx);
1776
+ var score = words.length - distance;
1777
+ if (wordScores[word]) {
1778
+ wordScores[word] = Math.max(score, wordScores[word]);
1779
+ }
1780
+ else {
1781
+ wordScores[word] = score;
1782
+ }
1783
+ });
1784
+ return wordScores;
1785
+ }
1786
+ exports.getCompletions = function (editor, session, pos, prefix, callback) {
1787
+ var wordScore = wordDistance(session, pos);
1788
+ var wordList = Object.keys(wordScore);
1789
+ callback(null, wordList.map(function (word) {
1790
+ return {
1791
+ caption: word,
1792
+ value: word,
1793
+ score: wordScore[word],
1794
+ meta: "local"
1795
+ };
1796
+ }));
1797
+ };
1798
+
1799
+ });
1800
+
1801
+ define("ace/ext/language_tools",["require","exports","module","ace/snippets","ace/autocomplete","ace/config","ace/lib/lang","ace/autocomplete/util","ace/autocomplete/text_completer","ace/editor","ace/config"], function(require, exports, module){"use strict";
1802
+ var snippetManager = require("../snippets").snippetManager;
1803
+ var Autocomplete = require("../autocomplete").Autocomplete;
1804
+ var config = require("../config");
1805
+ var lang = require("../lib/lang");
1806
+ var util = require("../autocomplete/util");
1807
+ var textCompleter = require("../autocomplete/text_completer");
1808
+ var keyWordCompleter = {
1809
+ getCompletions: function (editor, session, pos, prefix, callback) {
1810
+ if (session.$mode.completer) {
1811
+ return session.$mode.completer.getCompletions(editor, session, pos, prefix, callback);
1812
+ }
1813
+ var state = editor.session.getState(pos.row);
1814
+ var completions = session.$mode.getCompletions(state, session, pos, prefix);
1815
+ callback(null, completions);
1816
+ }
1817
+ };
1818
+ var transformSnippetTooltip = function (str) {
1819
+ var record = {};
1820
+ return str.replace(/\${(\d+)(:(.*?))?}/g, function (_, p1, p2, p3) {
1821
+ return (record[p1] = p3 || '');
1822
+ }).replace(/\$(\d+?)/g, function (_, p1) {
1823
+ return record[p1];
1824
+ });
1825
+ };
1826
+ var snippetCompleter = {
1827
+ getCompletions: function (editor, session, pos, prefix, callback) {
1828
+ var scopes = [];
1829
+ var token = session.getTokenAt(pos.row, pos.column);
1830
+ if (token && token.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\.xml$/))
1831
+ scopes.push('html-tag');
1832
+ else
1833
+ scopes = snippetManager.getActiveScopes(editor);
1834
+ var snippetMap = snippetManager.snippetMap;
1835
+ var completions = [];
1836
+ scopes.forEach(function (scope) {
1837
+ var snippets = snippetMap[scope] || [];
1838
+ for (var i = snippets.length; i--;) {
1839
+ var s = snippets[i];
1840
+ var caption = s.name || s.tabTrigger;
1841
+ if (!caption)
1842
+ continue;
1843
+ completions.push({
1844
+ caption: caption,
1845
+ snippet: s.content,
1846
+ meta: s.tabTrigger && !s.name ? s.tabTrigger + "\u21E5 " : "snippet",
1847
+ type: "snippet"
1848
+ });
1849
+ }
1850
+ }, this);
1851
+ callback(null, completions);
1852
+ },
1853
+ getDocTooltip: function (item) {
1854
+ if (item.type == "snippet" && !item.docHTML) {
1855
+ item.docHTML = [
1856
+ "<b>", lang.escapeHTML(item.caption), "</b>", "<hr></hr>",
1857
+ lang.escapeHTML(transformSnippetTooltip(item.snippet))
1858
+ ].join("");
1859
+ }
1860
+ }
1861
+ };
1862
+ var completers = [snippetCompleter, textCompleter, keyWordCompleter];
1863
+ exports.setCompleters = function (val) {
1864
+ completers.length = 0;
1865
+ if (val)
1866
+ completers.push.apply(completers, val);
1867
+ };
1868
+ exports.addCompleter = function (completer) {
1869
+ completers.push(completer);
1870
+ };
1871
+ exports.textCompleter = textCompleter;
1872
+ exports.keyWordCompleter = keyWordCompleter;
1873
+ exports.snippetCompleter = snippetCompleter;
1874
+ var expandSnippet = {
1875
+ name: "expandSnippet",
1876
+ exec: function (editor) {
1877
+ return snippetManager.expandWithTab(editor);
1878
+ },
1879
+ bindKey: "Tab"
1880
+ };
1881
+ var onChangeMode = function (e, editor) {
1882
+ loadSnippetsForMode(editor.session.$mode);
1883
+ };
1884
+ var loadSnippetsForMode = function (mode) {
1885
+ if (typeof mode == "string")
1886
+ mode = config.$modes[mode];
1887
+ if (!mode)
1888
+ return;
1889
+ if (!snippetManager.files)
1890
+ snippetManager.files = {};
1891
+ loadSnippetFile(mode.$id, mode.snippetFileId);
1892
+ if (mode.modes)
1893
+ mode.modes.forEach(loadSnippetsForMode);
1894
+ };
1895
+ var loadSnippetFile = function (id, snippetFilePath) {
1896
+ if (!snippetFilePath || !id || snippetManager.files[id])
1897
+ return;
1898
+ snippetManager.files[id] = {};
1899
+ config.loadModule(snippetFilePath, function (m) {
1900
+ if (!m)
1901
+ return;
1902
+ snippetManager.files[id] = m;
1903
+ if (!m.snippets && m.snippetText)
1904
+ m.snippets = snippetManager.parseSnippetFile(m.snippetText);
1905
+ snippetManager.register(m.snippets || [], m.scope);
1906
+ if (m.includeScopes) {
1907
+ snippetManager.snippetMap[m.scope].includeScopes = m.includeScopes;
1908
+ m.includeScopes.forEach(function (x) {
1909
+ loadSnippetsForMode("ace/mode/" + x);
1910
+ });
1911
+ }
1912
+ });
1913
+ };
1914
+ var doLiveAutocomplete = function (e) {
1915
+ var editor = e.editor;
1916
+ var hasCompleter = editor.completer && editor.completer.activated;
1917
+ if (e.command.name === "backspace") {
1918
+ if (hasCompleter && !util.getCompletionPrefix(editor))
1919
+ editor.completer.detach();
1920
+ }
1921
+ else if (e.command.name === "insertstring") {
1922
+ var prefix = util.getCompletionPrefix(editor);
1923
+ if (prefix && !hasCompleter) {
1924
+ var completer = Autocomplete.for(editor);
1925
+ completer.autoInsert = false;
1926
+ completer.showPopup(editor);
1927
+ }
1928
+ }
1929
+ };
1930
+ var Editor = require("../editor").Editor;
1931
+ require("../config").defineOptions(Editor.prototype, "editor", {
1932
+ enableBasicAutocompletion: {
1933
+ set: function (val) {
1934
+ if (val) {
1935
+ if (!this.completers)
1936
+ this.completers = Array.isArray(val) ? val : completers;
1937
+ this.commands.addCommand(Autocomplete.startCommand);
1938
+ }
1939
+ else {
1940
+ this.commands.removeCommand(Autocomplete.startCommand);
1941
+ }
1942
+ },
1943
+ value: false
1944
+ },
1945
+ enableLiveAutocompletion: {
1946
+ set: function (val) {
1947
+ if (val) {
1948
+ if (!this.completers)
1949
+ this.completers = Array.isArray(val) ? val : completers;
1950
+ this.commands.on('afterExec', doLiveAutocomplete);
1951
+ }
1952
+ else {
1953
+ this.commands.removeListener('afterExec', doLiveAutocomplete);
1954
+ }
1955
+ },
1956
+ value: false
1957
+ },
1958
+ enableSnippets: {
1959
+ set: function (val) {
1960
+ if (val) {
1961
+ this.commands.addCommand(expandSnippet);
1962
+ this.on("changeMode", onChangeMode);
1963
+ onChangeMode(null, this);
1964
+ }
1965
+ else {
1966
+ this.commands.removeCommand(expandSnippet);
1967
+ this.off("changeMode", onChangeMode);
1968
+ }
1969
+ },
1970
+ value: false
1971
+ }
1972
+ });
1973
+
1974
+ }); (function() {
1975
+ window.require(["ace/ext/language_tools"], function(m) {
1976
+ if (typeof module == "object" && typeof exports == "object" && module) {
1977
+ module.exports = m;
1978
+ }
1979
+ });
1980
+ })();
1981
+