codemirror-rails 3.23 → 3.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +51 -10
  4. data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +1 -1
  5. data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +13 -3
  6. data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +14 -9
  7. data/vendor/assets/javascripts/codemirror/addons/mode/overlay.js +8 -2
  8. data/vendor/assets/javascripts/codemirror/addons/search/search.js +14 -14
  9. data/vendor/assets/javascripts/codemirror/modes/clike.js +4 -3
  10. data/vendor/assets/javascripts/codemirror/modes/css.js +3 -3
  11. data/vendor/assets/javascripts/codemirror/modes/django.js +55 -0
  12. data/vendor/assets/javascripts/codemirror/modes/erlang.js +1 -1
  13. data/vendor/assets/javascripts/codemirror/modes/go.js +1 -0
  14. data/vendor/assets/javascripts/codemirror/modes/haxe.js +7 -3
  15. data/vendor/assets/javascripts/codemirror/modes/javascript.js +13 -7
  16. data/vendor/assets/javascripts/codemirror/modes/jinja2.js +111 -35
  17. data/vendor/assets/javascripts/codemirror/modes/livescript.js +4 -4
  18. data/vendor/assets/javascripts/codemirror/modes/php.js +99 -9
  19. data/vendor/assets/javascripts/codemirror/modes/r.js +3 -1
  20. data/vendor/assets/javascripts/codemirror/modes/verilog.js +237 -80
  21. data/vendor/assets/javascripts/codemirror/modes/xml.js +4 -1
  22. data/vendor/assets/stylesheets/codemirror.css +4 -3
  23. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +0 -1
  24. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +0 -4
  25. data/vendor/assets/stylesheets/codemirror/themes/mdn-like.css +1 -1
  26. data/vendor/assets/stylesheets/codemirror/themes/pastel-on-dark.css +0 -1
  27. data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +0 -2
  28. data/vendor/assets/stylesheets/codemirror/themes/solarized.css +0 -1
  29. metadata +19 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a43600e7cc5c0826859fd737519ab1a93720bfd5
4
- data.tar.gz: 7bb9599e53f755a14682493259634e7bf3ef485e
3
+ metadata.gz: bf0b31dd487f679e0a4646c015ad22a5d11e66d5
4
+ data.tar.gz: 227d5d5e370d54903ce69c675b22aaeec7ee3fba
5
5
  SHA512:
6
- metadata.gz: 62bdf9e6c06fc7e21e468c8f1d346eb0b8bcf6ef4bca06795ec60c61ce0bbec3e503be8443a5e5a9f3a124ec7c96bbbbfe39c986307b335d8c0e0d4e3e3dcde2
7
- data.tar.gz: 1bc95b49a2b8c34126bed096693b0a7b231d78d0ca361522ab1dc6be1b9f55200ea76a5ab2327ec86b4d8ee5bb1adb162c8315b33e8e19a98f87f55a358a2355
6
+ metadata.gz: 28e548eccf9fb343ffbd032d170d998a45c24a5d0d223354cc55fa861c8d5b496d25751da018cbd183695ed7e2d04881aebfadc054a72132b6679fc6cfc88551
7
+ data.tar.gz: 79b4c3c30050e1e82366068a66da94a73d0f4dd6891ec0b2d712db7c1dbe3f07e082755555b39b4603db51e33c850c767a6f9c9d34c84de63bcee1ebf242f4d6
@@ -1,6 +1,6 @@
1
1
  module Codemirror
2
2
  module Rails
3
- VERSION = '3.23'
4
- CODEMIRROR_VERSION = '3.23'
3
+ VERSION = '3.24'
4
+ CODEMIRROR_VERSION = '3.24'
5
5
  end
6
6
  end
@@ -2811,7 +2811,6 @@ window.CodeMirror = (function() {
2811
2811
  else no = lineNo(handle);
2812
2812
  if (no == null) return null;
2813
2813
  if (op(line, no)) regChange(cm, no, no + 1);
2814
- else return null;
2815
2814
  return line;
2816
2815
  }
2817
2816
 
@@ -3619,6 +3618,11 @@ window.CodeMirror = (function() {
3619
3618
  insertTab: function(cm) {
3620
3619
  cm.replaceSelection("\t", "end", "+input");
3621
3620
  },
3621
+ insertSoftTab: function(cm) {
3622
+ var pos = cm.getCursor("from"), tabSize = cm.options.tabSize;
3623
+ var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
3624
+ cm.replaceSelection(new Array(tabSize - col % tabSize + 1).join(" "), "end", "+input");
3625
+ },
3622
3626
  defaultTab: function(cm) {
3623
3627
  if (cm.somethingSelected()) cm.indentSelection("add");
3624
3628
  else cm.replaceSelection("\t", "end", "+input");
@@ -3906,6 +3910,7 @@ window.CodeMirror = (function() {
3906
3910
  }
3907
3911
  if (cm) signalLater(cm, "markerCleared", cm, this);
3908
3912
  if (withOp) endOperation(cm);
3913
+ if (this.parent) this.parent.clear();
3909
3914
  };
3910
3915
 
3911
3916
  TextMarker.prototype.find = function(bothSides) {
@@ -3963,7 +3968,7 @@ window.CodeMirror = (function() {
3963
3968
  if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
3964
3969
 
3965
3970
  var marker = new TextMarker(doc, type);
3966
- if (options) copyObj(options, marker);
3971
+ if (options) copyObj(options, marker, false);
3967
3972
  if (posLess(to, from) || posEq(from, to) && marker.clearWhenEmpty !== false)
3968
3973
  return marker;
3969
3974
  if (marker.replacedWith) {
@@ -4023,10 +4028,8 @@ window.CodeMirror = (function() {
4023
4028
  function SharedTextMarker(markers, primary) {
4024
4029
  this.markers = markers;
4025
4030
  this.primary = primary;
4026
- for (var i = 0, me = this; i < markers.length; ++i) {
4031
+ for (var i = 0; i < markers.length; ++i)
4027
4032
  markers[i].parent = this;
4028
- on(markers[i], "clear", function(){me.clear();});
4029
- }
4030
4033
  }
4031
4034
  CodeMirror.SharedTextMarker = SharedTextMarker;
4032
4035
  eventMixin(SharedTextMarker);
@@ -4057,6 +4060,37 @@ window.CodeMirror = (function() {
4057
4060
  return new SharedTextMarker(markers, primary);
4058
4061
  }
4059
4062
 
4063
+ function findSharedMarkers(doc) {
4064
+ return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),
4065
+ function(m) { return m.parent; });
4066
+ }
4067
+
4068
+ function copySharedMarkers(doc, markers) {
4069
+ for (var i = 0; i < markers.length; i++) {
4070
+ var marker = markers[i], pos = marker.find();
4071
+ var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
4072
+ if (cmp(mFrom, mTo)) {
4073
+ var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
4074
+ marker.markers.push(subMark);
4075
+ subMark.parent = marker;
4076
+ }
4077
+ }
4078
+ }
4079
+
4080
+ function detachSharedMarkers(markers) {
4081
+ for (var i = 0; i < markers.length; i++) {
4082
+ var marker = markers[i], linked = [marker.primary.doc];;
4083
+ linkedDocs(marker.primary.doc, function(d) { linked.push(d); });
4084
+ for (var j = 0; j < marker.markers.length; j++) {
4085
+ var subMarker = marker.markers[j];
4086
+ if (indexOf(linked, subMarker.doc) == -1) {
4087
+ subMarker.parent = null;
4088
+ marker.markers.splice(j--, 1);
4089
+ }
4090
+ }
4091
+ }
4092
+ }
4093
+
4060
4094
  // TEXTMARKER SPANS
4061
4095
 
4062
4096
  function getMarkedSpanFor(spans, marker) {
@@ -4339,6 +4373,7 @@ window.CodeMirror = (function() {
4339
4373
  if (!ws.length) this.line.widgets = null;
4340
4374
  var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
4341
4375
  updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
4376
+ this.cm.curOp.forceUpdate = true;
4342
4377
  if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
4343
4378
  regChange(this.cm, no, no + 1);
4344
4379
  });
@@ -4348,6 +4383,7 @@ window.CodeMirror = (function() {
4348
4383
  var diff = widgetHeight(this) - oldH;
4349
4384
  if (!diff) return;
4350
4385
  updateLineHeight(this.line, this.line.height + diff);
4386
+ this.cm.curOp.forceUpdate = true;
4351
4387
  var no = lineNo(this.line);
4352
4388
  regChange(this.cm, no, no + 1);
4353
4389
  });
@@ -5076,7 +5112,7 @@ window.CodeMirror = (function() {
5076
5112
  }
5077
5113
  return markers;
5078
5114
  },
5079
- findMarks: function(from, to) {
5115
+ findMarks: function(from, to, filter) {
5080
5116
  from = clipPos(this, from); to = clipPos(this, to);
5081
5117
  var found = [], lineNo = from.line;
5082
5118
  this.iter(from.line, to.line + 1, function(line) {
@@ -5085,7 +5121,8 @@ window.CodeMirror = (function() {
5085
5121
  var span = spans[i];
5086
5122
  if (!(lineNo == from.line && from.ch > span.to ||
5087
5123
  span.from == null && lineNo != from.line||
5088
- lineNo == to.line && span.from > to.ch))
5124
+ lineNo == to.line && span.from > to.ch) &&
5125
+ (!filter || filter(span.marker)))
5089
5126
  found.push(span.marker.parent || span.marker);
5090
5127
  }
5091
5128
  ++lineNo;
@@ -5143,6 +5180,7 @@ window.CodeMirror = (function() {
5143
5180
  if (options.sharedHist) copy.history = this.history;
5144
5181
  (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
5145
5182
  copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
5183
+ copySharedMarkers(copy, findSharedMarkers(this));
5146
5184
  return copy;
5147
5185
  },
5148
5186
  unlinkDoc: function(other) {
@@ -5152,6 +5190,7 @@ window.CodeMirror = (function() {
5152
5190
  if (link.doc != other) continue;
5153
5191
  this.linked.splice(i, 1);
5154
5192
  other.unlinkDoc(this);
5193
+ detachSharedMarkers(findSharedMarkers(this));
5155
5194
  break;
5156
5195
  }
5157
5196
  // If the histories were shared, split them again
@@ -5632,9 +5671,11 @@ window.CodeMirror = (function() {
5632
5671
  return inst;
5633
5672
  }
5634
5673
 
5635
- function copyObj(obj, target) {
5674
+ function copyObj(obj, target, overwrite) {
5636
5675
  if (!target) target = {};
5637
- for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
5676
+ for (var prop in obj)
5677
+ if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
5678
+ target[prop] = obj[prop];
5638
5679
  return target;
5639
5680
  }
5640
5681
 
@@ -6089,7 +6130,7 @@ window.CodeMirror = (function() {
6089
6130
 
6090
6131
  // THE END
6091
6132
 
6092
- CodeMirror.version = "3.23.0";
6133
+ CodeMirror.version = "3.24.0";
6093
6134
 
6094
6135
  return CodeMirror;
6095
6136
  })();
@@ -24,7 +24,7 @@
24
24
  result.push(name);
25
25
  }
26
26
 
27
- var st = token.state.state;
27
+ var st = inner.state.state;
28
28
  if (st == "pseudo" || token.type == "variable-3") {
29
29
  add(pseudoClasses);
30
30
  } else if (st == "block" || st == "maybeprop") {
@@ -31,15 +31,25 @@
31
31
  for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0)
32
32
  result.push("<" + childList[i]);
33
33
  } else if (tagType != "close") {
34
- for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
35
- result.push("<" + name);
34
+ for (var name in tags)
35
+ if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
36
+ result.push("<" + name);
36
37
  }
37
38
  if (cx && (!prefix || tagType == "close" && cx.tagName.lastIndexOf(prefix, 0) == 0))
38
39
  result.push("</" + cx.tagName + ">");
39
40
  } else {
40
41
  // Attribute completion
41
42
  var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs;
42
- if (!attrs) return;
43
+ var globalAttrs = tags["!attrs"];
44
+ if (!attrs && !globalAttrs) return;
45
+ if (!attrs) {
46
+ attrs = globalAttrs;
47
+ } else if (globalAttrs) { // Combine tag-local and global attributes
48
+ var set = {};
49
+ for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm];
50
+ for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm];
51
+ attrs = set;
52
+ }
43
53
  if (token.type == "string" || token.string == "=") { // A value
44
54
  var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)),
45
55
  Pos(cur.line, token.type == "string" ? token.start : token.end));
@@ -46,6 +46,14 @@
46
46
  }
47
47
  };
48
48
 
49
+ function ensureDiff(dv) {
50
+ if (dv.diffOutOfDate) {
51
+ dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
52
+ dv.diffOutOfDate = false;
53
+ CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
54
+ }
55
+ }
56
+
49
57
  function registerUpdate(dv) {
50
58
  var edit = {from: 0, to: 0, marked: []};
51
59
  var orig = {from: 0, to: 0, marked: []};
@@ -58,11 +66,7 @@
58
66
  clearMarks(dv.orig, orig.marked, dv.classes);
59
67
  edit.from = edit.to = orig.from = orig.to = 0;
60
68
  }
61
- if (dv.diffOutOfDate) {
62
- dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
63
- dv.diffOutOfDate = false;
64
- CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
65
- }
69
+ ensureDiff(dv);
66
70
  if (dv.showDifferences) {
67
71
  updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
68
72
  updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
@@ -355,10 +359,10 @@
355
359
  if (this.left) this.left.setShowDifferences(val);
356
360
  },
357
361
  rightChunks: function() {
358
- return this.right && getChunks(this.right.diff);
362
+ return this.right && getChunks(this.right);
359
363
  },
360
364
  leftChunks: function() {
361
- return this.left && getChunks(this.left.diff);
365
+ return this.left && getChunks(this.left);
362
366
  }
363
367
  };
364
368
 
@@ -409,9 +413,10 @@
409
413
  f(startOrig, orig.line + 1, startEdit, edit.line + 1);
410
414
  }
411
415
 
412
- function getChunks(diff) {
416
+ function getChunks(dv) {
417
+ ensureDiff(dv);
413
418
  var collect = [];
414
- iterateChunks(diff, function(topOrig, botOrig, topEdit, botEdit) {
419
+ iterateChunks(dv.diff, function(topOrig, botOrig, topEdit, botEdit) {
415
420
  collect.push({origFrom: topOrig, origTo: botOrig,
416
421
  editFrom: topEdit, editTo: botEdit});
417
422
  });
@@ -14,7 +14,8 @@ CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, comb
14
14
  base: CodeMirror.startState(base),
15
15
  overlay: CodeMirror.startState(overlay),
16
16
  basePos: 0, baseCur: null,
17
- overlayPos: 0, overlayCur: null
17
+ overlayPos: 0, overlayCur: null,
18
+ lineSeen: null
18
19
  };
19
20
  },
20
21
  copyState: function(state) {
@@ -27,6 +28,12 @@ CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, comb
27
28
  },
28
29
 
29
30
  token: function(stream, state) {
31
+ if (stream.sol() || stream.string != state.lineSeen ||
32
+ Math.min(state.basePos, state.overlayPos) < stream.start) {
33
+ state.lineSeen = stream.string;
34
+ state.basePos = state.overlayPos = stream.start;
35
+ }
36
+
30
37
  if (stream.start == state.basePos) {
31
38
  state.baseCur = base.token(stream, state.base);
32
39
  state.basePos = stream.pos;
@@ -37,7 +44,6 @@ CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, comb
37
44
  state.overlayPos = stream.pos;
38
45
  }
39
46
  stream.pos = Math.min(state.basePos, state.overlayPos);
40
- if (stream.eol()) state.basePos = state.overlayPos = 0;
41
47
 
42
48
  if (state.overlayCur == null) return state.baseCur;
43
49
  if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
@@ -8,21 +8,21 @@
8
8
 
9
9
  (function() {
10
10
  function searchOverlay(query, caseInsensitive) {
11
- var startChar;
12
- if (typeof query == "string") {
13
- startChar = query.charAt(0);
14
- query = new RegExp("^" + query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"),
15
- caseInsensitive ? "i" : "");
16
- } else {
17
- query = new RegExp("^(?:" + query.source + ")", query.ignoreCase ? "i" : "");
18
- }
11
+ if (typeof query == "string")
12
+ query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
13
+ else if (!query.global)
14
+ query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
15
+
19
16
  return {token: function(stream) {
20
- if (stream.match(query)) return "searching";
21
- while (!stream.eol()) {
22
- stream.next();
23
- if (startChar && !caseInsensitive)
24
- stream.skipTo(startChar) || stream.skipToEnd();
25
- if (stream.match(query, false)) break;
17
+ query.lastIndex = stream.pos;
18
+ var match = query.exec(stream.string);
19
+ if (match && match.index == stream.pos) {
20
+ stream.pos += match[0].length;
21
+ return "searching";
22
+ } else if (match) {
23
+ stream.pos = match.index;
24
+ } else {
25
+ stream.skipToEnd();
26
26
  }
27
27
  }};
28
28
  }
@@ -241,6 +241,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
241
241
  }
242
242
 
243
243
  function def(mimes, mode) {
244
+ if (typeof mimes == "string") mimes = [mimes];
244
245
  var words = [];
245
246
  function add(obj) {
246
247
  if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
@@ -285,7 +286,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
285
286
  },
286
287
  modeProps: {fold: ["brace", "include"]}
287
288
  });
288
- CodeMirror.defineMIME("text/x-java", {
289
+ def("text/x-java", {
289
290
  name: "clike",
290
291
  keywords: words("abstract assert boolean break byte case catch char class const continue default " +
291
292
  "do double else enum extends final finally float for goto if implements import " +
@@ -302,7 +303,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
302
303
  },
303
304
  modeProps: {fold: ["brace", "import"]}
304
305
  });
305
- CodeMirror.defineMIME("text/x-csharp", {
306
+ def("text/x-csharp", {
306
307
  name: "clike",
307
308
  keywords: words("abstract as base break case catch checked class const continue" +
308
309
  " default delegate do else enum event explicit extern finally fixed for" +
@@ -328,7 +329,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
328
329
  }
329
330
  }
330
331
  });
331
- CodeMirror.defineMIME("text/x-scala", {
332
+ def("text/x-scala", {
332
333
  name: "clike",
333
334
  keywords: words(
334
335
 
@@ -84,7 +84,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
84
84
 
85
85
  function tokenParenthesized(stream, state) {
86
86
  stream.next(); // Must be '('
87
- if (!stream.match(/\s*[\"\']/, false))
87
+ if (!stream.match(/\s*[\"\')]/, false))
88
88
  state.tokenize = tokenString(")");
89
89
  else
90
90
  state.tokenize = null;
@@ -446,13 +446,13 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
446
446
  // SVG-specific
447
447
  "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
448
448
  "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
449
- "color-interpolation", "color-interpolation-filters", "color-profile",
449
+ "color-interpolation", "color-interpolation-filters",
450
450
  "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
451
451
  "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
452
452
  "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
453
453
  "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
454
454
  "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
455
- "glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode"
455
+ "glyph-orientation-vertical", "text-anchor", "writing-mode"
456
456
  ], propertyKeywords = keySet(propertyKeywords_);
457
457
 
458
458
  var nonStandardPropertyKeywords = [
@@ -0,0 +1,55 @@
1
+ (function(CodeMirror) {
2
+ "use strict";
3
+
4
+ CodeMirror.defineMode("django:inner", function() {
5
+ var keywords = ["block", "endblock", "for", "endfor", "in", "true", "false",
6
+ "loop", "none", "self", "super", "if", "endif", "as", "not", "and",
7
+ "else", "import", "with", "endwith", "without", "context", "ifequal", "endifequal",
8
+ "ifnotequal", "endifnotequal", "extends", "include", "load", "length", "comment",
9
+ "endcomment", "empty"];
10
+ keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");
11
+
12
+ function tokenBase (stream, state) {
13
+ stream.eatWhile(/[^\{]/);
14
+ var ch = stream.next();
15
+ if (ch == "{") {
16
+ if (ch = stream.eat(/\{|%|#/)) {
17
+ state.tokenize = inTag(ch);
18
+ return "tag";
19
+ }
20
+ }
21
+ }
22
+ function inTag (close) {
23
+ if (close == "{") {
24
+ close = "}";
25
+ }
26
+ return function (stream, state) {
27
+ var ch = stream.next();
28
+ if ((ch == close) && stream.eat("}")) {
29
+ state.tokenize = tokenBase;
30
+ return "tag";
31
+ }
32
+ if (stream.match(keywords)) {
33
+ return "keyword";
34
+ }
35
+ return close == "#" ? "comment" : "string";
36
+ };
37
+ }
38
+ return {
39
+ startState: function () {
40
+ return {tokenize: tokenBase};
41
+ },
42
+ token: function (stream, state) {
43
+ return state.tokenize(stream, state);
44
+ }
45
+ };
46
+ });
47
+
48
+ CodeMirror.defineMode("django", function(config) {
49
+ var htmlBase = CodeMirror.getMode(config, "text/html");
50
+ var djangoInner = CodeMirror.getMode(config, "django:inner");
51
+ return CodeMirror.overlayMode(htmlBase, djangoInner);
52
+ });
53
+
54
+ CodeMirror.defineMIME("text/x-django", "django");
55
+ })(CodeMirror);