codemirror-rails 4.8 → 4.9
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.
- checksums.yaml +4 -4
- data/README.md +24 -6
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +289 -184
- data/vendor/assets/javascripts/codemirror/addons/dialog/dialog.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/display/panel.js +94 -0
- data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +4 -4
- data/vendor/assets/javascripts/codemirror/addons/hint/anyword-hint.js +1 -2
- data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/hint/html-hint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +8 -3
- data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +7 -4
- data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +3 -4
- data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +170 -63
- data/vendor/assets/javascripts/codemirror/addons/mode/simple.js +11 -8
- data/vendor/assets/javascripts/codemirror/addons/scroll/annotatescrollbar.js +76 -0
- data/vendor/assets/javascripts/codemirror/addons/scroll/simplescrollbars.js +139 -0
- data/vendor/assets/javascripts/codemirror/addons/search/matchesonscrollbar.js +90 -0
- data/vendor/assets/javascripts/codemirror/addons/search/search.js +9 -4
- data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +5 -3
- data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +25 -7
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +181 -109
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/commonlisp.js +5 -3
- data/vendor/assets/javascripts/codemirror/modes/cypher.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/dart.js +50 -0
- data/vendor/assets/javascripts/codemirror/modes/dockerfile.js +5 -9
- data/vendor/assets/javascripts/codemirror/modes/ebnf.js +195 -0
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +2 -0
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +3 -3
- data/vendor/assets/javascripts/codemirror/modes/puppet.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/shell.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/soy.js +198 -0
- data/vendor/assets/javascripts/codemirror/modes/spreadsheet.js +109 -0
- data/vendor/assets/javascripts/codemirror/modes/stex.js +4 -6
- data/vendor/assets/javascripts/codemirror/modes/textile.js +392 -476
- data/vendor/assets/javascripts/codemirror/modes/turtle.js +3 -1
- data/vendor/assets/stylesheets/codemirror.css +2 -11
- data/vendor/assets/stylesheets/codemirror/addons/merge/merge.css +14 -0
- data/vendor/assets/stylesheets/codemirror/addons/scroll/simplescrollbars.css +66 -0
- data/vendor/assets/stylesheets/codemirror/addons/search/matchesonscrollbar.css +8 -0
- data/vendor/assets/stylesheets/codemirror/themes/tomorrow-night-bright.css +35 -0
- data/vendor/assets/stylesheets/codemirror/themes/zenburn.css +37 -0
- metadata +14 -3
- data/vendor/assets/javascripts/codemirror/addons/hint/python-hint.js +0 -102
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 284033712dc0b2bfb8a7dfacbf9978310a1a9da2
|
4
|
+
data.tar.gz: 9e39f05137ce738d972d9d52f557671d0449d9a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b786c5741f9fa9638104a273b5b5b1c3c7791add1ff0b0f9720e5d9e50a05e733d06bbb2e9d1addcbf2f609240c7b2ccdc96cdcc28a854b2edaa15a631ce080e
|
7
|
+
data.tar.gz: 54801430f624d1651b225da319fcd972d7cf699f9954521ec735ad71690cc00f0b0fc5eb3578d090abb5d8799988f988bd2558c5157e2e3ea3ecaf1ddd03b9a2
|
data/README.md
CHANGED
@@ -21,12 +21,20 @@ gem install codemirror-rails
|
|
21
21
|
|
22
22
|
All of the assets from the most latest stable CodeMirror release are vendored
|
23
23
|
so that you can use them with the asset pipeline. At a minimum, you will
|
24
|
-
probably want the following in your application.js
|
24
|
+
probably want the following in your application.js:
|
25
25
|
|
26
26
|
```js
|
27
27
|
//= require codemirror
|
28
28
|
```
|
29
29
|
|
30
|
+
And in your application.css:
|
31
|
+
|
32
|
+
```css
|
33
|
+
/*
|
34
|
+
*= require codemirror
|
35
|
+
*/
|
36
|
+
```
|
37
|
+
|
30
38
|
### Adding a mode
|
31
39
|
|
32
40
|
Additional syntax modes can be added to your application.js:
|
@@ -35,12 +43,20 @@ Additional syntax modes can be added to your application.js:
|
|
35
43
|
//= require codemirror/modes/ruby
|
36
44
|
```
|
37
45
|
|
38
|
-
### Adding
|
46
|
+
### Adding an addon
|
39
47
|
|
40
|
-
Additional
|
48
|
+
Additional addons can be added in your application.js:
|
41
49
|
|
42
50
|
```js
|
43
|
-
//=
|
51
|
+
//= require_tree codemirror/addons/dialog
|
52
|
+
```
|
53
|
+
|
54
|
+
And your application.css:
|
55
|
+
|
56
|
+
```css
|
57
|
+
/*
|
58
|
+
*= require_tree codemirror/addons/dialog
|
59
|
+
*/
|
44
60
|
```
|
45
61
|
|
46
62
|
### Adding a keymap
|
@@ -55,8 +71,10 @@ Additional keymap bindings can be added to your application.js:
|
|
55
71
|
|
56
72
|
Additional CSS themes can be added to your application.css
|
57
73
|
|
58
|
-
```
|
59
|
-
|
74
|
+
```css
|
75
|
+
/*
|
76
|
+
*= require codemirror/themes/night
|
77
|
+
*/
|
60
78
|
```
|
61
79
|
|
62
80
|
### Precompiling Codemirror
|
@@ -77,6 +77,7 @@
|
|
77
77
|
if (options.lineWrapping)
|
78
78
|
this.display.wrapper.className += " CodeMirror-wrap";
|
79
79
|
if (options.autofocus && !mobile) focusInput(this);
|
80
|
+
initScrollbars(this);
|
80
81
|
|
81
82
|
this.state = {
|
82
83
|
keyMaps: [], // stores maps added by addKeyMap
|
@@ -137,14 +138,13 @@
|
|
137
138
|
|
138
139
|
// Wraps and hides input textarea
|
139
140
|
d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
|
140
|
-
// The fake scrollbar elements.
|
141
|
-
d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
|
142
|
-
d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
|
143
141
|
// Covers bottom-right square when both scrollbars are present.
|
144
142
|
d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
|
143
|
+
d.scrollbarFiller.setAttribute("not-content", "true");
|
145
144
|
// Covers bottom of gutter when coverGutterNextToScrollbar is on
|
146
145
|
// and h scrollbar is present.
|
147
146
|
d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
|
147
|
+
d.gutterFiller.setAttribute("not-content", "true");
|
148
148
|
// Will contain the actual code, positioned to cover the viewport.
|
149
149
|
d.lineDiv = elt("div", null, "CodeMirror-code");
|
150
150
|
// Elements are added to these to represent selection and cursors.
|
@@ -161,10 +161,11 @@
|
|
161
161
|
d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
|
162
162
|
// Set to the height of the document, allowing scrolling.
|
163
163
|
d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
|
164
|
+
d.sizerWidth = null;
|
164
165
|
// Behavior of elts with overflow: auto and padding is
|
165
166
|
// inconsistent across browsers. This is used to ensure the
|
166
167
|
// scrollable area is big enough.
|
167
|
-
d.heightForcer = elt("div", null, null, "position: absolute; height: " +
|
168
|
+
d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
|
168
169
|
// Will contain the gutters, if any.
|
169
170
|
d.gutters = elt("div", null, "CodeMirror-gutters");
|
170
171
|
d.lineGutter = null;
|
@@ -172,8 +173,7 @@
|
|
172
173
|
d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
|
173
174
|
d.scroller.setAttribute("tabIndex", "-1");
|
174
175
|
// The element in which the editor lives.
|
175
|
-
d.wrapper = elt("div", [d.inputDiv, d.
|
176
|
-
d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
|
176
|
+
d.wrapper = elt("div", [d.inputDiv, d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
|
177
177
|
|
178
178
|
// Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
|
179
179
|
if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
|
@@ -182,8 +182,6 @@
|
|
182
182
|
if (!webkit) d.scroller.draggable = true;
|
183
183
|
// Needed to handle Tab key in KHTML
|
184
184
|
if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
|
185
|
-
// Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
|
186
|
-
if (ie && ie_version < 8) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px";
|
187
185
|
|
188
186
|
if (place) {
|
189
187
|
if (place.appendChild) place.appendChild(d.wrapper);
|
@@ -192,8 +190,10 @@
|
|
192
190
|
|
193
191
|
// Current rendered range (may be bigger than the view window).
|
194
192
|
d.viewFrom = d.viewTo = doc.first;
|
193
|
+
d.reportedViewFrom = d.reportedViewTo = doc.first;
|
195
194
|
// Information about the rendered lines.
|
196
195
|
d.view = [];
|
196
|
+
d.renderedView = null;
|
197
197
|
// Holds info about a single rendered line when it was rendered
|
198
198
|
// for measurement, while not in view.
|
199
199
|
d.externalMeasured = null;
|
@@ -202,6 +202,9 @@
|
|
202
202
|
d.lastWrapHeight = d.lastWrapWidth = 0;
|
203
203
|
d.updateLineNumbers = null;
|
204
204
|
|
205
|
+
d.nativeBarWidth = d.barHeight = d.barWidth = 0;
|
206
|
+
d.scrollbarsClipped = false;
|
207
|
+
|
205
208
|
// Used to only resize the line number gutter when necessary (when
|
206
209
|
// the amount of lines crosses a boundary that makes its width change)
|
207
210
|
d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
|
@@ -265,6 +268,7 @@
|
|
265
268
|
if (cm.options.lineWrapping) {
|
266
269
|
addClass(cm.display.wrapper, "CodeMirror-wrap");
|
267
270
|
cm.display.sizer.style.minWidth = "";
|
271
|
+
cm.display.sizerWidth = null;
|
268
272
|
} else {
|
269
273
|
rmClass(cm.display.wrapper, "CodeMirror-wrap");
|
270
274
|
findMaxLine(cm);
|
@@ -336,7 +340,6 @@
|
|
336
340
|
function updateGutterSpace(cm) {
|
337
341
|
var width = cm.display.gutters.offsetWidth;
|
338
342
|
cm.display.sizer.style.marginLeft = width + "px";
|
339
|
-
cm.display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0;
|
340
343
|
}
|
341
344
|
|
342
345
|
// Compute the character length of a line, taking into account
|
@@ -389,78 +392,166 @@
|
|
389
392
|
|
390
393
|
// SCROLLBARS
|
391
394
|
|
392
|
-
function hScrollbarTakesSpace(cm) {
|
393
|
-
return cm.display.scroller.clientHeight - cm.display.wrapper.clientHeight < scrollerCutOff - 3;
|
394
|
-
}
|
395
|
-
|
396
395
|
// Prepare DOM reads needed to update the scrollbars. Done in one
|
397
396
|
// shot to minimize update/measure roundtrips.
|
398
397
|
function measureForScrollbars(cm) {
|
399
|
-
var
|
398
|
+
var d = cm.display, gutterW = d.gutters.offsetWidth;
|
399
|
+
var docH = Math.round(cm.doc.height + paddingVert(cm.display));
|
400
400
|
return {
|
401
|
-
clientHeight:
|
402
|
-
|
403
|
-
scrollWidth:
|
404
|
-
|
405
|
-
|
406
|
-
docHeight:
|
401
|
+
clientHeight: d.scroller.clientHeight,
|
402
|
+
viewHeight: d.wrapper.clientHeight,
|
403
|
+
scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
|
404
|
+
viewWidth: d.wrapper.clientWidth,
|
405
|
+
barLeft: cm.options.fixedGutter ? gutterW : 0,
|
406
|
+
docHeight: docH,
|
407
|
+
scrollHeight: docH + scrollGap(cm) + d.barHeight,
|
408
|
+
nativeBarWidth: d.nativeBarWidth,
|
409
|
+
gutterWidth: gutterW
|
407
410
|
};
|
408
411
|
}
|
409
412
|
|
410
|
-
|
411
|
-
|
413
|
+
function NativeScrollbars(place, scroll, cm) {
|
414
|
+
this.cm = cm;
|
415
|
+
var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
|
416
|
+
var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
|
417
|
+
place(vert); place(horiz);
|
418
|
+
|
419
|
+
on(vert, "scroll", function() {
|
420
|
+
if (vert.clientHeight) scroll(vert.scrollTop, "vertical");
|
421
|
+
});
|
422
|
+
on(horiz, "scroll", function() {
|
423
|
+
if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal");
|
424
|
+
});
|
425
|
+
|
426
|
+
this.checkedOverlay = false;
|
427
|
+
// Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
|
428
|
+
if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px";
|
429
|
+
}
|
430
|
+
|
431
|
+
NativeScrollbars.prototype = copyObj({
|
432
|
+
update: function(measure) {
|
433
|
+
var needsH = measure.scrollWidth > measure.clientWidth + 1;
|
434
|
+
var needsV = measure.scrollHeight > measure.clientHeight + 1;
|
435
|
+
var sWidth = measure.nativeBarWidth;
|
436
|
+
|
437
|
+
if (needsV) {
|
438
|
+
this.vert.style.display = "block";
|
439
|
+
this.vert.style.bottom = needsH ? sWidth + "px" : "0";
|
440
|
+
var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
|
441
|
+
// A bug in IE8 can cause this value to be negative, so guard it.
|
442
|
+
this.vert.firstChild.style.height =
|
443
|
+
Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
|
444
|
+
} else {
|
445
|
+
this.vert.style.display = "";
|
446
|
+
this.vert.firstChild.style.height = "0";
|
447
|
+
}
|
448
|
+
|
449
|
+
if (needsH) {
|
450
|
+
this.horiz.style.display = "block";
|
451
|
+
this.horiz.style.right = needsV ? sWidth + "px" : "0";
|
452
|
+
this.horiz.style.left = measure.barLeft + "px";
|
453
|
+
var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
|
454
|
+
this.horiz.firstChild.style.width =
|
455
|
+
(measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
|
456
|
+
} else {
|
457
|
+
this.horiz.style.display = "";
|
458
|
+
this.horiz.firstChild.style.width = "0";
|
459
|
+
}
|
460
|
+
|
461
|
+
if (!this.checkedOverlay && measure.clientHeight > 0) {
|
462
|
+
if (sWidth == 0) this.overlayHack();
|
463
|
+
this.checkedOverlay = true;
|
464
|
+
}
|
465
|
+
|
466
|
+
return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};
|
467
|
+
},
|
468
|
+
setScrollLeft: function(pos) {
|
469
|
+
if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
|
470
|
+
},
|
471
|
+
setScrollTop: function(pos) {
|
472
|
+
if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
|
473
|
+
},
|
474
|
+
overlayHack: function() {
|
475
|
+
var w = mac && !mac_geMountainLion ? "12px" : "18px";
|
476
|
+
this.horiz.style.minHeight = this.vert.style.minWidth = w;
|
477
|
+
var self = this;
|
478
|
+
var barMouseDown = function(e) {
|
479
|
+
if (e_target(e) != self.vert && e_target(e) != self.horiz)
|
480
|
+
operation(self.cm, onMouseDown)(e);
|
481
|
+
};
|
482
|
+
on(this.vert, "mousedown", barMouseDown);
|
483
|
+
on(this.horiz, "mousedown", barMouseDown);
|
484
|
+
},
|
485
|
+
clear: function() {
|
486
|
+
var parent = this.horiz.parentNode;
|
487
|
+
parent.removeChild(this.horiz);
|
488
|
+
parent.removeChild(this.vert);
|
489
|
+
}
|
490
|
+
}, NativeScrollbars.prototype);
|
491
|
+
|
492
|
+
function NullScrollbars() {}
|
493
|
+
|
494
|
+
NullScrollbars.prototype = copyObj({
|
495
|
+
update: function() { return {bottom: 0, right: 0}; },
|
496
|
+
setScrollLeft: function() {},
|
497
|
+
setScrollTop: function() {},
|
498
|
+
clear: function() {}
|
499
|
+
}, NullScrollbars.prototype);
|
500
|
+
|
501
|
+
CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
|
502
|
+
|
503
|
+
function initScrollbars(cm) {
|
504
|
+
if (cm.display.scrollbars) {
|
505
|
+
cm.display.scrollbars.clear();
|
506
|
+
if (cm.display.scrollbars.addClass)
|
507
|
+
rmClass(cm.display.wrapper, cm.display.scrollbars.addClass);
|
508
|
+
}
|
509
|
+
|
510
|
+
cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) {
|
511
|
+
cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
|
512
|
+
on(node, "mousedown", function() {
|
513
|
+
if (cm.state.focused) setTimeout(bind(focusInput, cm), 0);
|
514
|
+
});
|
515
|
+
node.setAttribute("not-content", "true");
|
516
|
+
}, function(pos, axis) {
|
517
|
+
if (axis == "horizontal") setScrollLeft(cm, pos);
|
518
|
+
else setScrollTop(cm, pos);
|
519
|
+
}, cm);
|
520
|
+
if (cm.display.scrollbars.addClass)
|
521
|
+
addClass(cm.display.wrapper, cm.display.scrollbars.addClass);
|
522
|
+
}
|
523
|
+
|
412
524
|
function updateScrollbars(cm, measure) {
|
413
525
|
if (!measure) measure = measureForScrollbars(cm);
|
414
|
-
var
|
415
|
-
|
416
|
-
var
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
if (needsV) {
|
423
|
-
d.scrollbarV.style.display = "block";
|
424
|
-
d.scrollbarV.style.bottom = needsH ? sWidth + "px" : "0";
|
425
|
-
// A bug in IE8 can cause this value to be negative, so guard it.
|
426
|
-
d.scrollbarV.firstChild.style.height =
|
427
|
-
Math.max(0, scrollHeight - measure.clientHeight + (measure.barHeight || d.scrollbarV.clientHeight)) + "px";
|
428
|
-
} else {
|
429
|
-
d.scrollbarV.style.display = "";
|
430
|
-
d.scrollbarV.firstChild.style.height = "0";
|
431
|
-
}
|
432
|
-
if (needsH) {
|
433
|
-
d.scrollbarH.style.display = "block";
|
434
|
-
d.scrollbarH.style.right = needsV ? sWidth + "px" : "0";
|
435
|
-
d.scrollbarH.firstChild.style.width =
|
436
|
-
(measure.scrollWidth - measure.clientWidth + (measure.barWidth || d.scrollbarH.clientWidth)) + "px";
|
437
|
-
} else {
|
438
|
-
d.scrollbarH.style.display = "";
|
439
|
-
d.scrollbarH.firstChild.style.width = "0";
|
526
|
+
var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
|
527
|
+
updateScrollbarsInner(cm, measure);
|
528
|
+
for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
|
529
|
+
if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
|
530
|
+
updateHeightsInViewport(cm);
|
531
|
+
updateScrollbarsInner(cm, measureForScrollbars(cm));
|
532
|
+
startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
|
440
533
|
}
|
441
|
-
|
534
|
+
}
|
535
|
+
|
536
|
+
// Re-synchronize the fake scrollbars with the actual size of the
|
537
|
+
// content.
|
538
|
+
function updateScrollbarsInner(cm, measure) {
|
539
|
+
var d = cm.display;
|
540
|
+
var sizes = d.scrollbars.update(measure);
|
541
|
+
|
542
|
+
d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
|
543
|
+
d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
|
544
|
+
|
545
|
+
if (sizes.right && sizes.bottom) {
|
442
546
|
d.scrollbarFiller.style.display = "block";
|
443
|
-
d.scrollbarFiller.style.height =
|
547
|
+
d.scrollbarFiller.style.height = sizes.bottom + "px";
|
548
|
+
d.scrollbarFiller.style.width = sizes.right + "px";
|
444
549
|
} else d.scrollbarFiller.style.display = "";
|
445
|
-
if (
|
550
|
+
if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
|
446
551
|
d.gutterFiller.style.display = "block";
|
447
|
-
d.gutterFiller.style.height =
|
448
|
-
d.gutterFiller.style.width =
|
552
|
+
d.gutterFiller.style.height = sizes.bottom + "px";
|
553
|
+
d.gutterFiller.style.width = measure.gutterWidth + "px";
|
449
554
|
} else d.gutterFiller.style.display = "";
|
450
|
-
|
451
|
-
if (!cm.state.checkedOverlayScrollbar && measure.clientHeight > 0) {
|
452
|
-
if (sWidth === 0) {
|
453
|
-
var w = mac && !mac_geMountainLion ? "12px" : "18px";
|
454
|
-
d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = w;
|
455
|
-
var barMouseDown = function(e) {
|
456
|
-
if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH)
|
457
|
-
operation(cm, onMouseDown)(e);
|
458
|
-
};
|
459
|
-
on(d.scrollbarV, "mousedown", barMouseDown);
|
460
|
-
on(d.scrollbarH, "mousedown", barMouseDown);
|
461
|
-
}
|
462
|
-
cm.state.checkedOverlayScrollbar = true;
|
463
|
-
}
|
464
555
|
}
|
465
556
|
|
466
557
|
// Compute the lines that are visible in a given viewport (defaults
|
@@ -476,12 +567,13 @@
|
|
476
567
|
// forces those lines into the viewport (if possible).
|
477
568
|
if (viewport && viewport.ensure) {
|
478
569
|
var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
|
479
|
-
if (ensureFrom < from)
|
480
|
-
|
481
|
-
|
482
|
-
if (Math.min(ensureTo, doc.lastLine()) >= to)
|
483
|
-
|
484
|
-
|
570
|
+
if (ensureFrom < from) {
|
571
|
+
from = ensureFrom;
|
572
|
+
to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
|
573
|
+
} else if (Math.min(ensureTo, doc.lastLine()) >= to) {
|
574
|
+
from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
|
575
|
+
to = ensureTo;
|
576
|
+
}
|
485
577
|
}
|
486
578
|
return {from: from, to: Math.max(to, from + 1)};
|
487
579
|
}
|
@@ -549,17 +641,28 @@
|
|
549
641
|
this.editorIsHidden = !display.wrapper.offsetWidth;
|
550
642
|
this.wrapperHeight = display.wrapper.clientHeight;
|
551
643
|
this.wrapperWidth = display.wrapper.clientWidth;
|
552
|
-
this.
|
553
|
-
this.oldScrollerWidth = display.scroller.clientWidth;
|
644
|
+
this.oldDisplayWidth = displayWidth(cm);
|
554
645
|
this.force = force;
|
555
646
|
this.dims = getDimensions(cm);
|
556
647
|
}
|
557
648
|
|
649
|
+
function maybeClipScrollbars(cm) {
|
650
|
+
var display = cm.display;
|
651
|
+
if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
|
652
|
+
display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
|
653
|
+
display.heightForcer.style.height = scrollGap(cm) + "px";
|
654
|
+
display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
|
655
|
+
display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
|
656
|
+
display.scrollbarsClipped = true;
|
657
|
+
}
|
658
|
+
}
|
659
|
+
|
558
660
|
// Does the actual updating of the line display. Bails out
|
559
661
|
// (returning false) when there is nothing to be done and forced is
|
560
662
|
// false.
|
561
663
|
function updateDisplayIfNeeded(cm, update) {
|
562
664
|
var display = cm.display, doc = cm.doc;
|
665
|
+
|
563
666
|
if (update.editorIsHidden) {
|
564
667
|
resetView(cm);
|
565
668
|
return false;
|
@@ -569,7 +672,7 @@
|
|
569
672
|
if (!update.force &&
|
570
673
|
update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
|
571
674
|
(display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
|
572
|
-
countDirtyView(cm) == 0)
|
675
|
+
display.renderedView == display.view && countDirtyView(cm) == 0)
|
573
676
|
return false;
|
574
677
|
|
575
678
|
if (maybeUpdateLineNumberWidth(cm)) {
|
@@ -597,7 +700,7 @@
|
|
597
700
|
cm.display.mover.style.top = display.viewOffset + "px";
|
598
701
|
|
599
702
|
var toUpdate = countDirtyView(cm);
|
600
|
-
if (!different && toUpdate == 0 && !update.force &&
|
703
|
+
if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
|
601
704
|
(display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
|
602
705
|
return false;
|
603
706
|
|
@@ -607,14 +710,16 @@
|
|
607
710
|
if (toUpdate > 4) display.lineDiv.style.display = "none";
|
608
711
|
patchDisplay(cm, display.updateLineNumbers, update.dims);
|
609
712
|
if (toUpdate > 4) display.lineDiv.style.display = "";
|
713
|
+
display.renderedView = display.view;
|
610
714
|
// There might have been a widget with a focused element that got
|
611
715
|
// hidden or updated, if so re-focus it.
|
612
716
|
if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
|
613
717
|
|
614
718
|
// Prevent selection and cursors from interfering with the scroll
|
615
|
-
// width.
|
719
|
+
// width and height.
|
616
720
|
removeChildren(display.cursorDiv);
|
617
721
|
removeChildren(display.selectionDiv);
|
722
|
+
display.heightForcer.style.top = display.gutters.style.height = 0;
|
618
723
|
|
619
724
|
if (different) {
|
620
725
|
display.lastWrapHeight = update.wrapperHeight;
|
@@ -630,14 +735,13 @@
|
|
630
735
|
function postUpdateDisplay(cm, update) {
|
631
736
|
var force = update.force, viewport = update.viewport;
|
632
737
|
for (var first = true;; first = false) {
|
633
|
-
if (first && cm.options.lineWrapping && update.
|
738
|
+
if (first && cm.options.lineWrapping && update.oldDisplayWidth != displayWidth(cm)) {
|
634
739
|
force = true;
|
635
740
|
} else {
|
636
741
|
force = false;
|
637
742
|
// Clip forced viewport to actual scrollable area.
|
638
743
|
if (viewport && viewport.top != null)
|
639
|
-
viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) -
|
640
|
-
cm.display.scroller.clientHeight, viewport.top)};
|
744
|
+
viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};
|
641
745
|
// Updated line heights might result in the drawn area not
|
642
746
|
// actually covering the viewport. Keep looping until it does.
|
643
747
|
update.visible = visibleLines(cm.display, cm.doc, viewport);
|
@@ -653,8 +757,10 @@
|
|
653
757
|
}
|
654
758
|
|
655
759
|
signalLater(cm, "update", cm);
|
656
|
-
if (cm.display.viewFrom !=
|
760
|
+
if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
|
657
761
|
signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
|
762
|
+
cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
|
763
|
+
}
|
658
764
|
}
|
659
765
|
|
660
766
|
function updateDisplaySimple(cm, viewport) {
|
@@ -671,16 +777,7 @@
|
|
671
777
|
|
672
778
|
function setDocumentHeight(cm, measure) {
|
673
779
|
cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = measure.docHeight + "px";
|
674
|
-
cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight
|
675
|
-
}
|
676
|
-
|
677
|
-
function checkForWebkitWidthBug(cm, measure) {
|
678
|
-
// Work around Webkit bug where it sometimes reserves space for a
|
679
|
-
// non-existing phantom scrollbar in the scroller (Issue #2420)
|
680
|
-
if (cm.display.sizer.offsetWidth + cm.display.gutters.offsetWidth < cm.display.scroller.clientWidth - 1) {
|
681
|
-
cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = "0px";
|
682
|
-
cm.display.gutters.style.height = measure.docHeight + "px";
|
683
|
-
}
|
780
|
+
cm.display.gutters.style.height = Math.max(measure.docHeight + scrollGap(cm), measure.clientHeight) + "px";
|
684
781
|
}
|
685
782
|
|
686
783
|
// Read the actual heights of the rendered lines, and update their
|
@@ -924,7 +1021,7 @@
|
|
924
1021
|
var wrap = ensureLineWrapped(lineView);
|
925
1022
|
for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
|
926
1023
|
var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
|
927
|
-
if (!widget.handleMouseEvents) node.
|
1024
|
+
if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true");
|
928
1025
|
positionLineWidget(widget, node, lineView, dims);
|
929
1026
|
if (allowAbove && widget.above)
|
930
1027
|
wrap.insertBefore(node, lineView.gutter || lineView.text);
|
@@ -1319,7 +1416,8 @@
|
|
1319
1416
|
function drawSelectionRange(cm, range, output) {
|
1320
1417
|
var display = cm.display, doc = cm.doc;
|
1321
1418
|
var fragment = document.createDocumentFragment();
|
1322
|
-
var padding = paddingH(cm.display), leftSide = padding.left
|
1419
|
+
var padding = paddingH(cm.display), leftSide = padding.left;
|
1420
|
+
var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
|
1323
1421
|
|
1324
1422
|
function add(left, top, width, bottom) {
|
1325
1423
|
if (top < 0) top = 0;
|
@@ -1498,13 +1596,21 @@
|
|
1498
1596
|
return data;
|
1499
1597
|
}
|
1500
1598
|
|
1599
|
+
function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; }
|
1600
|
+
function displayWidth(cm) {
|
1601
|
+
return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth;
|
1602
|
+
}
|
1603
|
+
function displayHeight(cm) {
|
1604
|
+
return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight;
|
1605
|
+
}
|
1606
|
+
|
1501
1607
|
// Ensure the lineView.wrapping.heights array is populated. This is
|
1502
1608
|
// an array of bottom offsets for the lines that make up a drawn
|
1503
1609
|
// line. When lineWrapping is on, there might be more than one
|
1504
1610
|
// height.
|
1505
1611
|
function ensureLineHeights(cm, lineView, rect) {
|
1506
1612
|
var wrapping = cm.options.lineWrapping;
|
1507
|
-
var curWidth = wrapping && cm
|
1613
|
+
var curWidth = wrapping && displayWidth(cm);
|
1508
1614
|
if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
|
1509
1615
|
var heights = lineView.measure.heights = [];
|
1510
1616
|
if (wrapping) {
|
@@ -2022,6 +2128,7 @@
|
|
2022
2128
|
|
2023
2129
|
function endOperation_R1(op) {
|
2024
2130
|
var cm = op.cm, display = cm.display;
|
2131
|
+
maybeClipScrollbars(cm);
|
2025
2132
|
if (op.updateMaxLine) findMaxLine(cm);
|
2026
2133
|
|
2027
2134
|
op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
|
@@ -2047,8 +2154,10 @@
|
|
2047
2154
|
// updateDisplay_W2 will use these properties to do the actual resizing
|
2048
2155
|
if (display.maxLineChanged && !cm.options.lineWrapping) {
|
2049
2156
|
op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
|
2050
|
-
|
2051
|
-
|
2157
|
+
cm.display.sizerWidth = op.adjustWidthTo;
|
2158
|
+
op.barMeasure.scrollWidth =
|
2159
|
+
Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
|
2160
|
+
op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
|
2052
2161
|
}
|
2053
2162
|
|
2054
2163
|
if (op.updatedDisplay || op.selectionChanged)
|
@@ -2081,9 +2190,6 @@
|
|
2081
2190
|
function endOperation_finish(op) {
|
2082
2191
|
var cm = op.cm, display = cm.display, doc = cm.doc;
|
2083
2192
|
|
2084
|
-
if (op.adjustWidthTo != null && Math.abs(op.barMeasure.scrollWidth - cm.display.scroller.scrollWidth) > 1)
|
2085
|
-
updateScrollbars(cm);
|
2086
|
-
|
2087
2193
|
if (op.updatedDisplay) postUpdateDisplay(cm, op.update);
|
2088
2194
|
|
2089
2195
|
// Abort mouse wheel delta measurement, when scrolling explicitly
|
@@ -2092,12 +2198,14 @@
|
|
2092
2198
|
|
2093
2199
|
// Propagate the scroll position to the actual DOM scroller
|
2094
2200
|
if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {
|
2095
|
-
|
2096
|
-
display.
|
2201
|
+
doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
|
2202
|
+
display.scrollbars.setScrollTop(doc.scrollTop);
|
2203
|
+
display.scroller.scrollTop = doc.scrollTop;
|
2097
2204
|
}
|
2098
2205
|
if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {
|
2099
|
-
|
2100
|
-
display.
|
2206
|
+
doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft));
|
2207
|
+
display.scrollbars.setScrollLeft(doc.scrollLeft);
|
2208
|
+
display.scroller.scrollLeft = doc.scrollLeft;
|
2101
2209
|
alignHorizontally(cm);
|
2102
2210
|
}
|
2103
2211
|
// If we need to scroll a specific position into view, do so.
|
@@ -2118,16 +2226,6 @@
|
|
2118
2226
|
if (display.wrapper.offsetHeight)
|
2119
2227
|
doc.scrollTop = cm.display.scroller.scrollTop;
|
2120
2228
|
|
2121
|
-
// Apply workaround for two webkit bugs
|
2122
|
-
if (op.updatedDisplay && webkit) {
|
2123
|
-
if (cm.options.lineWrapping)
|
2124
|
-
checkForWebkitWidthBug(cm, op.barMeasure); // (Issue #2420)
|
2125
|
-
if (op.barMeasure.scrollWidth > op.barMeasure.clientWidth &&
|
2126
|
-
op.barMeasure.scrollWidth < op.barMeasure.clientWidth + 1 &&
|
2127
|
-
!hScrollbarTakesSpace(cm))
|
2128
|
-
updateScrollbars(cm); // (Issue #2562)
|
2129
|
-
}
|
2130
|
-
|
2131
2229
|
// Fire change events, and delayed event handlers
|
2132
2230
|
if (op.changeObjs)
|
2133
2231
|
signal(cm, "changes", cm, op.changeObjs);
|
@@ -2486,6 +2584,7 @@
|
|
2486
2584
|
// Reset the input to correspond to the selection (or to be empty,
|
2487
2585
|
// when not typing and nothing is selected)
|
2488
2586
|
function resetInput(cm, typing) {
|
2587
|
+
if (cm.display.contextMenuPending) return;
|
2489
2588
|
var minimal, selected, doc = cm.doc;
|
2490
2589
|
if (cm.somethingSelected()) {
|
2491
2590
|
cm.display.prevInput = "";
|
@@ -2552,28 +2651,18 @@
|
|
2552
2651
|
signal(cm, "scroll", cm);
|
2553
2652
|
}
|
2554
2653
|
});
|
2555
|
-
on(d.scrollbarV, "scroll", function() {
|
2556
|
-
if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
|
2557
|
-
});
|
2558
|
-
on(d.scrollbarH, "scroll", function() {
|
2559
|
-
if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
|
2560
|
-
});
|
2561
2654
|
|
2562
2655
|
// Listen to wheel events in order to try and update the viewport on time.
|
2563
2656
|
on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
|
2564
2657
|
on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
|
2565
2658
|
|
2566
|
-
// Prevent clicks in the scrollbars from killing focus
|
2567
|
-
function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
|
2568
|
-
on(d.scrollbarH, "mousedown", reFocus);
|
2569
|
-
on(d.scrollbarV, "mousedown", reFocus);
|
2570
2659
|
// Prevent wrapper from ever scrolling
|
2571
2660
|
on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
|
2572
2661
|
|
2573
2662
|
on(d.input, "keyup", function(e) { onKeyUp.call(cm, e); });
|
2574
2663
|
on(d.input, "input", function() {
|
2575
2664
|
if (ie && ie_version >= 9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
|
2576
|
-
|
2665
|
+
readInput(cm);
|
2577
2666
|
});
|
2578
2667
|
on(d.input, "keydown", operation(cm, onKeyDown));
|
2579
2668
|
on(d.input, "keypress", operation(cm, onKeyPress));
|
@@ -2659,6 +2748,7 @@
|
|
2659
2748
|
return;
|
2660
2749
|
// Might be a text scaling operation, clear size caches.
|
2661
2750
|
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
|
2751
|
+
d.scrollbarsClipped = false;
|
2662
2752
|
cm.setSize();
|
2663
2753
|
}
|
2664
2754
|
|
@@ -2667,7 +2757,7 @@
|
|
2667
2757
|
// Return true when the given mouse event happened in a widget
|
2668
2758
|
function eventInWidget(display, e) {
|
2669
2759
|
for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
|
2670
|
-
if (!n || n.
|
2760
|
+
if (!n || n.getAttribute("cm-ignore-events") == "true" || n.parentNode == display.sizer && n != display.mover) return true;
|
2671
2761
|
}
|
2672
2762
|
}
|
2673
2763
|
|
@@ -2678,11 +2768,8 @@
|
|
2678
2768
|
// coordinates beyond the right of the text.
|
2679
2769
|
function posFromMouse(cm, e, liberal, forRect) {
|
2680
2770
|
var display = cm.display;
|
2681
|
-
if (!liberal)
|
2682
|
-
|
2683
|
-
if (target == display.scrollbarH || target == display.scrollbarV ||
|
2684
|
-
target == display.scrollbarFiller || target == display.gutterFiller) return null;
|
2685
|
-
}
|
2771
|
+
if (!liberal && e_target(e).getAttribute("not-content") == "true") return null;
|
2772
|
+
|
2686
2773
|
var x, y, space = display.lineSpace.getBoundingClientRect();
|
2687
2774
|
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
|
2688
2775
|
try { x = e.clientX - space.left; y = e.clientY - space.top; }
|
@@ -2752,9 +2839,10 @@
|
|
2752
2839
|
lastClick = {time: now, pos: start};
|
2753
2840
|
}
|
2754
2841
|
|
2755
|
-
var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey;
|
2842
|
+
var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;
|
2756
2843
|
if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
|
2757
|
-
type == "single" && sel.contains(start) > -1 &&
|
2844
|
+
type == "single" && (contained = sel.contains(start)) > -1 &&
|
2845
|
+
!sel.ranges[contained].empty())
|
2758
2846
|
leftButtonStartDrag(cm, e, start, modifier);
|
2759
2847
|
else
|
2760
2848
|
leftButtonSelect(cm, e, start, type, modifier);
|
@@ -2793,11 +2881,11 @@
|
|
2793
2881
|
var display = cm.display, doc = cm.doc;
|
2794
2882
|
e_preventDefault(e);
|
2795
2883
|
|
2796
|
-
var ourRange, ourIndex, startSel = doc.sel;
|
2884
|
+
var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
|
2797
2885
|
if (addNew && !e.shiftKey) {
|
2798
2886
|
ourIndex = doc.sel.contains(start);
|
2799
2887
|
if (ourIndex > -1)
|
2800
|
-
ourRange =
|
2888
|
+
ourRange = ranges[ourIndex];
|
2801
2889
|
else
|
2802
2890
|
ourRange = new Range(start, start);
|
2803
2891
|
} else {
|
@@ -2829,12 +2917,15 @@
|
|
2829
2917
|
ourIndex = 0;
|
2830
2918
|
setSelection(doc, new Selection([ourRange], 0), sel_mouse);
|
2831
2919
|
startSel = doc.sel;
|
2832
|
-
} else if (ourIndex
|
2833
|
-
|
2834
|
-
|
2835
|
-
ourIndex = doc.sel.ranges.length;
|
2836
|
-
setSelection(doc, normalizeSelection(doc.sel.ranges.concat([ourRange]), ourIndex),
|
2920
|
+
} else if (ourIndex == -1) {
|
2921
|
+
ourIndex = ranges.length;
|
2922
|
+
setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
|
2837
2923
|
{scroll: false, origin: "*mouse"});
|
2924
|
+
} else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single") {
|
2925
|
+
setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0));
|
2926
|
+
startSel = doc.sel;
|
2927
|
+
} else {
|
2928
|
+
replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
|
2838
2929
|
}
|
2839
2930
|
|
2840
2931
|
var lastPos = start;
|
@@ -3040,7 +3131,7 @@
|
|
3040
3131
|
cm.doc.scrollTop = val;
|
3041
3132
|
if (!gecko) updateDisplaySimple(cm, {top: val});
|
3042
3133
|
if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
|
3043
|
-
|
3134
|
+
cm.display.scrollbars.setScrollTop(val);
|
3044
3135
|
if (gecko) updateDisplaySimple(cm);
|
3045
3136
|
startWorker(cm, 100);
|
3046
3137
|
}
|
@@ -3052,7 +3143,7 @@
|
|
3052
3143
|
cm.doc.scrollLeft = val;
|
3053
3144
|
alignHorizontally(cm);
|
3054
3145
|
if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
|
3055
|
-
|
3146
|
+
cm.display.scrollbars.setScrollLeft(val);
|
3056
3147
|
}
|
3057
3148
|
|
3058
3149
|
// Since the delta values reported on mouse wheel events are
|
@@ -3076,11 +3167,22 @@
|
|
3076
3167
|
else if (chrome) wheelPixelsPerUnit = -.7;
|
3077
3168
|
else if (safari) wheelPixelsPerUnit = -1/3;
|
3078
3169
|
|
3079
|
-
function
|
3170
|
+
var wheelEventDelta = function(e) {
|
3080
3171
|
var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
|
3081
3172
|
if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
|
3082
3173
|
if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
|
3083
3174
|
else if (dy == null) dy = e.wheelDelta;
|
3175
|
+
return {x: dx, y: dy};
|
3176
|
+
};
|
3177
|
+
CodeMirror.wheelEventPixels = function(e) {
|
3178
|
+
var delta = wheelEventDelta(e);
|
3179
|
+
delta.x *= wheelPixelsPerUnit;
|
3180
|
+
delta.y *= wheelPixelsPerUnit;
|
3181
|
+
return delta;
|
3182
|
+
};
|
3183
|
+
|
3184
|
+
function onScrollWheel(cm, e) {
|
3185
|
+
var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
|
3084
3186
|
|
3085
3187
|
var display = cm.display, scroll = display.scroller;
|
3086
3188
|
// Quit if there's nothing to scroll here
|
@@ -3173,11 +3275,11 @@
|
|
3173
3275
|
|
3174
3276
|
function lookupKeyForEditor(cm, name, handle) {
|
3175
3277
|
for (var i = 0; i < cm.state.keyMaps.length; i++) {
|
3176
|
-
var result = lookupKey(name, cm.state.keyMaps[i], handle);
|
3278
|
+
var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
|
3177
3279
|
if (result) return result;
|
3178
3280
|
}
|
3179
|
-
return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle))
|
3180
|
-
|| lookupKey(name, cm.options.keyMap, handle);
|
3281
|
+
return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
|
3282
|
+
|| lookupKey(name, cm.options.keyMap, handle, cm);
|
3181
3283
|
}
|
3182
3284
|
|
3183
3285
|
var stopSeq = new Delayed;
|
@@ -3351,6 +3453,7 @@
|
|
3351
3453
|
resetInput(cm);
|
3352
3454
|
// Adds "Select all" to context menu in FF
|
3353
3455
|
if (!cm.somethingSelected()) display.input.value = display.prevInput = " ";
|
3456
|
+
display.contextMenuPending = true;
|
3354
3457
|
display.selForContextMenu = cm.doc.sel;
|
3355
3458
|
clearTimeout(display.detectingSelectAll);
|
3356
3459
|
|
@@ -3369,9 +3472,10 @@
|
|
3369
3472
|
}
|
3370
3473
|
}
|
3371
3474
|
function rehide() {
|
3475
|
+
display.contextMenuPending = false;
|
3372
3476
|
display.inputDiv.style.position = "relative";
|
3373
3477
|
display.input.style.cssText = oldCSS;
|
3374
|
-
if (ie && ie_version < 9) display.
|
3478
|
+
if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos);
|
3375
3479
|
slowPoll(cm);
|
3376
3480
|
|
3377
3481
|
// Try to detect the user choosing select-all
|
@@ -3721,7 +3825,7 @@
|
|
3721
3825
|
if (doScroll != null && !phantom) {
|
3722
3826
|
var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
|
3723
3827
|
(coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
|
3724
|
-
(coords.bottom - coords.top +
|
3828
|
+
(coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " +
|
3725
3829
|
coords.left + "px; width: 2px;");
|
3726
3830
|
cm.display.lineSpace.appendChild(scrollNode);
|
3727
3831
|
scrollNode.scrollIntoView(doScroll);
|
@@ -3750,8 +3854,9 @@
|
|
3750
3854
|
setScrollLeft(cm, scrollPos.scrollLeft);
|
3751
3855
|
if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
|
3752
3856
|
}
|
3753
|
-
if (!changed)
|
3857
|
+
if (!changed) break;
|
3754
3858
|
}
|
3859
|
+
return coords;
|
3755
3860
|
}
|
3756
3861
|
|
3757
3862
|
// Scroll a given set of coordinates into view (immediately).
|
@@ -3769,7 +3874,7 @@
|
|
3769
3874
|
var display = cm.display, snapMargin = textHeight(cm.display);
|
3770
3875
|
if (y1 < 0) y1 = 0;
|
3771
3876
|
var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
|
3772
|
-
var screen =
|
3877
|
+
var screen = displayHeight(cm), result = {};
|
3773
3878
|
if (y2 - y1 > screen) y2 = y1 + screen;
|
3774
3879
|
var docBottom = cm.doc.height + paddingVert(display);
|
3775
3880
|
var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
|
@@ -3781,7 +3886,7 @@
|
|
3781
3886
|
}
|
3782
3887
|
|
3783
3888
|
var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
|
3784
|
-
var screenw =
|
3889
|
+
var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
|
3785
3890
|
var tooWide = x2 - x1 > screenw;
|
3786
3891
|
if (tooWide) x2 = x1 + screenw;
|
3787
3892
|
if (x1 < 10)
|
@@ -3790,7 +3895,6 @@
|
|
3790
3895
|
result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));
|
3791
3896
|
else if (x2 > screenw + screenleft - 3)
|
3792
3897
|
result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;
|
3793
|
-
|
3794
3898
|
return result;
|
3795
3899
|
}
|
3796
3900
|
|
@@ -4245,6 +4349,7 @@
|
|
4245
4349
|
pos = cursorCoords(this, clipPos(this.doc, pos));
|
4246
4350
|
var top = pos.bottom, left = pos.left;
|
4247
4351
|
node.style.position = "absolute";
|
4352
|
+
node.setAttribute("cm-ignore-events", "true");
|
4248
4353
|
display.sizer.appendChild(node);
|
4249
4354
|
if (vert == "over") {
|
4250
4355
|
top = pos.top;
|
@@ -4379,10 +4484,11 @@
|
|
4379
4484
|
if (y != null) this.curOp.scrollTop = y;
|
4380
4485
|
}),
|
4381
4486
|
getScrollInfo: function() {
|
4382
|
-
var scroller = this.display.scroller
|
4487
|
+
var scroller = this.display.scroller;
|
4383
4488
|
return {left: scroller.scrollLeft, top: scroller.scrollTop,
|
4384
|
-
height: scroller.scrollHeight -
|
4385
|
-
|
4489
|
+
height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,
|
4490
|
+
width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,
|
4491
|
+
clientHeight: displayHeight(this), clientWidth: displayWidth(this)};
|
4386
4492
|
},
|
4387
4493
|
|
4388
4494
|
scrollIntoView: methodOp(function(range, margin) {
|
@@ -4524,7 +4630,13 @@
|
|
4524
4630
|
cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
|
4525
4631
|
cm.refresh();
|
4526
4632
|
}, true);
|
4527
|
-
option("coverGutterNextToScrollbar", false, updateScrollbars, true);
|
4633
|
+
option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true);
|
4634
|
+
option("scrollbarStyle", "native", function(cm) {
|
4635
|
+
initScrollbars(cm);
|
4636
|
+
updateScrollbars(cm);
|
4637
|
+
cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);
|
4638
|
+
cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);
|
4639
|
+
}, true);
|
4528
4640
|
option("lineNumbers", false, function(cm) {
|
4529
4641
|
setGuttersForLineNumbers(cm.options);
|
4530
4642
|
guttersChanged(cm);
|
@@ -4954,18 +5066,18 @@
|
|
4954
5066
|
return keymap;
|
4955
5067
|
};
|
4956
5068
|
|
4957
|
-
var lookupKey = CodeMirror.lookupKey = function(key, map, handle) {
|
5069
|
+
var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) {
|
4958
5070
|
map = getKeyMap(map);
|
4959
|
-
var found = map.call ? map.call(key) : map[key];
|
5071
|
+
var found = map.call ? map.call(key, context) : map[key];
|
4960
5072
|
if (found === false) return "nothing";
|
4961
5073
|
if (found === "...") return "multi";
|
4962
5074
|
if (found != null && handle(found)) return "handled";
|
4963
5075
|
|
4964
5076
|
if (map.fallthrough) {
|
4965
5077
|
if (Object.prototype.toString.call(map.fallthrough) != "[object Array]")
|
4966
|
-
return lookupKey(key, map.fallthrough, handle);
|
5078
|
+
return lookupKey(key, map.fallthrough, handle, context);
|
4967
5079
|
for (var i = 0; i < map.fallthrough.length; i++) {
|
4968
|
-
var result = lookupKey(key, map.fallthrough[i], handle);
|
5080
|
+
var result = lookupKey(key, map.fallthrough[i], handle, context);
|
4969
5081
|
if (result) return result;
|
4970
5082
|
}
|
4971
5083
|
}
|
@@ -5272,7 +5384,7 @@
|
|
5272
5384
|
// Showing up as a widget implies collapsed (widget replaces text)
|
5273
5385
|
marker.collapsed = true;
|
5274
5386
|
marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
|
5275
|
-
if (!options.handleMouseEvents) marker.widgetNode.
|
5387
|
+
if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true");
|
5276
5388
|
if (options.insertLeft) marker.widgetNode.insertLeft = true;
|
5277
5389
|
}
|
5278
5390
|
if (marker.collapsed) {
|
@@ -5316,7 +5428,7 @@
|
|
5316
5428
|
if (updateMaxLine) cm.curOp.updateMaxLine = true;
|
5317
5429
|
if (marker.collapsed)
|
5318
5430
|
regChange(cm, from.line, to.line + 1);
|
5319
|
-
else if (marker.className || marker.title || marker.startStyle || marker.endStyle)
|
5431
|
+
else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
|
5320
5432
|
for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
|
5321
5433
|
if (marker.atomic) reCheckSelection(cm.doc);
|
5322
5434
|
signalLater(cm, "markerAdded", cm, marker);
|
@@ -5896,8 +6008,11 @@
|
|
5896
6008
|
if (mName) style = "m-" + (style ? mName + " " + style : mName);
|
5897
6009
|
}
|
5898
6010
|
if (!flattenSpans || curStyle != style) {
|
5899
|
-
|
5900
|
-
|
6011
|
+
while (curStart < stream.start) {
|
6012
|
+
curStart = Math.min(stream.start, curStart + 50000);
|
6013
|
+
f(curStart, curStyle);
|
6014
|
+
}
|
6015
|
+
curStyle = style;
|
5901
6016
|
}
|
5902
6017
|
stream.start = stream.pos;
|
5903
6018
|
}
|
@@ -6054,7 +6169,7 @@
|
|
6054
6169
|
|
6055
6170
|
// Build up the DOM representation for a single token, and add it to
|
6056
6171
|
// the line map. Takes care to render special characters separately.
|
6057
|
-
function buildToken(builder, text, style, startStyle, endStyle, title) {
|
6172
|
+
function buildToken(builder, text, style, startStyle, endStyle, title, css) {
|
6058
6173
|
if (!text) return;
|
6059
6174
|
var special = builder.cm.options.specialChars, mustWrap = false;
|
6060
6175
|
if (!special.test(text)) {
|
@@ -6093,11 +6208,11 @@
|
|
6093
6208
|
builder.pos++;
|
6094
6209
|
}
|
6095
6210
|
}
|
6096
|
-
if (style || startStyle || endStyle || mustWrap) {
|
6211
|
+
if (style || startStyle || endStyle || mustWrap || css) {
|
6097
6212
|
var fullStyle = style || "";
|
6098
6213
|
if (startStyle) fullStyle += startStyle;
|
6099
6214
|
if (endStyle) fullStyle += endStyle;
|
6100
|
-
var token = elt("span", [content], fullStyle);
|
6215
|
+
var token = elt("span", [content], fullStyle, css);
|
6101
6216
|
if (title) token.title = title;
|
6102
6217
|
return builder.content.appendChild(token);
|
6103
6218
|
}
|
@@ -6156,11 +6271,11 @@
|
|
6156
6271
|
return;
|
6157
6272
|
}
|
6158
6273
|
|
6159
|
-
var len = allText.length, pos = 0, i = 1, text = "", style;
|
6274
|
+
var len = allText.length, pos = 0, i = 1, text = "", style, css;
|
6160
6275
|
var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
|
6161
6276
|
for (;;) {
|
6162
6277
|
if (nextChange == pos) { // Update current marker set
|
6163
|
-
spanStyle = spanEndStyle = spanStartStyle = title = "";
|
6278
|
+
spanStyle = spanEndStyle = spanStartStyle = title = css = "";
|
6164
6279
|
collapsed = null; nextChange = Infinity;
|
6165
6280
|
var foundBookmarks = [];
|
6166
6281
|
for (var j = 0; j < spans.length; ++j) {
|
@@ -6168,6 +6283,7 @@
|
|
6168
6283
|
if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
|
6169
6284
|
if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
|
6170
6285
|
if (m.className) spanStyle += " " + m.className;
|
6286
|
+
if (m.css) css = m.css;
|
6171
6287
|
if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
|
6172
6288
|
if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
|
6173
6289
|
if (m.title && !title) title = m.title;
|
@@ -6195,7 +6311,7 @@
|
|
6195
6311
|
if (!collapsed) {
|
6196
6312
|
var tokenText = end > upto ? text.slice(0, upto - pos) : text;
|
6197
6313
|
builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
|
6198
|
-
spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
|
6314
|
+
spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css);
|
6199
6315
|
}
|
6200
6316
|
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
|
6201
6317
|
pos = end;
|
@@ -6622,7 +6738,7 @@
|
|
6622
6738
|
});
|
6623
6739
|
}),
|
6624
6740
|
removeLineClass: docMethodOp(function(handle, where, cls) {
|
6625
|
-
return changeLine(this, handle, "class", function(line) {
|
6741
|
+
return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
|
6626
6742
|
var prop = where == "text" ? "textClass"
|
6627
6743
|
: where == "background" ? "bgClass"
|
6628
6744
|
: where == "gutter" ? "gutterClass" : "wrapClass";
|
@@ -7278,7 +7394,7 @@
|
|
7278
7394
|
// MISC UTILITIES
|
7279
7395
|
|
7280
7396
|
// Number of pixels added to scroller and sizer to hide scrollbar
|
7281
|
-
var
|
7397
|
+
var scrollerGap = 30;
|
7282
7398
|
|
7283
7399
|
// Returned or thrown by various protocols to signal 'I'm not
|
7284
7400
|
// handling this'.
|
@@ -7504,7 +7620,6 @@
|
|
7504
7620
|
on(window, "resize", function() {
|
7505
7621
|
if (resizeTimer == null) resizeTimer = setTimeout(function() {
|
7506
7622
|
resizeTimer = null;
|
7507
|
-
knownScrollbarWidth = null;
|
7508
7623
|
forEachCodeMirror(onResize);
|
7509
7624
|
}, 100);
|
7510
7625
|
});
|
@@ -7525,16 +7640,6 @@
|
|
7525
7640
|
return "draggable" in div || "dragDrop" in div;
|
7526
7641
|
}();
|
7527
7642
|
|
7528
|
-
var knownScrollbarWidth;
|
7529
|
-
function scrollbarWidth(measure) {
|
7530
|
-
if (knownScrollbarWidth != null) return knownScrollbarWidth;
|
7531
|
-
var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
|
7532
|
-
removeChildrenAndAdd(measure, test);
|
7533
|
-
if (test.offsetWidth)
|
7534
|
-
knownScrollbarWidth = test.offsetHeight - test.clientHeight;
|
7535
|
-
return knownScrollbarWidth || 0;
|
7536
|
-
}
|
7537
|
-
|
7538
7643
|
var zwspSupported;
|
7539
7644
|
function zeroWidthElement(measure) {
|
7540
7645
|
if (zwspSupported == null) {
|
@@ -7916,7 +8021,7 @@
|
|
7916
8021
|
|
7917
8022
|
// THE END
|
7918
8023
|
|
7919
|
-
CodeMirror.version = "4.
|
8024
|
+
CodeMirror.version = "4.9.0";
|
7920
8025
|
|
7921
8026
|
return CodeMirror;
|
7922
8027
|
});
|