codemirror-rails 3.00 → 3.02
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|
})();
|