codemirror-rails 4.3 → 4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +321 -158
- data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +11 -0
- data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +20 -5
- data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +2 -2
- data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +2 -3
- data/vendor/assets/javascripts/codemirror/addons/search/search.js +1 -0
- data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +1 -1
- data/vendor/assets/javascripts/codemirror/keymaps/sublime.js +23 -5
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +425 -118
- data/vendor/assets/javascripts/codemirror/modes/clike.js +1 -0
- data/vendor/assets/javascripts/codemirror/modes/css.js +3 -3
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +2 -0
- data/vendor/assets/javascripts/codemirror/modes/kotlin.js +280 -0
- data/vendor/assets/javascripts/codemirror/modes/puppet.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +18 -4
- data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +17 -12
- data/vendor/assets/javascripts/codemirror/modes/vbscript.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/yaml.js +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f231dd42a91b4d2a0ecc9440cad8f8e505f239d
|
4
|
+
data.tar.gz: 3482d82a48c052c4472c55a0db8a648fb87e0b87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0989abb66c57e0f95cb9f20646f797c6eb296da0d1a87845379ea52db4488e24458bd40e61176d0125433abb0b7c6fc4dca586a0b4dcfe66273742ccb0a7973b
|
7
|
+
data.tar.gz: 74161b00c7c25f04c3468e58e304f989691cc6cc5c51c3017c7471f9f2112dc5a39a31779d960b9be3813ca28774b30a1ed9ca201e381f546c66bc2a1b571138
|
@@ -108,6 +108,7 @@
|
|
108
108
|
|
109
109
|
for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
|
110
110
|
optionHandlers[opt](cm, options[opt], Init);
|
111
|
+
maybeUpdateLineNumberWidth(cm);
|
111
112
|
for (var i = 0; i < initHooks.length; ++i) initHooks[i](cm);
|
112
113
|
});
|
113
114
|
}
|
@@ -467,18 +468,18 @@
|
|
467
468
|
}
|
468
469
|
|
469
470
|
// Compute the lines that are visible in a given viewport (defaults
|
470
|
-
// the the current scroll position).
|
471
|
+
// the the current scroll position). viewport may contain top,
|
471
472
|
// height, and ensure (see op.scrollToPos) properties.
|
472
|
-
function visibleLines(display, doc,
|
473
|
-
var top =
|
473
|
+
function visibleLines(display, doc, viewport) {
|
474
|
+
var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
|
474
475
|
top = Math.floor(top - paddingTop(display));
|
475
|
-
var bottom =
|
476
|
+
var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
|
476
477
|
|
477
478
|
var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
|
478
479
|
// Ensure is a {from: {line, ch}, to: {line, ch}} object, and
|
479
480
|
// forces those lines into the viewport (if possible).
|
480
|
-
if (
|
481
|
-
var ensureFrom =
|
481
|
+
if (viewport && viewport.ensure) {
|
482
|
+
var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
|
482
483
|
if (ensureFrom < from)
|
483
484
|
return {from: ensureFrom,
|
484
485
|
to: lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)};
|
@@ -543,83 +544,46 @@
|
|
543
544
|
|
544
545
|
// DISPLAY DRAWING
|
545
546
|
|
546
|
-
|
547
|
-
|
548
|
-
// up-to-date. Tries to bail out early when no changes are needed,
|
549
|
-
// unless forced is true.
|
550
|
-
// Returns true if an actual update happened, false otherwise.
|
551
|
-
function updateDisplay(cm, viewPort, forced) {
|
552
|
-
var oldFrom = cm.display.viewFrom, oldTo = cm.display.viewTo, updated;
|
553
|
-
var visible = visibleLines(cm.display, cm.doc, viewPort);
|
554
|
-
for (var first = true;; first = false) {
|
555
|
-
var oldWidth = cm.display.scroller.clientWidth;
|
556
|
-
if (!updateDisplayInner(cm, visible, forced)) break;
|
557
|
-
updated = true;
|
558
|
-
|
559
|
-
// If the max line changed since it was last measured, measure it,
|
560
|
-
// and ensure the document's width matches it.
|
561
|
-
if (cm.display.maxLineChanged && !cm.options.lineWrapping)
|
562
|
-
adjustContentWidth(cm);
|
563
|
-
|
564
|
-
var barMeasure = measureForScrollbars(cm);
|
565
|
-
updateSelection(cm);
|
566
|
-
setDocumentHeight(cm, barMeasure);
|
567
|
-
updateScrollbars(cm, barMeasure);
|
568
|
-
if (webkit && cm.options.lineWrapping)
|
569
|
-
checkForWebkitWidthBug(cm, barMeasure); // (Issue #2420)
|
570
|
-
if (webkit && barMeasure.scrollWidth > barMeasure.clientWidth &&
|
571
|
-
barMeasure.scrollWidth < barMeasure.clientWidth + 1 &&
|
572
|
-
!hScrollbarTakesSpace(cm))
|
573
|
-
updateScrollbars(cm); // (Issue #2562)
|
574
|
-
if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {
|
575
|
-
forced = true;
|
576
|
-
continue;
|
577
|
-
}
|
578
|
-
forced = false;
|
579
|
-
|
580
|
-
// Clip forced viewport to actual scrollable area.
|
581
|
-
if (viewPort && viewPort.top != null)
|
582
|
-
viewPort = {top: Math.min(barMeasure.docHeight - scrollerCutOff - barMeasure.clientHeight, viewPort.top)};
|
583
|
-
// Updated line heights might result in the drawn area not
|
584
|
-
// actually covering the viewport. Keep looping until it does.
|
585
|
-
visible = visibleLines(cm.display, cm.doc, viewPort);
|
586
|
-
if (visible.from >= cm.display.viewFrom && visible.to <= cm.display.viewTo)
|
587
|
-
break;
|
588
|
-
}
|
547
|
+
function DisplayUpdate(cm, viewport, force) {
|
548
|
+
var display = cm.display;
|
589
549
|
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
550
|
+
this.viewport = viewport;
|
551
|
+
// Store some values that we'll need later (but don't want to force a relayout for)
|
552
|
+
this.visible = visibleLines(display, cm.doc, viewport);
|
553
|
+
this.editorIsHidden = !display.wrapper.offsetWidth;
|
554
|
+
this.wrapperHeight = display.wrapper.clientHeight;
|
555
|
+
this.oldViewFrom = display.viewFrom; this.oldViewTo = display.viewTo;
|
556
|
+
this.oldScrollerWidth = display.scroller.clientWidth;
|
557
|
+
this.force = force;
|
558
|
+
this.dims = getDimensions(cm);
|
597
559
|
}
|
598
560
|
|
599
561
|
// Does the actual updating of the line display. Bails out
|
600
562
|
// (returning false) when there is nothing to be done and forced is
|
601
563
|
// false.
|
602
|
-
function
|
564
|
+
function updateDisplayIfNeeded(cm, update) {
|
603
565
|
var display = cm.display, doc = cm.doc;
|
604
|
-
if (
|
566
|
+
if (update.editorIsHidden) {
|
605
567
|
resetView(cm);
|
606
|
-
return;
|
568
|
+
return false;
|
607
569
|
}
|
608
570
|
|
609
571
|
// Bail out if the visible area is already rendered and nothing changed.
|
610
|
-
if (!
|
572
|
+
if (!update.force &&
|
573
|
+
update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
|
611
574
|
(display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
|
612
575
|
countDirtyView(cm) == 0)
|
613
|
-
return;
|
576
|
+
return false;
|
614
577
|
|
615
|
-
if (maybeUpdateLineNumberWidth(cm))
|
578
|
+
if (maybeUpdateLineNumberWidth(cm)) {
|
616
579
|
resetView(cm);
|
617
|
-
|
580
|
+
update.dims = getDimensions(cm);
|
581
|
+
}
|
618
582
|
|
619
583
|
// Compute a suitable new viewport (from & to)
|
620
584
|
var end = doc.first + doc.size;
|
621
|
-
var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
|
622
|
-
var to = Math.min(end, visible.to + cm.options.viewportMargin);
|
585
|
+
var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
|
586
|
+
var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
|
623
587
|
if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
|
624
588
|
if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
|
625
589
|
if (sawCollapsedSpans) {
|
@@ -628,7 +592,7 @@
|
|
628
592
|
}
|
629
593
|
|
630
594
|
var different = from != display.viewFrom || to != display.viewTo ||
|
631
|
-
display.lastSizeC !=
|
595
|
+
display.lastSizeC != update.wrapperHeight;
|
632
596
|
adjustView(cm, from, to);
|
633
597
|
|
634
598
|
display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
|
@@ -636,13 +600,15 @@
|
|
636
600
|
cm.display.mover.style.top = display.viewOffset + "px";
|
637
601
|
|
638
602
|
var toUpdate = countDirtyView(cm);
|
639
|
-
if (!different && toUpdate == 0 && !
|
603
|
+
if (!different && toUpdate == 0 && !update.force &&
|
604
|
+
(display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
|
605
|
+
return false;
|
640
606
|
|
641
607
|
// For big changes, we hide the enclosing element during the
|
642
608
|
// update, since that speeds up the operations on most browsers.
|
643
609
|
var focused = activeElt();
|
644
610
|
if (toUpdate > 4) display.lineDiv.style.display = "none";
|
645
|
-
patchDisplay(cm, display.updateLineNumbers, dims);
|
611
|
+
patchDisplay(cm, display.updateLineNumbers, update.dims);
|
646
612
|
if (toUpdate > 4) display.lineDiv.style.display = "";
|
647
613
|
// There might have been a widget with a focused element that got
|
648
614
|
// hidden or updated, if so re-focus it.
|
@@ -654,24 +620,54 @@
|
|
654
620
|
removeChildren(display.selectionDiv);
|
655
621
|
|
656
622
|
if (different) {
|
657
|
-
display.lastSizeC =
|
623
|
+
display.lastSizeC = update.wrapperHeight;
|
658
624
|
startWorker(cm, 400);
|
659
625
|
}
|
660
626
|
|
661
|
-
|
627
|
+
display.updateLineNumbers = null;
|
662
628
|
|
663
629
|
return true;
|
664
630
|
}
|
665
631
|
|
666
|
-
function
|
667
|
-
var
|
668
|
-
var
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
632
|
+
function postUpdateDisplay(cm, update) {
|
633
|
+
var force = update.force, viewport = update.viewport;
|
634
|
+
for (var first = true;; first = false) {
|
635
|
+
if (first && cm.options.lineWrapping && update.oldScrollerWidth != cm.display.scroller.clientWidth) {
|
636
|
+
force = true;
|
637
|
+
} else {
|
638
|
+
force = false;
|
639
|
+
// Clip forced viewport to actual scrollable area.
|
640
|
+
if (viewport && viewport.top != null)
|
641
|
+
viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - scrollerCutOff -
|
642
|
+
cm.display.scroller.clientHeight, viewport.top)};
|
643
|
+
// Updated line heights might result in the drawn area not
|
644
|
+
// actually covering the viewport. Keep looping until it does.
|
645
|
+
update.visible = visibleLines(cm.display, cm.doc, viewport);
|
646
|
+
if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
|
647
|
+
break;
|
648
|
+
}
|
649
|
+
if (!updateDisplayIfNeeded(cm, update)) break;
|
650
|
+
updateHeightsInViewport(cm);
|
651
|
+
var barMeasure = measureForScrollbars(cm);
|
652
|
+
updateSelection(cm);
|
653
|
+
setDocumentHeight(cm, barMeasure);
|
654
|
+
updateScrollbars(cm, barMeasure);
|
655
|
+
}
|
656
|
+
|
657
|
+
signalLater(cm, "update", cm);
|
658
|
+
if (cm.display.viewFrom != update.oldViewFrom || cm.display.viewTo != update.oldViewTo)
|
659
|
+
signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
|
660
|
+
}
|
661
|
+
|
662
|
+
function updateDisplaySimple(cm, viewport) {
|
663
|
+
var update = new DisplayUpdate(cm, viewport);
|
664
|
+
if (updateDisplayIfNeeded(cm, update)) {
|
665
|
+
postUpdateDisplay(cm, update);
|
666
|
+
var barMeasure = measureForScrollbars(cm);
|
667
|
+
updateSelection(cm);
|
668
|
+
setDocumentHeight(cm, barMeasure);
|
669
|
+
updateScrollbars(cm, barMeasure);
|
670
|
+
}
|
675
671
|
}
|
676
672
|
|
677
673
|
function setDocumentHeight(cm, measure) {
|
@@ -1257,10 +1253,10 @@
|
|
1257
1253
|
// SELECTION DRAWING
|
1258
1254
|
|
1259
1255
|
// Redraw the selection and/or cursor
|
1260
|
-
function
|
1261
|
-
var display = cm.display, doc = cm.doc;
|
1262
|
-
var curFragment = document.createDocumentFragment();
|
1263
|
-
var selFragment = document.createDocumentFragment();
|
1256
|
+
function drawSelection(cm) {
|
1257
|
+
var display = cm.display, doc = cm.doc, result = {};
|
1258
|
+
var curFragment = result.cursors = document.createDocumentFragment();
|
1259
|
+
var selFragment = result.selection = document.createDocumentFragment();
|
1264
1260
|
|
1265
1261
|
for (var i = 0; i < doc.sel.ranges.length; i++) {
|
1266
1262
|
var range = doc.sel.ranges[i];
|
@@ -1275,16 +1271,23 @@
|
|
1275
1271
|
if (cm.options.moveInputWithCursor) {
|
1276
1272
|
var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
|
1277
1273
|
var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
display.inputDiv.style.top = top + "px";
|
1283
|
-
display.inputDiv.style.left = left + "px";
|
1274
|
+
result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
|
1275
|
+
headPos.top + lineOff.top - wrapOff.top));
|
1276
|
+
result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
|
1277
|
+
headPos.left + lineOff.left - wrapOff.left));
|
1284
1278
|
}
|
1285
1279
|
|
1286
|
-
|
1287
|
-
|
1280
|
+
return result;
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
function updateSelection(cm, drawn) {
|
1284
|
+
if (!drawn) drawn = drawSelection(cm);
|
1285
|
+
removeChildrenAndAdd(cm.display.cursorDiv, drawn.cursors);
|
1286
|
+
removeChildrenAndAdd(cm.display.selectionDiv, drawn.selection);
|
1287
|
+
if (drawn.teTop != null) {
|
1288
|
+
cm.display.inputDiv.style.top = drawn.teTop + "px";
|
1289
|
+
cm.display.inputDiv.style.left = drawn.teLeft + "px";
|
1290
|
+
}
|
1288
1291
|
}
|
1289
1292
|
|
1290
1293
|
// Draws a cursor for the given range
|
@@ -1408,8 +1411,8 @@
|
|
1408
1411
|
if (doc.frontier >= cm.display.viewTo) return;
|
1409
1412
|
var end = +new Date + cm.options.workTime;
|
1410
1413
|
var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
|
1414
|
+
var changedLines = [];
|
1411
1415
|
|
1412
|
-
runInOp(cm, function() {
|
1413
1416
|
doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
|
1414
1417
|
if (doc.frontier >= cm.display.viewFrom) { // Visible
|
1415
1418
|
var oldStyles = line.styles;
|
@@ -1421,7 +1424,7 @@
|
|
1421
1424
|
var ischange = !oldStyles || oldStyles.length != line.styles.length ||
|
1422
1425
|
oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
|
1423
1426
|
for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
|
1424
|
-
if (ischange)
|
1427
|
+
if (ischange) changedLines.push(doc.frontier);
|
1425
1428
|
line.stateAfter = copyState(doc.mode, state);
|
1426
1429
|
} else {
|
1427
1430
|
processLine(cm, line.text, state);
|
@@ -1433,6 +1436,9 @@
|
|
1433
1436
|
return true;
|
1434
1437
|
}
|
1435
1438
|
});
|
1439
|
+
if (changedLines.length) runInOp(cm, function() {
|
1440
|
+
for (var i = 0; i < changedLines.length; i++)
|
1441
|
+
regLineChange(cm, changedLines[i], "text");
|
1436
1442
|
});
|
1437
1443
|
}
|
1438
1444
|
|
@@ -1665,6 +1671,8 @@
|
|
1665
1671
|
rect = nullRect;
|
1666
1672
|
}
|
1667
1673
|
|
1674
|
+
if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect);
|
1675
|
+
|
1668
1676
|
var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
|
1669
1677
|
var mid = (rtop + rbot) / 2;
|
1670
1678
|
var heights = prepared.view.measure.heights;
|
@@ -1676,9 +1684,22 @@
|
|
1676
1684
|
top: top, bottom: bot};
|
1677
1685
|
if (!rect.left && !rect.right) result.bogus = true;
|
1678
1686
|
if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
|
1687
|
+
|
1679
1688
|
return result;
|
1680
1689
|
}
|
1681
1690
|
|
1691
|
+
// Work around problem with bounding client rects on ranges being
|
1692
|
+
// returned incorrectly when zoomed on IE10 and below.
|
1693
|
+
function maybeUpdateRectForZooming(measure, rect) {
|
1694
|
+
if (!window.screen || screen.logicalXDPI == null ||
|
1695
|
+
screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
|
1696
|
+
return rect;
|
1697
|
+
var scaleX = screen.logicalXDPI / screen.deviceXDPI;
|
1698
|
+
var scaleY = screen.logicalYDPI / screen.deviceYDPI;
|
1699
|
+
return {left: rect.left * scaleX, right: rect.right * scaleX,
|
1700
|
+
top: rect.top * scaleY, bottom: rect.bottom * scaleY};
|
1701
|
+
}
|
1702
|
+
|
1682
1703
|
function clearLineMeasurementCacheFor(lineView) {
|
1683
1704
|
if (lineView.measure) {
|
1684
1705
|
lineView.measure.cache = {};
|
@@ -1911,10 +1932,13 @@
|
|
1911
1932
|
// error-prone). Instead, display updates are batched and then all
|
1912
1933
|
// combined and executed at once.
|
1913
1934
|
|
1935
|
+
var operationGroup = null;
|
1936
|
+
|
1914
1937
|
var nextOpId = 0;
|
1915
1938
|
// Start a new operation.
|
1916
1939
|
function startOperation(cm) {
|
1917
1940
|
cm.curOp = {
|
1941
|
+
cm: cm,
|
1918
1942
|
viewChanged: false, // Flag that indicates that lines might need to be redrawn
|
1919
1943
|
startHeight: cm.doc.height, // Used to detect need to update scrollbar
|
1920
1944
|
forceUpdate: false, // Used to force a redraw
|
@@ -1922,33 +1946,129 @@
|
|
1922
1946
|
typing: false, // Whether this reset should be careful to leave existing text (for compositing)
|
1923
1947
|
changeObjs: null, // Accumulated changes, for firing change events
|
1924
1948
|
cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
|
1949
|
+
cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
|
1925
1950
|
selectionChanged: false, // Whether the selection needs to be redrawn
|
1926
1951
|
updateMaxLine: false, // Set when the widest line needs to be determined anew
|
1927
1952
|
scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
|
1928
1953
|
scrollToPos: null, // Used to scroll to a specific position
|
1929
1954
|
id: ++nextOpId // Unique ID
|
1930
1955
|
};
|
1931
|
-
if (
|
1956
|
+
if (operationGroup) {
|
1957
|
+
operationGroup.ops.push(cm.curOp);
|
1958
|
+
} else {
|
1959
|
+
cm.curOp.ownsGroup = operationGroup = {
|
1960
|
+
ops: [cm.curOp],
|
1961
|
+
delayedCallbacks: []
|
1962
|
+
};
|
1963
|
+
}
|
1964
|
+
}
|
1965
|
+
|
1966
|
+
function fireCallbacksForOps(group) {
|
1967
|
+
// Calls delayed callbacks and cursorActivity handlers until no
|
1968
|
+
// new ones appear
|
1969
|
+
var callbacks = group.delayedCallbacks, i = 0;
|
1970
|
+
do {
|
1971
|
+
for (; i < callbacks.length; i++)
|
1972
|
+
callbacks[i]();
|
1973
|
+
for (var j = 0; j < group.ops.length; j++) {
|
1974
|
+
var op = group.ops[j];
|
1975
|
+
if (op.cursorActivityHandlers)
|
1976
|
+
while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
|
1977
|
+
op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);
|
1978
|
+
}
|
1979
|
+
} while (i < callbacks.length);
|
1932
1980
|
}
|
1933
1981
|
|
1934
1982
|
// Finish an operation, updating the display and signalling delayed events
|
1935
1983
|
function endOperation(cm) {
|
1936
|
-
var op = cm.curOp,
|
1937
|
-
|
1938
|
-
|
1984
|
+
var op = cm.curOp, group = op.ownsGroup;
|
1985
|
+
if (!group) return;
|
1986
|
+
|
1987
|
+
try { fireCallbacksForOps(group); }
|
1988
|
+
finally {
|
1989
|
+
operationGroup = null;
|
1990
|
+
for (var i = 0; i < group.ops.length; i++)
|
1991
|
+
group.ops[i].cm.curOp = null;
|
1992
|
+
endOperations(group);
|
1993
|
+
}
|
1994
|
+
}
|
1995
|
+
|
1996
|
+
// The DOM updates done when an operation finishes are batched so
|
1997
|
+
// that the minimum number of relayouts are required.
|
1998
|
+
function endOperations(group) {
|
1999
|
+
var ops = group.ops;
|
2000
|
+
for (var i = 0; i < ops.length; i++) // Read DOM
|
2001
|
+
endOperation_R1(ops[i]);
|
2002
|
+
for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
|
2003
|
+
endOperation_W1(ops[i]);
|
2004
|
+
for (var i = 0; i < ops.length; i++) // Read DOM
|
2005
|
+
endOperation_R2(ops[i]);
|
2006
|
+
for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
|
2007
|
+
endOperation_W2(ops[i]);
|
2008
|
+
for (var i = 0; i < ops.length; i++) // Read DOM
|
2009
|
+
endOperation_finish(ops[i]);
|
2010
|
+
}
|
2011
|
+
|
2012
|
+
function endOperation_R1(op) {
|
2013
|
+
var cm = op.cm, display = cm.display;
|
1939
2014
|
if (op.updateMaxLine) findMaxLine(cm);
|
1940
2015
|
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
2016
|
+
op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
|
2017
|
+
op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
|
2018
|
+
op.scrollToPos.to.line >= display.viewTo) ||
|
2019
|
+
display.maxLineChanged && cm.options.lineWrapping;
|
2020
|
+
op.update = op.mustUpdate &&
|
2021
|
+
new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
|
2022
|
+
}
|
2023
|
+
|
2024
|
+
function endOperation_W1(op) {
|
2025
|
+
op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
|
2026
|
+
}
|
2027
|
+
|
2028
|
+
function endOperation_R2(op) {
|
2029
|
+
var cm = op.cm, display = cm.display;
|
2030
|
+
if (op.updatedDisplay) updateHeightsInViewport(cm);
|
2031
|
+
|
2032
|
+
// If the max line changed since it was last measured, measure it,
|
2033
|
+
// and ensure the document's width matches it.
|
2034
|
+
// updateDisplayIfNeeded will use these properties to do the actual resizing
|
2035
|
+
if (display.maxLineChanged && !cm.options.lineWrapping) {
|
2036
|
+
op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left;
|
2037
|
+
op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo +
|
2038
|
+
scrollerCutOff - display.scroller.clientWidth);
|
2039
|
+
}
|
2040
|
+
|
2041
|
+
op.barMeasure = measureForScrollbars(cm);
|
2042
|
+
if (op.updatedDisplay || op.selectionChanged)
|
2043
|
+
op.newSelectionNodes = drawSelection(cm);
|
2044
|
+
}
|
2045
|
+
|
2046
|
+
function endOperation_W2(op) {
|
2047
|
+
var cm = op.cm;
|
2048
|
+
|
2049
|
+
if (op.adjustWidthTo != null) {
|
2050
|
+
cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
|
2051
|
+
if (op.maxScrollLeft < cm.doc.scrollLeft)
|
2052
|
+
setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true);
|
1948
2053
|
}
|
1949
|
-
|
1950
|
-
if (
|
1951
|
-
|
2054
|
+
|
2055
|
+
if (op.newSelectionNodes)
|
2056
|
+
updateSelection(cm, op.newSelectionNodes);
|
2057
|
+
if (op.updatedDisplay)
|
2058
|
+
setDocumentHeight(cm, op.barMeasure);
|
2059
|
+
if (op.updatedDisplay || op.startHeight != cm.doc.height)
|
2060
|
+
updateScrollbars(cm, op.barMeasure);
|
2061
|
+
|
2062
|
+
if (op.selectionChanged) restartBlink(cm);
|
2063
|
+
|
2064
|
+
if (cm.state.focused && op.updateInput)
|
2065
|
+
resetInput(cm, op.typing);
|
2066
|
+
}
|
2067
|
+
|
2068
|
+
function endOperation_finish(op) {
|
2069
|
+
var cm = op.cm, display = cm.display, doc = cm.doc;
|
2070
|
+
|
2071
|
+
if (op.updatedDisplay) postUpdateDisplay(cm, op.update);
|
1952
2072
|
|
1953
2073
|
// Abort mouse wheel delta measurement, when scrolling explicitly
|
1954
2074
|
if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
|
@@ -1966,16 +2086,11 @@
|
|
1966
2086
|
}
|
1967
2087
|
// If we need to scroll a specific position into view, do so.
|
1968
2088
|
if (op.scrollToPos) {
|
1969
|
-
var coords = scrollPosIntoView(cm, clipPos(
|
1970
|
-
clipPos(
|
2089
|
+
var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
|
2090
|
+
clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
|
1971
2091
|
if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);
|
1972
2092
|
}
|
1973
2093
|
|
1974
|
-
if (op.selectionChanged) restartBlink(cm);
|
1975
|
-
|
1976
|
-
if (cm.state.focused && op.updateInput)
|
1977
|
-
resetInput(cm, op.typing);
|
1978
|
-
|
1979
2094
|
// Fire events for markers that are hidden/unidden by editing or
|
1980
2095
|
// undoing
|
1981
2096
|
var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
|
@@ -1984,18 +2099,22 @@
|
|
1984
2099
|
if (unhidden) for (var i = 0; i < unhidden.length; ++i)
|
1985
2100
|
if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
|
1986
2101
|
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
2102
|
+
if (display.wrapper.offsetHeight)
|
2103
|
+
doc.scrollTop = cm.display.scroller.scrollTop;
|
2104
|
+
|
2105
|
+
// Apply workaround for two webkit bugs
|
2106
|
+
if (op.updatedDisplay && webkit) {
|
2107
|
+
if (cm.options.lineWrapping)
|
2108
|
+
checkForWebkitWidthBug(cm, op.barMeasure); // (Issue #2420)
|
2109
|
+
if (op.barMeasure.scrollWidth > op.barMeasure.clientWidth &&
|
2110
|
+
op.barMeasure.scrollWidth < op.barMeasure.clientWidth + 1 &&
|
2111
|
+
!hScrollbarTakesSpace(cm))
|
2112
|
+
updateScrollbars(cm); // (Issue #2562)
|
1991
2113
|
}
|
2114
|
+
|
1992
2115
|
// Fire change events, and delayed event handlers
|
1993
2116
|
if (op.changeObjs)
|
1994
2117
|
signal(cm, "changes", cm, op.changeObjs);
|
1995
|
-
if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
|
1996
|
-
if (op.cursorActivityHandlers)
|
1997
|
-
for (var i = 0; i < op.cursorActivityHandlers.length; i++)
|
1998
|
-
op.cursorActivityHandlers[i](cm);
|
1999
2118
|
}
|
2000
2119
|
|
2001
2120
|
// Run the given function in an operation
|
@@ -2247,6 +2366,11 @@
|
|
2247
2366
|
cm.display.poll.set(20, p);
|
2248
2367
|
}
|
2249
2368
|
|
2369
|
+
// This will be set to an array of strings when copying, so that,
|
2370
|
+
// when pasting, we know what kind of selections the copied text
|
2371
|
+
// was made out of.
|
2372
|
+
var lastCopied = null;
|
2373
|
+
|
2250
2374
|
// Read input from the textarea, and update the document to match.
|
2251
2375
|
// When something is selected, it is present in the textarea, and
|
2252
2376
|
// selected (unless it is huge, in which case a placeholder is
|
@@ -2269,8 +2393,11 @@
|
|
2269
2393
|
var text = input.value;
|
2270
2394
|
// If nothing changed, bail.
|
2271
2395
|
if (text == prevInput && !cm.somethingSelected()) return false;
|
2272
|
-
// Work around nonsensical selection resetting in IE9/10
|
2273
|
-
|
2396
|
+
// Work around nonsensical selection resetting in IE9/10, and
|
2397
|
+
// inexplicable appearance of private area unicode characters on
|
2398
|
+
// some key combos in Mac (#2689).
|
2399
|
+
if (ie && ie_version >= 9 && cm.display.inputHasSelection === text ||
|
2400
|
+
mac && /[\uf700-\uf7ff]/.test(text)) {
|
2274
2401
|
resetInput(cm);
|
2275
2402
|
return false;
|
2276
2403
|
}
|
@@ -2287,7 +2414,13 @@
|
|
2287
2414
|
var inserted = text.slice(same), textLines = splitLines(inserted);
|
2288
2415
|
|
2289
2416
|
// When pasing N lines into N selections, insert one line per selection
|
2290
|
-
var multiPaste =
|
2417
|
+
var multiPaste = null;
|
2418
|
+
if (cm.state.pasteIncoming && doc.sel.ranges.length > 1) {
|
2419
|
+
if (lastCopied && lastCopied.join("\n") == inserted)
|
2420
|
+
multiPaste = doc.sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);
|
2421
|
+
else if (textLines.length == doc.sel.ranges.length)
|
2422
|
+
multiPaste = map(textLines, function(l) { return [l]; });
|
2423
|
+
}
|
2291
2424
|
|
2292
2425
|
// Normal behavior is to insert the new text into every selection
|
2293
2426
|
for (var i = doc.sel.ranges.length - 1; i >= 0; i--) {
|
@@ -2300,7 +2433,7 @@
|
|
2300
2433
|
else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming)
|
2301
2434
|
to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
|
2302
2435
|
var updateInput = cm.curOp.updateInput;
|
2303
|
-
var changeEvent = {from: from, to: to, text: multiPaste ? [
|
2436
|
+
var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
|
2304
2437
|
origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"};
|
2305
2438
|
makeChange(cm.doc, changeEvent);
|
2306
2439
|
signalLater(cm, "inputRead", cm, changeEvent);
|
@@ -2421,7 +2554,7 @@
|
|
2421
2554
|
// Prevent wrapper from ever scrolling
|
2422
2555
|
on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
|
2423
2556
|
|
2424
|
-
on(d.input, "keyup",
|
2557
|
+
on(d.input, "keyup", function(e) { onKeyUp.call(cm, e); });
|
2425
2558
|
on(d.input, "input", function() {
|
2426
2559
|
if (ie && ie_version >= 9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
|
2427
2560
|
fastPoll(cm);
|
@@ -2467,27 +2600,29 @@
|
|
2467
2600
|
|
2468
2601
|
function prepareCopyCut(e) {
|
2469
2602
|
if (cm.somethingSelected()) {
|
2603
|
+
lastCopied = cm.getSelections();
|
2470
2604
|
if (d.inaccurateSelection) {
|
2471
2605
|
d.prevInput = "";
|
2472
2606
|
d.inaccurateSelection = false;
|
2473
|
-
d.input.value =
|
2607
|
+
d.input.value = lastCopied.join("\n");
|
2474
2608
|
selectInput(d.input);
|
2475
2609
|
}
|
2476
2610
|
} else {
|
2477
|
-
var text =
|
2611
|
+
var text = [], ranges = [];
|
2478
2612
|
for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
|
2479
2613
|
var line = cm.doc.sel.ranges[i].head.line;
|
2480
2614
|
var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
|
2481
2615
|
ranges.push(lineRange);
|
2482
|
-
text
|
2616
|
+
text.push(cm.getRange(lineRange.anchor, lineRange.head));
|
2483
2617
|
}
|
2484
2618
|
if (e.type == "cut") {
|
2485
2619
|
cm.setSelections(ranges, null, sel_dontScroll);
|
2486
2620
|
} else {
|
2487
2621
|
d.prevInput = "";
|
2488
|
-
d.input.value = text;
|
2622
|
+
d.input.value = text.join("\n");
|
2489
2623
|
selectInput(d.input);
|
2490
2624
|
}
|
2625
|
+
lastCopied = text;
|
2491
2626
|
}
|
2492
2627
|
if (e.type == "cut") cm.state.cutIncoming = true;
|
2493
2628
|
}
|
@@ -2885,10 +3020,10 @@
|
|
2885
3020
|
function setScrollTop(cm, val) {
|
2886
3021
|
if (Math.abs(cm.doc.scrollTop - val) < 2) return;
|
2887
3022
|
cm.doc.scrollTop = val;
|
2888
|
-
if (!gecko)
|
3023
|
+
if (!gecko) updateDisplaySimple(cm, {top: val});
|
2889
3024
|
if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
|
2890
3025
|
if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
|
2891
|
-
if (gecko)
|
3026
|
+
if (gecko) updateDisplaySimple(cm);
|
2892
3027
|
startWorker(cm, 100);
|
2893
3028
|
}
|
2894
3029
|
// Sync scroller and scrollbar, ensure the gutter elements are
|
@@ -2971,7 +3106,7 @@
|
|
2971
3106
|
var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
|
2972
3107
|
if (pixels < 0) top = Math.max(0, top + pixels - 50);
|
2973
3108
|
else bot = Math.min(cm.doc.height, bot + pixels + 50);
|
2974
|
-
|
3109
|
+
updateDisplaySimple(cm, {top: top, bottom: bot});
|
2975
3110
|
}
|
2976
3111
|
|
2977
3112
|
if (wheelSamples < 20) {
|
@@ -3114,13 +3249,13 @@
|
|
3114
3249
|
}
|
3115
3250
|
|
3116
3251
|
function onKeyUp(e) {
|
3117
|
-
if (signalDOMEvent(this, e)) return;
|
3118
3252
|
if (e.keyCode == 16) this.doc.sel.shift = false;
|
3253
|
+
signalDOMEvent(this, e);
|
3119
3254
|
}
|
3120
3255
|
|
3121
3256
|
function onKeyPress(e) {
|
3122
3257
|
var cm = this;
|
3123
|
-
if (signalDOMEvent(cm, e) || e.ctrlKey || mac && e.metaKey) return;
|
3258
|
+
if (signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;
|
3124
3259
|
var keyCode = e.keyCode, charCode = e.charCode;
|
3125
3260
|
if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
|
3126
3261
|
if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
|
@@ -3184,7 +3319,9 @@
|
|
3184
3319
|
"px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
|
3185
3320
|
(ie ? "rgba(255, 255, 255, .05)" : "transparent") +
|
3186
3321
|
"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
|
3322
|
+
if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
|
3187
3323
|
focusInput(cm);
|
3324
|
+
if (webkit) window.scrollTo(null, oldScrollY);
|
3188
3325
|
resetInput(cm);
|
3189
3326
|
// Adds "Select all" to context menu in FF
|
3190
3327
|
if (!cm.somethingSelected()) display.input.value = display.prevInput = " ";
|
@@ -3414,7 +3551,7 @@
|
|
3414
3551
|
|
3415
3552
|
antiChanges.push(historyChangeFromChange(doc, change));
|
3416
3553
|
|
3417
|
-
var after = i ? computeSelAfterChange(doc, change
|
3554
|
+
var after = i ? computeSelAfterChange(doc, change) : lst(source);
|
3418
3555
|
makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
|
3419
3556
|
if (!i && doc.cm) doc.cm.scrollIntoView(change);
|
3420
3557
|
var rebased = [];
|
@@ -3473,7 +3610,7 @@
|
|
3473
3610
|
|
3474
3611
|
change.removed = getBetween(doc, change.from, change.to);
|
3475
3612
|
|
3476
|
-
if (!selAfter) selAfter = computeSelAfterChange(doc, change
|
3613
|
+
if (!selAfter) selAfter = computeSelAfterChange(doc, change);
|
3477
3614
|
if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);
|
3478
3615
|
else updateDoc(doc, change, spans);
|
3479
3616
|
setSelectionNoUndo(doc, selAfter, sel_dontScroll);
|
@@ -3680,7 +3817,7 @@
|
|
3680
3817
|
if (how == "smart") {
|
3681
3818
|
// Fall back to "prev" when the mode doesn't have an indentation
|
3682
3819
|
// method.
|
3683
|
-
if (!
|
3820
|
+
if (!doc.mode.indent) how = "prev";
|
3684
3821
|
else state = getStateBefore(cm, n);
|
3685
3822
|
}
|
3686
3823
|
|
@@ -3692,8 +3829,8 @@
|
|
3692
3829
|
indentation = 0;
|
3693
3830
|
how = "not";
|
3694
3831
|
} else if (how == "smart") {
|
3695
|
-
indentation =
|
3696
|
-
if (indentation == Pass) {
|
3832
|
+
indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
|
3833
|
+
if (indentation == Pass || indentation > 150) {
|
3697
3834
|
if (!aggressive) return;
|
3698
3835
|
how = "prev";
|
3699
3836
|
}
|
@@ -3716,7 +3853,7 @@
|
|
3716
3853
|
if (pos < indentation) indentString += spaceStr(indentation - pos);
|
3717
3854
|
|
3718
3855
|
if (indentString != curSpaceString) {
|
3719
|
-
replaceRange(
|
3856
|
+
replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
|
3720
3857
|
} else {
|
3721
3858
|
// Ensure that, if the cursor was in the whitespace at the start
|
3722
3859
|
// of the line, it is moved to the end of that space.
|
@@ -4133,7 +4270,7 @@
|
|
4133
4270
|
|
4134
4271
|
triggerOnKeyDown: methodOp(onKeyDown),
|
4135
4272
|
triggerOnKeyPress: methodOp(onKeyPress),
|
4136
|
-
triggerOnKeyUp:
|
4273
|
+
triggerOnKeyUp: onKeyUp,
|
4137
4274
|
|
4138
4275
|
execCommand: function(cmd) {
|
4139
4276
|
if (commands.hasOwnProperty(cmd))
|
@@ -4568,6 +4705,20 @@
|
|
4568
4705
|
return {from: Pos(range.from().line, 0), to: range.from()};
|
4569
4706
|
});
|
4570
4707
|
},
|
4708
|
+
delWrappedLineLeft: function(cm) {
|
4709
|
+
deleteNearSelection(cm, function(range) {
|
4710
|
+
var top = cm.charCoords(range.head, "div").top + 5;
|
4711
|
+
var leftPos = cm.coordsChar({left: 0, top: top}, "div");
|
4712
|
+
return {from: leftPos, to: range.from()};
|
4713
|
+
});
|
4714
|
+
},
|
4715
|
+
delWrappedLineRight: function(cm) {
|
4716
|
+
deleteNearSelection(cm, function(range) {
|
4717
|
+
var top = cm.charCoords(range.head, "div").top + 5;
|
4718
|
+
var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
|
4719
|
+
return {from: range.from(), to: rightPos };
|
4720
|
+
});
|
4721
|
+
},
|
4571
4722
|
undo: function(cm) {cm.undo();},
|
4572
4723
|
redo: function(cm) {cm.redo();},
|
4573
4724
|
undoSelection: function(cm) {cm.undoSelection();},
|
@@ -4705,11 +4856,11 @@
|
|
4705
4856
|
};
|
4706
4857
|
keyMap.macDefault = {
|
4707
4858
|
"Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
|
4708
|
-
"Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
|
4709
|
-
"Alt-Right": "goGroupRight", "Cmd-Left": "
|
4859
|
+
"Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
|
4860
|
+
"Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
|
4710
4861
|
"Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
|
4711
4862
|
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
|
4712
|
-
"Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "
|
4863
|
+
"Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
|
4713
4864
|
"Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection",
|
4714
4865
|
fallthrough: ["basic", "emacsy"]
|
4715
4866
|
};
|
@@ -6960,6 +7111,8 @@
|
|
6960
7111
|
for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
|
6961
7112
|
};
|
6962
7113
|
|
7114
|
+
var orphanDelayedCallbacks = null;
|
7115
|
+
|
6963
7116
|
// Often, we want to signal events at a point where we are in the
|
6964
7117
|
// middle of some work, but don't want the handler to start calling
|
6965
7118
|
// other methods on the editor, which might be in an inconsistent
|
@@ -6967,25 +7120,26 @@
|
|
6967
7120
|
// signalLater looks whether there are any handlers, and schedules
|
6968
7121
|
// them to be executed when the last operation ends, or, if no
|
6969
7122
|
// operation is active, when a timeout fires.
|
6970
|
-
var delayedCallbacks, delayedCallbackDepth = 0;
|
6971
7123
|
function signalLater(emitter, type /*, values...*/) {
|
6972
7124
|
var arr = emitter._handlers && emitter._handlers[type];
|
6973
7125
|
if (!arr) return;
|
6974
|
-
var args = Array.prototype.slice.call(arguments, 2);
|
6975
|
-
if (
|
6976
|
-
|
6977
|
-
|
6978
|
-
|
7126
|
+
var args = Array.prototype.slice.call(arguments, 2), list;
|
7127
|
+
if (operationGroup) {
|
7128
|
+
list = operationGroup.delayedCallbacks;
|
7129
|
+
} else if (orphanDelayedCallbacks) {
|
7130
|
+
list = orphanDelayedCallbacks;
|
7131
|
+
} else {
|
7132
|
+
list = orphanDelayedCallbacks = [];
|
7133
|
+
setTimeout(fireOrphanDelayed, 0);
|
6979
7134
|
}
|
6980
7135
|
function bnd(f) {return function(){f.apply(null, args);};};
|
6981
7136
|
for (var i = 0; i < arr.length; ++i)
|
6982
|
-
|
7137
|
+
list.push(bnd(arr[i]));
|
6983
7138
|
}
|
6984
7139
|
|
6985
|
-
function
|
6986
|
-
|
6987
|
-
|
6988
|
-
delayedCallbacks = null;
|
7140
|
+
function fireOrphanDelayed() {
|
7141
|
+
var delayed = orphanDelayedCallbacks;
|
7142
|
+
orphanDelayedCallbacks = null;
|
6989
7143
|
for (var i = 0; i < delayed.length; ++i) delayed[i]();
|
6990
7144
|
}
|
6991
7145
|
|
@@ -7331,6 +7485,15 @@
|
|
7331
7485
|
return typeof e.oncopy == "function";
|
7332
7486
|
})();
|
7333
7487
|
|
7488
|
+
var badZoomedRects = null;
|
7489
|
+
function hasBadZoomedRects(measure) {
|
7490
|
+
if (badZoomedRects != null) return badZoomedRects;
|
7491
|
+
var node = removeChildrenAndAdd(measure, elt("span", "x"));
|
7492
|
+
var normal = node.getBoundingClientRect();
|
7493
|
+
var fromRange = range(node, 0, 1).getBoundingClientRect();
|
7494
|
+
return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1;
|
7495
|
+
}
|
7496
|
+
|
7334
7497
|
// KEY NAMES
|
7335
7498
|
|
7336
7499
|
var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
|
@@ -7632,7 +7795,7 @@
|
|
7632
7795
|
|
7633
7796
|
// THE END
|
7634
7797
|
|
7635
|
-
CodeMirror.version = "4.
|
7798
|
+
CodeMirror.version = "4.4.0";
|
7636
7799
|
|
7637
7800
|
return CodeMirror;
|
7638
7801
|
});
|