codemirror-rails 2.23 → 2.24
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|