codemirror-rails 5.1 → 5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +92 -39
  4. data/vendor/assets/javascripts/codemirror/addons/display/panel.js +22 -4
  5. data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +5 -5
  6. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +63 -65
  7. data/vendor/assets/javascripts/codemirror/addons/lint/javascript-lint.js +1 -1
  8. data/vendor/assets/javascripts/codemirror/addons/mode/multiplex.js +14 -9
  9. data/vendor/assets/javascripts/codemirror/addons/scroll/annotatescrollbar.js +19 -4
  10. data/vendor/assets/javascripts/codemirror/addons/search/matchesonscrollbar.js +3 -1
  11. data/vendor/assets/javascripts/codemirror/addons/search/search.js +7 -4
  12. data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +2 -2
  13. data/vendor/assets/javascripts/codemirror/keymaps/sublime.js +1 -1
  14. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +117 -23
  15. data/vendor/assets/javascripts/codemirror/modes/clike.js +1 -1
  16. data/vendor/assets/javascripts/codemirror/modes/css.js +3 -1
  17. data/vendor/assets/javascripts/codemirror/modes/django.js +307 -24
  18. data/vendor/assets/javascripts/codemirror/modes/handlebars.js +53 -0
  19. data/vendor/assets/javascripts/codemirror/modes/javascript.js +5 -1
  20. data/vendor/assets/javascripts/codemirror/modes/less_test.js +3 -0
  21. data/vendor/assets/javascripts/codemirror/modes/markdown.js +15 -13
  22. data/vendor/assets/javascripts/codemirror/modes/mumps.js +148 -0
  23. data/vendor/assets/javascripts/codemirror/modes/python.js +2 -4
  24. data/vendor/assets/javascripts/codemirror/modes/scss_test.js +1 -1
  25. data/vendor/assets/javascripts/codemirror/modes/smarty.js +17 -6
  26. data/vendor/assets/javascripts/codemirror/modes/soy.js +3 -3
  27. data/vendor/assets/javascripts/codemirror/modes/sql.js +4 -4
  28. data/vendor/assets/javascripts/codemirror/modes/stylus.js +8 -3
  29. data/vendor/assets/javascripts/codemirror/modes/z80.js +34 -18
  30. data/vendor/assets/stylesheets/codemirror.css +2 -0
  31. data/vendor/assets/stylesheets/codemirror/themes/liquibyte.css +95 -0
  32. data/vendor/assets/stylesheets/codemirror/themes/monokai.css +1 -1
  33. data/vendor/assets/stylesheets/codemirror/themes/solarized.css +1 -1
  34. metadata +4 -1
@@ -185,7 +185,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
185
185
  return obj;
186
186
  }
187
187
  var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
188
- "double static else struct entry switch extern typedef float union for unsigned " +
188
+ "double static else struct switch extern typedef float union for unsigned " +
189
189
  "goto while enum void const signed volatile";
190
190
 
191
191
  function cppHook(stream, state) {
@@ -328,7 +328,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
328
328
  states.interpolation = function(type, stream, state) {
329
329
  if (type == "}") return popContext(state);
330
330
  if (type == "{" || type == ";") return popAndPass(type, stream, state);
331
- if (type != "variable") override = "error";
331
+ if (type == "word") override = "variable";
332
+ else if (type != "variable") override = "error";
332
333
  return "interpolation";
333
334
  };
334
335
 
@@ -750,6 +751,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
750
751
  }
751
752
  },
752
753
  "@": function(stream) {
754
+ if (stream.eat("{")) return [null, "interpolation"];
753
755
  if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
754
756
  stream.eatWhile(/[\w\\\-]/);
755
757
  if (stream.match(/^\s*:/, false))
@@ -14,46 +14,329 @@
14
14
  "use strict";
15
15
 
16
16
  CodeMirror.defineMode("django:inner", function() {
17
- var keywords = ["block", "endblock", "for", "endfor", "in", "true", "false",
18
- "loop", "none", "self", "super", "if", "endif", "as", "not", "and",
17
+ var keywords = ["block", "endblock", "for", "endfor", "true", "false",
18
+ "loop", "none", "self", "super", "if", "endif", "as",
19
19
  "else", "import", "with", "endwith", "without", "context", "ifequal", "endifequal",
20
- "ifnotequal", "endifnotequal", "extends", "include", "load", "length", "comment",
21
- "endcomment", "empty"];
22
- keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");
20
+ "ifnotequal", "endifnotequal", "extends", "include", "load", "comment",
21
+ "endcomment", "empty", "url", "static", "trans", "blocktrans", "now", "regroup",
22
+ "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle", "csrf_token",
23
+ "autoescape", "endautoescape", "spaceless", "ssi", "templatetag",
24
+ "verbatim", "endverbatim", "widthratio"],
25
+ filters = ["add", "addslashes", "capfirst", "center", "cut", "date",
26
+ "default", "default_if_none", "dictsort",
27
+ "dictsortreversed", "divisibleby", "escape", "escapejs",
28
+ "filesizeformat", "first", "floatformat", "force_escape",
29
+ "get_digit", "iriencode", "join", "last", "length",
30
+ "length_is", "linebreaks", "linebreaksbr", "linenumbers",
31
+ "ljust", "lower", "make_list", "phone2numeric", "pluralize",
32
+ "pprint", "random", "removetags", "rjust", "safe",
33
+ "safeseq", "slice", "slugify", "stringformat", "striptags",
34
+ "time", "timesince", "timeuntil", "title", "truncatechars",
35
+ "truncatechars_html", "truncatewords", "truncatewords_html",
36
+ "unordered_list", "upper", "urlencode", "urlize",
37
+ "urlizetrunc", "wordcount", "wordwrap", "yesno"],
38
+ operators = ["==", "!=", "<", ">", "<=", ">=", "in", "not", "or", "and"];
23
39
 
40
+ keywords = new RegExp("^\\b(" + keywords.join("|") + ")\\b");
41
+ filters = new RegExp("^\\b(" + filters.join("|") + ")\\b");
42
+ operators = new RegExp("^\\b(" + operators.join("|") + ")\\b");
43
+
44
+ // We have to return "null" instead of null, in order to avoid string
45
+ // styling as the default, when using Django templates inside HTML
46
+ // element attributes
24
47
  function tokenBase (stream, state) {
25
- stream.eatWhile(/[^\{]/);
26
- var ch = stream.next();
27
- if (ch == "{") {
28
- if (ch = stream.eat(/\{|%|#/)) {
29
- state.tokenize = inTag(ch);
30
- return "tag";
48
+ // Attempt to identify a variable, template or comment tag respectively
49
+ if (stream.match("{{")) {
50
+ state.tokenize = inVariable;
51
+ return "tag";
52
+ } else if (stream.match("{%")) {
53
+ state.tokenize = inTag;
54
+ return "tag";
55
+ } else if (stream.match("{#")) {
56
+ state.tokenize = inComment;
57
+ return "comment";
58
+ }
59
+
60
+ // Ignore completely any stream series that do not match the
61
+ // Django template opening tags.
62
+ while (stream.next() != null && !stream.match("{{", false) && !stream.match("{%", false)) {}
63
+ return null;
64
+ }
65
+
66
+ // A string can be included in either single or double quotes (this is
67
+ // the delimeter). Mark everything as a string until the start delimeter
68
+ // occurs again.
69
+ function inString (delimeter, previousTokenizer) {
70
+ return function (stream, state) {
71
+ if (!state.escapeNext && stream.eat(delimeter)) {
72
+ state.tokenize = previousTokenizer;
73
+ } else {
74
+ if (state.escapeNext) {
75
+ state.escapeNext = false;
76
+ }
77
+
78
+ var ch = stream.next();
79
+
80
+ // Take into account the backslash for escaping characters, such as
81
+ // the string delimeter.
82
+ if (ch == "\\") {
83
+ state.escapeNext = true;
84
+ }
85
+ }
86
+
87
+ return "string";
88
+ };
89
+ }
90
+
91
+ // Apply Django template variable syntax highlighting
92
+ function inVariable (stream, state) {
93
+ // Attempt to match a dot that precedes a property
94
+ if (state.waitDot) {
95
+ state.waitDot = false;
96
+
97
+ if (stream.peek() != ".") {
98
+ return "null";
99
+ }
100
+
101
+ // Dot folowed by a non-word character should be considered an error.
102
+ if (stream.match(/\.\W+/)) {
103
+ return "error";
104
+ } else if (stream.eat(".")) {
105
+ state.waitProperty = true;
106
+ return "null";
107
+ } else {
108
+ throw Error ("Unexpected error while waiting for property.");
109
+ }
110
+ }
111
+
112
+ // Attempt to match a pipe that precedes a filter
113
+ if (state.waitPipe) {
114
+ state.waitPipe = false;
115
+
116
+ if (stream.peek() != "|") {
117
+ return "null";
118
+ }
119
+
120
+ // Pipe folowed by a non-word character should be considered an error.
121
+ if (stream.match(/\.\W+/)) {
122
+ return "error";
123
+ } else if (stream.eat("|")) {
124
+ state.waitFilter = true;
125
+ return "null";
126
+ } else {
127
+ throw Error ("Unexpected error while waiting for filter.");
128
+ }
129
+ }
130
+
131
+ // Highlight properties
132
+ if (state.waitProperty) {
133
+ state.waitProperty = false;
134
+ if (stream.match(/\b(\w+)\b/)) {
135
+ state.waitDot = true; // A property can be followed by another property
136
+ state.waitPipe = true; // A property can be followed by a filter
137
+ return "property";
31
138
  }
32
139
  }
140
+
141
+ // Highlight filters
142
+ if (state.waitFilter) {
143
+ state.waitFilter = false;
144
+ if (stream.match(filters)) {
145
+ return "variable-2";
146
+ }
147
+ }
148
+
149
+ // Ignore all white spaces
150
+ if (stream.eatSpace()) {
151
+ state.waitProperty = false;
152
+ return "null";
153
+ }
154
+
155
+ // Identify numbers
156
+ if (stream.match(/\b\d+(\.\d+)?\b/)) {
157
+ return "number";
158
+ }
159
+
160
+ // Identify strings
161
+ if (stream.match("'")) {
162
+ state.tokenize = inString("'", state.tokenize);
163
+ return "string";
164
+ } else if (stream.match('"')) {
165
+ state.tokenize = inString('"', state.tokenize);
166
+ return "string";
167
+ }
168
+
169
+ // Attempt to find the variable
170
+ if (stream.match(/\b(\w+)\b/) && !state.foundVariable) {
171
+ state.waitDot = true;
172
+ state.waitPipe = true; // A property can be followed by a filter
173
+ return "variable";
174
+ }
175
+
176
+ // If found closing tag reset
177
+ if (stream.match("}}")) {
178
+ state.waitProperty = null;
179
+ state.waitFilter = null;
180
+ state.waitDot = null;
181
+ state.waitPipe = null;
182
+ state.tokenize = tokenBase;
183
+ return "tag";
184
+ }
185
+
186
+ // If nothing was found, advance to the next character
187
+ stream.next();
188
+ return "null";
33
189
  }
34
- function inTag (close) {
35
- if (close == "{") {
36
- close = "}";
190
+
191
+ function inTag (stream, state) {
192
+ // Attempt to match a dot that precedes a property
193
+ if (state.waitDot) {
194
+ state.waitDot = false;
195
+
196
+ if (stream.peek() != ".") {
197
+ return "null";
198
+ }
199
+
200
+ // Dot folowed by a non-word character should be considered an error.
201
+ if (stream.match(/\.\W+/)) {
202
+ return "error";
203
+ } else if (stream.eat(".")) {
204
+ state.waitProperty = true;
205
+ return "null";
206
+ } else {
207
+ throw Error ("Unexpected error while waiting for property.");
208
+ }
37
209
  }
38
- return function (stream, state) {
39
- var ch = stream.next();
40
- if ((ch == close) && stream.eat("}")) {
41
- state.tokenize = tokenBase;
42
- return "tag";
210
+
211
+ // Attempt to match a pipe that precedes a filter
212
+ if (state.waitPipe) {
213
+ state.waitPipe = false;
214
+
215
+ if (stream.peek() != "|") {
216
+ return "null";
43
217
  }
44
- if (stream.match(keywords)) {
45
- return "keyword";
218
+
219
+ // Pipe folowed by a non-word character should be considered an error.
220
+ if (stream.match(/\.\W+/)) {
221
+ return "error";
222
+ } else if (stream.eat("|")) {
223
+ state.waitFilter = true;
224
+ return "null";
225
+ } else {
226
+ throw Error ("Unexpected error while waiting for filter.");
46
227
  }
47
- return close == "#" ? "comment" : "string";
48
- };
228
+ }
229
+
230
+ // Highlight properties
231
+ if (state.waitProperty) {
232
+ state.waitProperty = false;
233
+ if (stream.match(/\b(\w+)\b/)) {
234
+ state.waitDot = true; // A property can be followed by another property
235
+ state.waitPipe = true; // A property can be followed by a filter
236
+ return "property";
237
+ }
238
+ }
239
+
240
+ // Highlight filters
241
+ if (state.waitFilter) {
242
+ state.waitFilter = false;
243
+ if (stream.match(filters)) {
244
+ return "variable-2";
245
+ }
246
+ }
247
+
248
+ // Ignore all white spaces
249
+ if (stream.eatSpace()) {
250
+ state.waitProperty = false;
251
+ return "null";
252
+ }
253
+
254
+ // Identify numbers
255
+ if (stream.match(/\b\d+(\.\d+)?\b/)) {
256
+ return "number";
257
+ }
258
+
259
+ // Identify strings
260
+ if (stream.match("'")) {
261
+ state.tokenize = inString("'", state.tokenize);
262
+ return "string";
263
+ } else if (stream.match('"')) {
264
+ state.tokenize = inString('"', state.tokenize);
265
+ return "string";
266
+ }
267
+
268
+ // Attempt to match an operator
269
+ if (stream.match(operators)) {
270
+ return "operator";
271
+ }
272
+
273
+ // Attempt to match a keyword
274
+ var keywordMatch = stream.match(keywords);
275
+ if (keywordMatch) {
276
+ if (keywordMatch[0] == "comment") {
277
+ state.blockCommentTag = true;
278
+ }
279
+ return "keyword";
280
+ }
281
+
282
+ // Attempt to match a variable
283
+ if (stream.match(/\b(\w+)\b/)) {
284
+ state.waitDot = true;
285
+ state.waitPipe = true; // A property can be followed by a filter
286
+ return "variable";
287
+ }
288
+
289
+ // If found closing tag reset
290
+ if (stream.match("%}")) {
291
+ state.waitProperty = null;
292
+ state.waitFilter = null;
293
+ state.waitDot = null;
294
+ state.waitPipe = null;
295
+ // If the tag that closes is a block comment tag, we want to mark the
296
+ // following code as comment, until the tag closes.
297
+ if (state.blockCommentTag) {
298
+ state.blockCommentTag = false; // Release the "lock"
299
+ state.tokenize = inBlockComment;
300
+ } else {
301
+ state.tokenize = tokenBase;
302
+ }
303
+ return "tag";
304
+ }
305
+
306
+ // If nothing was found, advance to the next character
307
+ stream.next();
308
+ return "null";
309
+ }
310
+
311
+ // Mark everything as comment inside the tag and the tag itself.
312
+ function inComment (stream, state) {
313
+ if (stream.match("#}")) {
314
+ state.tokenize = tokenBase;
315
+ }
316
+ return "comment";
317
+ }
318
+
319
+ // Mark everything as a comment until the `blockcomment` tag closes.
320
+ function inBlockComment (stream, state) {
321
+ if (stream.match(/\{%\s*endcomment\s*%\}/, false)) {
322
+ state.tokenize = inTag;
323
+ stream.match("{%");
324
+ return "tag";
325
+ } else {
326
+ stream.next();
327
+ return "comment";
328
+ }
49
329
  }
330
+
50
331
  return {
51
332
  startState: function () {
52
333
  return {tokenize: tokenBase};
53
334
  },
54
335
  token: function (stream, state) {
55
336
  return state.tokenize(stream, state);
56
- }
337
+ },
338
+ blockCommentStart: "{% comment %}",
339
+ blockCommentEnd: "{% endcomment %}"
57
340
  };
58
341
  });
59
342
 
@@ -0,0 +1,53 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineSimpleMode("handlebars", {
15
+ start: [
16
+ { regex: /\{\{!--/, push: "dash_comment", token: "comment" },
17
+ { regex: /\{\{!/, push: "comment", token: "comment" },
18
+ { regex: /\{\{/, push: "handlebars", token: "tag" }
19
+ ],
20
+ handlebars: [
21
+ { regex: /\}\}/, pop: true, token: "tag" },
22
+
23
+ // Double and single quotes
24
+ { regex: /"(?:[^\\]|\\.)*?"/, token: "string" },
25
+ { regex: /'(?:[^\\]|\\.)*?'/, token: "string" },
26
+
27
+ // Handlebars keywords
28
+ { regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" },
29
+ { regex: /(?:else|this)\b/, token: "keyword" },
30
+
31
+ // Numeral
32
+ { regex: /\d+/i, token: "number" },
33
+
34
+ // Atoms like = and .
35
+ { regex: /=|~|@|true|false/, token: "atom" },
36
+
37
+ // Paths
38
+ { regex: /(?:\.\.\/)*(?:[A-Za-z_][\w\.]*)+/, token: "variable-2" }
39
+ ],
40
+ dash_comment: [
41
+ { regex: /--\}\}/, pop: true, token: "comment" },
42
+
43
+ // Commented code
44
+ { regex: /./, token: "comment"}
45
+ ],
46
+ comment: [
47
+ { regex: /\}\}/, pop: true, token: "comment" },
48
+ { regex: /./, token: "comment" }
49
+ ]
50
+ });
51
+
52
+ CodeMirror.defineMIME("text/x-handlebars-template", "handlebars");
53
+ });
@@ -585,7 +585,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
585
585
  function importSpec(type, value) {
586
586
  if (type == "{") return contCommasep(importSpec, "}");
587
587
  if (type == "variable") register(value);
588
- return cont();
588
+ if (value == "*") cx.marked = "keyword";
589
+ return cont(maybeAs);
590
+ }
591
+ function maybeAs(_type, value) {
592
+ if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
589
593
  }
590
594
  function maybeFrom(_type, value) {
591
595
  if (value == "from") { cx.marked = "keyword"; return cont(expression); }