codemirror-rails 4.1 → 4.2

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 (138) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +133 -58
  4. data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +3 -0
  5. data/vendor/assets/javascripts/codemirror/addons/comment/continuecomment.js +3 -0
  6. data/vendor/assets/javascripts/codemirror/addons/dialog/dialog.js +3 -0
  7. data/vendor/assets/javascripts/codemirror/addons/display/fullscreen.js +3 -0
  8. data/vendor/assets/javascripts/codemirror/addons/display/placeholder.js +3 -0
  9. data/vendor/assets/javascripts/codemirror/addons/display/rulers.js +16 -6
  10. data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +3 -0
  11. data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +28 -3
  12. data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +3 -0
  13. data/vendor/assets/javascripts/codemirror/addons/edit/matchbrackets.js +3 -0
  14. data/vendor/assets/javascripts/codemirror/addons/edit/matchtags.js +3 -0
  15. data/vendor/assets/javascripts/codemirror/addons/edit/trailingspace.js +3 -0
  16. data/vendor/assets/javascripts/codemirror/addons/fold/brace-fold.js +3 -0
  17. data/vendor/assets/javascripts/codemirror/addons/fold/comment-fold.js +3 -0
  18. data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +36 -8
  19. data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +3 -0
  20. data/vendor/assets/javascripts/codemirror/addons/fold/indent-fold.js +3 -0
  21. data/vendor/assets/javascripts/codemirror/addons/fold/markdown-fold.js +3 -0
  22. data/vendor/assets/javascripts/codemirror/addons/fold/xml-fold.js +4 -1
  23. data/vendor/assets/javascripts/codemirror/addons/hint/anyword-hint.js +3 -0
  24. data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +3 -0
  25. data/vendor/assets/javascripts/codemirror/addons/hint/html-hint.js +3 -0
  26. data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +7 -2
  27. data/vendor/assets/javascripts/codemirror/addons/hint/python-hint.js +3 -0
  28. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +74 -36
  29. data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +3 -0
  30. data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +3 -0
  31. data/vendor/assets/javascripts/codemirror/addons/lint/coffeescript-lint.js +3 -0
  32. data/vendor/assets/javascripts/codemirror/addons/lint/css-lint.js +3 -0
  33. data/vendor/assets/javascripts/codemirror/addons/lint/javascript-lint.js +3 -0
  34. data/vendor/assets/javascripts/codemirror/addons/lint/json-lint.js +3 -0
  35. data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +3 -0
  36. data/vendor/assets/javascripts/codemirror/addons/lint/yaml-lint.js +3 -0
  37. data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +3 -0
  38. data/vendor/assets/javascripts/codemirror/addons/mode/loadmode.js +3 -0
  39. data/vendor/assets/javascripts/codemirror/addons/mode/multiplex.js +3 -0
  40. data/vendor/assets/javascripts/codemirror/addons/mode/overlay.js +12 -3
  41. data/vendor/assets/javascripts/codemirror/addons/runmode/colorize.js +3 -0
  42. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +4 -1
  43. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +4 -1
  44. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +4 -1
  45. data/vendor/assets/javascripts/codemirror/addons/scroll/scrollpastend.js +3 -0
  46. data/vendor/assets/javascripts/codemirror/addons/search/match-highlighter.js +6 -2
  47. data/vendor/assets/javascripts/codemirror/addons/search/search.js +3 -0
  48. data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +3 -0
  49. data/vendor/assets/javascripts/codemirror/addons/selection/active-line.js +3 -0
  50. data/vendor/assets/javascripts/codemirror/addons/selection/mark-selection.js +3 -0
  51. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +23 -16
  52. data/vendor/assets/javascripts/codemirror/addons/tern/worker.js +3 -0
  53. data/vendor/assets/javascripts/codemirror/addons/wrap/hardwrap.js +3 -0
  54. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +4 -7
  55. data/vendor/assets/javascripts/codemirror/keymaps/sublime.js +11 -8
  56. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +92 -33
  57. data/vendor/assets/javascripts/codemirror/modes/apl.js +3 -0
  58. data/vendor/assets/javascripts/codemirror/modes/asterisk.js +3 -0
  59. data/vendor/assets/javascripts/codemirror/modes/clike.js +3 -0
  60. data/vendor/assets/javascripts/codemirror/modes/clojure.js +3 -0
  61. data/vendor/assets/javascripts/codemirror/modes/cobol.js +3 -0
  62. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +3 -0
  63. data/vendor/assets/javascripts/codemirror/modes/commonlisp.js +3 -0
  64. data/vendor/assets/javascripts/codemirror/modes/css.js +13 -14
  65. data/vendor/assets/javascripts/codemirror/modes/cypher.js +146 -0
  66. data/vendor/assets/javascripts/codemirror/modes/d.js +3 -0
  67. data/vendor/assets/javascripts/codemirror/modes/diff.js +3 -0
  68. data/vendor/assets/javascripts/codemirror/modes/django.js +3 -0
  69. data/vendor/assets/javascripts/codemirror/modes/dtd.js +3 -0
  70. data/vendor/assets/javascripts/codemirror/modes/dylan.js +15 -0
  71. data/vendor/assets/javascripts/codemirror/modes/ecl.js +3 -0
  72. data/vendor/assets/javascripts/codemirror/modes/eiffel.js +3 -0
  73. data/vendor/assets/javascripts/codemirror/modes/erlang.js +3 -0
  74. data/vendor/assets/javascripts/codemirror/modes/fortran.js +3 -0
  75. data/vendor/assets/javascripts/codemirror/modes/gas.js +3 -0
  76. data/vendor/assets/javascripts/codemirror/modes/gfm.js +9 -1
  77. data/vendor/assets/javascripts/codemirror/modes/gherkin.js +3 -0
  78. data/vendor/assets/javascripts/codemirror/modes/go.js +3 -0
  79. data/vendor/assets/javascripts/codemirror/modes/groovy.js +3 -0
  80. data/vendor/assets/javascripts/codemirror/modes/haml.js +3 -0
  81. data/vendor/assets/javascripts/codemirror/modes/haskell.js +3 -0
  82. data/vendor/assets/javascripts/codemirror/modes/haxe.js +5 -1
  83. data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +3 -0
  84. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +3 -0
  85. data/vendor/assets/javascripts/codemirror/modes/http.js +3 -0
  86. data/vendor/assets/javascripts/codemirror/modes/jade.js +569 -81
  87. data/vendor/assets/javascripts/codemirror/modes/javascript.js +5 -0
  88. data/vendor/assets/javascripts/codemirror/modes/jinja2.js +3 -0
  89. data/vendor/assets/javascripts/codemirror/modes/julia.js +3 -0
  90. data/vendor/assets/javascripts/codemirror/modes/livescript.js +17 -17
  91. data/vendor/assets/javascripts/codemirror/modes/lua.js +3 -0
  92. data/vendor/assets/javascripts/codemirror/modes/markdown.js +5 -3
  93. data/vendor/assets/javascripts/codemirror/modes/mirc.js +3 -0
  94. data/vendor/assets/javascripts/codemirror/modes/mllike.js +3 -0
  95. data/vendor/assets/javascripts/codemirror/modes/nginx.js +3 -0
  96. data/vendor/assets/javascripts/codemirror/modes/ntriples.js +3 -0
  97. data/vendor/assets/javascripts/codemirror/modes/octave.js +3 -0
  98. data/vendor/assets/javascripts/codemirror/modes/pascal.js +3 -0
  99. data/vendor/assets/javascripts/codemirror/modes/pegjs.js +3 -0
  100. data/vendor/assets/javascripts/codemirror/modes/perl.js +5 -0
  101. data/vendor/assets/javascripts/codemirror/modes/php.js +5 -2
  102. data/vendor/assets/javascripts/codemirror/modes/pig.js +3 -0
  103. data/vendor/assets/javascripts/codemirror/modes/properties.js +3 -0
  104. data/vendor/assets/javascripts/codemirror/modes/puppet.js +3 -0
  105. data/vendor/assets/javascripts/codemirror/modes/python.js +284 -328
  106. data/vendor/assets/javascripts/codemirror/modes/q.js +3 -0
  107. data/vendor/assets/javascripts/codemirror/modes/r.js +3 -0
  108. data/vendor/assets/javascripts/codemirror/modes/rpm.js +3 -0
  109. data/vendor/assets/javascripts/codemirror/modes/rst.js +3 -0
  110. data/vendor/assets/javascripts/codemirror/modes/ruby.js +3 -0
  111. data/vendor/assets/javascripts/codemirror/modes/rust.js +3 -0
  112. data/vendor/assets/javascripts/codemirror/modes/sass.js +3 -0
  113. data/vendor/assets/javascripts/codemirror/modes/scheme.js +3 -0
  114. data/vendor/assets/javascripts/codemirror/modes/shell.js +9 -2
  115. data/vendor/assets/javascripts/codemirror/modes/sieve.js +3 -0
  116. data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +3 -0
  117. data/vendor/assets/javascripts/codemirror/modes/smarty.js +3 -0
  118. data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +3 -0
  119. data/vendor/assets/javascripts/codemirror/modes/solr.js +3 -0
  120. data/vendor/assets/javascripts/codemirror/modes/sparql.js +3 -0
  121. data/vendor/assets/javascripts/codemirror/modes/sql.js +3 -0
  122. data/vendor/assets/javascripts/codemirror/modes/stex.js +3 -0
  123. data/vendor/assets/javascripts/codemirror/modes/tcl.js +3 -0
  124. data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +3 -0
  125. data/vendor/assets/javascripts/codemirror/modes/tiki.js +3 -0
  126. data/vendor/assets/javascripts/codemirror/modes/toml.js +3 -0
  127. data/vendor/assets/javascripts/codemirror/modes/turtle.js +3 -0
  128. data/vendor/assets/javascripts/codemirror/modes/vb.js +3 -0
  129. data/vendor/assets/javascripts/codemirror/modes/vbscript.js +3 -0
  130. data/vendor/assets/javascripts/codemirror/modes/velocity.js +3 -0
  131. data/vendor/assets/javascripts/codemirror/modes/verilog.js +3 -0
  132. data/vendor/assets/javascripts/codemirror/modes/xml.js +4 -1
  133. data/vendor/assets/javascripts/codemirror/modes/xquery.js +3 -0
  134. data/vendor/assets/javascripts/codemirror/modes/yaml.js +3 -0
  135. data/vendor/assets/javascripts/codemirror/modes/z80.js +3 -0
  136. data/vendor/assets/stylesheets/codemirror/addons/tern/tern.css +1 -0
  137. data/vendor/assets/stylesheets/codemirror/themes/neo.css +40 -0
  138. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dd16e48b5a4bf97bb9b7d6e9fe4369007477156a
4
- data.tar.gz: e2cd3b0008e31a240d67416decca66fde5d62ec5
3
+ metadata.gz: a61f66e6dd0e16149f2c19e1adc9019a21a812ed
4
+ data.tar.gz: 7c7855b16003ce87a7a9f0b40f4d6d697e38dc16
5
5
  SHA512:
6
- metadata.gz: 1a4dbd28831a7db000009ca3abf95ecda5f30352e637c49b26936ea258fbb9f5f8f2a2d0ef086bb4b5aff3c69211253985b47205e289365e02838dfa3900e020
7
- data.tar.gz: 1006bd816e052f66e24cbfb00ac4500aca09d043b772880cd7b8445072f129fd27208a95172d9d53d6466fcf4a6f8b8052c22d62af167fb4c065c88ebb371d70
6
+ metadata.gz: 9ab0ee0506c895bda4c06534e4a334d34050aedc14c3133c9e1dc6f92356434ce52758206f53e10ed9257ff9a82520d5d38d478cdc751e5f7a4e261fec3693ad
7
+ data.tar.gz: cc3e80eae3e1950147c28b9a06c60b21ca944b40dd221d8d8236ef494fa6e58ec875da515daaec4fa2cee56265a45cadad61c0f4308e4859a3a3281e1608ab92
@@ -1,6 +1,6 @@
1
1
  module Codemirror
2
2
  module Rails
3
- VERSION = '4.1'
4
- CODEMIRROR_VERSION = '4.1'
3
+ VERSION = '4.2'
4
+ CODEMIRROR_VERSION = '4.2'
5
5
  end
6
6
  end
@@ -1,3 +1,6 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
1
4
  // This is CodeMirror (http://codemirror.net), a code editor
2
5
  // implemented in JavaScript on top of the browser's DOM.
3
6
  //
@@ -93,6 +96,7 @@
93
96
  if (ie_upto10) setTimeout(bind(resetInput, this, true), 20);
94
97
 
95
98
  registerEventHandlers(this);
99
+ ensureGlobalHandlers();
96
100
 
97
101
  var cm = this;
98
102
  runInOp(this, function() {
@@ -230,6 +234,10 @@
230
234
 
231
235
  // True when shift is held down.
232
236
  d.shift = false;
237
+
238
+ // Used to track whether anything happened since the context menu
239
+ // was opened.
240
+ d.selForContextMenu = null;
233
241
  }
234
242
 
235
243
  // STATE UPDATES
@@ -455,7 +463,7 @@
455
463
  // the the current scroll position). viewPort may contain top,
456
464
  // height, and ensure (see op.scrollToPos) properties.
457
465
  function visibleLines(display, doc, viewPort) {
458
- var top = viewPort && viewPort.top != null ? viewPort.top : display.scroller.scrollTop;
466
+ var top = viewPort && viewPort.top != null ? Math.max(0, viewPort.top) : display.scroller.scrollTop;
459
467
  top = Math.floor(top - paddingTop(display));
460
468
  var bottom = viewPort && viewPort.bottom != null ? viewPort.bottom : top + display.wrapper.clientHeight;
461
469
 
@@ -471,7 +479,7 @@
471
479
  return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight),
472
480
  to: ensureTo};
473
481
  }
474
- return {from: from, to: to};
482
+ return {from: from, to: Math.max(to, from + 1)};
475
483
  }
476
484
 
477
485
  // LINE NUMBERS
@@ -659,7 +667,6 @@
659
667
  cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px";
660
668
  }
661
669
 
662
-
663
670
  function checkForWebkitWidthBug(cm, measure) {
664
671
  // Work around Webkit bug where it sometimes reserves space for a
665
672
  // non-existing phantom scrollbar in the scroller (Issue #2420)
@@ -1142,7 +1149,8 @@
1142
1149
  if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
1143
1150
  sel = filterSelectionChange(doc, sel);
1144
1151
 
1145
- var bias = cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1;
1152
+ var bias = options && options.bias ||
1153
+ (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
1146
1154
  setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
1147
1155
 
1148
1156
  if (!(options && options.scroll === false) && doc.cm)
@@ -1621,7 +1629,7 @@
1621
1629
  else
1622
1630
  rect = nullRect;
1623
1631
  } else {
1624
- rect = range(node, start, end).getBoundingClientRect();
1632
+ rect = range(node, start, end).getBoundingClientRect() || nullRect;
1625
1633
  }
1626
1634
  } else { // If it is a widget, simply get the box for the whole widget.
1627
1635
  if (start > 0) collapse = bias = "right";
@@ -1922,6 +1930,10 @@
1922
1930
  if (!updated && op.selectionChanged) updateSelection(cm);
1923
1931
  if (!updated && op.startHeight != cm.doc.height) updateScrollbars(cm);
1924
1932
 
1933
+ // Abort mouse wheel delta measurement, when scrolling explicitly
1934
+ if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
1935
+ display.wheelStartX = display.wheelStartY = null;
1936
+
1925
1937
  // Propagate the scroll position to the actual DOM scroller
1926
1938
  if (op.scrollTop != null && display.scroller.scrollTop != op.scrollTop) {
1927
1939
  var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
@@ -2135,7 +2147,8 @@
2135
2147
 
2136
2148
  function viewCuttingPoint(cm, oldN, newN, dir) {
2137
2149
  var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
2138
- if (!sawCollapsedSpans) return {index: index, lineN: newN};
2150
+ if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
2151
+ return {index: index, lineN: newN};
2139
2152
  for (var i = 0, n = cm.display.viewFrom; i < index; i++)
2140
2153
  n += view[i].size;
2141
2154
  if (n != oldN) {
@@ -2246,6 +2259,8 @@
2246
2259
  if (withOp) startOperation(cm);
2247
2260
  cm.display.shift = false;
2248
2261
 
2262
+ if (text.charCodeAt(0) == 0x200b && doc.sel == cm.display.selForContextMenu && !prevInput)
2263
+ prevInput = "\u200b";
2249
2264
  // Find the part of the input that is actually new
2250
2265
  var same = 0, l = Math.min(prevInput.length, text.length);
2251
2266
  while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
@@ -2345,7 +2360,7 @@
2345
2360
  var pos = posFromMouse(cm, e);
2346
2361
  if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
2347
2362
  e_preventDefault(e);
2348
- var word = findWordAt(cm.doc, pos);
2363
+ var word = findWordAt(cm, pos);
2349
2364
  extendSelection(cm.doc, word.anchor, word.head);
2350
2365
  }));
2351
2366
  else
@@ -2386,26 +2401,6 @@
2386
2401
  // Prevent wrapper from ever scrolling
2387
2402
  on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
2388
2403
 
2389
- // When the window resizes, we need to refresh active editors.
2390
- var resizeTimer;
2391
- function onResize() {
2392
- if (resizeTimer == null) resizeTimer = setTimeout(function() {
2393
- resizeTimer = null;
2394
- // Might be a text scaling operation, clear size caches.
2395
- d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = knownScrollbarWidth = null;
2396
- cm.setSize();
2397
- }, 100);
2398
- }
2399
- on(window, "resize", onResize);
2400
- // The above handler holds on to the editor and its data
2401
- // structures. Here we poll to unregister it when the editor is no
2402
- // longer in the document, so that it can be garbage-collected.
2403
- function unregister() {
2404
- if (contains(document.body, d.wrapper)) setTimeout(unregister, 5000);
2405
- else off(window, "resize", onResize);
2406
- }
2407
- setTimeout(unregister, 5000);
2408
-
2409
2404
  on(d.input, "keyup", operation(cm, onKeyUp));
2410
2405
  on(d.input, "input", function() {
2411
2406
  if (ie && !ie_upto8 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
@@ -2482,6 +2477,14 @@
2482
2477
  });
2483
2478
  }
2484
2479
 
2480
+ // Called when the window resizes
2481
+ function onResize(cm) {
2482
+ // Might be a text scaling operation, clear size caches.
2483
+ var d = cm.display;
2484
+ d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
2485
+ cm.setSize();
2486
+ }
2487
+
2485
2488
  // MOUSE EVENTS
2486
2489
 
2487
2490
  // Return true when the given mouse event happened in a widget
@@ -2572,17 +2575,17 @@
2572
2575
  lastClick = {time: now, pos: start};
2573
2576
  }
2574
2577
 
2575
- var sel = cm.doc.sel, addNew = mac ? e.metaKey : e.ctrlKey;
2576
- if (cm.options.dragDrop && dragAndDrop && !addNew && !isReadOnly(cm) &&
2578
+ var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey;
2579
+ if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
2577
2580
  type == "single" && sel.contains(start) > -1 && sel.somethingSelected())
2578
- leftButtonStartDrag(cm, e, start);
2581
+ leftButtonStartDrag(cm, e, start, modifier);
2579
2582
  else
2580
- leftButtonSelect(cm, e, start, type, addNew);
2583
+ leftButtonSelect(cm, e, start, type, modifier);
2581
2584
  }
2582
2585
 
2583
2586
  // Start a text drag. When it ends, see if any dragging actually
2584
2587
  // happen, and treat as a click if it didn't.
2585
- function leftButtonStartDrag(cm, e, start) {
2588
+ function leftButtonStartDrag(cm, e, start, modifier) {
2586
2589
  var display = cm.display;
2587
2590
  var dragEnd = operation(cm, function(e2) {
2588
2591
  if (webkit) display.scroller.draggable = false;
@@ -2591,7 +2594,8 @@
2591
2594
  off(display.scroller, "drop", dragEnd);
2592
2595
  if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
2593
2596
  e_preventDefault(e2);
2594
- extendSelection(cm.doc, start);
2597
+ if (!modifier)
2598
+ extendSelection(cm.doc, start);
2595
2599
  focusInput(cm);
2596
2600
  // Work around unexplainable focus problem in IE9 (#2127)
2597
2601
  if (ie_upto10 && !ie_upto8)
@@ -2629,7 +2633,7 @@
2629
2633
  start = posFromMouse(cm, e, true, true);
2630
2634
  ourIndex = -1;
2631
2635
  } else if (type == "double") {
2632
- var word = findWordAt(doc, start);
2636
+ var word = findWordAt(cm, start);
2633
2637
  if (cm.display.shift || doc.extend)
2634
2638
  ourRange = extendRange(doc, ourRange, word.anchor, word.head);
2635
2639
  else
@@ -2675,13 +2679,15 @@
2675
2679
  ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
2676
2680
  }
2677
2681
  if (!ranges.length) ranges.push(new Range(start, start));
2678
- setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), sel_mouse);
2682
+ setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
2683
+ {origin: "*mouse", scroll: false});
2684
+ cm.scrollIntoView(pos);
2679
2685
  } else {
2680
2686
  var oldRange = ourRange;
2681
2687
  var anchor = oldRange.anchor, head = pos;
2682
2688
  if (type != "single") {
2683
2689
  if (type == "double")
2684
- var range = findWordAt(doc, pos);
2690
+ var range = findWordAt(cm, pos);
2685
2691
  else
2686
2692
  var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
2687
2693
  if (cmp(range.anchor, anchor) > 0) {
@@ -2813,7 +2819,8 @@
2813
2819
  try {
2814
2820
  var text = e.dataTransfer.getData("Text");
2815
2821
  if (text) {
2816
- var selected = cm.state.draggingText && cm.listSelections();
2822
+ if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey))
2823
+ var selected = cm.listSelections();
2817
2824
  setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
2818
2825
  if (selected) for (var i = 0; i < selected.length; ++i)
2819
2826
  replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
@@ -3110,7 +3117,7 @@
3110
3117
  // The prevInput test prevents this from firing when a context
3111
3118
  // menu is closed (since the resetInput would kill the
3112
3119
  // select-all detection hack)
3113
- if (!cm.curOp && cm.display.selForContextMenu == cm.doc.sel) {
3120
+ if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
3114
3121
  resetInput(cm);
3115
3122
  if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
3116
3123
  }
@@ -3130,7 +3137,6 @@
3130
3137
 
3131
3138
  // CONTEXT MENU HANDLING
3132
3139
 
3133
- var detectingSelectAll;
3134
3140
  // To make the context menu work, we need to briefly unhide the
3135
3141
  // textarea (making it as unobtrusive as possible) to let the
3136
3142
  // right-click take effect on it.
@@ -3159,6 +3165,7 @@
3159
3165
  // Adds "Select all" to context menu in FF
3160
3166
  if (!cm.somethingSelected()) display.input.value = display.prevInput = " ";
3161
3167
  display.selForContextMenu = cm.doc.sel;
3168
+ clearTimeout(display.detectingSelectAll);
3162
3169
 
3163
3170
  // Select-all will be greyed out if there's nothing to select, so
3164
3171
  // this adds a zero-width space so that we can later check whether
@@ -3169,6 +3176,9 @@
3169
3176
  var extval = display.input.value = "\u200b" + (selected ? display.input.value : "");
3170
3177
  display.prevInput = selected ? "" : "\u200b";
3171
3178
  display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
3179
+ // Re-set this, in case some other handler touched the
3180
+ // selection in the meantime.
3181
+ display.selForContextMenu = cm.doc.sel;
3172
3182
  }
3173
3183
  }
3174
3184
  function rehide() {
@@ -3180,14 +3190,13 @@
3180
3190
  // Try to detect the user choosing select-all
3181
3191
  if (display.input.selectionStart != null) {
3182
3192
  if (!ie || ie_upto8) prepareSelectAllHack();
3183
- clearTimeout(detectingSelectAll);
3184
3193
  var i = 0, poll = function() {
3185
3194
  if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0)
3186
3195
  operation(cm, commands.selectAll)(cm);
3187
- else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
3196
+ else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
3188
3197
  else resetInput(cm);
3189
3198
  };
3190
- detectingSelectAll = setTimeout(poll, 200);
3199
+ display.detectingSelectAll = setTimeout(poll, 200);
3191
3200
  }
3192
3201
  }
3193
3202
 
@@ -3383,7 +3392,7 @@
3383
3392
 
3384
3393
  var after = i ? computeSelAfterChange(doc, change, null) : lst(source);
3385
3394
  makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
3386
- if (doc.cm) ensureCursorVisible(doc.cm);
3395
+ if (!i && doc.cm) doc.cm.scrollIntoView(change);
3387
3396
  var rebased = [];
3388
3397
 
3389
3398
  // Propagate to the linked documents
@@ -3400,12 +3409,17 @@
3400
3409
  // Sub-views need their line numbers shifted when text is added
3401
3410
  // above or below them in the parent document.
3402
3411
  function shiftDoc(doc, distance) {
3412
+ if (distance == 0) return;
3403
3413
  doc.first += distance;
3404
3414
  doc.sel = new Selection(map(doc.sel.ranges, function(range) {
3405
3415
  return new Range(Pos(range.anchor.line + distance, range.anchor.ch),
3406
3416
  Pos(range.head.line + distance, range.head.ch));
3407
3417
  }), doc.sel.primIndex);
3408
- if (doc.cm) regChange(doc.cm, doc.first, doc.first - distance, distance);
3418
+ if (doc.cm) {
3419
+ regChange(doc.cm, doc.first, doc.first - distance, distance);
3420
+ for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
3421
+ regLineChange(doc.cm, l, "gutter");
3422
+ }
3409
3423
  }
3410
3424
 
3411
3425
  // More lower-level change function, handling only a single document
@@ -3497,6 +3511,7 @@
3497
3511
  if (changeHandler) signalLater(cm, "change", cm, obj);
3498
3512
  if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj);
3499
3513
  }
3514
+ cm.display.selForContextMenu = null;
3500
3515
  }
3501
3516
 
3502
3517
  function replaceRange(doc, code, from, to, origin) {
@@ -3764,10 +3779,11 @@
3764
3779
  else if (unit == "column") moveOnce(true);
3765
3780
  else if (unit == "word" || unit == "group") {
3766
3781
  var sawType = null, group = unit == "group";
3782
+ var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
3767
3783
  for (var first = true;; first = false) {
3768
3784
  if (dir < 0 && !moveOnce(!first)) break;
3769
3785
  var cur = lineObj.text.charAt(ch) || "\n";
3770
- var type = isWordChar(cur) ? "w"
3786
+ var type = isWordChar(cur, helper) ? "w"
3771
3787
  : group && cur == "\n" ? "n"
3772
3788
  : !group || /\s/.test(cur) ? null
3773
3789
  : "p";
@@ -3807,13 +3823,15 @@
3807
3823
  }
3808
3824
 
3809
3825
  // Find the word at the given position (as returned by coordsChar).
3810
- function findWordAt(doc, pos) {
3811
- var line = getLine(doc, pos.line).text;
3826
+ function findWordAt(cm, pos) {
3827
+ var doc = cm.doc, line = getLine(doc, pos.line).text;
3812
3828
  var start = pos.ch, end = pos.ch;
3813
3829
  if (line) {
3830
+ var helper = cm.getHelper(pos, "wordChars");
3814
3831
  if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
3815
3832
  var startChar = line.charAt(start);
3816
- var check = isWordChar(startChar) ? isWordChar
3833
+ var check = isWordChar(startChar, helper)
3834
+ ? function(ch) { return isWordChar(ch, helper); }
3817
3835
  : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
3818
3836
  : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
3819
3837
  while (start > 0 && check(line.charAt(start - 1))) --start;
@@ -4618,13 +4636,25 @@
4618
4636
  },
4619
4637
  transposeChars: function(cm) {
4620
4638
  runInOp(cm, function() {
4621
- var ranges = cm.listSelections();
4639
+ var ranges = cm.listSelections(), newSel = [];
4622
4640
  for (var i = 0; i < ranges.length; i++) {
4623
4641
  var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
4624
- if (cur.ch > 0 && cur.ch < line.length - 1)
4625
- cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
4626
- Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
4642
+ if (line) {
4643
+ if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);
4644
+ if (cur.ch > 0) {
4645
+ cur = new Pos(cur.line, cur.ch + 1);
4646
+ cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
4647
+ Pos(cur.line, cur.ch - 2), cur, "+transpose");
4648
+ } else if (cur.line > cm.doc.first) {
4649
+ var prev = getLine(cm.doc, cur.line - 1).text;
4650
+ if (prev)
4651
+ cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
4652
+ Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
4653
+ }
4654
+ }
4655
+ newSel.push(new Range(cur, cur));
4627
4656
  }
4657
+ cm.setSelections(newSel);
4628
4658
  });
4629
4659
  },
4630
4660
  newlineAndIndent: function(cm) {
@@ -5584,10 +5614,11 @@
5584
5614
  }
5585
5615
 
5586
5616
  function readToken(mode, stream, state) {
5587
- var style = mode.token(stream, state);
5588
- if (stream.pos <= stream.start)
5589
- throw new Error("Mode " + mode.name + " failed to advance stream.");
5590
- return style;
5617
+ for (var i = 0; i < 10; i++) {
5618
+ var style = mode.token(stream, state);
5619
+ if (stream.pos > stream.start) return style;
5620
+ }
5621
+ throw new Error("Mode " + mode.name + " failed to advance stream.");
5591
5622
  }
5592
5623
 
5593
5624
  // Run the given mode's parser over a line, calling f for each token.
@@ -5749,6 +5780,8 @@
5749
5780
  }
5750
5781
 
5751
5782
  signal(cm, "renderLine", cm, lineView.line, builder.pre);
5783
+ if (builder.pre.className)
5784
+ builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
5752
5785
  return builder;
5753
5786
  }
5754
5787
 
@@ -7053,10 +7086,15 @@
7053
7086
  }
7054
7087
 
7055
7088
  var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
7056
- var isWordChar = CodeMirror.isWordChar = function(ch) {
7089
+ var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
7057
7090
  return /\w/.test(ch) || ch > "\x80" &&
7058
7091
  (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
7059
7092
  };
7093
+ function isWordChar(ch, helper) {
7094
+ if (!helper) return isWordCharBasic(ch);
7095
+ if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true;
7096
+ return helper.test(ch);
7097
+ }
7060
7098
 
7061
7099
  function isEmpty(obj) {
7062
7100
  for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
@@ -7138,6 +7176,43 @@
7138
7176
  return b;
7139
7177
  }
7140
7178
 
7179
+ // WINDOW-WIDE EVENTS
7180
+
7181
+ // These must be handled carefully, because naively registering a
7182
+ // handler for each editor will cause the editors to never be
7183
+ // garbage collected.
7184
+
7185
+ function forEachCodeMirror(f) {
7186
+ if (!document.body.getElementsByClassName) return;
7187
+ var byClass = document.body.getElementsByClassName("CodeMirror");
7188
+ for (var i = 0; i < byClass.length; i++) {
7189
+ var cm = byClass[i].CodeMirror;
7190
+ if (cm) f(cm);
7191
+ }
7192
+ }
7193
+
7194
+ var globalsRegistered = false;
7195
+ function ensureGlobalHandlers() {
7196
+ if (globalsRegistered) return;
7197
+ registerGlobalHandlers();
7198
+ globalsRegistered = true;
7199
+ }
7200
+ function registerGlobalHandlers() {
7201
+ // When the window resizes, we need to refresh active editors.
7202
+ var resizeTimer;
7203
+ on(window, "resize", function() {
7204
+ if (resizeTimer == null) resizeTimer = setTimeout(function() {
7205
+ resizeTimer = null;
7206
+ knownScrollbarWidth = null;
7207
+ forEachCodeMirror(onResize);
7208
+ }, 100);
7209
+ });
7210
+ // When the window loses focus, we want to show the editor as blurred
7211
+ on(window, "blur", function() {
7212
+ forEachCodeMirror(onBlur);
7213
+ });
7214
+ }
7215
+
7141
7216
  // FEATURE DETECTION
7142
7217
 
7143
7218
  // Detect drag-and-drop
@@ -7520,7 +7595,7 @@
7520
7595
 
7521
7596
  // THE END
7522
7597
 
7523
- CodeMirror.version = "4.1.0";
7598
+ CodeMirror.version = "4.2.0";
7524
7599
 
7525
7600
  return CodeMirror;
7526
7601
  });