codemirror-rails 2.23 → 2.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.
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +163 -88
- data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +1 -1
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +85 -202
- data/vendor/assets/javascripts/codemirror/modes/clike.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +3 -1
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +4 -3
- data/vendor/assets/javascripts/codemirror/modes/less.js +27 -13
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/php.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/pig.js +172 -0
- data/vendor/assets/javascripts/codemirror/modes/python.js +1 -0
- data/vendor/assets/javascripts/codemirror/modes/rpm-spec.css +5 -0
- data/vendor/assets/javascripts/codemirror/modes/rst.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/shell.js +103 -0
- data/vendor/assets/javascripts/codemirror/modes/tiki.js +316 -0
- data/vendor/assets/javascripts/codemirror/modes/xml.js +63 -6
- data/vendor/assets/javascripts/codemirror/utils/foldcode.js +13 -8
- data/vendor/assets/javascripts/codemirror/utils/loadmode.js +50 -0
- data/vendor/assets/javascripts/codemirror/utils/overlay.js +1 -1
- data/vendor/assets/javascripts/codemirror/utils/search.js +2 -2
- data/vendor/assets/stylesheets/codemirror.css +2 -0
- data/vendor/assets/stylesheets/codemirror/modes/tiki.css +26 -0
- data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +82 -0
- data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +25 -0
- data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +1 -1
- metadata +12 -4
@@ -1,4 +1,4 @@
|
|
1
|
-
// CodeMirror version 2.
|
1
|
+
// CodeMirror version 2.24
|
2
2
|
//
|
3
3
|
// All functions that need access to the editor's state live inside
|
4
4
|
// the CodeMirror function. Below that, at the bottom of the file,
|
@@ -98,7 +98,6 @@ var CodeMirror = (function() {
|
|
98
98
|
// Register our event handlers.
|
99
99
|
connect(scroller, "mousedown", operation(onMouseDown));
|
100
100
|
connect(scroller, "dblclick", operation(onDoubleClick));
|
101
|
-
connect(lineSpace, "dragstart", onDragStart);
|
102
101
|
connect(lineSpace, "selectstart", e_preventDefault);
|
103
102
|
// Gecko browsers fire contextmenu *after* opening the menu, at
|
104
103
|
// which point we can't mess with it anymore. Context menu is
|
@@ -118,9 +117,16 @@ var CodeMirror = (function() {
|
|
118
117
|
connect(input, "focus", onFocus);
|
119
118
|
connect(input, "blur", onBlur);
|
120
119
|
|
121
|
-
|
122
|
-
|
123
|
-
|
120
|
+
if (options.dragDrop) {
|
121
|
+
connect(lineSpace, "dragstart", onDragStart);
|
122
|
+
function drag_(e) {
|
123
|
+
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
|
124
|
+
e_stop(e);
|
125
|
+
}
|
126
|
+
connect(scroller, "dragenter", drag_);
|
127
|
+
connect(scroller, "dragover", drag_);
|
128
|
+
connect(scroller, "drop", operation(onDrop));
|
129
|
+
}
|
124
130
|
connect(scroller, "paste", function(){focusInput(); fastPoll();});
|
125
131
|
connect(input, "paste", fastPoll);
|
126
132
|
connect(input, "cut", operation(function(){
|
@@ -312,6 +318,7 @@ var CodeMirror = (function() {
|
|
312
318
|
},
|
313
319
|
|
314
320
|
operation: function(f){return operation(f)();},
|
321
|
+
compoundChange: function(f){return compoundChange(f);},
|
315
322
|
refresh: function(){
|
316
323
|
updateDisplay(true);
|
317
324
|
if (scroller.scrollHeight > lastScrollPos)
|
@@ -336,7 +343,7 @@ var CodeMirror = (function() {
|
|
336
343
|
splitLines(code), top, top);
|
337
344
|
updateInput = true;
|
338
345
|
}
|
339
|
-
function getValue(
|
346
|
+
function getValue() {
|
340
347
|
var text = [];
|
341
348
|
doc.iter(0, doc.size, function(line) { text.push(line.text); });
|
342
349
|
return text.join("\n");
|
@@ -385,20 +392,22 @@ var CodeMirror = (function() {
|
|
385
392
|
} else { lastClick = {time: now, pos: start}; }
|
386
393
|
|
387
394
|
var last = start, going;
|
388
|
-
if (dragAndDrop && !options.readOnly && !posEq(sel.from, sel.to) &&
|
395
|
+
if (options.dragDrop && dragAndDrop && !options.readOnly && !posEq(sel.from, sel.to) &&
|
389
396
|
!posLess(start, sel.from) && !posLess(sel.to, start)) {
|
390
397
|
// Let the drag handler handle this.
|
391
398
|
if (webkit) lineSpace.draggable = true;
|
392
|
-
|
399
|
+
function dragEnd(e2) {
|
393
400
|
if (webkit) lineSpace.draggable = false;
|
394
401
|
draggingText = false;
|
395
|
-
up();
|
402
|
+
up(); drop();
|
396
403
|
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
|
397
404
|
e_preventDefault(e2);
|
398
405
|
setCursor(start.line, start.ch, true);
|
399
406
|
focusInput();
|
400
407
|
}
|
401
|
-
}
|
408
|
+
}
|
409
|
+
var up = connect(document, "mouseup", operation(dragEnd), true);
|
410
|
+
var drop = connect(scroller, "drop", operation(dragEnd), true);
|
402
411
|
draggingText = true;
|
403
412
|
// IE's approach to draggable
|
404
413
|
if (lineSpace.dragDrop) lineSpace.dragDrop();
|
@@ -447,6 +456,7 @@ var CodeMirror = (function() {
|
|
447
456
|
selectWordAt(start);
|
448
457
|
}
|
449
458
|
function onDrop(e) {
|
459
|
+
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
|
450
460
|
e.preventDefault();
|
451
461
|
var pos = posFromMouse(e, true), files = e.dataTransfer.files;
|
452
462
|
if (!pos || options.readOnly) return;
|
@@ -456,12 +466,12 @@ var CodeMirror = (function() {
|
|
456
466
|
reader.onload = function() {
|
457
467
|
text[i] = reader.result;
|
458
468
|
if (++read == n) {
|
459
|
-
|
460
|
-
|
469
|
+
pos = clipPos(pos);
|
470
|
+
operation(function() {
|
461
471
|
var end = replaceRange(text.join(""), pos, pos);
|
462
472
|
setSelectionUser(pos, end);
|
463
473
|
})();
|
464
|
-
|
474
|
+
}
|
465
475
|
};
|
466
476
|
reader.readAsText(file);
|
467
477
|
}
|
@@ -472,12 +482,14 @@ var CodeMirror = (function() {
|
|
472
482
|
try {
|
473
483
|
var text = e.dataTransfer.getData("Text");
|
474
484
|
if (text) {
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
485
|
+
compoundChange(function() {
|
486
|
+
var curFrom = sel.from, curTo = sel.to;
|
487
|
+
setSelectionUser(pos, pos);
|
488
|
+
if (draggingText) replaceRange("", curFrom, curTo);
|
489
|
+
replaceSelection(text);
|
490
|
+
focusInput();
|
491
|
+
});
|
492
|
+
}
|
481
493
|
}
|
482
494
|
catch(e){}
|
483
495
|
}
|
@@ -529,15 +541,19 @@ var CodeMirror = (function() {
|
|
529
541
|
if (e_prop(e, "ctrlKey")) name = "Ctrl-" + name;
|
530
542
|
if (e_prop(e, "metaKey")) name = "Cmd-" + name;
|
531
543
|
|
544
|
+
var stopped = false;
|
545
|
+
function stop() { stopped = true; }
|
546
|
+
|
532
547
|
if (e_prop(e, "shiftKey")) {
|
533
548
|
handled = lookupKey("Shift-" + name, options.extraKeys, options.keyMap,
|
534
|
-
function(b) {return doHandleBinding(b, true);})
|
549
|
+
function(b) {return doHandleBinding(b, true);}, stop)
|
535
550
|
|| lookupKey(name, options.extraKeys, options.keyMap, function(b) {
|
536
551
|
if (typeof b == "string" && /^go[A-Z]/.test(b)) return doHandleBinding(b);
|
537
|
-
});
|
552
|
+
}, stop);
|
538
553
|
} else {
|
539
|
-
handled = lookupKey(name, options.extraKeys, options.keyMap, doHandleBinding);
|
554
|
+
handled = lookupKey(name, options.extraKeys, options.keyMap, doHandleBinding, stop);
|
540
555
|
}
|
556
|
+
if (stopped) handled = false;
|
541
557
|
if (handled) {
|
542
558
|
e_preventDefault(e);
|
543
559
|
if (ie) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
|
@@ -546,7 +562,7 @@ var CodeMirror = (function() {
|
|
546
562
|
}
|
547
563
|
function handleCharBinding(e, ch) {
|
548
564
|
var handled = lookupKey("'" + ch + "'", options.extraKeys,
|
549
|
-
options.keyMap, doHandleBinding);
|
565
|
+
options.keyMap, function(b) { return doHandleBinding(b, true); });
|
550
566
|
if (handled) e_preventDefault(e);
|
551
567
|
return handled;
|
552
568
|
}
|
@@ -648,7 +664,7 @@ var CodeMirror = (function() {
|
|
648
664
|
if (suppressEdits) return;
|
649
665
|
var recomputeMaxLength = false, maxLineLength = maxLine.length;
|
650
666
|
if (!options.lineWrapping)
|
651
|
-
doc.iter(from.line, to.line, function(line) {
|
667
|
+
doc.iter(from.line, to.line + 1, function(line) {
|
652
668
|
if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
|
653
669
|
});
|
654
670
|
if (from.line != to.line || newText.length > 1) gutterDirty = true;
|
@@ -696,14 +712,14 @@ var CodeMirror = (function() {
|
|
696
712
|
doc.insert(from.line + 1, added);
|
697
713
|
}
|
698
714
|
if (options.lineWrapping) {
|
699
|
-
var perLine = scroller.clientWidth / charWidth() - 3;
|
715
|
+
var perLine = Math.max(5, scroller.clientWidth / charWidth() - 3);
|
700
716
|
doc.iter(from.line, from.line + newText.length, function(line) {
|
701
717
|
if (line.hidden) return;
|
702
718
|
var guess = Math.ceil(line.text.length / perLine) || 1;
|
703
719
|
if (guess != line.height) updateLineHeight(line, guess);
|
704
720
|
});
|
705
721
|
} else {
|
706
|
-
doc.iter(from.line,
|
722
|
+
doc.iter(from.line, from.line + newText.length, function(line) {
|
707
723
|
var l = line.text;
|
708
724
|
if (l.length > maxLineLength) {
|
709
725
|
maxLine = l; maxLineLength = l.length; maxWidth = null;
|
@@ -874,8 +890,9 @@ var CodeMirror = (function() {
|
|
874
890
|
|
875
891
|
var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
|
876
892
|
var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
|
877
|
-
|
878
|
-
|
893
|
+
var atLeft = x1 < gutterw + pl + 10;
|
894
|
+
if (x1 < screenleft + gutterw || atLeft) {
|
895
|
+
if (atLeft) x1 = 0;
|
879
896
|
scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
|
880
897
|
scrolled = true;
|
881
898
|
}
|
@@ -890,10 +907,10 @@ var CodeMirror = (function() {
|
|
890
907
|
|
891
908
|
function visibleLines() {
|
892
909
|
var lh = textHeight(), top = scroller.scrollTop - paddingTop();
|
893
|
-
var
|
894
|
-
var
|
895
|
-
return {from: lineAtHeight(doc,
|
896
|
-
to: lineAtHeight(doc,
|
910
|
+
var fromHeight = Math.max(0, Math.floor(top / lh));
|
911
|
+
var toHeight = Math.ceil((top + scroller.clientHeight) / lh);
|
912
|
+
return {from: lineAtHeight(doc, fromHeight),
|
913
|
+
to: lineAtHeight(doc, toHeight)};
|
897
914
|
}
|
898
915
|
// Uses a set of changes plus the current scroll position to
|
899
916
|
// determine which DOM updates have to be made, and makes the
|
@@ -924,7 +941,7 @@ var CodeMirror = (function() {
|
|
924
941
|
if (range.from >= range.to) intact.splice(i--, 1);
|
925
942
|
else intactLines += range.to - range.from;
|
926
943
|
}
|
927
|
-
if (intactLines == to - from) return;
|
944
|
+
if (intactLines == to - from && from == showingFrom && to == showingTo) return;
|
928
945
|
intact.sort(function(a, b) {return a.domStart - b.domStart;});
|
929
946
|
|
930
947
|
var th = textHeight(), gutterDisplay = gutter.style.display;
|
@@ -1108,12 +1125,14 @@ var CodeMirror = (function() {
|
|
1108
1125
|
selectionDiv.style.display = "none";
|
1109
1126
|
} else {
|
1110
1127
|
var sameLine = fromPos.y == toPos.y, html = "";
|
1128
|
+
var clientWidth = lineSpace.clientWidth || lineSpace.offsetWidth;
|
1129
|
+
var clientHeight = lineSpace.clientHeight || lineSpace.offsetHeight;
|
1111
1130
|
function add(left, top, right, height) {
|
1131
|
+
var rstyle = quirksMode ? "width: " + (!right ? clientWidth : clientWidth - right - left) + "px"
|
1132
|
+
: "right: " + right + "px";
|
1112
1133
|
html += '<div class="CodeMirror-selected" style="position: absolute; left: ' + left +
|
1113
|
-
'px; top: ' + top + 'px;
|
1134
|
+
'px; top: ' + top + 'px; ' + rstyle + '; height: ' + height + 'px"></div>';
|
1114
1135
|
}
|
1115
|
-
var clientWidth = lineSpace.clientWidth || lineSpace.offsetWidth;
|
1116
|
-
var clientHeight = lineSpace.clientHeight || lineSpace.offsetHeight;
|
1117
1136
|
if (sel.from.ch && fromPos.y >= 0) {
|
1118
1137
|
var right = sameLine ? clientWidth - toPos.x : 0;
|
1119
1138
|
add(fromPos.x, fromPos.y, right, th);
|
@@ -1189,13 +1208,14 @@ var CodeMirror = (function() {
|
|
1189
1208
|
var line = getLine(lNo);
|
1190
1209
|
if (!line.hidden) {
|
1191
1210
|
var ch = pos.ch;
|
1192
|
-
if (ch > oldCh || ch > line.text.length) ch = line.text.length;
|
1211
|
+
if (toEnd || ch > oldCh || ch > line.text.length) ch = line.text.length;
|
1193
1212
|
return {line: lNo, ch: ch};
|
1194
1213
|
}
|
1195
1214
|
lNo += dir;
|
1196
1215
|
}
|
1197
1216
|
}
|
1198
1217
|
var line = getLine(pos.line);
|
1218
|
+
var toEnd = pos.ch == line.text.length && pos.ch != oldCh;
|
1199
1219
|
if (!line.hidden) return pos;
|
1200
1220
|
if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
|
1201
1221
|
else return getNonHidden(-1) || getNonHidden(1);
|
@@ -1355,7 +1375,7 @@ var CodeMirror = (function() {
|
|
1355
1375
|
return (tabCache[w] = {html: str + "</span>", width: w});
|
1356
1376
|
}
|
1357
1377
|
function themeChanged() {
|
1358
|
-
scroller.className = scroller.className.replace(/\s*cm-s-\
|
1378
|
+
scroller.className = scroller.className.replace(/\s*cm-s-\S+/g, "") +
|
1359
1379
|
options.theme.replace(/(^|\s)\s*/g, " cm-s-");
|
1360
1380
|
}
|
1361
1381
|
|
@@ -1506,8 +1526,7 @@ var CodeMirror = (function() {
|
|
1506
1526
|
if (x <= 0) return 0;
|
1507
1527
|
var lineObj = getLine(line), text = lineObj.text;
|
1508
1528
|
function getX(len) {
|
1509
|
-
|
1510
|
-
return measure.firstChild.firstChild.offsetWidth;
|
1529
|
+
return measureLine(lineObj, len).left;
|
1511
1530
|
}
|
1512
1531
|
var from = 0, fromX = 0, to = text.length, toX;
|
1513
1532
|
// Guess a suitable upper bound for our search.
|
@@ -1530,19 +1549,13 @@ var CodeMirror = (function() {
|
|
1530
1549
|
}
|
1531
1550
|
}
|
1532
1551
|
|
1533
|
-
var tempId = Math.floor(Math.random() * 0xffffff).toString(16);
|
1552
|
+
var tempId = "CodeMirror-temp-" + Math.floor(Math.random() * 0xffffff).toString(16);
|
1534
1553
|
function measureLine(line, ch) {
|
1535
1554
|
if (ch == 0) return {top: 0, left: 0};
|
1536
|
-
var
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
extra = htmlEscape(line.text.slice(ch + 1, end < 0 ? line.text.length : end + (ie ? 5 : 0)));
|
1541
|
-
}
|
1542
|
-
measure.innerHTML = "<pre>" + line.getHTML(makeTab, ch) +
|
1543
|
-
'<span id="CodeMirror-temp-' + tempId + '">' + htmlEscape(line.text.charAt(ch) || " ") + "</span>" +
|
1544
|
-
extra + "</pre>";
|
1545
|
-
var elt = document.getElementById("CodeMirror-temp-" + tempId);
|
1555
|
+
var wbr = options.lineWrapping && ch < line.text.length &&
|
1556
|
+
spanAffectsWrapping.test(line.text.slice(ch - 1, ch + 1));
|
1557
|
+
measure.innerHTML = "<pre>" + line.getHTML(makeTab, ch, tempId, wbr) + "</pre>";
|
1558
|
+
var elt = document.getElementById(tempId);
|
1546
1559
|
var top = elt.offsetTop, left = elt.offsetLeft;
|
1547
1560
|
// Older IEs report zero offsets for spans directly after a wrap
|
1548
1561
|
if (ie && top == 0 && left == 0) {
|
@@ -1790,13 +1803,17 @@ var CodeMirror = (function() {
|
|
1790
1803
|
var changed = line.highlight(mode, state, options.tabSize);
|
1791
1804
|
if (changed) realChange = true;
|
1792
1805
|
line.stateAfter = copyState(mode, state);
|
1806
|
+
var done = null;
|
1793
1807
|
if (compare) {
|
1794
|
-
|
1795
|
-
|
1808
|
+
var same = hadState && compare(hadState, state);
|
1809
|
+
if (same != Pass) done = !!same;
|
1810
|
+
}
|
1811
|
+
if (done == null) {
|
1796
1812
|
if (changed !== false || !hadState) unchanged = 0;
|
1797
1813
|
else if (++unchanged > 3 && (!mode.indent || mode.indent(hadState, "") == mode.indent(state, "")))
|
1798
|
-
|
1814
|
+
done = true;
|
1799
1815
|
}
|
1816
|
+
if (done) return true;
|
1800
1817
|
++i;
|
1801
1818
|
});
|
1802
1819
|
if (bail) return;
|
@@ -1856,6 +1873,11 @@ var CodeMirror = (function() {
|
|
1856
1873
|
};
|
1857
1874
|
}
|
1858
1875
|
|
1876
|
+
function compoundChange(f) {
|
1877
|
+
history.startCompound();
|
1878
|
+
try { return f(); } finally { history.endCompound(); }
|
1879
|
+
}
|
1880
|
+
|
1859
1881
|
for (var ext in extensions)
|
1860
1882
|
if (extensions.propertyIsEnumerable(ext) &&
|
1861
1883
|
!instance.propertyIsEnumerable(ext))
|
@@ -1877,12 +1899,14 @@ var CodeMirror = (function() {
|
|
1877
1899
|
electricChars: true,
|
1878
1900
|
autoClearEmptyLines: false,
|
1879
1901
|
onKeyEvent: null,
|
1902
|
+
onDragEvent: null,
|
1880
1903
|
lineWrapping: false,
|
1881
1904
|
lineNumbers: false,
|
1882
1905
|
gutter: false,
|
1883
1906
|
fixedGutter: false,
|
1884
1907
|
firstLineNumber: 1,
|
1885
1908
|
readOnly: false,
|
1909
|
+
dragDrop: true,
|
1886
1910
|
onChange: null,
|
1887
1911
|
onCursorActivity: null,
|
1888
1912
|
onGutterClick: null,
|
@@ -1906,6 +1930,10 @@ var CodeMirror = (function() {
|
|
1906
1930
|
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
|
1907
1931
|
CodeMirror.defineMode = function(name, mode) {
|
1908
1932
|
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
|
1933
|
+
if (arguments.length > 2) {
|
1934
|
+
mode.dependencies = [];
|
1935
|
+
for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
|
1936
|
+
}
|
1909
1937
|
modes[name] = mode;
|
1910
1938
|
};
|
1911
1939
|
CodeMirror.defineMIME = function(mime, spec) {
|
@@ -1922,10 +1950,7 @@ var CodeMirror = (function() {
|
|
1922
1950
|
CodeMirror.getMode = function(options, spec) {
|
1923
1951
|
var spec = CodeMirror.resolveMode(spec);
|
1924
1952
|
var mfactory = modes[spec.name];
|
1925
|
-
if (!mfactory)
|
1926
|
-
if (window.console) console.warn("No mode " + spec.name + " found, falling back to plain text.");
|
1927
|
-
return CodeMirror.getMode(options, "text/plain");
|
1928
|
-
}
|
1953
|
+
if (!mfactory) return CodeMirror.getMode(options, "text/plain");
|
1929
1954
|
return mfactory(options, spec);
|
1930
1955
|
};
|
1931
1956
|
CodeMirror.listModes = function() {
|
@@ -2035,12 +2060,15 @@ var CodeMirror = (function() {
|
|
2035
2060
|
if (typeof val == "string") return keyMap[val];
|
2036
2061
|
else return val;
|
2037
2062
|
}
|
2038
|
-
function lookupKey(name, extraMap, map, handle) {
|
2063
|
+
function lookupKey(name, extraMap, map, handle, stop) {
|
2039
2064
|
function lookup(map) {
|
2040
2065
|
map = getKeyMap(map);
|
2041
2066
|
var found = map[name];
|
2042
2067
|
if (found != null && handle(found)) return true;
|
2043
|
-
if (map.
|
2068
|
+
if (map.nofallthrough) {
|
2069
|
+
if (stop) stop();
|
2070
|
+
return true;
|
2071
|
+
}
|
2044
2072
|
var fallthrough = map.fallthrough;
|
2045
2073
|
if (fallthrough == null) return false;
|
2046
2074
|
if (Object.prototype.toString.call(fallthrough) != "[object Array]")
|
@@ -2402,9 +2430,9 @@ var CodeMirror = (function() {
|
|
2402
2430
|
indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
|
2403
2431
|
// Produces an HTML fragment for the line, taking selection,
|
2404
2432
|
// marking, and highlighting into account.
|
2405
|
-
getHTML: function(makeTab,
|
2433
|
+
getHTML: function(makeTab, wrapAt, wrapId, wrapWBR) {
|
2406
2434
|
var html = [], first = true, col = 0;
|
2407
|
-
function
|
2435
|
+
function span_(text, style) {
|
2408
2436
|
if (!text) return;
|
2409
2437
|
// Work around a bug where, in some compat modes, IE ignores leading spaces
|
2410
2438
|
if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
|
@@ -2432,24 +2460,50 @@ var CodeMirror = (function() {
|
|
2432
2460
|
if (style) html.push('<span class="', style, '">', escaped, "</span>");
|
2433
2461
|
else html.push(escaped);
|
2434
2462
|
}
|
2463
|
+
var span = span_;
|
2464
|
+
if (wrapAt != null) {
|
2465
|
+
var outPos = 0, open = "<span id=\"" + wrapId + "\">";
|
2466
|
+
span = function(text, style) {
|
2467
|
+
var l = text.length;
|
2468
|
+
if (wrapAt >= outPos && wrapAt < outPos + l) {
|
2469
|
+
if (wrapAt > outPos) {
|
2470
|
+
span_(text.slice(0, wrapAt - outPos), style);
|
2471
|
+
// See comment at the definition of spanAffectsWrapping
|
2472
|
+
if (wrapWBR) html.push("<wbr>");
|
2473
|
+
}
|
2474
|
+
html.push(open);
|
2475
|
+
span_(text.slice(wrapAt - outPos), style);
|
2476
|
+
html.push("</span>");
|
2477
|
+
wrapAt--;
|
2478
|
+
outPos += l;
|
2479
|
+
} else {
|
2480
|
+
outPos += l;
|
2481
|
+
span_(text, style);
|
2482
|
+
// Output empty wrapper when at end of line
|
2483
|
+
if (outPos == wrapAt && outPos == len) html.push(open + "</span>");
|
2484
|
+
// Stop outputting HTML when gone sufficiently far beyond measure
|
2485
|
+
else if (outPos > wrapAt + 10 && /\s/.test(text)) span = function(){};
|
2486
|
+
}
|
2487
|
+
}
|
2488
|
+
}
|
2489
|
+
|
2435
2490
|
var st = this.styles, allText = this.text, marked = this.marked;
|
2436
2491
|
var len = allText.length;
|
2437
|
-
if (endAt != null) len = Math.min(endAt, len);
|
2438
2492
|
function styleToClass(style) {
|
2439
2493
|
if (!style) return null;
|
2440
2494
|
return "cm-" + style.replace(/ +/g, " cm-");
|
2441
2495
|
}
|
2442
2496
|
|
2443
|
-
if (!allText &&
|
2497
|
+
if (!allText && wrapAt == null) {
|
2444
2498
|
span(" ");
|
2445
|
-
else if (!marked || !marked.length)
|
2499
|
+
} else if (!marked || !marked.length) {
|
2446
2500
|
for (var i = 0, ch = 0; ch < len; i+=2) {
|
2447
2501
|
var str = st[i], style = st[i+1], l = str.length;
|
2448
2502
|
if (ch + l > len) str = str.slice(0, len - ch);
|
2449
2503
|
ch += l;
|
2450
2504
|
span(str, styleToClass(style));
|
2451
2505
|
}
|
2452
|
-
else {
|
2506
|
+
} else {
|
2453
2507
|
var pos = 0, i = 0, text = "", style, sg = 0;
|
2454
2508
|
var nextChange = marked[0].from || 0, marks = [], markpos = 0;
|
2455
2509
|
function advanceMarks() {
|
@@ -2535,7 +2589,11 @@ var CodeMirror = (function() {
|
|
2535
2589
|
},
|
2536
2590
|
insertHeight: function(at, lines, height) {
|
2537
2591
|
this.height += height;
|
2538
|
-
|
2592
|
+
// The trick below is apparently too advanced for IE, which
|
2593
|
+
// occasionally corrupts this.lines (duplicating elements) when
|
2594
|
+
// it is used.
|
2595
|
+
if (ie) this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
|
2596
|
+
else this.lines.splice.apply(this.lines, [at, 0].concat(lines));
|
2539
2597
|
for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
|
2540
2598
|
},
|
2541
2599
|
iterN: function(at, n, op) {
|
@@ -2701,33 +2759,36 @@ var CodeMirror = (function() {
|
|
2701
2759
|
function History() {
|
2702
2760
|
this.time = 0;
|
2703
2761
|
this.done = []; this.undone = [];
|
2762
|
+
this.compound = 0;
|
2763
|
+
this.closed = false;
|
2704
2764
|
}
|
2705
2765
|
History.prototype = {
|
2706
2766
|
addChange: function(start, added, old) {
|
2707
2767
|
this.undone.length = 0;
|
2708
2768
|
var time = +new Date, cur = this.done[this.done.length - 1], last = cur && cur[cur.length - 1];
|
2709
2769
|
var dtime = time - this.time;
|
2710
|
-
|
2711
|
-
|
2712
|
-
} else if (last.start > start + old.length || last.start + last.added < start - last.added + last.old.length) {
|
2770
|
+
|
2771
|
+
if (this.compound && cur && !this.closed) {
|
2713
2772
|
cur.push({start: start, added: added, old: old});
|
2773
|
+
} else if (dtime > 400 || !last || this.closed ||
|
2774
|
+
last.start > start + old.length || last.start + last.added < start) {
|
2775
|
+
this.done.push([{start: start, added: added, old: old}]);
|
2776
|
+
this.closed = false;
|
2714
2777
|
} else {
|
2715
|
-
var
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
last.start = start;
|
2722
|
-
} else if (last.start < start) {
|
2723
|
-
oldoff = start - last.start;
|
2724
|
-
added += oldoff;
|
2725
|
-
}
|
2726
|
-
for (var i = last.added - oldoff, e = old.length; i < e; ++i)
|
2727
|
-
last.old.push(old[i]);
|
2728
|
-
if (last.added < added) last.added = added;
|
2778
|
+
var startBefore = Math.max(0, last.start - start),
|
2779
|
+
endAfter = Math.max(0, (start + old.length) - (last.start + last.added));
|
2780
|
+
for (var i = startBefore; i > 0; --i) last.old.unshift(old[i - 1]);
|
2781
|
+
for (var i = endAfter; i > 0; --i) last.old.push(old[old.length - i]);
|
2782
|
+
if (startBefore) last.start = start;
|
2783
|
+
last.added += added - (old.length - startBefore - endAfter);
|
2729
2784
|
}
|
2730
2785
|
this.time = time;
|
2786
|
+
},
|
2787
|
+
startCompound: function() {
|
2788
|
+
if (!this.compound++) this.closed = true;
|
2789
|
+
},
|
2790
|
+
endCompound: function() {
|
2791
|
+
if (!--this.compound) this.closed = true;
|
2731
2792
|
}
|
2732
2793
|
};
|
2733
2794
|
|
@@ -2789,8 +2850,10 @@ var CodeMirror = (function() {
|
|
2789
2850
|
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
|
2790
2851
|
var ie = /MSIE \d/.test(navigator.userAgent);
|
2791
2852
|
var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
|
2853
|
+
var quirksMode = ie && document.documentMode == 5;
|
2792
2854
|
var webkit = /WebKit\//.test(navigator.userAgent);
|
2793
2855
|
var chrome = /Chrome\//.test(navigator.userAgent);
|
2856
|
+
var safari = /Apple Computer/.test(navigator.vendor);
|
2794
2857
|
var khtml = /KHTML\//.test(navigator.userAgent);
|
2795
2858
|
|
2796
2859
|
// Detect drag-and-drop
|
@@ -2802,13 +2865,25 @@ var CodeMirror = (function() {
|
|
2802
2865
|
return "draggable" in div || "dragDrop" in div;
|
2803
2866
|
}();
|
2804
2867
|
|
2805
|
-
var lineSep = "\n";
|
2806
2868
|
// Feature-detect whether newlines in textareas are converted to \r\n
|
2807
|
-
|
2869
|
+
var lineSep = function () {
|
2808
2870
|
var te = document.createElement("textarea");
|
2809
2871
|
te.value = "foo\nbar";
|
2810
|
-
if (te.value.indexOf("\r") > -1)
|
2811
|
-
|
2872
|
+
if (te.value.indexOf("\r") > -1) return "\r\n";
|
2873
|
+
return "\n";
|
2874
|
+
}();
|
2875
|
+
|
2876
|
+
// For a reason I have yet to figure out, some browsers disallow
|
2877
|
+
// word wrapping between certain characters *only* if a new inline
|
2878
|
+
// element is started between them. This makes it hard to reliably
|
2879
|
+
// measure the position of things, since that requires inserting an
|
2880
|
+
// extra span. This terribly fragile set of regexps matches the
|
2881
|
+
// character combinations that suffer from this phenomenon on the
|
2882
|
+
// various browsers.
|
2883
|
+
var spanAffectsWrapping = /^$/; // Won't match any two-character string
|
2884
|
+
if (gecko) spanAffectsWrapping = /$'/;
|
2885
|
+
else if (safari) spanAffectsWrapping = /\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/;
|
2886
|
+
else if (chrome) spanAffectsWrapping = /\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/;
|
2812
2887
|
|
2813
2888
|
// Counts the column offset in a string, taking tabs into account.
|
2814
2889
|
// Used mostly to find indentation.
|