codemirror-rails 3.00 → 3.02
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +5 -2
- data/lib/codemirror/rails/version.rb +2 -2
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/db/.gitkeep +0 -0
- data/test/integration/codemirror_rails_integration_test.rb +1 -1
- data/vendor/assets/javascripts/codemirror.js +385 -152
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +279 -66
- data/vendor/assets/javascripts/codemirror/modes/apl.js +160 -0
- data/vendor/assets/javascripts/codemirror/modes/asterisk.js +183 -0
- data/vendor/assets/javascripts/codemirror/modes/clike.js +2 -0
- data/vendor/assets/javascripts/codemirror/modes/clojure.js +3 -3
- data/vendor/assets/javascripts/codemirror/modes/css.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/d.js +205 -0
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +13 -2
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +8 -7
- data/vendor/assets/javascripts/codemirror/modes/properties.js +0 -0
- data/vendor/assets/javascripts/codemirror/modes/sass.js +349 -0
- data/vendor/assets/javascripts/codemirror/modes/sieve.js +37 -10
- data/vendor/assets/javascripts/codemirror/modes/sql.js +268 -0
- data/vendor/assets/javascripts/codemirror/modes/xquery.js +8 -8
- data/vendor/assets/javascripts/codemirror/utils/collapserange.js +68 -0
- data/vendor/assets/javascripts/codemirror/utils/dialog.js +1 -0
- data/vendor/assets/javascripts/codemirror/utils/foldcode.js +2 -1
- data/vendor/assets/javascripts/codemirror/utils/formatting.js +9 -3
- data/vendor/assets/javascripts/codemirror/utils/javascript-hint.js +5 -4
- data/vendor/assets/javascripts/codemirror/utils/python-hint.js +93 -0
- data/vendor/assets/javascripts/codemirror/utils/runmode-standalone.js +51 -10
- data/vendor/assets/javascripts/codemirror/utils/search.js +20 -8
- data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +17 -10
- data/vendor/assets/stylesheets/codemirror.css +10 -9
- metadata +47 -15
- data/vendor/assets/javascripts/codemirror/modes/xmlpure.js +0 -490
- data/vendor/assets/stylesheets/codemirror/modes/diff.css +0 -3
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# codemirror-rails
|
2
2
|
|
3
|
-
Wire up the [CodeMirror](http://codemirror.net/) assets for your Rails
|
3
|
+
Wire up the [CodeMirror](http://codemirror.net/) assets for your Rails
|
4
4
|
applications.
|
5
5
|
|
6
6
|
## Getting Started
|
@@ -17,7 +17,7 @@ Or manually install the codemirror-rails gem:
|
|
17
17
|
gem install codemirror-rails
|
18
18
|
```
|
19
19
|
|
20
|
-
## CodeMirror for Rails 3.1
|
20
|
+
## CodeMirror for Rails >= 3.1
|
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
|
@@ -67,3 +67,6 @@ assets into your Rails 3 public directory.
|
|
67
67
|
```shell
|
68
68
|
rails generate codemirror:install
|
69
69
|
```
|
70
|
+
### Contributing
|
71
|
+
|
72
|
+
Find a mistake? New version of CodeMirror? Submit a pull request!
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# SQLite version 3.x
|
2
|
+
# gem install sqlite3
|
3
|
+
#
|
4
|
+
# Ensure the SQLite 3 gem is defined in your Gemfile
|
5
|
+
# gem 'sqlite3'
|
6
|
+
development:
|
7
|
+
adapter: sqlite3
|
8
|
+
database: db/development.sqlite3
|
9
|
+
pool: 5
|
10
|
+
timeout: 5000
|
11
|
+
|
12
|
+
# Warning: The database defined as "test" will be erased and
|
13
|
+
# re-generated from your development database when you run "rake".
|
14
|
+
# Do not set this db to the same as development or production.
|
15
|
+
test:
|
16
|
+
adapter: sqlite3
|
17
|
+
database: db/test.sqlite3
|
18
|
+
pool: 5
|
19
|
+
timeout: 5000
|
20
|
+
|
21
|
+
production:
|
22
|
+
adapter: sqlite3
|
23
|
+
database: db/production.sqlite3
|
24
|
+
pool: 5
|
25
|
+
timeout: 5000
|
File without changes
|
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
describe 'codemiror-rails integration' do
|
4
4
|
it 'provides codemirror.js on the asset pipeline' do
|
5
5
|
visit '/assets/codemirror.js'
|
6
|
-
page.text.must_include '
|
6
|
+
page.text.must_include 'window.CodeMirror'
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'provides codemirror css on the asset pipeline' do
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// CodeMirror version 3.
|
1
|
+
// CodeMirror version 3.02
|
2
2
|
//
|
3
3
|
// CodeMirror is the only global var we claim
|
4
4
|
window.CodeMirror = (function() {
|
@@ -10,8 +10,8 @@ window.CodeMirror = (function() {
|
|
10
10
|
// bugs and behavior differences.
|
11
11
|
var gecko = /gecko\/\d/i.test(navigator.userAgent);
|
12
12
|
var ie = /MSIE \d/.test(navigator.userAgent);
|
13
|
-
var ie_lt8 =
|
14
|
-
var ie_lt9 =
|
13
|
+
var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
|
14
|
+
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
|
15
15
|
var webkit = /WebKit\//.test(navigator.userAgent);
|
16
16
|
var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
|
17
17
|
var chrome = /Chrome\//.test(navigator.userAgent);
|
@@ -24,8 +24,14 @@ window.CodeMirror = (function() {
|
|
24
24
|
|
25
25
|
var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
|
26
26
|
// This is woefully incomplete. Suggestions for alternative methods welcome.
|
27
|
-
var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|IEMobile/i.test(navigator.userAgent);
|
27
|
+
var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
|
28
28
|
var mac = ios || /Mac/.test(navigator.platform);
|
29
|
+
var windows = /windows/i.test(navigator.platform);
|
30
|
+
|
31
|
+
var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
|
32
|
+
if (opera_version) opera_version = Number(opera_version[1]);
|
33
|
+
// Some browsers use the wrong event properties to signal cmd/ctrl on OS X
|
34
|
+
var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
|
29
35
|
|
30
36
|
// Optimize some code when these features are not used
|
31
37
|
var sawReadOnlySpans = false, sawCollapsedSpans = false;
|
@@ -80,7 +86,9 @@ window.CodeMirror = (function() {
|
|
80
86
|
function makeDisplay(place) {
|
81
87
|
var d = {};
|
82
88
|
var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none;");
|
83
|
-
|
89
|
+
if (webkit) input.style.width = "1000px";
|
90
|
+
else input.setAttribute("wrap", "off");
|
91
|
+
input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off");
|
84
92
|
// Wraps and hides input textarea
|
85
93
|
d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
|
86
94
|
// The actual fake scrollbars.
|
@@ -91,9 +99,9 @@ window.CodeMirror = (function() {
|
|
91
99
|
d.lineDiv = elt("div");
|
92
100
|
d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
|
93
101
|
// Blinky cursor, and element used to ensure cursor fits at the end of a line
|
94
|
-
d.cursor = elt("
|
102
|
+
d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
|
95
103
|
// Secondary cursor, shown when on a 'jump' in bi-directional text
|
96
|
-
d.otherCursor = elt("
|
104
|
+
d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
|
97
105
|
// Used to measure text size
|
98
106
|
d.measure = elt("div", null, "CodeMirror-measure");
|
99
107
|
// Wraps everything that needs to exist inside the vertically-padded coordinate system
|
@@ -160,6 +168,9 @@ window.CodeMirror = (function() {
|
|
160
168
|
// detected
|
161
169
|
d.pasteIncoming = false;
|
162
170
|
|
171
|
+
// Used for measuring wheel scrolling granularity
|
172
|
+
d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
|
173
|
+
|
163
174
|
return d;
|
164
175
|
}
|
165
176
|
|
@@ -183,7 +194,9 @@ window.CodeMirror = (function() {
|
|
183
194
|
suppressEdits: false,
|
184
195
|
goalColumn: null,
|
185
196
|
cantEdit: false,
|
186
|
-
keyMaps: []
|
197
|
+
keyMaps: [],
|
198
|
+
overlays: [],
|
199
|
+
modeGen: 0
|
187
200
|
};
|
188
201
|
}
|
189
202
|
|
@@ -194,9 +207,14 @@ window.CodeMirror = (function() {
|
|
194
207
|
function loadMode(cm) {
|
195
208
|
var doc = cm.view.doc;
|
196
209
|
cm.view.mode = CodeMirror.getMode(cm.options, cm.options.mode);
|
197
|
-
doc.iter(0, doc.size, function(line) {
|
210
|
+
doc.iter(0, doc.size, function(line) {
|
211
|
+
if (line.stateAfter) line.stateAfter = null;
|
212
|
+
if (line.styles) line.styles = null;
|
213
|
+
});
|
198
214
|
cm.view.frontier = 0;
|
199
215
|
startWorker(cm, 100);
|
216
|
+
cm.view.modeGen++;
|
217
|
+
if (cm.curOp) regChange(cm, 0, doc.size);
|
200
218
|
}
|
201
219
|
|
202
220
|
function wrappingChanged(cm) {
|
@@ -342,13 +360,14 @@ window.CodeMirror = (function() {
|
|
342
360
|
|
343
361
|
function alignHorizontally(cm) {
|
344
362
|
var display = cm.display;
|
345
|
-
if (!display.alignWidgets && !display.gutters.firstChild) return;
|
363
|
+
if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
|
346
364
|
var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.view.scrollLeft;
|
347
365
|
var gutterW = display.gutters.offsetWidth, l = comp + "px";
|
348
366
|
for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
|
349
367
|
for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
|
350
368
|
}
|
351
|
-
|
369
|
+
if (cm.options.fixedGutter)
|
370
|
+
display.gutters.style.left = (comp + gutterW) + "px";
|
352
371
|
}
|
353
372
|
|
354
373
|
function maybeUpdateLineNumberWidth(cm) {
|
@@ -412,7 +431,8 @@ window.CodeMirror = (function() {
|
|
412
431
|
|
413
432
|
if (changes && maybeUpdateLineNumberWidth(cm))
|
414
433
|
changes = true;
|
415
|
-
|
434
|
+
var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
|
435
|
+
display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";
|
416
436
|
|
417
437
|
// When merged lines are present, the line that needs to be
|
418
438
|
// redrawn might not be the one that was changed.
|
@@ -458,9 +478,11 @@ window.CodeMirror = (function() {
|
|
458
478
|
return;
|
459
479
|
intact.sort(function(a, b) {return a.from - b.from;});
|
460
480
|
|
481
|
+
var focused = document.activeElement;
|
461
482
|
if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
|
462
483
|
patchDisplay(cm, from, to, intact, positionsChangedFrom);
|
463
484
|
display.lineDiv.style.display = "";
|
485
|
+
if (document.activeElement != focused && focused.offsetHeight) focused.focus();
|
464
486
|
|
465
487
|
var different = from != display.showingFrom || to != display.showingTo ||
|
466
488
|
display.lastSizeC != display.wrapper.clientHeight;
|
@@ -482,12 +504,19 @@ window.CodeMirror = (function() {
|
|
482
504
|
}
|
483
505
|
var diff = node.lineObj.height - height;
|
484
506
|
if (height < 2) height = textHeight(display);
|
485
|
-
if (diff > .001 || diff < -.001)
|
507
|
+
if (diff > .001 || diff < -.001) {
|
486
508
|
updateLineHeight(node.lineObj, height);
|
509
|
+
var widgets = node.lineObj.widgets;
|
510
|
+
if (widgets) for (var i = 0; i < widgets.length; ++i)
|
511
|
+
widgets[i].height = widgets[i].node.offsetHeight;
|
512
|
+
}
|
487
513
|
}
|
488
514
|
display.viewOffset = heightAtLine(cm, getLine(doc, from));
|
489
515
|
// Position the mover div to align with the current virtual scroll position
|
490
516
|
display.mover.style.top = display.viewOffset + "px";
|
517
|
+
|
518
|
+
if (visibleLines(display, doc, viewPort).to >= to)
|
519
|
+
updateDisplayInner(cm, [], viewPort);
|
491
520
|
return true;
|
492
521
|
}
|
493
522
|
|
@@ -528,9 +557,7 @@ window.CodeMirror = (function() {
|
|
528
557
|
function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
|
529
558
|
var dims = getDimensions(cm);
|
530
559
|
var display = cm.display, lineNumbers = cm.options.lineNumbers;
|
531
|
-
|
532
|
-
// we still need widgets and markers intact to add back to the new content later
|
533
|
-
if (!intact.length && !ie && (!webkit || !cm.display.currentWheelTarget))
|
560
|
+
if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
|
534
561
|
removeChildren(display.lineDiv);
|
535
562
|
var container = display.lineDiv, cur = container.firstChild;
|
536
563
|
|
@@ -540,7 +567,7 @@ window.CodeMirror = (function() {
|
|
540
567
|
node.style.display = "none";
|
541
568
|
node.lineObj = null;
|
542
569
|
} else {
|
543
|
-
|
570
|
+
node.parentNode.removeChild(node);
|
544
571
|
}
|
545
572
|
return next;
|
546
573
|
}
|
@@ -550,6 +577,17 @@ window.CodeMirror = (function() {
|
|
550
577
|
if (nextIntact && nextIntact.to == lineNo) nextIntact = intact.shift();
|
551
578
|
if (lineIsHidden(line)) {
|
552
579
|
if (line.height != 0) updateLineHeight(line, 0);
|
580
|
+
if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i)
|
581
|
+
if (line.widgets[i].showIfHidden) {
|
582
|
+
var prev = cur.previousSibling;
|
583
|
+
if (prev.nodeType == "pre") {
|
584
|
+
var wrap = elt("div", null, null, "position: relative");
|
585
|
+
prev.parentNode.replaceChild(wrap, prev);
|
586
|
+
wrap.appendChild(prev);
|
587
|
+
prev = wrap;
|
588
|
+
}
|
589
|
+
prev.appendChild(buildLineWidget(line.widgets[i], prev, dims));
|
590
|
+
}
|
553
591
|
} else if (nextIntact && nextIntact.from <= lineNo && nextIntact.to > lineNo) {
|
554
592
|
// This line is intact. Skip to the actual node. Update its
|
555
593
|
// line number if needed.
|
@@ -582,8 +620,8 @@ window.CodeMirror = (function() {
|
|
582
620
|
var wrap = elt("div", null, line.wrapClass, "position: relative");
|
583
621
|
if (cm.options.lineNumbers || markers) {
|
584
622
|
var gutterWrap = wrap.appendChild(elt("div", null, null, "position: absolute; left: " +
|
585
|
-
dims.fixedPos + "px"));
|
586
|
-
wrap.alignable = [gutterWrap];
|
623
|
+
(cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"));
|
624
|
+
if (cm.options.fixedGutter) wrap.alignable = [gutterWrap];
|
587
625
|
if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
|
588
626
|
wrap.lineNumber = gutterWrap.appendChild(
|
589
627
|
elt("div", lineNumberFor(cm.options, lineNo),
|
@@ -602,35 +640,38 @@ window.CodeMirror = (function() {
|
|
602
640
|
if (line.bgClass)
|
603
641
|
wrap.appendChild(elt("div", "\u00a0", line.bgClass + " CodeMirror-linebackground"));
|
604
642
|
wrap.appendChild(lineElement);
|
605
|
-
if (line.widgets)
|
606
|
-
|
607
|
-
|
608
|
-
node.
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
node.style.left = dims.fixedPos + "px";
|
613
|
-
if (!widget.coverGutter) {
|
614
|
-
width -= dims.gutterTotalWidth;
|
615
|
-
node.style.paddingLeft = dims.gutterTotalWidth + "px";
|
616
|
-
}
|
617
|
-
node.style.width = width + "px";
|
618
|
-
}
|
619
|
-
if (widget.coverGutter) {
|
620
|
-
node.style.zIndex = 5;
|
621
|
-
node.style.position = "relative";
|
622
|
-
if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
|
623
|
-
}
|
624
|
-
if (widget.above)
|
625
|
-
wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
|
626
|
-
else
|
627
|
-
wrap.appendChild(node);
|
628
|
-
}
|
629
|
-
|
643
|
+
if (line.widgets) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
|
644
|
+
var widget = ws[i], node = buildLineWidget(widget, wrap, dims);
|
645
|
+
if (widget.above)
|
646
|
+
wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
|
647
|
+
else
|
648
|
+
wrap.appendChild(node);
|
649
|
+
}
|
630
650
|
if (ie_lt8) wrap.style.zIndex = 2;
|
631
651
|
return wrap;
|
632
652
|
}
|
633
653
|
|
654
|
+
function buildLineWidget(widget, wrap, dims) {
|
655
|
+
var node = elt("div", [widget.node], "CodeMirror-linewidget");
|
656
|
+
node.widget = widget;
|
657
|
+
if (widget.noHScroll) {
|
658
|
+
(wrap.alignable || (wrap.alignable = [])).push(node);
|
659
|
+
var width = dims.wrapperWidth;
|
660
|
+
node.style.left = dims.fixedPos + "px";
|
661
|
+
if (!widget.coverGutter) {
|
662
|
+
width -= dims.gutterTotalWidth;
|
663
|
+
node.style.paddingLeft = dims.gutterTotalWidth + "px";
|
664
|
+
}
|
665
|
+
node.style.width = width + "px";
|
666
|
+
}
|
667
|
+
if (widget.coverGutter) {
|
668
|
+
node.style.zIndex = 5;
|
669
|
+
node.style.position = "relative";
|
670
|
+
if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
|
671
|
+
}
|
672
|
+
return node;
|
673
|
+
}
|
674
|
+
|
634
675
|
// SELECTION / CURSOR
|
635
676
|
|
636
677
|
function updateSelection(cm) {
|
@@ -765,7 +806,7 @@ window.CodeMirror = (function() {
|
|
765
806
|
// HIGHLIGHT WORKER
|
766
807
|
|
767
808
|
function startWorker(cm, time) {
|
768
|
-
if (cm.view.frontier < cm.display.showingTo)
|
809
|
+
if (cm.view.mode.startState && cm.view.frontier < cm.display.showingTo)
|
769
810
|
cm.view.highlight.set(time, bind(highlightWorker, cm));
|
770
811
|
}
|
771
812
|
|
@@ -777,7 +818,12 @@ window.CodeMirror = (function() {
|
|
777
818
|
var changed = [], prevChange;
|
778
819
|
doc.iter(view.frontier, Math.min(doc.size, cm.display.showingTo + 500), function(line) {
|
779
820
|
if (view.frontier >= cm.display.showingFrom) { // Visible
|
780
|
-
|
821
|
+
var oldStyles = line.styles;
|
822
|
+
line.styles = highlightLine(cm, line, state);
|
823
|
+
var ischange = !oldStyles || oldStyles.length != line.styles.length;
|
824
|
+
for (var i = 0; !ischange && i < oldStyles.length; ++i)
|
825
|
+
ischange = oldStyles[i] != line.styles[i];
|
826
|
+
if (ischange) {
|
781
827
|
if (prevChange && prevChange.end == view.frontier) prevChange.end++;
|
782
828
|
else changed.push(prevChange = {start: view.frontier, end: view.frontier + 1});
|
783
829
|
}
|
@@ -821,6 +867,7 @@ window.CodeMirror = (function() {
|
|
821
867
|
|
822
868
|
function getStateBefore(cm, n) {
|
823
869
|
var view = cm.view;
|
870
|
+
if (!view.mode.startState) return true;
|
824
871
|
var pos = findStartLine(cm, n), state = pos && getLine(view.doc, pos-1).stateAfter;
|
825
872
|
if (!state) state = startState(view.mode);
|
826
873
|
else state = copyState(view.mode, state);
|
@@ -842,7 +889,9 @@ window.CodeMirror = (function() {
|
|
842
889
|
}
|
843
890
|
|
844
891
|
function measureChar(cm, line, ch, data) {
|
845
|
-
var
|
892
|
+
var dir = -1;
|
893
|
+
data = data || measureLine(cm, line);
|
894
|
+
|
846
895
|
for (var pos = ch;; pos += dir) {
|
847
896
|
var r = data[pos];
|
848
897
|
if (r) break;
|
@@ -938,7 +987,7 @@ window.CodeMirror = (function() {
|
|
938
987
|
// Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
|
939
988
|
function intoCoordSystem(cm, lineObj, rect, context) {
|
940
989
|
if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
|
941
|
-
var size = lineObj.widgets[i]
|
990
|
+
var size = widgetHeight(lineObj.widgets[i]);
|
942
991
|
rect.top += size; rect.bottom += size;
|
943
992
|
}
|
944
993
|
if (context == "line") return rect;
|
@@ -1010,8 +1059,9 @@ window.CodeMirror = (function() {
|
|
1010
1059
|
var lineObj = getLine(doc, lineNo);
|
1011
1060
|
var found = coordsCharInner(cm, lineObj, lineNo, x, y);
|
1012
1061
|
var merged = collapsedSpanAtEnd(lineObj);
|
1013
|
-
|
1014
|
-
|
1062
|
+
var mergedPos = merged && merged.find();
|
1063
|
+
if (merged && found.ch >= mergedPos.from.ch)
|
1064
|
+
lineNo = mergedPos.to.line;
|
1015
1065
|
else
|
1016
1066
|
return found;
|
1017
1067
|
}
|
@@ -1121,6 +1171,9 @@ window.CodeMirror = (function() {
|
|
1121
1171
|
var width = measureChar(cm, view.maxLine, view.maxLine.text.length).right;
|
1122
1172
|
display.sizer.style.minWidth = (width + 3 + scrollerCutOff) + "px";
|
1123
1173
|
view.maxLineChanged = false;
|
1174
|
+
var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
|
1175
|
+
if (maxScrollLeft < view.scrollLeft)
|
1176
|
+
setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
|
1124
1177
|
}
|
1125
1178
|
var newScrollPos, updated;
|
1126
1179
|
if (op.selectionChanged) {
|
@@ -1237,7 +1290,7 @@ window.CodeMirror = (function() {
|
|
1237
1290
|
on(d.scroller, "mousedown", operation(cm, onMouseDown));
|
1238
1291
|
on(d.scroller, "dblclick", operation(cm, e_preventDefault));
|
1239
1292
|
on(d.lineSpace, "selectstart", function(e) {
|
1240
|
-
if (!
|
1293
|
+
if (!eventInWidget(d, e)) e_preventDefault(e);
|
1241
1294
|
});
|
1242
1295
|
// Gecko browsers fire contextmenu *after* opening the menu, at
|
1243
1296
|
// which point we can't mess with it anymore. Context menu is
|
@@ -1264,13 +1317,24 @@ window.CodeMirror = (function() {
|
|
1264
1317
|
on(d.scrollbarV, "mousedown", reFocus);
|
1265
1318
|
// Prevent wrapper from ever scrolling
|
1266
1319
|
on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
|
1267
|
-
|
1320
|
+
|
1321
|
+
if (!window.registered) window.registered = 0;
|
1322
|
+
++window.registered;
|
1323
|
+
function onResize() {
|
1268
1324
|
// Might be a text scaling operation, clear size caches.
|
1269
1325
|
d.cachedCharWidth = d.cachedTextHeight = null;
|
1270
1326
|
clearCaches(cm);
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1327
|
+
updateDisplay(cm, true);
|
1328
|
+
}
|
1329
|
+
on(window, "resize", onResize);
|
1330
|
+
// Above handler holds on to the editor and its data structures.
|
1331
|
+
// Here we poll to unregister it when the editor is no longer in
|
1332
|
+
// the document, so that it can be garbage-collected.
|
1333
|
+
setTimeout(function unregister() {
|
1334
|
+
for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
|
1335
|
+
if (p) setTimeout(unregister, 5000);
|
1336
|
+
else {--window.registered; off(window, "resize", onResize);}
|
1337
|
+
}, 5000);
|
1274
1338
|
|
1275
1339
|
on(d.input, "keyup", operation(cm, function(e) {
|
1276
1340
|
if (cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
|
@@ -1292,7 +1356,11 @@ window.CodeMirror = (function() {
|
|
1292
1356
|
on(d.scroller, "dragover", drag_);
|
1293
1357
|
on(d.scroller, "drop", operation(cm, onDrop));
|
1294
1358
|
}
|
1295
|
-
on(d.scroller, "paste", function(){
|
1359
|
+
on(d.scroller, "paste", function(e){
|
1360
|
+
if (eventInWidget(d, e)) return;
|
1361
|
+
focusInput(cm);
|
1362
|
+
fastPoll(cm);
|
1363
|
+
});
|
1296
1364
|
on(d.input, "paste", function() {
|
1297
1365
|
d.pasteIncoming = true;
|
1298
1366
|
fastPoll(cm);
|
@@ -1316,10 +1384,12 @@ window.CodeMirror = (function() {
|
|
1316
1384
|
});
|
1317
1385
|
}
|
1318
1386
|
|
1319
|
-
function
|
1320
|
-
for (var n = e_target(e); n != display.wrapper; n = n.parentNode)
|
1387
|
+
function eventInWidget(display, e) {
|
1388
|
+
for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
|
1389
|
+
if (!n) return true;
|
1321
1390
|
if (/\bCodeMirror-(?:line)?widget\b/.test(n.className) ||
|
1322
1391
|
n.parentNode == display.sizer && n != display.mover) return true;
|
1392
|
+
}
|
1323
1393
|
}
|
1324
1394
|
|
1325
1395
|
function posFromMouse(cm, e, liberal) {
|
@@ -1341,7 +1411,7 @@ window.CodeMirror = (function() {
|
|
1341
1411
|
var cm = this, display = cm.display, view = cm.view, sel = view.sel, doc = view.doc;
|
1342
1412
|
sel.shift = e_prop(e, "shiftKey");
|
1343
1413
|
|
1344
|
-
if (
|
1414
|
+
if (eventInWidget(display, e)) {
|
1345
1415
|
if (!webkit) {
|
1346
1416
|
display.scroller.draggable = false;
|
1347
1417
|
setTimeout(function(){display.scroller.draggable = true;}, 100);
|
@@ -1477,7 +1547,8 @@ window.CodeMirror = (function() {
|
|
1477
1547
|
|
1478
1548
|
function onDrop(e) {
|
1479
1549
|
var cm = this;
|
1480
|
-
if (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e)))
|
1550
|
+
if (eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
|
1551
|
+
return;
|
1481
1552
|
e_preventDefault(e);
|
1482
1553
|
var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
|
1483
1554
|
if (!pos || isReadOnly(cm)) return;
|
@@ -1502,7 +1573,8 @@ window.CodeMirror = (function() {
|
|
1502
1573
|
// Don't do a replace if the drop happened inside of the selected text.
|
1503
1574
|
if (cm.view.draggingText && !(posLess(pos, cm.view.sel.from) || posLess(cm.view.sel.to, pos))) {
|
1504
1575
|
cm.view.draggingText(e);
|
1505
|
-
|
1576
|
+
// Ensure the editor is re-focused
|
1577
|
+
setTimeout(bind(focusInput, cm), 20);
|
1506
1578
|
return;
|
1507
1579
|
}
|
1508
1580
|
try {
|
@@ -1546,13 +1618,24 @@ window.CodeMirror = (function() {
|
|
1546
1618
|
}
|
1547
1619
|
|
1548
1620
|
function onDragStart(cm, e) {
|
1621
|
+
if (eventInWidget(cm.display, e)) return;
|
1622
|
+
|
1549
1623
|
var txt = cm.getSelection();
|
1550
1624
|
e.dataTransfer.setData("Text", txt);
|
1551
1625
|
|
1552
1626
|
// Use dummy image instead of default browsers image.
|
1553
1627
|
// Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
|
1554
|
-
if (e.dataTransfer.setDragImage && !safari)
|
1555
|
-
|
1628
|
+
if (e.dataTransfer.setDragImage && !safari) {
|
1629
|
+
var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
|
1630
|
+
if (opera) {
|
1631
|
+
img.width = img.height = 1;
|
1632
|
+
cm.display.wrapper.appendChild(img);
|
1633
|
+
// Force a relayout, or Opera won't use our image for some obscure reason
|
1634
|
+
img._top = img.offsetTop;
|
1635
|
+
}
|
1636
|
+
e.dataTransfer.setDragImage(img, 0, 0);
|
1637
|
+
if (opera) img.parentNode.removeChild(img);
|
1638
|
+
}
|
1556
1639
|
}
|
1557
1640
|
|
1558
1641
|
function setScrollTop(cm, val) {
|
@@ -1565,6 +1648,7 @@ window.CodeMirror = (function() {
|
|
1565
1648
|
}
|
1566
1649
|
function setScrollLeft(cm, val, isScroller) {
|
1567
1650
|
if (isScroller ? val == cm.view.scrollLeft : Math.abs(cm.view.scrollLeft - val) < 2) return;
|
1651
|
+
val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
|
1568
1652
|
cm.view.scrollLeft = val;
|
1569
1653
|
alignHorizontally(cm);
|
1570
1654
|
if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
|
@@ -1582,7 +1666,7 @@ window.CodeMirror = (function() {
|
|
1582
1666
|
// is that it gives us a chance to update the display before the
|
1583
1667
|
// actual scrolling happens, reducing flickering.
|
1584
1668
|
|
1585
|
-
var wheelSamples = 0,
|
1669
|
+
var wheelSamples = 0, wheelPixelsPerUnit = null;
|
1586
1670
|
// Fill in a browser-detected starting value on browsers where we
|
1587
1671
|
// know one. These don't have to be accurate -- the result of them
|
1588
1672
|
// being wrong would just be a slight flicker on the first wheel
|
@@ -1611,7 +1695,7 @@ window.CodeMirror = (function() {
|
|
1611
1695
|
}
|
1612
1696
|
}
|
1613
1697
|
|
1614
|
-
var
|
1698
|
+
var display = cm.display, scroll = display.scroller;
|
1615
1699
|
// On some browsers, horizontal scrolling will cause redraws to
|
1616
1700
|
// happen before the gutter has been realigned, causing it to
|
1617
1701
|
// wriggle around in a most unseemly way. When we have an
|
@@ -1623,35 +1707,35 @@ window.CodeMirror = (function() {
|
|
1623
1707
|
setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
|
1624
1708
|
setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
|
1625
1709
|
e_preventDefault(e);
|
1626
|
-
wheelStartX = null; // Abort measurement, if in progress
|
1710
|
+
display.wheelStartX = null; // Abort measurement, if in progress
|
1627
1711
|
return;
|
1628
1712
|
}
|
1629
1713
|
|
1630
1714
|
if (dy && wheelPixelsPerUnit != null) {
|
1631
1715
|
var pixels = dy * wheelPixelsPerUnit;
|
1632
|
-
var top = cm.view.scrollTop, bot = top +
|
1716
|
+
var top = cm.view.scrollTop, bot = top + display.wrapper.clientHeight;
|
1633
1717
|
if (pixels < 0) top = Math.max(0, top + pixels - 50);
|
1634
1718
|
else bot = Math.min(cm.view.doc.height, bot + pixels + 50);
|
1635
1719
|
updateDisplay(cm, [], {top: top, bottom: bot});
|
1636
1720
|
}
|
1637
1721
|
|
1638
1722
|
if (wheelSamples < 20) {
|
1639
|
-
if (wheelStartX == null) {
|
1640
|
-
wheelStartX = scroll.scrollLeft; wheelStartY = scroll.scrollTop;
|
1641
|
-
wheelDX = dx; wheelDY = dy;
|
1723
|
+
if (display.wheelStartX == null) {
|
1724
|
+
display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
|
1725
|
+
display.wheelDX = dx; display.wheelDY = dy;
|
1642
1726
|
setTimeout(function() {
|
1643
|
-
if (wheelStartX == null) return;
|
1644
|
-
var movedX = scroll.scrollLeft - wheelStartX;
|
1645
|
-
var movedY = scroll.scrollTop - wheelStartY;
|
1646
|
-
var sample = (movedY && wheelDY && movedY / wheelDY) ||
|
1647
|
-
(movedX && wheelDX && movedX / wheelDX);
|
1648
|
-
wheelStartX = wheelStartY = null;
|
1727
|
+
if (display.wheelStartX == null) return;
|
1728
|
+
var movedX = scroll.scrollLeft - display.wheelStartX;
|
1729
|
+
var movedY = scroll.scrollTop - display.wheelStartY;
|
1730
|
+
var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
|
1731
|
+
(movedX && display.wheelDX && movedX / display.wheelDX);
|
1732
|
+
display.wheelStartX = display.wheelStartY = null;
|
1649
1733
|
if (!sample) return;
|
1650
1734
|
wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
|
1651
1735
|
++wheelSamples;
|
1652
1736
|
}, 200);
|
1653
1737
|
} else {
|
1654
|
-
wheelDX += dx; wheelDY += dy;
|
1738
|
+
display.wheelDX += dx; display.wheelDY += dy;
|
1655
1739
|
}
|
1656
1740
|
}
|
1657
1741
|
}
|
@@ -1697,7 +1781,6 @@ window.CodeMirror = (function() {
|
|
1697
1781
|
}, 50);
|
1698
1782
|
|
1699
1783
|
var name = keyNames[e_prop(e, "keyCode")], handled = false;
|
1700
|
-
var flipCtrlCmd = mac && (opera || qtwebkit);
|
1701
1784
|
if (name == null || e.altGraphKey) return false;
|
1702
1785
|
if (e_prop(e, "altKey")) name = "Alt-" + name;
|
1703
1786
|
if (e_prop(e, flipCtrlCmd ? "metaKey" : "ctrlKey")) name = "Ctrl-" + name;
|
@@ -1794,7 +1877,10 @@ window.CodeMirror = (function() {
|
|
1794
1877
|
|
1795
1878
|
var detectingSelectAll;
|
1796
1879
|
function onContextMenu(cm, e) {
|
1797
|
-
var display = cm.display
|
1880
|
+
var display = cm.display;
|
1881
|
+
if (eventInWidget(display, e)) return;
|
1882
|
+
|
1883
|
+
var sel = cm.view.sel;
|
1798
1884
|
var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
|
1799
1885
|
if (!pos || opera) return; // Opera is difficult.
|
1800
1886
|
if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
|
@@ -1904,7 +1990,7 @@ window.CodeMirror = (function() {
|
|
1904
1990
|
if (!cm.options.lineWrapping) {
|
1905
1991
|
checkWidthStart = lineNo(visualLine(doc, firstLine));
|
1906
1992
|
doc.iter(checkWidthStart, to.line + 1, function(line) {
|
1907
|
-
if (
|
1993
|
+
if (line == view.maxLine) {
|
1908
1994
|
recomputeMaxLength = true;
|
1909
1995
|
return true;
|
1910
1996
|
}
|
@@ -2351,6 +2437,25 @@ window.CodeMirror = (function() {
|
|
2351
2437
|
}
|
2352
2438
|
},
|
2353
2439
|
|
2440
|
+
addOverlay: operation(null, function(spec, options) {
|
2441
|
+
var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
|
2442
|
+
if (mode.startState) throw new Error("Overlays may not be stateful.");
|
2443
|
+
this.view.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
|
2444
|
+
this.view.modeGen++;
|
2445
|
+
regChange(this, 0, this.view.doc.size);
|
2446
|
+
}),
|
2447
|
+
removeOverlay: operation(null, function(spec) {
|
2448
|
+
var overlays = this.view.overlays;
|
2449
|
+
for (var i = 0; i < overlays.length; ++i) {
|
2450
|
+
if (overlays[i].modeSpec == spec) {
|
2451
|
+
overlays.splice(i, 1);
|
2452
|
+
this.view.modeGen++;
|
2453
|
+
regChange(this, 0, this.view.doc.size);
|
2454
|
+
return;
|
2455
|
+
}
|
2456
|
+
}
|
2457
|
+
}),
|
2458
|
+
|
2354
2459
|
undo: operation(null, function() {unredoHelper(this, "undo");}),
|
2355
2460
|
redo: operation(null, function() {unredoHelper(this, "redo");}),
|
2356
2461
|
|
@@ -2522,23 +2627,10 @@ window.CodeMirror = (function() {
|
|
2522
2627
|
}),
|
2523
2628
|
|
2524
2629
|
addLineWidget: operation(null, function(handle, node, options) {
|
2525
|
-
|
2526
|
-
widget.node = node;
|
2527
|
-
if (widget.noHScroll) this.display.alignWidgets = true;
|
2528
|
-
changeLine(this, handle, function(line) {
|
2529
|
-
(line.widgets || (line.widgets = [])).push(widget);
|
2530
|
-
widget.line = line;
|
2531
|
-
return true;
|
2532
|
-
});
|
2533
|
-
return widget;
|
2630
|
+
return addLineWidget(this, handle, node, options);
|
2534
2631
|
}),
|
2535
2632
|
|
2536
|
-
removeLineWidget:
|
2537
|
-
var ws = widget.line.widgets, no = lineNo(widget.line);
|
2538
|
-
if (no == null) return;
|
2539
|
-
for (var i = 0; i < ws.length; ++i) if (ws[i] == widget) ws.splice(i--, 1);
|
2540
|
-
regChange(this, no, no + 1);
|
2541
|
-
}),
|
2633
|
+
removeLineWidget: function(widget) { widget.clear(); },
|
2542
2634
|
|
2543
2635
|
lineInfo: function(line) {
|
2544
2636
|
if (typeof line == "number") {
|
@@ -2663,7 +2755,8 @@ window.CodeMirror = (function() {
|
|
2663
2755
|
// Stuff used by commands, probably not much use to outside code.
|
2664
2756
|
moveH: operation(null, function(dir, unit) {
|
2665
2757
|
var sel = this.view.sel, pos = dir < 0 ? sel.from : sel.to;
|
2666
|
-
if (sel.shift || sel.extend || posEq(sel.from, sel.to))
|
2758
|
+
if (sel.shift || sel.extend || posEq(sel.from, sel.to))
|
2759
|
+
pos = findPosH(this, dir, unit, this.options.rtlMoveVisually);
|
2667
2760
|
extendSelection(this, pos, pos, dir);
|
2668
2761
|
}),
|
2669
2762
|
|
@@ -2713,7 +2806,7 @@ window.CodeMirror = (function() {
|
|
2713
2806
|
return clipPos(doc, {line: lineNo, ch: ch});
|
2714
2807
|
},
|
2715
2808
|
indexFromPos: function (coords) {
|
2716
|
-
|
2809
|
+
coords = clipPos(this.view.doc, coords);
|
2717
2810
|
var index = coords.ch;
|
2718
2811
|
this.view.doc.iter(0, coords.line, function (line) {
|
2719
2812
|
index += line.text.length + 1;
|
@@ -2735,8 +2828,12 @@ window.CodeMirror = (function() {
|
|
2735
2828
|
|
2736
2829
|
scrollIntoView: function(pos) {
|
2737
2830
|
if (typeof pos == "number") pos = {line: pos, ch: 0};
|
2738
|
-
pos
|
2739
|
-
|
2831
|
+
if (!pos || pos.line != null) {
|
2832
|
+
pos = pos ? clipPos(this.view.doc, pos) : this.view.sel.head;
|
2833
|
+
scrollPosIntoView(this, pos);
|
2834
|
+
} else {
|
2835
|
+
scrollIntoView(this, pos.left, pos.top, pos.right, pos.bottom);
|
2836
|
+
}
|
2740
2837
|
},
|
2741
2838
|
|
2742
2839
|
setSize: function(width, height) {
|
@@ -2755,8 +2852,11 @@ window.CodeMirror = (function() {
|
|
2755
2852
|
|
2756
2853
|
refresh: function() {
|
2757
2854
|
clearCaches(this);
|
2758
|
-
|
2759
|
-
|
2855
|
+
var sTop = this.view.scrollTop, sLeft = this.view.scrollLeft;
|
2856
|
+
if (this.display.scroller.scrollHeight > sTop)
|
2857
|
+
this.display.scrollbarV.scrollTop = this.display.scroller.scrollTop = sTop;
|
2858
|
+
if (this.display.scroller.scrollWidth > sLeft)
|
2859
|
+
this.display.scrollbarH.scrollLeft = this.display.scroller.scrollLeft = sLeft;
|
2760
2860
|
updateDisplay(this, true);
|
2761
2861
|
},
|
2762
2862
|
|
@@ -2795,6 +2895,7 @@ window.CodeMirror = (function() {
|
|
2795
2895
|
updateDisplay(cm, true);
|
2796
2896
|
}, true);
|
2797
2897
|
option("electricChars", true);
|
2898
|
+
option("rtlMoveVisually", !windows);
|
2798
2899
|
|
2799
2900
|
option("theme", "default", function(cm) {
|
2800
2901
|
themeChanged(cm);
|
@@ -2811,6 +2912,10 @@ window.CodeMirror = (function() {
|
|
2811
2912
|
setGuttersForLineNumbers(cm.options);
|
2812
2913
|
guttersChanged(cm);
|
2813
2914
|
}, true);
|
2915
|
+
option("fixedGutter", true, function(cm, val) {
|
2916
|
+
cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
|
2917
|
+
cm.refresh();
|
2918
|
+
}, true);
|
2814
2919
|
option("lineNumbers", false, function(cm) {
|
2815
2920
|
setGuttersForLineNumbers(cm.options);
|
2816
2921
|
guttersChanged(cm);
|
@@ -2867,7 +2972,7 @@ window.CodeMirror = (function() {
|
|
2867
2972
|
};
|
2868
2973
|
|
2869
2974
|
CodeMirror.getMode = function(options, spec) {
|
2870
|
-
|
2975
|
+
spec = CodeMirror.resolveMode(spec);
|
2871
2976
|
var mfactory = modes[spec.name];
|
2872
2977
|
if (!mfactory) return CodeMirror.getMode(options, "text/plain");
|
2873
2978
|
var modeObj = mfactory(options, spec);
|
@@ -3204,11 +3309,12 @@ window.CodeMirror = (function() {
|
|
3204
3309
|
this.type = type;
|
3205
3310
|
this.cm = cm;
|
3206
3311
|
}
|
3312
|
+
CodeMirror.TextMarker = TextMarker;
|
3207
3313
|
|
3208
3314
|
TextMarker.prototype.clear = function() {
|
3209
3315
|
if (this.explicitlyCleared) return;
|
3210
3316
|
startOperation(this.cm);
|
3211
|
-
var min = null, max = null;
|
3317
|
+
var view = this.cm.view, min = null, max = null;
|
3212
3318
|
for (var i = 0; i < this.lines.length; ++i) {
|
3213
3319
|
var line = this.lines[i];
|
3214
3320
|
var span = getMarkedSpanFor(line.markedSpans, this);
|
@@ -3219,6 +3325,15 @@ window.CodeMirror = (function() {
|
|
3219
3325
|
else if (this.collapsed && !lineIsHidden(line))
|
3220
3326
|
updateLineHeight(line, textHeight(this.cm.display));
|
3221
3327
|
}
|
3328
|
+
if (this.collapsed && !this.cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
|
3329
|
+
var visual = visualLine(view.doc, this.lines[i]), len = lineLength(view.doc, visual);
|
3330
|
+
if (len > view.maxLineLength) {
|
3331
|
+
view.maxLine = visual;
|
3332
|
+
view.maxLineLength = len;
|
3333
|
+
view.maxLineChanged = true;
|
3334
|
+
}
|
3335
|
+
}
|
3336
|
+
|
3222
3337
|
if (min != null) regChange(this.cm, min, max + 1);
|
3223
3338
|
this.lines.length = 0;
|
3224
3339
|
this.explicitlyCleared = true;
|
@@ -3245,6 +3360,18 @@ window.CodeMirror = (function() {
|
|
3245
3360
|
return from && {from: from, to: to};
|
3246
3361
|
};
|
3247
3362
|
|
3363
|
+
TextMarker.prototype.getOptions = function(copyWidget) {
|
3364
|
+
var repl = this.replacedWith;
|
3365
|
+
return {className: this.className,
|
3366
|
+
inclusiveLeft: this.inclusiveLeft, inclusiveRight: this.inclusiveRight,
|
3367
|
+
atomic: this.atomic,
|
3368
|
+
collapsed: this.collapsed,
|
3369
|
+
clearOnEnter: this.clearOnEnter,
|
3370
|
+
replacedWith: copyWidget ? repl && repl.cloneNode(true) : repl,
|
3371
|
+
readOnly: this.readOnly,
|
3372
|
+
startStyle: this.startStyle, endStyle: this.endStyle};
|
3373
|
+
};
|
3374
|
+
|
3248
3375
|
function markText(cm, from, to, options, type) {
|
3249
3376
|
var doc = cm.view.doc;
|
3250
3377
|
var marker = new TextMarker(cm, type);
|
@@ -3259,6 +3386,8 @@ window.CodeMirror = (function() {
|
|
3259
3386
|
|
3260
3387
|
var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd;
|
3261
3388
|
doc.iter(curLine, to.line + 1, function(line) {
|
3389
|
+
if (marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.view.maxLine)
|
3390
|
+
cm.curOp.updateMaxLine = true;
|
3262
3391
|
var span = {from: null, to: null, marker: marker};
|
3263
3392
|
size += line.text.length;
|
3264
3393
|
if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
|
@@ -3269,10 +3398,11 @@ window.CodeMirror = (function() {
|
|
3269
3398
|
else updateLineHeight(line, 0);
|
3270
3399
|
}
|
3271
3400
|
addMarkedSpan(line, span);
|
3272
|
-
if (marker.collapsed && curLine == from.line && lineIsHidden(line))
|
3273
|
-
updateLineHeight(line, 0);
|
3274
3401
|
++curLine;
|
3275
3402
|
});
|
3403
|
+
if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
|
3404
|
+
if (lineIsHidden(line)) updateLineHeight(line, 0);
|
3405
|
+
});
|
3276
3406
|
|
3277
3407
|
if (marker.readOnly) {
|
3278
3408
|
sawReadOnlySpans = true;
|
@@ -3447,9 +3577,12 @@ window.CodeMirror = (function() {
|
|
3447
3577
|
return true;
|
3448
3578
|
}
|
3449
3579
|
}
|
3450
|
-
window.lineIsHidden = lineIsHidden;
|
3451
3580
|
function lineIsHiddenInner(line, span) {
|
3452
|
-
if (span.to == null
|
3581
|
+
if (span.to == null) {
|
3582
|
+
var end = span.marker.find().to, endLine = getLine(lineDoc(line), end.line);
|
3583
|
+
return lineIsHiddenInner(endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
|
3584
|
+
}
|
3585
|
+
if (span.marker.inclusiveRight && span.to == line.text.length)
|
3453
3586
|
return true;
|
3454
3587
|
for (var sp, i = 0; i < line.markedSpans.length; ++i) {
|
3455
3588
|
sp = line.markedSpans[i];
|
@@ -3491,6 +3624,63 @@ window.CodeMirror = (function() {
|
|
3491
3624
|
line.markedSpans = spans;
|
3492
3625
|
}
|
3493
3626
|
|
3627
|
+
// LINE WIDGETS
|
3628
|
+
|
3629
|
+
var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
|
3630
|
+
for (var opt in options) if (options.hasOwnProperty(opt))
|
3631
|
+
this[opt] = options[opt];
|
3632
|
+
this.cm = cm;
|
3633
|
+
this.node = node;
|
3634
|
+
};
|
3635
|
+
function widgetOperation(f) {
|
3636
|
+
return function() {
|
3637
|
+
startOperation(this.cm);
|
3638
|
+
try {var result = f.apply(this, arguments);}
|
3639
|
+
finally {endOperation(this.cm);}
|
3640
|
+
return result;
|
3641
|
+
};
|
3642
|
+
}
|
3643
|
+
LineWidget.prototype.clear = widgetOperation(function() {
|
3644
|
+
var ws = this.line.widgets, no = lineNo(this.line);
|
3645
|
+
if (no == null || !ws) return;
|
3646
|
+
for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
|
3647
|
+
updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
|
3648
|
+
regChange(this.cm, no, no + 1);
|
3649
|
+
});
|
3650
|
+
LineWidget.prototype.changed = widgetOperation(function() {
|
3651
|
+
var oldH = this.height;
|
3652
|
+
this.height = null;
|
3653
|
+
var diff = widgetHeight(this) - oldH;
|
3654
|
+
if (!diff) return;
|
3655
|
+
updateLineHeight(this.line, this.line.height + diff);
|
3656
|
+
var no = lineNo(this.line);
|
3657
|
+
regChange(this.cm, no, no + 1);
|
3658
|
+
});
|
3659
|
+
|
3660
|
+
function widgetHeight(widget) {
|
3661
|
+
if (widget.height != null) return widget.height;
|
3662
|
+
if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
|
3663
|
+
removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
|
3664
|
+
return widget.height = widget.node.offsetHeight;
|
3665
|
+
}
|
3666
|
+
|
3667
|
+
function addLineWidget(cm, handle, node, options) {
|
3668
|
+
var widget = new LineWidget(cm, node, options);
|
3669
|
+
if (widget.noHScroll) cm.display.alignWidgets = true;
|
3670
|
+
changeLine(cm, handle, function(line) {
|
3671
|
+
(line.widgets || (line.widgets = [])).push(widget);
|
3672
|
+
widget.line = line;
|
3673
|
+
if (!lineIsHidden(line) || widget.showIfHidden) {
|
3674
|
+
var aboveVisible = heightAtLine(cm, line) < cm.display.scroller.scrollTop;
|
3675
|
+
updateLineHeight(line, line.height + widgetHeight(widget));
|
3676
|
+
if (aboveVisible)
|
3677
|
+
setTimeout(function() {cm.display.scroller.scrollTop += widget.height;});
|
3678
|
+
}
|
3679
|
+
return true;
|
3680
|
+
});
|
3681
|
+
return widget;
|
3682
|
+
}
|
3683
|
+
|
3494
3684
|
// LINE DATA STRUCTURE
|
3495
3685
|
|
3496
3686
|
// Line objects. These hold state related to a line, including
|
@@ -3504,7 +3694,8 @@ window.CodeMirror = (function() {
|
|
3504
3694
|
|
3505
3695
|
function updateLine(cm, line, text, markedSpans) {
|
3506
3696
|
line.text = text;
|
3507
|
-
line.stateAfter
|
3697
|
+
if (line.stateAfter) line.stateAfter = null;
|
3698
|
+
if (line.styles) line.styles = null;
|
3508
3699
|
if (line.order != null) line.order = null;
|
3509
3700
|
detachMarkedSpans(line);
|
3510
3701
|
attachMarkedSpans(line, markedSpans);
|
@@ -3521,31 +3712,72 @@ window.CodeMirror = (function() {
|
|
3521
3712
|
// Run the given mode's parser over a line, update the styles
|
3522
3713
|
// array, which contains alternating fragments of text and CSS
|
3523
3714
|
// classes.
|
3524
|
-
function
|
3525
|
-
var
|
3526
|
-
var
|
3527
|
-
var stream = new StringStream(
|
3528
|
-
if (
|
3715
|
+
function runMode(cm, text, mode, state, f) {
|
3716
|
+
var flattenSpans = cm.options.flattenSpans;
|
3717
|
+
var curText = "", curStyle = null;
|
3718
|
+
var stream = new StringStream(text, cm.options.tabSize);
|
3719
|
+
if (text == "" && mode.blankLine) mode.blankLine(state);
|
3529
3720
|
while (!stream.eol()) {
|
3530
|
-
var style = mode.token(stream, state)
|
3721
|
+
var style = mode.token(stream, state);
|
3722
|
+
if (stream.pos > 5000) {
|
3723
|
+
flattenSpans = false;
|
3724
|
+
// Webkit seems to refuse to render text nodes longer than 57444 characters
|
3725
|
+
stream.pos = Math.min(text.length, stream.start + 50000);
|
3726
|
+
style = null;
|
3727
|
+
}
|
3728
|
+
var substr = stream.current();
|
3531
3729
|
stream.start = stream.pos;
|
3532
3730
|
if (!flattenSpans || curStyle != style) {
|
3533
|
-
if (curText)
|
3534
|
-
changed = changed || pos >= st.length || curText != st[pos] || curStyle != st[pos+1];
|
3535
|
-
st[pos++] = curText; st[pos++] = curStyle;
|
3536
|
-
}
|
3731
|
+
if (curText) f(curText, curStyle);
|
3537
3732
|
curText = substr; curStyle = style;
|
3538
3733
|
} else curText = curText + substr;
|
3539
|
-
// Give up when line is ridiculously long
|
3540
|
-
if (stream.pos > 5000) break;
|
3541
3734
|
}
|
3542
|
-
if (curText)
|
3543
|
-
|
3544
|
-
|
3735
|
+
if (curText) f(curText, curStyle);
|
3736
|
+
}
|
3737
|
+
|
3738
|
+
function highlightLine(cm, line, state) {
|
3739
|
+
// A styles array always starts with a number identifying the
|
3740
|
+
// mode/overlays that it is based on (for easy invalidation).
|
3741
|
+
var st = [cm.view.modeGen];
|
3742
|
+
// Compute the base array of styles
|
3743
|
+
runMode(cm, line.text, cm.view.mode, state, function(txt, style) {st.push(txt, style);});
|
3744
|
+
|
3745
|
+
// Run overlays, adjust style array.
|
3746
|
+
for (var o = 0; o < cm.view.overlays.length; ++o) {
|
3747
|
+
var overlay = cm.view.overlays[o], i = 1;
|
3748
|
+
runMode(cm, line.text, overlay.mode, true, function(txt, style) {
|
3749
|
+
var start = i, len = txt.length;
|
3750
|
+
// Ensure there's a token end at the current position, and that i points at it
|
3751
|
+
while (len) {
|
3752
|
+
var cur = st[i], len_ = cur.length;
|
3753
|
+
if (len_ <= len) {
|
3754
|
+
len -= len_;
|
3755
|
+
} else {
|
3756
|
+
st.splice(i, 1, cur.slice(0, len), st[i+1], cur.slice(len));
|
3757
|
+
len = 0;
|
3758
|
+
}
|
3759
|
+
i += 2;
|
3760
|
+
}
|
3761
|
+
if (!style) return;
|
3762
|
+
if (overlay.opaque) {
|
3763
|
+
st.splice(start, i - start, txt, style);
|
3764
|
+
i = start + 2;
|
3765
|
+
} else {
|
3766
|
+
for (; start < i; start += 2) {
|
3767
|
+
var cur = st[start+1];
|
3768
|
+
st[start+1] = cur ? cur + " " + style : style;
|
3769
|
+
}
|
3770
|
+
}
|
3771
|
+
});
|
3545
3772
|
}
|
3546
|
-
|
3547
|
-
|
3548
|
-
|
3773
|
+
|
3774
|
+
return st;
|
3775
|
+
}
|
3776
|
+
|
3777
|
+
function getLineStyles(cm, line) {
|
3778
|
+
if (!line.styles || line.styles[0] != cm.view.modeGen)
|
3779
|
+
line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
|
3780
|
+
return line.styles;
|
3549
3781
|
}
|
3550
3782
|
|
3551
3783
|
// Lightweight form of highlight -- proceed over this line and
|
@@ -3580,8 +3812,6 @@ window.CodeMirror = (function() {
|
|
3580
3812
|
if (line.textClass) builder.pre.className = line.textClass;
|
3581
3813
|
|
3582
3814
|
do {
|
3583
|
-
if (!line.styles)
|
3584
|
-
highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
|
3585
3815
|
builder.measure = line == realLine && measure;
|
3586
3816
|
builder.pos = 0;
|
3587
3817
|
builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
|
@@ -3589,7 +3819,7 @@ window.CodeMirror = (function() {
|
|
3589
3819
|
measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
|
3590
3820
|
builder.addedOne = true;
|
3591
3821
|
}
|
3592
|
-
var next = insertLineContent(line, builder);
|
3822
|
+
var next = insertLineContent(line, builder, getLineStyles(cm, line));
|
3593
3823
|
sawBefore = line == lineBefore;
|
3594
3824
|
if (next) {
|
3595
3825
|
line = getLine(cm.view.doc, next.to.line);
|
@@ -3646,7 +3876,7 @@ window.CodeMirror = (function() {
|
|
3646
3876
|
|
3647
3877
|
function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
|
3648
3878
|
for (var i = 0; i < text.length; ++i) {
|
3649
|
-
if (i && i < text.length
|
3879
|
+
if (i && i < text.length &&
|
3650
3880
|
builder.cm.options.lineWrapping &&
|
3651
3881
|
spanAffectsWrapping.test(text.slice(i - 1, i + 1)))
|
3652
3882
|
builder.pre.appendChild(elt("wbr"));
|
@@ -3671,16 +3901,16 @@ window.CodeMirror = (function() {
|
|
3671
3901
|
|
3672
3902
|
// Outputs a number of spans to make up a line, taking highlighting
|
3673
3903
|
// and marked text into account.
|
3674
|
-
function insertLineContent(line, builder) {
|
3675
|
-
var
|
3904
|
+
function insertLineContent(line, builder, styles) {
|
3905
|
+
var spans = line.markedSpans;
|
3676
3906
|
if (!spans) {
|
3677
|
-
for (var i =
|
3678
|
-
builder.addToken(builder,
|
3907
|
+
for (var i = 1; i < styles.length; i+=2)
|
3908
|
+
builder.addToken(builder, styles[i], styleToClass(styles[i+1]));
|
3679
3909
|
return;
|
3680
3910
|
}
|
3681
3911
|
|
3682
3912
|
var allText = line.text, len = allText.length;
|
3683
|
-
var pos = 0, i =
|
3913
|
+
var pos = 0, i = 1, text = "", style;
|
3684
3914
|
var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, collapsed;
|
3685
3915
|
for (;;) {
|
3686
3916
|
if (nextChange == pos) { // Update current marker set
|
@@ -3724,7 +3954,7 @@ window.CodeMirror = (function() {
|
|
3724
3954
|
pos = end;
|
3725
3955
|
spanStartStyle = "";
|
3726
3956
|
}
|
3727
|
-
text =
|
3957
|
+
text = styles[i++]; style = styleToClass(styles[i++]);
|
3728
3958
|
}
|
3729
3959
|
}
|
3730
3960
|
}
|
@@ -3896,6 +4126,11 @@ window.CodeMirror = (function() {
|
|
3896
4126
|
return no;
|
3897
4127
|
}
|
3898
4128
|
|
4129
|
+
function lineDoc(line) {
|
4130
|
+
for (var d = line.parent; d.parent; d = d.parent) {}
|
4131
|
+
return d;
|
4132
|
+
}
|
4133
|
+
|
3899
4134
|
function lineAtHeight(chunk, h) {
|
3900
4135
|
var n = 0;
|
3901
4136
|
outer: do {
|
@@ -4177,7 +4412,9 @@ window.CodeMirror = (function() {
|
|
4177
4412
|
}
|
4178
4413
|
|
4179
4414
|
function removeChildren(e) {
|
4180
|
-
|
4415
|
+
// IE will break all parent-child relations in subnodes when setting innerHTML
|
4416
|
+
if (!ie) e.innerHTML = "";
|
4417
|
+
else while (e.firstChild) e.removeChild(e.firstChild);
|
4181
4418
|
return e;
|
4182
4419
|
}
|
4183
4420
|
|
@@ -4300,7 +4537,7 @@ window.CodeMirror = (function() {
|
|
4300
4537
|
if (!order) return f(from, to, "ltr");
|
4301
4538
|
for (var i = 0; i < order.length; ++i) {
|
4302
4539
|
var part = order[i];
|
4303
|
-
if (part.from < to && part.to > from)
|
4540
|
+
if (part.from < to && part.to > from || from == to && part.to == from)
|
4304
4541
|
f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
|
4305
4542
|
}
|
4306
4543
|
}
|
@@ -4418,24 +4655,20 @@ window.CodeMirror = (function() {
|
|
4418
4655
|
|
4419
4656
|
var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
|
4420
4657
|
var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
|
4658
|
+
// Browsers seem to always treat the boundaries of block elements as being L.
|
4659
|
+
var outerType = "L";
|
4421
4660
|
|
4422
4661
|
return function charOrdering(str) {
|
4423
4662
|
if (!bidiRE.test(str)) return false;
|
4424
|
-
var len = str.length, types = []
|
4425
|
-
for (var i = 0, type; i < len; ++i)
|
4663
|
+
var len = str.length, types = [];
|
4664
|
+
for (var i = 0, type; i < len; ++i)
|
4426
4665
|
types.push(type = charType(str.charCodeAt(i)));
|
4427
|
-
if (startType == null) {
|
4428
|
-
if (type == "L") startType = "L";
|
4429
|
-
else if (type == "R" || type == "r") startType = "R";
|
4430
|
-
}
|
4431
|
-
}
|
4432
|
-
if (startType == null) startType = "L";
|
4433
4666
|
|
4434
4667
|
// W1. Examine each non-spacing mark (NSM) in the level run, and
|
4435
4668
|
// change the type of the NSM to the type of the previous
|
4436
4669
|
// character. If the NSM is at the start of the level run, it will
|
4437
4670
|
// get the type of sor.
|
4438
|
-
for (var i = 0, prev =
|
4671
|
+
for (var i = 0, prev = outerType; i < len; ++i) {
|
4439
4672
|
var type = types[i];
|
4440
4673
|
if (type == "m") types[i] = prev;
|
4441
4674
|
else prev = type;
|
@@ -4446,7 +4679,7 @@ window.CodeMirror = (function() {
|
|
4446
4679
|
// AL is found, change the type of the European number to Arabic
|
4447
4680
|
// number.
|
4448
4681
|
// W3. Change all ALs to R.
|
4449
|
-
for (var i = 0, cur =
|
4682
|
+
for (var i = 0, cur = outerType; i < len; ++i) {
|
4450
4683
|
var type = types[i];
|
4451
4684
|
if (type == "1" && cur == "r") types[i] = "n";
|
4452
4685
|
else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
|
@@ -4481,7 +4714,7 @@ window.CodeMirror = (function() {
|
|
4481
4714
|
// W7. Search backwards from each instance of a European number
|
4482
4715
|
// until the first strong type (R, L, or sor) is found. If an L is
|
4483
4716
|
// found, then change the type of the European number to L.
|
4484
|
-
for (var i = 0, cur =
|
4717
|
+
for (var i = 0, cur = outerType; i < len; ++i) {
|
4485
4718
|
var type = types[i];
|
4486
4719
|
if (cur == "L" && type == "1") types[i] = "L";
|
4487
4720
|
else if (isStrong.test(type)) cur = type;
|
@@ -4496,8 +4729,8 @@ window.CodeMirror = (function() {
|
|
4496
4729
|
for (var i = 0; i < len; ++i) {
|
4497
4730
|
if (isNeutral.test(types[i])) {
|
4498
4731
|
for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
|
4499
|
-
var before = (i ? types[i-1] :
|
4500
|
-
var after = (end < len - 1 ? types[end] :
|
4732
|
+
var before = (i ? types[i-1] : outerType) == "L";
|
4733
|
+
var after = (end < len - 1 ? types[end] : outerType) == "L";
|
4501
4734
|
var replace = before || after ? "L" : "R";
|
4502
4735
|
for (var j = i; j < end; ++j) types[j] = replace;
|
4503
4736
|
i = end - 1;
|
@@ -4547,7 +4780,7 @@ window.CodeMirror = (function() {
|
|
4547
4780
|
|
4548
4781
|
// THE END
|
4549
4782
|
|
4550
|
-
CodeMirror.version = "3.
|
4783
|
+
CodeMirror.version = "3.02";
|
4551
4784
|
|
4552
4785
|
return CodeMirror;
|
4553
4786
|
})();
|