codemirror-rails 3.19 → 3.20

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 (28) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +61 -27
  4. data/vendor/assets/javascripts/codemirror/addons/dialog/dialog.js +42 -1
  5. data/vendor/assets/javascripts/codemirror/addons/display/fullscreen.js +2 -1
  6. data/vendor/assets/javascripts/codemirror/addons/display/placeholder.js +0 -6
  7. data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +13 -11
  8. data/vendor/assets/javascripts/codemirror/addons/edit/matchbrackets.js +2 -1
  9. data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +4 -4
  10. data/vendor/assets/javascripts/codemirror/addons/fold/indent-fold.js +25 -21
  11. data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +1 -0
  12. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +20 -8
  13. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +7 -7
  14. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +3 -4
  15. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +13 -8
  16. data/vendor/assets/javascripts/codemirror/modes/css.js +3 -3
  17. data/vendor/assets/javascripts/codemirror/modes/go.js +1 -1
  18. data/vendor/assets/javascripts/codemirror/modes/haskell.js +1 -1
  19. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +1 -1
  20. data/vendor/assets/javascripts/codemirror/modes/javascript.js +216 -79
  21. data/vendor/assets/javascripts/codemirror/modes/julia.js +262 -0
  22. data/vendor/assets/javascripts/codemirror/modes/less.js +4 -2
  23. data/vendor/assets/javascripts/codemirror/modes/markdown.js +16 -7
  24. data/vendor/assets/javascripts/codemirror/modes/pegjs.js +103 -0
  25. data/vendor/assets/javascripts/codemirror/modes/pig.js +1 -1
  26. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +1 -1
  27. data/vendor/assets/stylesheets/codemirror/themes/mbo.css +3 -1
  28. metadata +3 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9386202ed77c77960e25b33dfc99951976f4fae4
4
- data.tar.gz: b0e5fb1cb06211914a2fcd09e97d2fd05c419cc2
3
+ metadata.gz: f4d274479004f7971f3fb00405bcee8d1a2efbef
4
+ data.tar.gz: 58da8b05ad13207494ca43d926fcb370271b7b63
5
5
  SHA512:
6
- metadata.gz: b5f1e8a81e9800c2cc7718b3f2dd3ea07fa13a7ca9db1c35719569da67fc32d1cb2e3dccce1c206250b24b421b5600505724ac236bd423c54b70b8de58ab6537
7
- data.tar.gz: 414b29b5373f82921da9abe9f169d9de4728031c6193a60638bff52b751b90f283aa8149da0d8992b97ec4fb1e2dbffb8e0601b545f7dc748350a1b27d9cad69
6
+ metadata.gz: d771bf91908c86f73f91f92a053385a90bfa921fa8a2237b4bc3058d11db7860e5769d44ffe1a549f8f8718681ea1e179847cfafe0813c9df137e72f208b9c68
7
+ data.tar.gz: a9eeeab433dfc80ea5aa91de38ec46eda1749909838c7190f40b30f8985e82abc692dc258050b856ceea8eaad41cf3aabe3cf95fcf7c8982baa185b722f130c5
@@ -1,6 +1,6 @@
1
1
  module Codemirror
2
2
  module Rails
3
- VERSION = '3.19'
4
- CODEMIRROR_VERSION = '3.19'
3
+ VERSION = '3.20'
4
+ CODEMIRROR_VERSION = '3.20'
5
5
  end
6
6
  end
@@ -7,9 +7,13 @@ window.CodeMirror = (function() {
7
7
  // Crude, but necessary to handle a number of hard-to-feature-detect
8
8
  // bugs and behavior differences.
9
9
  var gecko = /gecko\/\d/i.test(navigator.userAgent);
10
+ // IE11 currently doesn't count as 'ie', since it has almost none of
11
+ // the same bugs as earlier versions. Use ie_gt10 to handle
12
+ // incompatibilities in that version.
10
13
  var ie = /MSIE \d/.test(navigator.userAgent);
11
14
  var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
12
15
  var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
16
+ var ie_gt10 = /Trident\/([7-9]|\d{2,})\./.test(navigator.userAgent);
13
17
  var webkit = /WebKit\//.test(navigator.userAgent);
14
18
  var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
15
19
  var chrome = /Chrome\//.test(navigator.userAgent);
@@ -906,7 +910,7 @@ window.CodeMirror = (function() {
906
910
  doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
907
911
  if (doc.frontier >= cm.display.showingFrom) { // Visible
908
912
  var oldStyles = line.styles;
909
- line.styles = highlightLine(cm, line, state);
913
+ line.styles = highlightLine(cm, line, state, true);
910
914
  var ischange = !oldStyles || oldStyles.length != line.styles.length;
911
915
  for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
912
916
  if (ischange) {
@@ -915,7 +919,7 @@ window.CodeMirror = (function() {
915
919
  }
916
920
  line.stateAfter = copyState(doc.mode, state);
917
921
  } else {
918
- processLine(cm, line, state);
922
+ processLine(cm, line.text, state);
919
923
  line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
920
924
  }
921
925
  ++doc.frontier;
@@ -959,7 +963,7 @@ window.CodeMirror = (function() {
959
963
  if (!state) state = startState(doc.mode);
960
964
  else state = copyState(doc.mode, state);
961
965
  doc.iter(pos, n, function(line) {
962
- processLine(cm, line, state);
966
+ processLine(cm, line.text, state);
963
967
  var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
964
968
  line.stateAfter = save ? copyState(doc.mode, state) : null;
965
969
  ++pos;
@@ -1383,8 +1387,10 @@ window.CodeMirror = (function() {
1383
1387
  }
1384
1388
  if (!updated && op.selectionChanged) updateSelection(cm);
1385
1389
  if (op.updateScrollPos) {
1386
- display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop;
1387
- display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft;
1390
+ var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, newScrollPos.scrollTop));
1391
+ var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, newScrollPos.scrollLeft));
1392
+ display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top;
1393
+ display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left;
1388
1394
  alignHorizontally(cm);
1389
1395
  if (op.scrollToPos)
1390
1396
  scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from),
@@ -1903,7 +1909,6 @@ window.CodeMirror = (function() {
1903
1909
  if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
1904
1910
  cm.replaceSelection(text, null, "paste");
1905
1911
  focusInput(cm);
1906
- onFocus(cm);
1907
1912
  }
1908
1913
  }
1909
1914
  catch(e){}
@@ -2761,6 +2766,8 @@ window.CodeMirror = (function() {
2761
2766
 
2762
2767
  if (indentString != curSpaceString)
2763
2768
  replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
2769
+ else if (doc.sel.head.line == n && doc.sel.head.ch < curSpaceString.length)
2770
+ setSelection(doc, Pos(n, curSpaceString.length), Pos(n, curSpaceString.length), 1);
2764
2771
  line.stateAfter = null;
2765
2772
  }
2766
2773
 
@@ -2861,7 +2868,7 @@ window.CodeMirror = (function() {
2861
2868
 
2862
2869
  CodeMirror.prototype = {
2863
2870
  constructor: CodeMirror,
2864
- focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},
2871
+ focus: function(){window.focus(); focusInput(this); fastPoll(this);},
2865
2872
 
2866
2873
  setOption: function(option, value) {
2867
2874
  var options = this.options, old = options[option];
@@ -3274,8 +3281,14 @@ window.CodeMirror = (function() {
3274
3281
  clearCaches(cm);
3275
3282
  regChange(cm);
3276
3283
  }, true);
3284
+ option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) {
3285
+ cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
3286
+ cm.refresh();
3287
+ }, true);
3288
+ option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
3277
3289
  option("electricChars", true);
3278
3290
  option("rtlMoveVisually", !windows);
3291
+ option("wholeLineUpdateBefore", true);
3279
3292
 
3280
3293
  option("theme", "default", function(cm) {
3281
3294
  themeChanged(cm);
@@ -3308,8 +3321,14 @@ window.CodeMirror = (function() {
3308
3321
  option("resetSelectionOnContextMenu", true);
3309
3322
 
3310
3323
  option("readOnly", false, function(cm, val) {
3311
- if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
3312
- else if (!val) resetInput(cm, true);
3324
+ if (val == "nocursor") {
3325
+ onBlur(cm);
3326
+ cm.display.input.blur();
3327
+ cm.display.disabled = true;
3328
+ } else {
3329
+ cm.display.disabled = false;
3330
+ if (!val) resetInput(cm, true);
3331
+ }
3313
3332
  });
3314
3333
  option("dragDrop", true);
3315
3334
 
@@ -3850,7 +3869,9 @@ window.CodeMirror = (function() {
3850
3869
  if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
3851
3870
 
3852
3871
  var marker = new TextMarker(doc, type);
3853
- if (type == "range" && !posLess(from, to)) return marker;
3872
+ if (posLess(to, from) || posEq(from, to) && type == "range" &&
3873
+ !(options.inclusiveLeft && options.inclusiveRight))
3874
+ return marker;
3854
3875
  if (options) copyObj(options, marker);
3855
3876
  if (marker.replacedWith) {
3856
3877
  marker.collapsed = true;
@@ -3966,7 +3987,9 @@ window.CodeMirror = (function() {
3966
3987
  if (old) for (var i = 0, nw; i < old.length; ++i) {
3967
3988
  var span = old[i], marker = span.marker;
3968
3989
  var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
3969
- if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
3990
+ if (startsBefore ||
3991
+ (marker.inclusiveLeft && marker.inclusiveRight || marker.type == "bookmark") &&
3992
+ span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
3970
3993
  var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
3971
3994
  (nw || (nw = [])).push({from: span.from,
3972
3995
  to: endsAfter ? null : span.to,
@@ -4239,6 +4262,7 @@ window.CodeMirror = (function() {
4239
4262
  this.height = estimateHeight ? estimateHeight(this) : 1;
4240
4263
  };
4241
4264
  eventMixin(Line);
4265
+ Line.prototype.lineNo = function() { return lineNo(this); };
4242
4266
 
4243
4267
  function updateLine(line, text, markedSpans, estimateHeight) {
4244
4268
  line.text = text;
@@ -4259,7 +4283,7 @@ window.CodeMirror = (function() {
4259
4283
  // Run the given mode's parser over a line, update the styles
4260
4284
  // array, which contains alternating fragments of text and CSS
4261
4285
  // classes.
4262
- function runMode(cm, text, mode, state, f) {
4286
+ function runMode(cm, text, mode, state, f, forceToEnd) {
4263
4287
  var flattenSpans = mode.flattenSpans;
4264
4288
  if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
4265
4289
  var curStart = 0, curStyle = null;
@@ -4268,6 +4292,7 @@ window.CodeMirror = (function() {
4268
4292
  while (!stream.eol()) {
4269
4293
  if (stream.pos > cm.options.maxHighlightLength) {
4270
4294
  flattenSpans = false;
4295
+ if (forceToEnd) processLine(cm, text, state, stream.pos);
4271
4296
  stream.pos = text.length;
4272
4297
  style = null;
4273
4298
  } else {
@@ -4287,12 +4312,14 @@ window.CodeMirror = (function() {
4287
4312
  }
4288
4313
  }
4289
4314
 
4290
- function highlightLine(cm, line, state) {
4315
+ function highlightLine(cm, line, state, forceToEnd) {
4291
4316
  // A styles array always starts with a number identifying the
4292
4317
  // mode/overlays that it is based on (for easy invalidation).
4293
4318
  var st = [cm.state.modeGen];
4294
4319
  // Compute the base array of styles
4295
- runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);});
4320
+ runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
4321
+ st.push(end, style);
4322
+ }, forceToEnd);
4296
4323
 
4297
4324
  // Run overlays, adjust style array.
4298
4325
  for (var o = 0; o < cm.state.overlays.length; ++o) {
@@ -4331,10 +4358,11 @@ window.CodeMirror = (function() {
4331
4358
 
4332
4359
  // Lightweight form of highlight -- proceed over this line and
4333
4360
  // update state, but don't save a style array.
4334
- function processLine(cm, line, state) {
4361
+ function processLine(cm, text, state, startAt) {
4335
4362
  var mode = cm.doc.mode;
4336
- var stream = new StringStream(line.text, cm.options.tabSize);
4337
- if (line.text == "" && mode.blankLine) mode.blankLine(state);
4363
+ var stream = new StringStream(text, cm.options.tabSize);
4364
+ stream.start = stream.pos = startAt || 0;
4365
+ if (text == "" && mode.blankLine) mode.blankLine(state);
4338
4366
  while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
4339
4367
  mode.token(stream, state);
4340
4368
  stream.start = stream.pos;
@@ -4391,7 +4419,7 @@ window.CodeMirror = (function() {
4391
4419
  // Work around problem with the reported dimensions of single-char
4392
4420
  // direction spans on IE (issue #1129). See also the comment in
4393
4421
  // cursorCoords.
4394
- if (measure && ie && (order = getOrder(line))) {
4422
+ if (measure && (ie || ie_gt10) && (order = getOrder(line))) {
4395
4423
  var l = order.length - 1;
4396
4424
  if (order[l].from == order[l].to) --l;
4397
4425
  var last = order[l], prev = order[l - 1];
@@ -4409,17 +4437,23 @@ window.CodeMirror = (function() {
4409
4437
  return builder;
4410
4438
  }
4411
4439
 
4412
- var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
4440
+ function defaultSpecialCharPlaceholder(ch) {
4441
+ var token = elt("span", "\u2022", "cm-invalidchar");
4442
+ token.title = "\\u" + ch.charCodeAt(0).toString(16);
4443
+ return token;
4444
+ }
4445
+
4413
4446
  function buildToken(builder, text, style, startStyle, endStyle, title) {
4414
4447
  if (!text) return;
4415
- if (!tokenSpecialChars.test(text)) {
4448
+ var special = builder.cm.options.specialChars;
4449
+ if (!special.test(text)) {
4416
4450
  builder.col += text.length;
4417
4451
  var content = document.createTextNode(text);
4418
4452
  } else {
4419
4453
  var content = document.createDocumentFragment(), pos = 0;
4420
4454
  while (true) {
4421
- tokenSpecialChars.lastIndex = pos;
4422
- var m = tokenSpecialChars.exec(text);
4455
+ special.lastIndex = pos;
4456
+ var m = special.exec(text);
4423
4457
  var skipped = m ? m.index - pos : text.length - pos;
4424
4458
  if (skipped) {
4425
4459
  content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
@@ -4432,8 +4466,7 @@ window.CodeMirror = (function() {
4432
4466
  content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
4433
4467
  builder.col += tabWidth;
4434
4468
  } else {
4435
- var token = elt("span", "\u2022", "cm-invalidchar");
4436
- token.title = "\\u" + m[0].charCodeAt(0).toString(16);
4469
+ var token = builder.cm.options.specialCharPlaceholder(m[0]);
4437
4470
  content.appendChild(token);
4438
4471
  builder.col += 1;
4439
4472
  }
@@ -4586,7 +4619,8 @@ window.CodeMirror = (function() {
4586
4619
  var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
4587
4620
 
4588
4621
  // First adjust the line structure
4589
- if (from.ch == 0 && to.ch == 0 && lastText == "") {
4622
+ if (from.ch == 0 && to.ch == 0 && lastText == "" &&
4623
+ (!doc.cm || doc.cm.options.wholeLineUpdateBefore)) {
4590
4624
  // This is a whole-line replace. Treated specially to make
4591
4625
  // sure line objects move the way they are supposed to.
4592
4626
  for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
@@ -5473,7 +5507,7 @@ window.CodeMirror = (function() {
5473
5507
  return true;
5474
5508
  }
5475
5509
 
5476
- var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;
5510
+ var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\u1DC0–\u1DFF\u20D0–\u20FF\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff\uFE20–\uFE2F]/;
5477
5511
 
5478
5512
  // DOM UTILITIES
5479
5513
 
@@ -5902,7 +5936,7 @@ window.CodeMirror = (function() {
5902
5936
 
5903
5937
  // THE END
5904
5938
 
5905
- CodeMirror.version = "3.19.0";
5939
+ CodeMirror.version = "3.20.0";
5906
5940
 
5907
5941
  return CodeMirror;
5908
5942
  })();
@@ -10,11 +10,22 @@
10
10
  } else {
11
11
  dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
12
12
  }
13
- dialog.innerHTML = template;
13
+ if (typeof template == "string") {
14
+ dialog.innerHTML = template;
15
+ } else { // Assuming it's a detached DOM element.
16
+ dialog.appendChild(template);
17
+ }
14
18
  return dialog;
15
19
  }
16
20
 
21
+ function closeNotification(cm, newVal) {
22
+ if (cm.state.currentNotificationClose)
23
+ cm.state.currentNotificationClose();
24
+ cm.state.currentNotificationClose = newVal;
25
+ }
26
+
17
27
  CodeMirror.defineExtension("openDialog", function(template, callback, options) {
28
+ closeNotification(this, null);
18
29
  var dialog = dialogDiv(this, template, options && options.bottom);
19
30
  var closed = false, me = this;
20
31
  function close() {
@@ -51,6 +62,7 @@
51
62
  });
52
63
 
53
64
  CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
65
+ closeNotification(this, null);
54
66
  var dialog = dialogDiv(this, template, options && options.bottom);
55
67
  var buttons = dialog.getElementsByTagName("button");
56
68
  var closed = false, me = this, blurring = 1;
@@ -77,4 +89,33 @@
77
89
  CodeMirror.on(b, "focus", function() { ++blurring; });
78
90
  }
79
91
  });
92
+
93
+ /*
94
+ * openNotification
95
+ * Opens a notification, that can be closed with an optional timer
96
+ * (default 5000ms timer) and always closes on click.
97
+ *
98
+ * If a notification is opened while another is opened, it will close the
99
+ * currently opened one and open the new one immediately.
100
+ */
101
+ CodeMirror.defineExtension("openNotification", function(template, options) {
102
+ closeNotification(this, close);
103
+ var dialog = dialogDiv(this, template, options && options.bottom);
104
+ var duration = options && (options.duration === undefined ? 5000 : options.duration);
105
+ var closed = false, doneTimer;
106
+
107
+ function close() {
108
+ if (closed) return;
109
+ closed = true;
110
+ clearTimeout(doneTimer);
111
+ dialog.parentNode.removeChild(dialog);
112
+ }
113
+
114
+ CodeMirror.on(dialog, 'click', function(e) {
115
+ CodeMirror.e_preventDefault(e);
116
+ close();
117
+ });
118
+ if (duration)
119
+ doneTimer = setTimeout(close, options.duration);
120
+ });
80
121
  })();
@@ -12,7 +12,8 @@
12
12
  var wrap = cm.getWrapperElement();
13
13
  cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
14
14
  width: wrap.style.width, height: wrap.style.height};
15
- wrap.style.width = wrap.style.height = "";
15
+ wrap.style.width = "";
16
+ wrap.style.height = "auto";
16
17
  wrap.className += " CodeMirror-fullscreen";
17
18
  document.documentElement.style.overflow = "hidden";
18
19
  cm.refresh();
@@ -2,12 +2,10 @@
2
2
  CodeMirror.defineOption("placeholder", "", function(cm, val, old) {
3
3
  var prev = old && old != CodeMirror.Init;
4
4
  if (val && !prev) {
5
- cm.on("focus", onFocus);
6
5
  cm.on("blur", onBlur);
7
6
  cm.on("change", onChange);
8
7
  onChange(cm);
9
8
  } else if (!val && prev) {
10
- cm.off("focus", onFocus);
11
9
  cm.off("blur", onBlur);
12
10
  cm.off("change", onChange);
13
11
  clearPlaceholder(cm);
@@ -33,9 +31,6 @@
33
31
  cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
34
32
  }
35
33
 
36
- function onFocus(cm) {
37
- clearPlaceholder(cm);
38
- }
39
34
  function onBlur(cm) {
40
35
  if (isEmpty(cm)) setPlaceholder(cm);
41
36
  }
@@ -43,7 +38,6 @@
43
38
  var wrapper = cm.getWrapperElement(), empty = isEmpty(cm);
44
39
  wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : "");
45
40
 
46
- if (cm.hasFocus()) return;
47
41
  if (empty) setPlaceholder(cm);
48
42
  else clearPlaceholder(cm);
49
43
  }
@@ -24,16 +24,15 @@
24
24
 
25
25
  (function() {
26
26
  CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) {
27
- if (val && (old == CodeMirror.Init || !old)) {
28
- var map = {name: "autoCloseTags"};
29
- if (typeof val != "object" || val.whenClosing)
30
- map["'/'"] = function(cm) { return autoCloseSlash(cm); };
31
- if (typeof val != "object" || val.whenOpening)
32
- map["'>'"] = function(cm) { return autoCloseGT(cm); };
33
- cm.addKeyMap(map);
34
- } else if (!val && (old != CodeMirror.Init && old)) {
27
+ if (old != CodeMirror.Init && old)
35
28
  cm.removeKeyMap("autoCloseTags");
36
- }
29
+ if (!val) return;
30
+ var map = {name: "autoCloseTags"};
31
+ if (typeof val != "object" || val.whenClosing)
32
+ map["'/'"] = function(cm) { return autoCloseSlash(cm); };
33
+ if (typeof val != "object" || val.whenOpening)
34
+ map["'>'"] = function(cm) { return autoCloseGT(cm); };
35
+ cm.addKeyMap(map);
37
36
  });
38
37
 
39
38
  var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
@@ -54,7 +53,8 @@
54
53
  if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
55
54
  var lowerTagName = tagName.toLowerCase();
56
55
  // Don't process the '>' at the end of an end-tag or self-closing tag
57
- if (tok.type == "tag" && state.type == "closeTag" ||
56
+ if (tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) ||
57
+ tok.type == "tag" && state.type == "closeTag" ||
58
58
  tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
59
59
  dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1)
60
60
  return CodeMirror.Pass;
@@ -72,7 +72,9 @@
72
72
  function autoCloseSlash(cm) {
73
73
  var pos = cm.getCursor(), tok = cm.getTokenAt(pos);
74
74
  var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
75
- if (tok.string.charAt(0) != "<" || tok.start != pos.ch - 1 || inner.mode.name != "xml") return CodeMirror.Pass;
75
+ if (tok.type == "string" || tok.string.charAt(0) != "<" ||
76
+ tok.start != pos.ch - 1 || inner.mode.name != "xml")
77
+ return CodeMirror.Pass;
76
78
 
77
79
  var tagName = state.context && state.context.tagName;
78
80
  if (tagName) cm.replaceSelection("/" + tagName + ">", "end");
@@ -8,6 +8,7 @@
8
8
  function findMatchingBracket(cm, where, strict) {
9
9
  var state = cm.state.matchBrackets;
10
10
  var maxScanLen = (state && state.maxScanLineLength) || 10000;
11
+ var maxScanLines = (state && state.maxScanLines) || 100;
11
12
 
12
13
  var cur = where || cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1;
13
14
  var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
@@ -32,7 +33,7 @@
32
33
  }
33
34
  }
34
35
  }
35
- for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) {
36
+ for (var i = cur.line, found, e = forward ? Math.min(i + maxScanLines, cm.lineCount()) : Math.max(-1, i - maxScanLines); i != e; i+=d) {
36
37
  if (i == cur.line) found = scan(line, i, pos);
37
38
  else found = scan(cm.getLineHandle(i), i);
38
39
  if (found) break;
@@ -88,14 +88,14 @@
88
88
  }
89
89
 
90
90
  function onChange(cm) {
91
- var state = cm.state.foldGutter;
91
+ var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
92
92
  state.from = state.to = 0;
93
93
  clearTimeout(state.changeUpdate);
94
- state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, 600);
94
+ state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
95
95
  }
96
96
 
97
97
  function onViewportChange(cm) {
98
- var state = cm.state.foldGutter;
98
+ var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
99
99
  clearTimeout(state.changeUpdate);
100
100
  state.changeUpdate = setTimeout(function() {
101
101
  var vp = cm.getViewport();
@@ -113,7 +113,7 @@
113
113
  }
114
114
  });
115
115
  }
116
- }, 400);
116
+ }, opts.updateViewportTimeSpan || 400);
117
117
  }
118
118
 
119
119
  function onFold(cm, from) {