codemirror-rails 2.3 → 2.21
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 +0 -16
- data/codemirror-rails.gemspec +1 -1
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +323 -687
- data/vendor/assets/javascripts/codemirror/modes/clike.js +3 -40
- data/vendor/assets/javascripts/codemirror/modes/clojure.js +14 -14
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +0 -6
- data/vendor/assets/javascripts/codemirror/modes/css.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/diff.js +5 -24
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +4 -40
- data/vendor/assets/javascripts/codemirror/modes/go.js +22 -20
- data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +2 -4
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +7 -8
- data/vendor/assets/javascripts/codemirror/modes/less.js +54 -100
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +49 -52
- data/vendor/assets/javascripts/codemirror/modes/pascal.js +46 -2
- data/vendor/assets/javascripts/codemirror/modes/perl.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/php.js +25 -54
- data/vendor/assets/javascripts/codemirror/modes/python.js +16 -14
- data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/rst.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +9 -4
- data/vendor/assets/javascripts/codemirror/modes/scheme.js +46 -74
- data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +16 -16
- data/vendor/assets/javascripts/codemirror/modes/stex.js +6 -21
- data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +45 -55
- data/vendor/assets/javascripts/codemirror/modes/xml.js +14 -79
- data/vendor/assets/javascripts/codemirror/{utils/overlay.js → overlay.js} +2 -3
- data/vendor/assets/javascripts/codemirror/runmode.js +27 -0
- data/vendor/assets/stylesheets/codemirror.css +2 -63
- data/vendor/assets/stylesheets/codemirror/modes/tiddlywiki.css +21 -14
- data/vendor/assets/stylesheets/codemirror/themes/eclipse.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/elegant.css +2 -2
- data/vendor/assets/stylesheets/codemirror/themes/neat.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +2 -2
- metadata +6 -39
- data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +0 -29
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +0 -766
- data/vendor/assets/javascripts/codemirror/modes/ecl.js +0 -203
- data/vendor/assets/javascripts/codemirror/modes/erlang.js +0 -251
- data/vendor/assets/javascripts/codemirror/modes/pig.js +0 -172
- data/vendor/assets/javascripts/codemirror/modes/properties.js +0 -63
- data/vendor/assets/javascripts/codemirror/modes/shell.js +0 -103
- data/vendor/assets/javascripts/codemirror/modes/smarty.js +0 -148
- data/vendor/assets/javascripts/codemirror/modes/tiki.js +0 -316
- data/vendor/assets/javascripts/codemirror/modes/vbscript.js +0 -26
- data/vendor/assets/javascripts/codemirror/modes/xquery.js +0 -448
- data/vendor/assets/javascripts/codemirror/utils/closetag.js +0 -146
- data/vendor/assets/javascripts/codemirror/utils/dialog.js +0 -63
- data/vendor/assets/javascripts/codemirror/utils/foldcode.js +0 -196
- data/vendor/assets/javascripts/codemirror/utils/formatting.js +0 -297
- data/vendor/assets/javascripts/codemirror/utils/javascript-hint.js +0 -134
- data/vendor/assets/javascripts/codemirror/utils/loadmode.js +0 -51
- data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +0 -44
- data/vendor/assets/javascripts/codemirror/utils/multiplex.js +0 -72
- data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +0 -123
- data/vendor/assets/javascripts/codemirror/utils/runmode.js +0 -49
- data/vendor/assets/javascripts/codemirror/utils/search.js +0 -118
- data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +0 -117
- data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +0 -72
- data/vendor/assets/stylesheets/codemirror/modes/tiki.css +0 -26
- data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +0 -81
- data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +0 -25
- data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +0 -21
- data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +0 -44
- data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +0 -27
- data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +0 -46
- data/vendor/assets/stylesheets/codemirror/utils/dialog.css +0 -23
- data/vendor/assets/stylesheets/codemirror/utils/simple-hint.css +0 -16
data/README.md
CHANGED
@@ -35,22 +35,6 @@ Additional syntax modes can be added to your application.js:
|
|
35
35
|
//= require codemirror/modes/ruby
|
36
36
|
```
|
37
37
|
|
38
|
-
### Adding a util
|
39
|
-
|
40
|
-
Additional reusable util components can be added in your application.js:
|
41
|
-
|
42
|
-
```js
|
43
|
-
//= require codemirror/utils/dialog
|
44
|
-
```
|
45
|
-
|
46
|
-
### Adding a keymap
|
47
|
-
|
48
|
-
Additional keymap bindings can be added to your application.js:
|
49
|
-
|
50
|
-
```js
|
51
|
-
//= require codemirror/keymaps/vim
|
52
|
-
```
|
53
|
-
|
54
38
|
### Adding a theme
|
55
39
|
|
56
40
|
Additional CSS themes can be added to your application.css
|
data/codemirror-rails.gemspec
CHANGED
@@ -3,7 +3,7 @@ require File.expand_path('../lib/codemirror/rails/version', __FILE__)
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'codemirror-rails'
|
5
5
|
s.version = Codemirror::Rails::VERSION
|
6
|
-
s.authors = ['Nathan Fixler'
|
6
|
+
s.authors = ['Nathan Fixler']
|
7
7
|
s.email = 'nathan@fixler.org'
|
8
8
|
s.summary = 'Use CodeMirror with Rails 3'
|
9
9
|
s.description = 'This gem provides CodeMirror assets for your Rails 3 application.'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// CodeMirror version 2.
|
1
|
+
// CodeMirror version 2.21
|
2
2
|
//
|
3
3
|
// All functions that need access to the editor's state live inside
|
4
4
|
// the CodeMirror function. Below that, at the bottom of the file,
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
// CodeMirror is the only global var we claim
|
8
8
|
var CodeMirror = (function() {
|
9
|
-
// This is the function that produces an editor instance.
|
9
|
+
// This is the function that produces an editor instance. It's
|
10
10
|
// closure is used to store the editor state.
|
11
11
|
function CodeMirror(place, givenOptions) {
|
12
12
|
// Determine effective options based on given values and defaults.
|
@@ -15,27 +15,23 @@ var CodeMirror = (function() {
|
|
15
15
|
if (defaults.hasOwnProperty(opt))
|
16
16
|
options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
|
17
17
|
|
18
|
+
var targetDocument = options["document"];
|
18
19
|
// The element in which the editor lives.
|
19
|
-
var wrapper =
|
20
|
+
var wrapper = targetDocument.createElement("div");
|
20
21
|
wrapper.className = "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : "");
|
21
22
|
// This mess creates the base DOM structure for the editor.
|
22
23
|
wrapper.innerHTML =
|
23
24
|
'<div style="overflow: hidden; position: relative; width: 3px; height: 0px;">' + // Wraps and hides input textarea
|
24
25
|
'<textarea style="position: absolute; padding: 0; width: 1px; height: 1em" wrap="off" ' +
|
25
26
|
'autocorrect="off" autocapitalize="off"></textarea></div>' +
|
26
|
-
'<div class="CodeMirror-scrollbar">' + // The vertical scrollbar. Horizontal scrolling is handled by the scroller itself.
|
27
|
-
'<div class="CodeMirror-scrollbar-inner">' + // The empty scrollbar content, used solely for managing the scrollbar thumb.
|
28
|
-
'</div></div>' + // This must be before the scroll area because it's float-right.
|
29
27
|
'<div class="CodeMirror-scroll" tabindex="-1">' +
|
30
28
|
'<div style="position: relative">' + // Set to the height of the text, causes scrolling
|
31
29
|
'<div style="position: relative">' + // Moved around its parent to cover visible view
|
32
30
|
'<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
|
33
31
|
// Provides positioning relative to (visible) text origin
|
34
32
|
'<div class="CodeMirror-lines"><div style="position: relative; z-index: 0">' +
|
35
|
-
|
36
|
-
'<div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden;"></div>' +
|
33
|
+
'<div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden; outline: 5px auto none"></div>' +
|
37
34
|
'<pre class="CodeMirror-cursor"> </pre>' + // Absolutely positioned blinky cursor
|
38
|
-
'<pre class="CodeMirror-cursor" style="visibility: hidden"> </pre>' + // Used to force a width
|
39
35
|
'<div style="position: relative; z-index: -1"></div><div></div>' + // DIVs containing the selection and the actual code
|
40
36
|
'</div></div></div></div></div>';
|
41
37
|
if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
|
@@ -44,30 +40,15 @@ var CodeMirror = (function() {
|
|
44
40
|
scroller = wrapper.lastChild, code = scroller.firstChild,
|
45
41
|
mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild,
|
46
42
|
lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,
|
47
|
-
cursor = measure.nextSibling,
|
48
|
-
|
49
|
-
|
50
|
-
themeChanged(); keyMapChanged();
|
43
|
+
cursor = measure.nextSibling, selectionDiv = cursor.nextSibling,
|
44
|
+
lineDiv = selectionDiv.nextSibling;
|
45
|
+
themeChanged();
|
51
46
|
// Needed to hide big blue blinking cursor on Mobile Safari
|
52
47
|
if (ios) input.style.width = "0px";
|
53
|
-
if (!webkit)
|
48
|
+
if (!webkit) lineSpace.draggable = true;
|
54
49
|
lineSpace.style.outline = "none";
|
55
50
|
if (options.tabindex != null) input.tabIndex = options.tabindex;
|
56
|
-
if (options.autofocus) focusInput();
|
57
51
|
if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
|
58
|
-
// Needed to handle Tab key in KHTML
|
59
|
-
if (khtml) inputDiv.style.height = "1px", inputDiv.style.position = "absolute";
|
60
|
-
|
61
|
-
// Check for OS X >= 10.7. If so, we need to force a width on the scrollbar, and
|
62
|
-
// make it overlap the content. (But we only do this if the scrollbar doesn't already
|
63
|
-
// have a natural width. If the mouse is plugged in or the user sets the system pref
|
64
|
-
// to always show scrollbars, the scrollbar shouldn't overlap.)
|
65
|
-
if (mac_geLion) {
|
66
|
-
scrollbar.className += (overlapScrollbars() ? " cm-sb-overlap" : " cm-sb-nonoverlap");
|
67
|
-
} else if (ie_lt8) {
|
68
|
-
// Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
|
69
|
-
scrollbar.className += " cm-sb-ie7";
|
70
|
-
}
|
71
52
|
|
72
53
|
// Check for problem with IE innerHTML not working when we have a
|
73
54
|
// P (or similar) parent node.
|
@@ -92,7 +73,7 @@ var CodeMirror = (function() {
|
|
92
73
|
var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
|
93
74
|
// Selection-related flags. shiftSelecting obviously tracks
|
94
75
|
// whether the user is holding shift.
|
95
|
-
var shiftSelecting, lastClick, lastDoubleClick,
|
76
|
+
var shiftSelecting, lastClick, lastDoubleClick, lastScrollPos = 0, draggingText,
|
96
77
|
overwrite = false, suppressEdits = false;
|
97
78
|
// Variables used by startOperation/endOperation to track what
|
98
79
|
// happened during the operation.
|
@@ -100,13 +81,12 @@ var CodeMirror = (function() {
|
|
100
81
|
gutterDirty, callbacks;
|
101
82
|
// Current visible range (may be bigger than the view window).
|
102
83
|
var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
|
103
|
-
// bracketHighlighted is used to remember that a
|
84
|
+
// bracketHighlighted is used to remember that a backet has been
|
104
85
|
// marked.
|
105
86
|
var bracketHighlighted;
|
106
87
|
// Tracks the maximum line length so that the horizontal scrollbar
|
107
88
|
// can be kept static when scrolling.
|
108
|
-
var maxLine = "",
|
109
|
-
var tabCache = {};
|
89
|
+
var maxLine = "", maxWidth, tabText = computeTabText();
|
110
90
|
|
111
91
|
// Initialize the content.
|
112
92
|
operation(function(){setValue(options.value || ""); updateInput = false;})();
|
@@ -115,16 +95,18 @@ var CodeMirror = (function() {
|
|
115
95
|
// Register our event handlers.
|
116
96
|
connect(scroller, "mousedown", operation(onMouseDown));
|
117
97
|
connect(scroller, "dblclick", operation(onDoubleClick));
|
98
|
+
connect(lineSpace, "dragstart", onDragStart);
|
118
99
|
connect(lineSpace, "selectstart", e_preventDefault);
|
119
100
|
// Gecko browsers fire contextmenu *after* opening the menu, at
|
120
101
|
// which point we can't mess with it anymore. Context menu is
|
121
102
|
// handled in onMouseDown for Gecko.
|
122
103
|
if (!gecko) connect(scroller, "contextmenu", onContextMenu);
|
123
|
-
connect(scroller, "scroll",
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
104
|
+
connect(scroller, "scroll", function() {
|
105
|
+
lastScrollPos = scroller.scrollTop;
|
106
|
+
updateDisplay([]);
|
107
|
+
if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
|
108
|
+
if (options.onScroll) options.onScroll(instance);
|
109
|
+
});
|
128
110
|
connect(window, "resize", function() {updateDisplay(true);});
|
129
111
|
connect(input, "keyup", operation(onKeyUp));
|
130
112
|
connect(input, "input", fastPoll);
|
@@ -133,32 +115,19 @@ var CodeMirror = (function() {
|
|
133
115
|
connect(input, "focus", onFocus);
|
134
116
|
connect(input, "blur", onBlur);
|
135
117
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
|
140
|
-
e_stop(e);
|
141
|
-
}
|
142
|
-
connect(scroller, "dragenter", drag_);
|
143
|
-
connect(scroller, "dragover", drag_);
|
144
|
-
connect(scroller, "drop", operation(onDrop));
|
145
|
-
}
|
118
|
+
connect(scroller, "dragenter", e_stop);
|
119
|
+
connect(scroller, "dragover", e_stop);
|
120
|
+
connect(scroller, "drop", operation(onDrop));
|
146
121
|
connect(scroller, "paste", function(){focusInput(); fastPoll();});
|
147
122
|
connect(input, "paste", fastPoll);
|
148
123
|
connect(input, "cut", operation(function(){
|
149
124
|
if (!options.readOnly) replaceSelection("");
|
150
125
|
}));
|
151
126
|
|
152
|
-
// Needed to handle Tab key in KHTML
|
153
|
-
if (khtml) connect(code, "mouseup", function() {
|
154
|
-
if (document.activeElement == input) input.blur();
|
155
|
-
focusInput();
|
156
|
-
});
|
157
|
-
|
158
127
|
// IE throws unspecified error in certain cases, when
|
159
128
|
// trying to access activeElement before onload
|
160
|
-
var hasFocus; try { hasFocus = (
|
161
|
-
if (hasFocus
|
129
|
+
var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { }
|
130
|
+
if (hasFocus) setTimeout(onFocus, 20);
|
162
131
|
else onBlur();
|
163
132
|
|
164
133
|
function isLine(l) {return l >= 0 && l < doc.size;}
|
@@ -172,7 +141,7 @@ var CodeMirror = (function() {
|
|
172
141
|
setValue: operation(setValue),
|
173
142
|
getSelection: getSelection,
|
174
143
|
replaceSelection: operation(replaceSelection),
|
175
|
-
focus: function(){
|
144
|
+
focus: function(){focusInput(); onFocus(); fastPoll();},
|
176
145
|
setOption: function(option, value) {
|
177
146
|
var oldVal = options[option];
|
178
147
|
options[option] = value;
|
@@ -181,12 +150,9 @@ var CodeMirror = (function() {
|
|
181
150
|
else if (option == "readOnly" && !value) {resetInput(true);}
|
182
151
|
else if (option == "theme") themeChanged();
|
183
152
|
else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
|
184
|
-
else if (option == "tabSize")
|
185
|
-
|
186
|
-
if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme") {
|
187
|
-
gutterChanged();
|
153
|
+
else if (option == "tabSize") operation(tabsChanged)();
|
154
|
+
if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme")
|
188
155
|
updateDisplay(true);
|
189
|
-
}
|
190
156
|
},
|
191
157
|
getOption: function(option) {return options[option];},
|
192
158
|
undo: operation(undo),
|
@@ -210,23 +176,17 @@ var CodeMirror = (function() {
|
|
210
176
|
line = clipLine(line == null ? doc.size - 1: line);
|
211
177
|
return getStateBefore(line + 1);
|
212
178
|
},
|
213
|
-
cursorCoords: function(start
|
179
|
+
cursorCoords: function(start){
|
214
180
|
if (start == null) start = sel.inverted;
|
215
|
-
return
|
216
|
-
},
|
217
|
-
charCoords: function(pos, mode) {
|
218
|
-
pos = clipPos(pos);
|
219
|
-
if (mode == "local") return localCoords(pos, false);
|
220
|
-
if (mode == "div") return localCoords(pos, true);
|
221
|
-
return pageCoords(pos);
|
181
|
+
return pageCoords(start ? sel.from : sel.to);
|
222
182
|
},
|
183
|
+
charCoords: function(pos){return pageCoords(clipPos(pos));},
|
223
184
|
coordsChar: function(coords) {
|
224
185
|
var off = eltOffset(lineSpace);
|
225
186
|
return coordsChar(coords.x - off.left, coords.y - off.top);
|
226
187
|
},
|
227
188
|
markText: operation(markText),
|
228
189
|
setBookmark: setBookmark,
|
229
|
-
findMarksAt: findMarksAt,
|
230
190
|
setMarker: operation(addGutterMarker),
|
231
191
|
clearMarker: operation(removeGutterMarker),
|
232
192
|
setLineClass: operation(setLineClass),
|
@@ -294,21 +254,12 @@ var CodeMirror = (function() {
|
|
294
254
|
replaceRange: operation(replaceRange),
|
295
255
|
getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));},
|
296
256
|
|
297
|
-
triggerOnKeyDown: operation(onKeyDown),
|
298
257
|
execCommand: function(cmd) {return commands[cmd](instance);},
|
299
258
|
// Stuff used by commands, probably not much use to outside code.
|
300
259
|
moveH: operation(moveH),
|
301
260
|
deleteH: operation(deleteH),
|
302
261
|
moveV: operation(moveV),
|
303
|
-
toggleOverwrite: function() {
|
304
|
-
if(overwrite){
|
305
|
-
overwrite = false;
|
306
|
-
cursor.className = cursor.className.replace(" CodeMirror-overwrite", "");
|
307
|
-
} else {
|
308
|
-
overwrite = true;
|
309
|
-
cursor.className += " CodeMirror-overwrite";
|
310
|
-
}
|
311
|
-
},
|
262
|
+
toggleOverwrite: function() {overwrite = !overwrite;},
|
312
263
|
|
313
264
|
posFromIndex: function(off) {
|
314
265
|
var lineNo = 0, ch;
|
@@ -329,21 +280,16 @@ var CodeMirror = (function() {
|
|
329
280
|
return index;
|
330
281
|
},
|
331
282
|
scrollTo: function(x, y) {
|
332
|
-
if (x != null) scroller.
|
333
|
-
if (y != null)
|
283
|
+
if (x != null) scroller.scrollTop = x;
|
284
|
+
if (y != null) scroller.scrollLeft = y;
|
334
285
|
updateDisplay([]);
|
335
286
|
},
|
336
|
-
getScrollInfo: function() {
|
337
|
-
return {x: scroller.scrollLeft, y: scrollbar.scrollTop,
|
338
|
-
height: scrollbar.scrollHeight, width: scroller.scrollWidth};
|
339
|
-
},
|
340
287
|
|
341
288
|
operation: function(f){return operation(f)();},
|
342
|
-
compoundChange: function(f){return compoundChange(f);},
|
343
289
|
refresh: function(){
|
344
290
|
updateDisplay(true);
|
345
|
-
if (
|
346
|
-
|
291
|
+
if (scroller.scrollHeight > lastScrollPos)
|
292
|
+
scroller.scrollTop = lastScrollPos;
|
347
293
|
},
|
348
294
|
getInputField: function(){return input;},
|
349
295
|
getWrapperElement: function(){return wrapper;},
|
@@ -364,22 +310,12 @@ var CodeMirror = (function() {
|
|
364
310
|
splitLines(code), top, top);
|
365
311
|
updateInput = true;
|
366
312
|
}
|
367
|
-
function getValue() {
|
313
|
+
function getValue(code) {
|
368
314
|
var text = [];
|
369
315
|
doc.iter(0, doc.size, function(line) { text.push(line.text); });
|
370
316
|
return text.join("\n");
|
371
317
|
}
|
372
318
|
|
373
|
-
function onScroll(e) {
|
374
|
-
if (lastScrollTop != scrollbar.scrollTop || lastScrollLeft != scroller.scrollLeft) {
|
375
|
-
lastScrollTop = scrollbar.scrollTop;
|
376
|
-
lastScrollLeft = scroller.scrollLeft;
|
377
|
-
updateDisplay([]);
|
378
|
-
if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
|
379
|
-
if (options.onScroll) options.onScroll(instance);
|
380
|
-
}
|
381
|
-
}
|
382
|
-
|
383
319
|
function onMouseDown(e) {
|
384
320
|
setShift(e_prop(e, "shiftKey"));
|
385
321
|
// Check whether this is a click in a widget
|
@@ -402,8 +338,6 @@ var CodeMirror = (function() {
|
|
402
338
|
return;
|
403
339
|
case 2:
|
404
340
|
if (start) setCursor(start.line, start.ch, true);
|
405
|
-
setTimeout(focusInput, 20);
|
406
|
-
e_preventDefault(e);
|
407
341
|
return;
|
408
342
|
}
|
409
343
|
// For button 1, if it was clicked inside the editor
|
@@ -425,25 +359,21 @@ var CodeMirror = (function() {
|
|
425
359
|
} else { lastClick = {time: now, pos: start}; }
|
426
360
|
|
427
361
|
var last = start, going;
|
428
|
-
if (
|
362
|
+
if (dragAndDrop && !options.readOnly && !posEq(sel.from, sel.to) &&
|
429
363
|
!posLess(start, sel.from) && !posLess(sel.to, start)) {
|
430
364
|
// Let the drag handler handle this.
|
431
|
-
if (webkit)
|
432
|
-
|
433
|
-
if (webkit)
|
365
|
+
if (webkit) lineSpace.draggable = true;
|
366
|
+
var up = connect(targetDocument, "mouseup", operation(function(e2) {
|
367
|
+
if (webkit) lineSpace.draggable = false;
|
434
368
|
draggingText = false;
|
435
|
-
up();
|
369
|
+
up();
|
436
370
|
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
|
437
371
|
e_preventDefault(e2);
|
438
372
|
setCursor(start.line, start.ch, true);
|
439
373
|
focusInput();
|
440
374
|
}
|
441
|
-
}
|
442
|
-
var up = connect(document, "mouseup", operation(dragEnd), true);
|
443
|
-
var drop = connect(scroller, "drop", operation(dragEnd), true);
|
375
|
+
}), true);
|
444
376
|
draggingText = true;
|
445
|
-
// IE's approach to draggable
|
446
|
-
if (scroller.dragDrop) scroller.dragDrop();
|
447
377
|
return;
|
448
378
|
}
|
449
379
|
e_preventDefault(e);
|
@@ -462,7 +392,12 @@ var CodeMirror = (function() {
|
|
462
392
|
}
|
463
393
|
}
|
464
394
|
|
465
|
-
|
395
|
+
var move = connect(targetDocument, "mousemove", operation(function(e) {
|
396
|
+
clearTimeout(going);
|
397
|
+
e_preventDefault(e);
|
398
|
+
extend(e);
|
399
|
+
}), true);
|
400
|
+
var up = connect(targetDocument, "mouseup", operation(function(e) {
|
466
401
|
clearTimeout(going);
|
467
402
|
var cur = posFromMouse(e);
|
468
403
|
if (cur) setSelectionUser(start, cur);
|
@@ -470,14 +405,7 @@ var CodeMirror = (function() {
|
|
470
405
|
focusInput();
|
471
406
|
updateInput = true;
|
472
407
|
move(); up();
|
473
|
-
}
|
474
|
-
var move = connect(document, "mousemove", operation(function(e) {
|
475
|
-
clearTimeout(going);
|
476
|
-
e_preventDefault(e);
|
477
|
-
if (!ie && !e_button(e)) done(e);
|
478
|
-
else extend(e);
|
479
408
|
}), true);
|
480
|
-
var up = connect(document, "mouseup", operation(done), true);
|
481
409
|
}
|
482
410
|
function onDoubleClick(e) {
|
483
411
|
for (var n = e_target(e); n != wrapper; n = n.parentNode)
|
@@ -489,7 +417,6 @@ var CodeMirror = (function() {
|
|
489
417
|
selectWordAt(start);
|
490
418
|
}
|
491
419
|
function onDrop(e) {
|
492
|
-
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
|
493
420
|
e.preventDefault();
|
494
421
|
var pos = posFromMouse(e, true), files = e.dataTransfer.files;
|
495
422
|
if (!pos || options.readOnly) return;
|
@@ -499,124 +426,86 @@ var CodeMirror = (function() {
|
|
499
426
|
reader.onload = function() {
|
500
427
|
text[i] = reader.result;
|
501
428
|
if (++read == n) {
|
502
|
-
|
503
|
-
|
429
|
+
pos = clipPos(pos);
|
430
|
+
operation(function() {
|
504
431
|
var end = replaceRange(text.join(""), pos, pos);
|
505
432
|
setSelectionUser(pos, end);
|
506
433
|
})();
|
507
|
-
|
434
|
+
}
|
508
435
|
};
|
509
436
|
reader.readAsText(file);
|
510
437
|
}
|
511
438
|
var n = files.length, text = Array(n), read = 0;
|
512
439
|
for (var i = 0; i < n; ++i) loadFile(files[i], i);
|
513
|
-
}
|
514
|
-
|
515
|
-
if (draggingText && !(posLess(pos, sel.from) || posLess(sel.to, pos))) return;
|
440
|
+
}
|
441
|
+
else {
|
516
442
|
try {
|
517
443
|
var text = e.dataTransfer.getData("Text");
|
518
444
|
if (text) {
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
});
|
526
|
-
}
|
445
|
+
var curFrom = sel.from, curTo = sel.to;
|
446
|
+
setSelectionUser(pos, pos);
|
447
|
+
if (draggingText) replaceRange("", curFrom, curTo);
|
448
|
+
replaceSelection(text);
|
449
|
+
focusInput();
|
450
|
+
}
|
527
451
|
}
|
528
452
|
catch(e){}
|
529
453
|
}
|
530
454
|
}
|
531
455
|
function onDragStart(e) {
|
532
456
|
var txt = getSelection();
|
457
|
+
// This will reset escapeElement
|
458
|
+
htmlEscape(txt);
|
459
|
+
e.dataTransfer.setDragImage(escapeElement, 0, 0);
|
533
460
|
e.dataTransfer.setData("Text", txt);
|
534
|
-
|
535
|
-
// Use dummy image instead of default browsers image.
|
536
|
-
if (gecko || chrome || opera) {
|
537
|
-
var img = document.createElement('img');
|
538
|
-
img.scr = 'data:image/gif;base64,R0lGODdhAgACAIAAAAAAAP///ywAAAAAAgACAAACAoRRADs='; //1x1 image
|
539
|
-
e.dataTransfer.setDragImage(img, 0, 0);
|
540
|
-
}
|
541
461
|
}
|
542
|
-
|
543
|
-
|
462
|
+
function handleKeyBinding(e) {
|
463
|
+
var name = keyNames[e_prop(e, "keyCode")], next = keyMap[options.keyMap].auto, bound, dropShift;
|
464
|
+
function handleNext() {
|
465
|
+
return next.call ? next.call(null, instance) : next;
|
466
|
+
}
|
467
|
+
if (name == null || e.altGraphKey) {
|
468
|
+
if (next) options.keyMap = handleNext();
|
469
|
+
return null;
|
470
|
+
}
|
471
|
+
if (e_prop(e, "altKey")) name = "Alt-" + name;
|
472
|
+
if (e_prop(e, "ctrlKey")) name = "Ctrl-" + name;
|
473
|
+
if (e_prop(e, "metaKey")) name = "Cmd-" + name;
|
474
|
+
if (e_prop(e, "shiftKey") &&
|
475
|
+
(bound = lookupKey("Shift-" + name, options.extraKeys, options.keyMap))) {
|
476
|
+
dropShift = true;
|
477
|
+
} else {
|
478
|
+
bound = lookupKey(name, options.extraKeys, options.keyMap);
|
479
|
+
}
|
544
480
|
if (typeof bound == "string") {
|
545
|
-
bound = commands[bound];
|
546
|
-
|
481
|
+
if (commands.propertyIsEnumerable(bound)) bound = commands[bound];
|
482
|
+
else bound = null;
|
547
483
|
}
|
484
|
+
if (next && (bound || !isModifierKey(e))) options.keyMap = handleNext();
|
485
|
+
if (!bound) return false;
|
548
486
|
var prevShift = shiftSelecting;
|
549
487
|
try {
|
550
488
|
if (options.readOnly) suppressEdits = true;
|
551
489
|
if (dropShift) shiftSelecting = null;
|
552
490
|
bound(instance);
|
553
|
-
} catch(e) {
|
554
|
-
if (e != Pass) throw e;
|
555
|
-
return false;
|
556
491
|
} finally {
|
557
492
|
shiftSelecting = prevShift;
|
558
493
|
suppressEdits = false;
|
559
494
|
}
|
495
|
+
e_preventDefault(e);
|
560
496
|
return true;
|
561
497
|
}
|
562
|
-
|
563
|
-
// Handle auto keymap transitions
|
564
|
-
var startMap = getKeyMap(options.keyMap), next = startMap.auto;
|
565
|
-
clearTimeout(maybeTransition);
|
566
|
-
if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
|
567
|
-
if (getKeyMap(options.keyMap) == startMap) {
|
568
|
-
options.keyMap = (next.call ? next.call(null, instance) : next);
|
569
|
-
}
|
570
|
-
}, 50);
|
571
|
-
|
572
|
-
var name = keyNames[e_prop(e, "keyCode")], handled = false;
|
573
|
-
if (name == null || e.altGraphKey) return false;
|
574
|
-
if (e_prop(e, "altKey")) name = "Alt-" + name;
|
575
|
-
if (e_prop(e, "ctrlKey")) name = "Ctrl-" + name;
|
576
|
-
if (e_prop(e, "metaKey")) name = "Cmd-" + name;
|
577
|
-
|
578
|
-
var stopped = false;
|
579
|
-
function stop() { stopped = true; }
|
580
|
-
|
581
|
-
if (e_prop(e, "shiftKey")) {
|
582
|
-
handled = lookupKey("Shift-" + name, options.extraKeys, options.keyMap,
|
583
|
-
function(b) {return doHandleBinding(b, true);}, stop)
|
584
|
-
|| lookupKey(name, options.extraKeys, options.keyMap, function(b) {
|
585
|
-
if (typeof b == "string" && /^go[A-Z]/.test(b)) return doHandleBinding(b);
|
586
|
-
}, stop);
|
587
|
-
} else {
|
588
|
-
handled = lookupKey(name, options.extraKeys, options.keyMap, doHandleBinding, stop);
|
589
|
-
}
|
590
|
-
if (stopped) handled = false;
|
591
|
-
if (handled) {
|
592
|
-
e_preventDefault(e);
|
593
|
-
restartBlink();
|
594
|
-
if (ie) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
|
595
|
-
}
|
596
|
-
return handled;
|
597
|
-
}
|
598
|
-
function handleCharBinding(e, ch) {
|
599
|
-
var handled = lookupKey("'" + ch + "'", options.extraKeys,
|
600
|
-
options.keyMap, function(b) { return doHandleBinding(b, true); });
|
601
|
-
if (handled) {
|
602
|
-
e_preventDefault(e);
|
603
|
-
restartBlink();
|
604
|
-
}
|
605
|
-
return handled;
|
606
|
-
}
|
607
|
-
|
608
|
-
var lastStoppedKey = null, maybeTransition;
|
498
|
+
var lastStoppedKey = null;
|
609
499
|
function onKeyDown(e) {
|
610
500
|
if (!focused) onFocus();
|
611
501
|
if (ie && e.keyCode == 27) { e.returnValue = false; }
|
612
|
-
if (pollingFast) { if (readInput()) pollingFast = false; }
|
613
502
|
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
|
614
503
|
var code = e_prop(e, "keyCode");
|
615
504
|
// IE does strange things with escape.
|
616
505
|
setShift(code == 16 || e_prop(e, "shiftKey"));
|
617
506
|
// First give onKeyEvent option a chance to handle this.
|
618
507
|
var handled = handleKeyBinding(e);
|
619
|
-
if (opera) {
|
508
|
+
if (window.opera) {
|
620
509
|
lastStoppedKey = handled ? code : null;
|
621
510
|
// Opera has no cut event... we try to at least catch the key combo
|
622
511
|
if (!handled && code == 88 && e_prop(e, mac ? "metaKey" : "ctrlKey"))
|
@@ -624,17 +513,15 @@ var CodeMirror = (function() {
|
|
624
513
|
}
|
625
514
|
}
|
626
515
|
function onKeyPress(e) {
|
627
|
-
if (pollingFast) readInput();
|
628
|
-
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
|
629
516
|
var keyCode = e_prop(e, "keyCode"), charCode = e_prop(e, "charCode");
|
630
|
-
if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
|
631
|
-
if (
|
632
|
-
|
517
|
+
if (window.opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
|
518
|
+
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
|
519
|
+
if (window.opera && !e.which && handleKeyBinding(e)) return;
|
633
520
|
if (options.electricChars && mode.electricChars && options.smartIndent && !options.readOnly) {
|
521
|
+
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
|
634
522
|
if (mode.electricChars.indexOf(ch) > -1)
|
635
523
|
setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 75);
|
636
524
|
}
|
637
|
-
if (handleCharBinding(e, ch)) return;
|
638
525
|
fastPoll();
|
639
526
|
}
|
640
527
|
function onKeyUp(e) {
|
@@ -647,8 +534,8 @@ var CodeMirror = (function() {
|
|
647
534
|
if (!focused) {
|
648
535
|
if (options.onFocus) options.onFocus(instance);
|
649
536
|
focused = true;
|
650
|
-
if (
|
651
|
-
|
537
|
+
if (wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
|
538
|
+
wrapper.className += " CodeMirror-focused";
|
652
539
|
if (!leaveInputAlone) resetInput(true);
|
653
540
|
}
|
654
541
|
slowPoll();
|
@@ -662,48 +549,12 @@ var CodeMirror = (function() {
|
|
662
549
|
operation(function(){
|
663
550
|
if (bracketHighlighted) { bracketHighlighted(); bracketHighlighted = null; }
|
664
551
|
})();
|
665
|
-
|
552
|
+
wrapper.className = wrapper.className.replace(" CodeMirror-focused", "");
|
666
553
|
}
|
667
554
|
clearInterval(blinker);
|
668
555
|
setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);
|
669
556
|
}
|
670
557
|
|
671
|
-
function chopDelta(delta) {
|
672
|
-
// Make sure we always scroll a little bit for any nonzero delta.
|
673
|
-
if (delta > 0.0 && delta < 1.0) return 1;
|
674
|
-
else if (delta > -1.0 && delta < 0.0) return -1;
|
675
|
-
else return Math.round(delta);
|
676
|
-
}
|
677
|
-
|
678
|
-
function onMouseWheel(e) {
|
679
|
-
var deltaX = 0, deltaY = 0;
|
680
|
-
if (e.type == "DOMMouseScroll") { // Firefox
|
681
|
-
var delta = -e.detail * 8.0;
|
682
|
-
if (e.axis == e.HORIZONTAL_AXIS) deltaX = delta;
|
683
|
-
else if (e.axis == e.VERTICAL_AXIS) deltaY = delta;
|
684
|
-
} else if (e.wheelDeltaX !== undefined && e.wheelDeltaY !== undefined) { // WebKit
|
685
|
-
deltaX = e.wheelDeltaX / 3.0;
|
686
|
-
deltaY = e.wheelDeltaY / 3.0;
|
687
|
-
} else if (e.wheelDelta !== undefined) { // IE or Opera
|
688
|
-
deltaY = e.wheelDelta / 3.0;
|
689
|
-
}
|
690
|
-
|
691
|
-
var scrolled = false;
|
692
|
-
deltaX = chopDelta(deltaX);
|
693
|
-
deltaY = chopDelta(deltaY);
|
694
|
-
if ((deltaX > 0 && scroller.scrollLeft > 0) ||
|
695
|
-
(deltaX < 0 && scroller.scrollLeft + scroller.clientWidth < scroller.scrollWidth)) {
|
696
|
-
scroller.scrollLeft -= deltaX;
|
697
|
-
scrolled = true;
|
698
|
-
}
|
699
|
-
if ((deltaY > 0 && scrollbar.scrollTop > 0) ||
|
700
|
-
(deltaY < 0 && scrollbar.scrollTop + scrollbar.clientHeight < scrollbar.scrollHeight)) {
|
701
|
-
scrollbar.scrollTop -= deltaY;
|
702
|
-
scrolled = true;
|
703
|
-
}
|
704
|
-
if (scrolled) e_stop(e);
|
705
|
-
}
|
706
|
-
|
707
558
|
// Replace the range from from to to by the strings in newText.
|
708
559
|
// Afterwards, set the selection to selFrom, selTo.
|
709
560
|
function updateLines(from, to, newText, selFrom, selTo) {
|
@@ -716,30 +567,29 @@ var CodeMirror = (function() {
|
|
716
567
|
}
|
717
568
|
updateLinesNoUndo(from, to, newText, selFrom, selTo);
|
718
569
|
}
|
719
|
-
function unredoHelper(from, to) {
|
720
|
-
|
721
|
-
var
|
722
|
-
for (var i = set.length - 1; i >= 0; i -= 1) {
|
570
|
+
function unredoHelper(from, to, dir) {
|
571
|
+
var set = from.pop(), len = set ? set.length : 0, out = [];
|
572
|
+
for (var i = dir > 0 ? 0 : len - 1, e = dir > 0 ? len : -1; i != e; i += dir) {
|
723
573
|
var change = set[i];
|
724
574
|
var replaced = [], end = change.start + change.added;
|
725
575
|
doc.iter(change.start, end, function(line) { replaced.push(line.text); });
|
726
576
|
out.push({start: change.start, added: change.old.length, old: replaced});
|
727
|
-
var pos = {line: change.start + change.old.length - 1,
|
728
|
-
|
577
|
+
var pos = clipPos({line: change.start + change.old.length - 1,
|
578
|
+
ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])});
|
729
579
|
updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length}, change.old, pos, pos);
|
730
580
|
}
|
731
581
|
updateInput = true;
|
732
582
|
to.push(out);
|
733
583
|
}
|
734
|
-
function undo() {unredoHelper(history.done, history.undone);}
|
735
|
-
function redo() {unredoHelper(history.undone, history.done);}
|
584
|
+
function undo() {unredoHelper(history.done, history.undone, -1);}
|
585
|
+
function redo() {unredoHelper(history.undone, history.done, 1);}
|
736
586
|
|
737
587
|
function updateLinesNoUndo(from, to, newText, selFrom, selTo) {
|
738
588
|
if (suppressEdits) return;
|
739
589
|
var recomputeMaxLength = false, maxLineLength = maxLine.length;
|
740
590
|
if (!options.lineWrapping)
|
741
|
-
doc.iter(from.line, to.line
|
742
|
-
if (
|
591
|
+
doc.iter(from.line, to.line, function(line) {
|
592
|
+
if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
|
743
593
|
});
|
744
594
|
if (from.line != to.line || newText.length > 1) gutterDirty = true;
|
745
595
|
|
@@ -786,21 +636,29 @@ var CodeMirror = (function() {
|
|
786
636
|
doc.insert(from.line + 1, added);
|
787
637
|
}
|
788
638
|
if (options.lineWrapping) {
|
789
|
-
var perLine =
|
639
|
+
var perLine = scroller.clientWidth / charWidth() - 3;
|
790
640
|
doc.iter(from.line, from.line + newText.length, function(line) {
|
791
641
|
if (line.hidden) return;
|
792
642
|
var guess = Math.ceil(line.text.length / perLine) || 1;
|
793
643
|
if (guess != line.height) updateLineHeight(line, guess);
|
794
644
|
});
|
795
645
|
} else {
|
796
|
-
doc.iter(from.line,
|
646
|
+
doc.iter(from.line, i + newText.length, function(line) {
|
797
647
|
var l = line.text;
|
798
|
-
if (
|
799
|
-
maxLine = l; maxLineLength = l.length;
|
648
|
+
if (l.length > maxLineLength) {
|
649
|
+
maxLine = l; maxLineLength = l.length; maxWidth = null;
|
800
650
|
recomputeMaxLength = false;
|
801
651
|
}
|
802
652
|
});
|
803
|
-
if (recomputeMaxLength)
|
653
|
+
if (recomputeMaxLength) {
|
654
|
+
maxLineLength = 0; maxLine = ""; maxWidth = null;
|
655
|
+
doc.iter(0, doc.size, function(line) {
|
656
|
+
var l = line.text;
|
657
|
+
if (l.length > maxLineLength) {
|
658
|
+
maxLineLength = l.length; maxLine = l;
|
659
|
+
}
|
660
|
+
});
|
661
|
+
}
|
804
662
|
}
|
805
663
|
|
806
664
|
// Add these lines to the work array, so that they will be
|
@@ -826,49 +684,11 @@ var CodeMirror = (function() {
|
|
826
684
|
|
827
685
|
// Update the selection
|
828
686
|
function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}
|
829
|
-
setSelection(
|
830
|
-
updateLine(sel.from.line), updateLine(sel.to.line));
|
831
|
-
}
|
687
|
+
setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line));
|
832
688
|
|
833
|
-
|
834
|
-
var th = textHeight(), virtualHeight = Math.floor(doc.height * th + 2 * paddingTop()), scrollbarHeight = scroller.clientHeight;
|
835
|
-
scrollbar.style.height = scrollbarHeight + "px";
|
689
|
+
// Make sure the scroll-size div has the correct height.
|
836
690
|
if (scroller.clientHeight)
|
837
|
-
|
838
|
-
// Position the mover div to align with the current virtual scroll position
|
839
|
-
if (scrollTop != null) scrollbar.scrollTop = scrollTop;
|
840
|
-
mover.style.top = (displayOffset * th - scrollbar.scrollTop) + "px";
|
841
|
-
scrollbar.style.display = (virtualHeight > scrollbarHeight) ? "block" : "none";
|
842
|
-
}
|
843
|
-
|
844
|
-
// On Mac OS X Lion and up, detect whether the mouse is plugged in by measuring
|
845
|
-
// the width of a div with a scrollbar in it. If the width is <= 1, then
|
846
|
-
// the mouse isn't plugged in and scrollbars should overlap the content.
|
847
|
-
function overlapScrollbars() {
|
848
|
-
var tmpSb = document.createElement('div'),
|
849
|
-
tmpSbInner = document.createElement('div');
|
850
|
-
tmpSb.className = "CodeMirror-scrollbar";
|
851
|
-
tmpSb.style.cssText = "position: absolute; left: -9999px; height: 100px;";
|
852
|
-
tmpSbInner.className = "CodeMirror-scrollbar-inner";
|
853
|
-
tmpSbInner.style.height = "200px";
|
854
|
-
tmpSb.appendChild(tmpSbInner);
|
855
|
-
|
856
|
-
document.body.appendChild(tmpSb);
|
857
|
-
var result = (tmpSb.offsetWidth <= 1);
|
858
|
-
document.body.removeChild(tmpSb);
|
859
|
-
return result;
|
860
|
-
}
|
861
|
-
|
862
|
-
function computeMaxLength() {
|
863
|
-
var maxLineLength = 0;
|
864
|
-
maxLine = ""; maxLineChanged = true;
|
865
|
-
doc.iter(0, doc.size, function(line) {
|
866
|
-
var l = line.text;
|
867
|
-
if (!line.hidden && l.length > maxLineLength) {
|
868
|
-
maxLineLength = l.length; maxLine = l;
|
869
|
-
}
|
870
|
-
});
|
871
|
-
updateMaxLine = false;
|
691
|
+
code.style.height = (doc.height * textHeight() + 2 * paddingTop()) + "px";
|
872
692
|
}
|
873
693
|
|
874
694
|
function replaceRange(code, from, to) {
|
@@ -957,15 +777,14 @@ var CodeMirror = (function() {
|
|
957
777
|
else if (overwrite && posEq(sel.from, sel.to))
|
958
778
|
sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};
|
959
779
|
replaceSelection(text.slice(same), "end");
|
960
|
-
|
961
|
-
else prevInput = text;
|
780
|
+
prevInput = text;
|
962
781
|
return true;
|
963
782
|
}
|
964
783
|
function resetInput(user) {
|
965
784
|
if (!posEq(sel.from, sel.to)) {
|
966
785
|
prevInput = "";
|
967
786
|
input.value = getSelection();
|
968
|
-
|
787
|
+
input.select();
|
969
788
|
} else if (user) prevInput = input.value = "";
|
970
789
|
}
|
971
790
|
|
@@ -979,67 +798,55 @@ var CodeMirror = (function() {
|
|
979
798
|
// IE returns bogus coordinates when the instance sits inside of an iframe and the cursor is hidden
|
980
799
|
if (ie && rect.top == rect.bottom) return;
|
981
800
|
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
|
982
|
-
if (rect.top < 0 || rect.bottom > winH)
|
801
|
+
if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();
|
983
802
|
}
|
984
803
|
function scrollCursorIntoView() {
|
985
|
-
var coords = calculateCursorCoords();
|
986
|
-
return scrollIntoView(coords.x, coords.y, coords.x, coords.yBot);
|
987
|
-
}
|
988
|
-
function calculateCursorCoords() {
|
989
804
|
var cursor = localCoords(sel.inverted ? sel.from : sel.to);
|
990
805
|
var x = options.lineWrapping ? Math.min(cursor.x, lineSpace.offsetWidth) : cursor.x;
|
991
|
-
return
|
806
|
+
return scrollIntoView(x, cursor.y, x, cursor.yBot);
|
992
807
|
}
|
993
808
|
function scrollIntoView(x1, y1, x2, y2) {
|
994
|
-
var
|
995
|
-
if (scrollPos.scrollLeft != null) {scroller.scrollLeft = scrollPos.scrollLeft; scrolled = true;}
|
996
|
-
if (scrollPos.scrollTop != null) {scrollbar.scrollTop = scrollPos.scrollTop; scrolled = true;}
|
997
|
-
if (scrolled && options.onScroll) options.onScroll(instance);
|
998
|
-
}
|
999
|
-
function calculateScrollPos(x1, y1, x2, y2) {
|
1000
|
-
var pl = paddingLeft(), pt = paddingTop();
|
809
|
+
var pl = paddingLeft(), pt = paddingTop(), lh = textHeight();
|
1001
810
|
y1 += pt; y2 += pt; x1 += pl; x2 += pl;
|
1002
|
-
var screen = scroller.clientHeight, screentop =
|
1003
|
-
|
1004
|
-
if (
|
1005
|
-
else if (y2 > screentop + screen) result.scrollTop = y2 - screen;
|
811
|
+
var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true;
|
812
|
+
if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1 - 2*lh); scrolled = true;}
|
813
|
+
else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
|
1006
814
|
|
1007
815
|
var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
|
1008
816
|
var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
} else if (x2 > screenw + screenleft - 3) {
|
1014
|
-
result.scrollLeft = x2 + 10 - screenw;
|
817
|
+
if (x1 < screenleft + gutterw) {
|
818
|
+
if (x1 < 50) x1 = 0;
|
819
|
+
scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
|
820
|
+
scrolled = true;
|
1015
821
|
}
|
822
|
+
else if (x2 > screenw + screenleft - 3) {
|
823
|
+
scroller.scrollLeft = x2 + 10 - screenw;
|
824
|
+
scrolled = true;
|
825
|
+
if (x2 > code.clientWidth) result = false;
|
826
|
+
}
|
827
|
+
if (scrolled && options.onScroll) options.onScroll(instance);
|
1016
828
|
return result;
|
1017
829
|
}
|
1018
830
|
|
1019
|
-
function visibleLines(
|
1020
|
-
var lh = textHeight(), top =
|
1021
|
-
var
|
1022
|
-
var
|
1023
|
-
return {from: lineAtHeight(doc,
|
1024
|
-
to: lineAtHeight(doc,
|
831
|
+
function visibleLines() {
|
832
|
+
var lh = textHeight(), top = scroller.scrollTop - paddingTop();
|
833
|
+
var from_height = Math.max(0, Math.floor(top / lh));
|
834
|
+
var to_height = Math.ceil((top + scroller.clientHeight) / lh);
|
835
|
+
return {from: lineAtHeight(doc, from_height),
|
836
|
+
to: lineAtHeight(doc, to_height)};
|
1025
837
|
}
|
1026
838
|
// Uses a set of changes plus the current scroll position to
|
1027
839
|
// determine which DOM updates have to be made, and makes the
|
1028
840
|
// updates.
|
1029
|
-
function updateDisplay(changes, suppressCallback
|
841
|
+
function updateDisplay(changes, suppressCallback) {
|
1030
842
|
if (!scroller.clientWidth) {
|
1031
843
|
showingFrom = showingTo = displayOffset = 0;
|
1032
844
|
return;
|
1033
845
|
}
|
1034
846
|
// Compute the new visible window
|
1035
|
-
|
1036
|
-
// to render instead of the current scrollbar position.
|
1037
|
-
var visible = visibleLines(scrollTop);
|
847
|
+
var visible = visibleLines();
|
1038
848
|
// Bail out if the visible area is already rendered and nothing changed.
|
1039
|
-
if (changes !== true && changes.length == 0 && visible.from > showingFrom && visible.to < showingTo)
|
1040
|
-
updateVerticalScroll(scrollTop);
|
1041
|
-
return;
|
1042
|
-
}
|
849
|
+
if (changes !== true && changes.length == 0 && visible.from > showingFrom && visible.to < showingTo) return;
|
1043
850
|
var from = Math.max(visible.from - 100, 0), to = Math.min(doc.size, visible.to + 100);
|
1044
851
|
if (showingFrom < from && from - showingFrom < 20) from = showingFrom;
|
1045
852
|
if (showingTo > to && showingTo - to < 20) to = Math.min(doc.size, showingTo);
|
@@ -1057,10 +864,7 @@ var CodeMirror = (function() {
|
|
1057
864
|
if (range.from >= range.to) intact.splice(i--, 1);
|
1058
865
|
else intactLines += range.to - range.from;
|
1059
866
|
}
|
1060
|
-
if (intactLines == to - from
|
1061
|
-
updateVerticalScroll(scrollTop);
|
1062
|
-
return;
|
1063
|
-
}
|
867
|
+
if (intactLines == to - from) return;
|
1064
868
|
intact.sort(function(a, b) {return a.domStart - b.domStart;});
|
1065
869
|
|
1066
870
|
var th = textHeight(), gutterDisplay = gutter.style.display;
|
@@ -1068,12 +872,17 @@ var CodeMirror = (function() {
|
|
1068
872
|
patchDisplay(from, to, intact);
|
1069
873
|
lineDiv.style.display = gutter.style.display = "";
|
1070
874
|
|
875
|
+
// Position the mover div to align with the lines it's supposed
|
876
|
+
// to be showing (which will cover the visible display)
|
1071
877
|
var different = from != showingFrom || to != showingTo || lastSizeC != scroller.clientHeight + th;
|
1072
878
|
// This is just a bogus formula that detects when the editor is
|
1073
879
|
// resized or the font size changes.
|
1074
880
|
if (different) lastSizeC = scroller.clientHeight + th;
|
1075
881
|
showingFrom = from; showingTo = to;
|
1076
882
|
displayOffset = heightAtLine(doc, from);
|
883
|
+
mover.style.top = (displayOffset * th) + "px";
|
884
|
+
if (scroller.clientHeight)
|
885
|
+
code.style.height = (doc.height * th + 2 * paddingTop()) + "px";
|
1077
886
|
|
1078
887
|
// Since this is all rather error prone, it is honoured with the
|
1079
888
|
// only assertion in the whole file.
|
@@ -1081,7 +890,8 @@ var CodeMirror = (function() {
|
|
1081
890
|
throw new Error("BAD PATCH! " + JSON.stringify(intact) + " size=" + (showingTo - showingFrom) +
|
1082
891
|
" nodes=" + lineDiv.childNodes.length);
|
1083
892
|
|
1084
|
-
|
893
|
+
if (options.lineWrapping) {
|
894
|
+
maxWidth = scroller.clientWidth;
|
1085
895
|
var curNode = lineDiv.firstChild, heightChanged = false;
|
1086
896
|
doc.iter(showingFrom, showingTo, function(line) {
|
1087
897
|
if (!line.hidden) {
|
@@ -1093,26 +903,22 @@ var CodeMirror = (function() {
|
|
1093
903
|
}
|
1094
904
|
curNode = curNode.nextSibling;
|
1095
905
|
});
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
906
|
+
if (heightChanged)
|
907
|
+
code.style.height = (doc.height * th + 2 * paddingTop()) + "px";
|
908
|
+
} else {
|
909
|
+
if (maxWidth == null) maxWidth = stringWidth(maxLine);
|
910
|
+
if (maxWidth > scroller.clientWidth) {
|
911
|
+
lineSpace.style.width = maxWidth + "px";
|
912
|
+
// Needed to prevent odd wrapping/hiding of widgets placed in here.
|
913
|
+
code.style.width = "";
|
914
|
+
code.style.width = scroller.scrollWidth + "px";
|
915
|
+
} else {
|
916
|
+
lineSpace.style.width = code.style.width = "";
|
917
|
+
}
|
1107
918
|
}
|
1108
|
-
|
1109
919
|
gutter.style.display = gutterDisplay;
|
1110
|
-
if (different || gutterDirty)
|
1111
|
-
// If the gutter grew in size, re-check heights. If those changed, re-draw gutter.
|
1112
|
-
updateGutter() && options.lineWrapping && checkHeights() && updateGutter();
|
1113
|
-
}
|
920
|
+
if (different || gutterDirty) updateGutter();
|
1114
921
|
updateSelection();
|
1115
|
-
updateVerticalScroll(scrollTop);
|
1116
922
|
if (!suppressCallback && options.onUpdate) options.onUpdate(instance);
|
1117
923
|
return true;
|
1118
924
|
}
|
@@ -1159,17 +965,16 @@ var CodeMirror = (function() {
|
|
1159
965
|
}
|
1160
966
|
// This pass fills in the lines that actually changed.
|
1161
967
|
var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
|
1162
|
-
var scratch =
|
968
|
+
var scratch = targetDocument.createElement("div"), newElt;
|
1163
969
|
doc.iter(from, to, function(line) {
|
1164
970
|
if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
|
1165
971
|
if (!nextIntact || nextIntact.from > j) {
|
1166
972
|
if (line.hidden) var html = scratch.innerHTML = "<pre></pre>";
|
1167
973
|
else {
|
1168
|
-
var html = '<pre' +
|
1169
|
-
+ line.getHTML(makeTab) + '</pre>';
|
974
|
+
var html = '<pre>' + line.getHTML(tabText) + '</pre>';
|
1170
975
|
// Kludge to make sure the styled element lies behind the selection (by z-index)
|
1171
|
-
if (line.
|
1172
|
-
html = '<div style="position: relative"><pre class="' + line.
|
976
|
+
if (line.className)
|
977
|
+
html = '<div style="position: relative"><pre class="' + line.className +
|
1173
978
|
'" style="position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2"> </pre>' + html + "</div>";
|
1174
979
|
}
|
1175
980
|
scratch.innerHTML = html;
|
@@ -1185,7 +990,7 @@ var CodeMirror = (function() {
|
|
1185
990
|
if (!options.gutter && !options.lineNumbers) return;
|
1186
991
|
var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
|
1187
992
|
gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
|
1188
|
-
var html = [], i = showingFrom
|
993
|
+
var html = [], i = showingFrom;
|
1189
994
|
doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
|
1190
995
|
if (line.hidden) {
|
1191
996
|
html.push("<pre></pre>");
|
@@ -1199,24 +1004,17 @@ var CodeMirror = (function() {
|
|
1199
1004
|
html.push((marker && marker.style ? '<pre class="' + marker.style + '">' : "<pre>"), text);
|
1200
1005
|
for (var j = 1; j < line.height; ++j) html.push("<br/> ");
|
1201
1006
|
html.push("</pre>");
|
1202
|
-
if (!marker) normalNode = i;
|
1203
1007
|
}
|
1204
1008
|
++i;
|
1205
1009
|
});
|
1206
1010
|
gutter.style.display = "none";
|
1207
1011
|
gutterText.innerHTML = html.join("");
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
var minwidth = String(doc.size).length, val = eltText(node.firstChild), pad = "";
|
1212
|
-
while (val.length + pad.length < minwidth) pad += "\u00a0";
|
1213
|
-
if (pad) node.insertBefore(document.createTextNode(pad), node.firstChild);
|
1214
|
-
}
|
1012
|
+
var minwidth = String(doc.size).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = "";
|
1013
|
+
while (val.length + pad.length < minwidth) pad += "\u00a0";
|
1014
|
+
if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
|
1215
1015
|
gutter.style.display = "";
|
1216
|
-
var resized = Math.abs((parseInt(lineSpace.style.marginLeft) || 0) - gutter.offsetWidth) > 2;
|
1217
1016
|
lineSpace.style.marginLeft = gutter.offsetWidth + "px";
|
1218
1017
|
gutterDirty = false;
|
1219
|
-
return resized;
|
1220
1018
|
}
|
1221
1019
|
function updateSelection() {
|
1222
1020
|
var collapsed = posEq(sel.from, sel.to);
|
@@ -1233,24 +1031,20 @@ var CodeMirror = (function() {
|
|
1233
1031
|
selectionDiv.style.display = "none";
|
1234
1032
|
} else {
|
1235
1033
|
var sameLine = fromPos.y == toPos.y, html = "";
|
1236
|
-
var clientWidth = lineSpace.clientWidth || lineSpace.offsetWidth;
|
1237
|
-
var clientHeight = lineSpace.clientHeight || lineSpace.offsetHeight;
|
1238
1034
|
function add(left, top, right, height) {
|
1239
|
-
var rstyle = quirksMode ? "width: " + (!right ? clientWidth : clientWidth - right - left) + "px"
|
1240
|
-
: "right: " + right + "px";
|
1241
1035
|
html += '<div class="CodeMirror-selected" style="position: absolute; left: ' + left +
|
1242
|
-
'px; top: ' + top + 'px; ' +
|
1036
|
+
'px; top: ' + top + 'px; right: ' + right + 'px; height: ' + height + 'px"></div>';
|
1243
1037
|
}
|
1244
1038
|
if (sel.from.ch && fromPos.y >= 0) {
|
1245
|
-
var right = sameLine ? clientWidth - toPos.x : 0;
|
1039
|
+
var right = sameLine ? lineSpace.clientWidth - toPos.x : 0;
|
1246
1040
|
add(fromPos.x, fromPos.y, right, th);
|
1247
1041
|
}
|
1248
1042
|
var middleStart = Math.max(0, fromPos.y + (sel.from.ch ? th : 0));
|
1249
|
-
var middleHeight = Math.min(toPos.y, clientHeight) - middleStart;
|
1043
|
+
var middleHeight = Math.min(toPos.y, lineSpace.clientHeight) - middleStart;
|
1250
1044
|
if (middleHeight > 0.2 * th)
|
1251
1045
|
add(0, middleStart, 0, middleHeight);
|
1252
|
-
if ((!sameLine || !sel.from.ch) && toPos.y < clientHeight - .5 * th)
|
1253
|
-
add(0, toPos.y, clientWidth - toPos.x, th);
|
1046
|
+
if ((!sameLine || !sel.from.ch) && toPos.y < lineSpace.clientHeight - .5 * th)
|
1047
|
+
add(0, toPos.y, lineSpace.clientWidth - toPos.x, th);
|
1254
1048
|
selectionDiv.innerHTML = html;
|
1255
1049
|
cursor.style.display = "none";
|
1256
1050
|
selectionDiv.style.display = "";
|
@@ -1280,32 +1074,13 @@ var CodeMirror = (function() {
|
|
1280
1074
|
if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
|
1281
1075
|
|
1282
1076
|
// Skip over hidden lines.
|
1283
|
-
if (from.line != oldFrom)
|
1284
|
-
var from1 = skipHidden(from, oldFrom, sel.from.ch);
|
1285
|
-
// If there is no non-hidden line left, force visibility on current line
|
1286
|
-
if (!from1) setLineHidden(from.line, false);
|
1287
|
-
else from = from1;
|
1288
|
-
}
|
1077
|
+
if (from.line != oldFrom) from = skipHidden(from, oldFrom, sel.from.ch);
|
1289
1078
|
if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);
|
1290
1079
|
|
1291
1080
|
if (posEq(from, to)) sel.inverted = false;
|
1292
1081
|
else if (posEq(from, sel.to)) sel.inverted = false;
|
1293
1082
|
else if (posEq(to, sel.from)) sel.inverted = true;
|
1294
1083
|
|
1295
|
-
if (options.autoClearEmptyLines && posEq(sel.from, sel.to)) {
|
1296
|
-
var head = sel.inverted ? from : to;
|
1297
|
-
if (head.line != sel.from.line && sel.from.line < doc.size) {
|
1298
|
-
var oldLine = getLine(sel.from.line);
|
1299
|
-
if (/^\s+$/.test(oldLine.text))
|
1300
|
-
setTimeout(operation(function() {
|
1301
|
-
if (oldLine.parent && /^\s+$/.test(oldLine.text)) {
|
1302
|
-
var no = lineNo(oldLine);
|
1303
|
-
replaceRange("", {line: no, ch: 0}, {line: no, ch: oldLine.text.length});
|
1304
|
-
}
|
1305
|
-
}, 10));
|
1306
|
-
}
|
1307
|
-
}
|
1308
|
-
|
1309
1084
|
sel.from = from; sel.to = to;
|
1310
1085
|
selectionChanged = true;
|
1311
1086
|
}
|
@@ -1316,14 +1091,13 @@ var CodeMirror = (function() {
|
|
1316
1091
|
var line = getLine(lNo);
|
1317
1092
|
if (!line.hidden) {
|
1318
1093
|
var ch = pos.ch;
|
1319
|
-
if (
|
1094
|
+
if (ch > oldCh || ch > line.text.length) ch = line.text.length;
|
1320
1095
|
return {line: lNo, ch: ch};
|
1321
1096
|
}
|
1322
1097
|
lNo += dir;
|
1323
1098
|
}
|
1324
1099
|
}
|
1325
1100
|
var line = getLine(pos.line);
|
1326
|
-
var toEnd = pos.ch == line.text.length && pos.ch != oldCh;
|
1327
1101
|
if (!line.hidden) return pos;
|
1328
1102
|
if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
|
1329
1103
|
else return getNonHidden(-1) || getNonHidden(1);
|
@@ -1390,7 +1164,6 @@ var CodeMirror = (function() {
|
|
1390
1164
|
if (unit == "page") dist = Math.min(scroller.clientHeight, window.innerHeight || document.documentElement.clientHeight);
|
1391
1165
|
else if (unit == "line") dist = textHeight();
|
1392
1166
|
var target = coordsChar(pos.x, pos.y + dist * dir + 2);
|
1393
|
-
if (unit == "page") scrollbar.scrollTop += localCoords(target, true).y - pos.y;
|
1394
1167
|
setCursor(target.line, target.ch, true);
|
1395
1168
|
goalColumn = pos.x;
|
1396
1169
|
}
|
@@ -1403,7 +1176,7 @@ var CodeMirror = (function() {
|
|
1403
1176
|
setSelectionUser({line: pos.line, ch: start}, {line: pos.line, ch: end});
|
1404
1177
|
}
|
1405
1178
|
function selectLine(line) {
|
1406
|
-
setSelectionUser({line: line, ch: 0},
|
1179
|
+
setSelectionUser({line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
|
1407
1180
|
}
|
1408
1181
|
function indentSelected(mode) {
|
1409
1182
|
if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode);
|
@@ -1420,14 +1193,11 @@ var CodeMirror = (function() {
|
|
1420
1193
|
|
1421
1194
|
var line = getLine(n), curSpace = line.indentation(options.tabSize),
|
1422
1195
|
curSpaceString = line.text.match(/^\s*/)[0], indentation;
|
1423
|
-
if (how == "smart") {
|
1424
|
-
indentation = mode.indent(state, line.text.slice(curSpaceString.length), line.text);
|
1425
|
-
if (indentation == Pass) how = "prev";
|
1426
|
-
}
|
1427
1196
|
if (how == "prev") {
|
1428
1197
|
if (n) indentation = getLine(n-1).indentation(options.tabSize);
|
1429
1198
|
else indentation = 0;
|
1430
1199
|
}
|
1200
|
+
else if (how == "smart") indentation = mode.indent(state, line.text.slice(curSpaceString.length), line.text);
|
1431
1201
|
else if (how == "add") indentation = curSpace + options.indentUnit;
|
1432
1202
|
else if (how == "subtract") indentation = curSpace - options.indentUnit;
|
1433
1203
|
indentation = Math.max(0, indentation);
|
@@ -1436,7 +1206,8 @@ var CodeMirror = (function() {
|
|
1436
1206
|
if (!diff) {
|
1437
1207
|
if (sel.from.line != n && sel.to.line != n) return;
|
1438
1208
|
var indentString = curSpaceString;
|
1439
|
-
}
|
1209
|
+
}
|
1210
|
+
else {
|
1440
1211
|
var indentString = "", pos = 0;
|
1441
1212
|
if (options.indentWithTabs)
|
1442
1213
|
for (var i = Math.floor(indentation / options.tabSize); i; --i) {pos += options.tabSize; indentString += "\t";}
|
@@ -1468,10 +1239,9 @@ var CodeMirror = (function() {
|
|
1468
1239
|
if (guess != 1) updateLineHeight(line, guess);
|
1469
1240
|
});
|
1470
1241
|
lineSpace.style.width = code.style.width = "";
|
1471
|
-
widthForcer.style.left = "";
|
1472
1242
|
} else {
|
1473
1243
|
wrapper.className = wrapper.className.replace(" CodeMirror-wrap", "");
|
1474
|
-
|
1244
|
+
maxWidth = null; maxLine = "";
|
1475
1245
|
doc.iter(0, doc.size, function(line) {
|
1476
1246
|
if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);
|
1477
1247
|
if (line.text.length > maxLine.length) maxLine = line.text;
|
@@ -1479,21 +1249,18 @@ var CodeMirror = (function() {
|
|
1479
1249
|
}
|
1480
1250
|
changes.push({from: 0, to: doc.size});
|
1481
1251
|
}
|
1482
|
-
function
|
1483
|
-
var
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1252
|
+
function computeTabText() {
|
1253
|
+
for (var str = '<span class="cm-tab">', i = 0; i < options.tabSize; ++i) str += " ";
|
1254
|
+
return str + "</span>";
|
1255
|
+
}
|
1256
|
+
function tabsChanged() {
|
1257
|
+
tabText = computeTabText();
|
1258
|
+
updateDisplay(true);
|
1487
1259
|
}
|
1488
1260
|
function themeChanged() {
|
1489
|
-
scroller.className = scroller.className.replace(/\s*cm-s-\
|
1261
|
+
scroller.className = scroller.className.replace(/\s*cm-s-\w+/g, "") +
|
1490
1262
|
options.theme.replace(/(^|\s)\s*/g, " cm-s-");
|
1491
1263
|
}
|
1492
|
-
function keyMapChanged() {
|
1493
|
-
var style = keyMap[options.keyMap].style;
|
1494
|
-
wrapper.className = wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
|
1495
|
-
(style ? " cm-keymap-" + style : "");
|
1496
|
-
}
|
1497
1264
|
|
1498
1265
|
function TextMarker() { this.set = []; }
|
1499
1266
|
TextMarker.prototype.clear = operation(function() {
|
@@ -1504,7 +1271,7 @@ var CodeMirror = (function() {
|
|
1504
1271
|
var lineN = lineNo(line);
|
1505
1272
|
min = Math.min(min, lineN); max = Math.max(max, lineN);
|
1506
1273
|
for (var j = 0; j < mk.length; ++j)
|
1507
|
-
if (mk[j].
|
1274
|
+
if (mk[j].set == this.set) mk.splice(j--, 1);
|
1508
1275
|
}
|
1509
1276
|
if (min != Infinity)
|
1510
1277
|
changes.push({from: min, to: max + 1});
|
@@ -1515,7 +1282,7 @@ var CodeMirror = (function() {
|
|
1515
1282
|
var line = this.set[i], mk = line.marked;
|
1516
1283
|
for (var j = 0; j < mk.length; ++j) {
|
1517
1284
|
var mark = mk[j];
|
1518
|
-
if (mark.
|
1285
|
+
if (mark.set == this.set) {
|
1519
1286
|
if (mark.from != null || mark.to != null) {
|
1520
1287
|
var found = lineNo(line);
|
1521
1288
|
if (found != null) {
|
@@ -1532,9 +1299,8 @@ var CodeMirror = (function() {
|
|
1532
1299
|
function markText(from, to, className) {
|
1533
1300
|
from = clipPos(from); to = clipPos(to);
|
1534
1301
|
var tm = new TextMarker();
|
1535
|
-
if (!posLess(from, to)) return tm;
|
1536
1302
|
function add(line, from, to, className) {
|
1537
|
-
getLine(line).addMark(new MarkedText(from, to, className, tm));
|
1303
|
+
getLine(line).addMark(new MarkedText(from, to, className, tm.set));
|
1538
1304
|
}
|
1539
1305
|
if (from.line == to.line) add(from.line, from.ch, to.ch, className);
|
1540
1306
|
else {
|
@@ -1554,19 +1320,6 @@ var CodeMirror = (function() {
|
|
1554
1320
|
return bm;
|
1555
1321
|
}
|
1556
1322
|
|
1557
|
-
function findMarksAt(pos) {
|
1558
|
-
pos = clipPos(pos);
|
1559
|
-
var markers = [], marked = getLine(pos.line).marked;
|
1560
|
-
if (!marked) return markers;
|
1561
|
-
for (var i = 0, e = marked.length; i < e; ++i) {
|
1562
|
-
var m = marked[i];
|
1563
|
-
if ((m.from == null || m.from <= pos.ch) &&
|
1564
|
-
(m.to == null || m.to >= pos.ch))
|
1565
|
-
markers.push(m.marker || m);
|
1566
|
-
}
|
1567
|
-
return markers;
|
1568
|
-
}
|
1569
|
-
|
1570
1323
|
function addGutterMarker(line, text, className) {
|
1571
1324
|
if (typeof line == "number") line = getLine(clipLine(line));
|
1572
1325
|
line.gutterMarker = {text: text, style: className};
|
@@ -1588,11 +1341,10 @@ var CodeMirror = (function() {
|
|
1588
1341
|
else return null;
|
1589
1342
|
return line;
|
1590
1343
|
}
|
1591
|
-
function setLineClass(handle, className
|
1344
|
+
function setLineClass(handle, className) {
|
1592
1345
|
return changeLine(handle, function(line) {
|
1593
|
-
if (line.className != className
|
1346
|
+
if (line.className != className) {
|
1594
1347
|
line.className = className;
|
1595
|
-
line.bgClassName = bgClassName;
|
1596
1348
|
return true;
|
1597
1349
|
}
|
1598
1350
|
});
|
@@ -1601,21 +1353,11 @@ var CodeMirror = (function() {
|
|
1601
1353
|
return changeLine(handle, function(line, no) {
|
1602
1354
|
if (line.hidden != hidden) {
|
1603
1355
|
line.hidden = hidden;
|
1604
|
-
if (!options.lineWrapping) {
|
1605
|
-
var l = line.text;
|
1606
|
-
if (hidden && l.length == maxLine.length) {
|
1607
|
-
updateMaxLine = true;
|
1608
|
-
} else if (!hidden && l.length > maxLine.length) {
|
1609
|
-
maxLine = l; maxWidth = null; updateMaxLine = false;
|
1610
|
-
}
|
1611
|
-
}
|
1612
1356
|
updateLineHeight(line, hidden ? 0 : 1);
|
1613
1357
|
var fline = sel.from.line, tline = sel.to.line;
|
1614
1358
|
if (hidden && (fline == no || tline == no)) {
|
1615
1359
|
var from = fline == no ? skipHidden({line: fline, ch: 0}, fline, 0) : sel.from;
|
1616
1360
|
var to = tline == no ? skipHidden({line: tline, ch: 0}, tline, 0) : sel.to;
|
1617
|
-
// Can't hide the last visible line, we'd have no place to put the cursor
|
1618
|
-
if (!to) return;
|
1619
1361
|
setSelection(from, to);
|
1620
1362
|
}
|
1621
1363
|
return (gutterDirty = true);
|
@@ -1629,13 +1371,14 @@ var CodeMirror = (function() {
|
|
1629
1371
|
var n = line;
|
1630
1372
|
line = getLine(line);
|
1631
1373
|
if (!line) return null;
|
1632
|
-
}
|
1374
|
+
}
|
1375
|
+
else {
|
1633
1376
|
var n = lineNo(line);
|
1634
1377
|
if (n == null) return null;
|
1635
1378
|
}
|
1636
1379
|
var marker = line.gutterMarker;
|
1637
1380
|
return {line: n, handle: line, text: line.text, markerText: marker && marker.text,
|
1638
|
-
markerClass: marker && marker.style, lineClass: line.className
|
1381
|
+
markerClass: marker && marker.style, lineClass: line.className};
|
1639
1382
|
}
|
1640
1383
|
|
1641
1384
|
function stringWidth(str) {
|
@@ -1649,7 +1392,8 @@ var CodeMirror = (function() {
|
|
1649
1392
|
if (x <= 0) return 0;
|
1650
1393
|
var lineObj = getLine(line), text = lineObj.text;
|
1651
1394
|
function getX(len) {
|
1652
|
-
|
1395
|
+
measure.innerHTML = "<pre><span>" + lineObj.getHTML(tabText, len) + "</span></pre>";
|
1396
|
+
return measure.firstChild.firstChild.offsetWidth;
|
1653
1397
|
}
|
1654
1398
|
var from = 0, fromX = 0, to = text.length, toX;
|
1655
1399
|
// Guess a suitable upper bound for our search.
|
@@ -1672,13 +1416,19 @@ var CodeMirror = (function() {
|
|
1672
1416
|
}
|
1673
1417
|
}
|
1674
1418
|
|
1675
|
-
var tempId =
|
1419
|
+
var tempId = Math.floor(Math.random() * 0xffffff).toString(16);
|
1676
1420
|
function measureLine(line, ch) {
|
1677
1421
|
if (ch == 0) return {top: 0, left: 0};
|
1678
|
-
var
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1422
|
+
var extra = "";
|
1423
|
+
// Include extra text at the end to make sure the measured line is wrapped in the right way.
|
1424
|
+
if (options.lineWrapping) {
|
1425
|
+
var end = line.text.indexOf(" ", ch + 2);
|
1426
|
+
extra = htmlEscape(line.text.slice(ch + 1, end < 0 ? line.text.length : end + (ie ? 5 : 0)));
|
1427
|
+
}
|
1428
|
+
measure.innerHTML = "<pre>" + line.getHTML(tabText, ch) +
|
1429
|
+
'<span id="CodeMirror-temp-' + tempId + '">' + htmlEscape(line.text.charAt(ch) || " ") + "</span>" +
|
1430
|
+
extra + "</pre>";
|
1431
|
+
var elt = document.getElementById("CodeMirror-temp-" + tempId);
|
1682
1432
|
var top = elt.offsetTop, left = elt.offsetLeft;
|
1683
1433
|
// Older IEs report zero offsets for spans directly after a wrap
|
1684
1434
|
if (ie && top == 0 && left == 0) {
|
@@ -1778,8 +1528,8 @@ var CodeMirror = (function() {
|
|
1778
1528
|
return coordsChar(x - offL.left, y - offL.top);
|
1779
1529
|
}
|
1780
1530
|
function onContextMenu(e) {
|
1781
|
-
var pos = posFromMouse(e)
|
1782
|
-
if (!pos || opera) return; // Opera is difficult.
|
1531
|
+
var pos = posFromMouse(e);
|
1532
|
+
if (!pos || window.opera) return; // Opera is difficult.
|
1783
1533
|
if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
|
1784
1534
|
operation(setCursor)(pos.line, pos.ch);
|
1785
1535
|
|
@@ -1791,13 +1541,12 @@ var CodeMirror = (function() {
|
|
1791
1541
|
leaveInputAlone = true;
|
1792
1542
|
var val = input.value = getSelection();
|
1793
1543
|
focusInput();
|
1794
|
-
|
1544
|
+
input.select();
|
1795
1545
|
function rehide() {
|
1796
1546
|
var newVal = splitLines(input.value).join("\n");
|
1797
|
-
if (newVal != val
|
1547
|
+
if (newVal != val) operation(replaceSelection)(newVal, "end");
|
1798
1548
|
inputDiv.style.position = "relative";
|
1799
1549
|
input.style.cssText = oldCSS;
|
1800
|
-
if (ie_lt9) scrollbar.scrollTop = scrollPos;
|
1801
1550
|
leaveInputAlone = false;
|
1802
1551
|
resetInput(true);
|
1803
1552
|
slowPoll();
|
@@ -1809,7 +1558,8 @@ var CodeMirror = (function() {
|
|
1809
1558
|
mouseup();
|
1810
1559
|
setTimeout(rehide, 20);
|
1811
1560
|
}, true);
|
1812
|
-
}
|
1561
|
+
}
|
1562
|
+
else {
|
1813
1563
|
setTimeout(rehide, 50);
|
1814
1564
|
}
|
1815
1565
|
}
|
@@ -1839,7 +1589,7 @@ var CodeMirror = (function() {
|
|
1839
1589
|
var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur;
|
1840
1590
|
for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) {
|
1841
1591
|
var text = st[i];
|
1842
|
-
if (st[i+1] != style) {pos += d * text.length; continue;}
|
1592
|
+
if (st[i+1] != null && st[i+1] != style) {pos += d * text.length; continue;}
|
1843
1593
|
for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) {
|
1844
1594
|
if (pos >= from && pos < to && re.test(cur = text.charAt(j))) {
|
1845
1595
|
var match = matching[cur];
|
@@ -1926,17 +1676,13 @@ var CodeMirror = (function() {
|
|
1926
1676
|
var changed = line.highlight(mode, state, options.tabSize);
|
1927
1677
|
if (changed) realChange = true;
|
1928
1678
|
line.stateAfter = copyState(mode, state);
|
1929
|
-
var done = null;
|
1930
1679
|
if (compare) {
|
1931
|
-
|
1932
|
-
|
1933
|
-
}
|
1934
|
-
if (done == null) {
|
1680
|
+
if (hadState && compare(hadState, state)) return true;
|
1681
|
+
} else {
|
1935
1682
|
if (changed !== false || !hadState) unchanged = 0;
|
1936
1683
|
else if (++unchanged > 3 && (!mode.indent || mode.indent(hadState, "") == mode.indent(state, "")))
|
1937
|
-
|
1684
|
+
return true;
|
1938
1685
|
}
|
1939
|
-
if (done) return true;
|
1940
1686
|
++i;
|
1941
1687
|
});
|
1942
1688
|
if (bail) return;
|
@@ -1959,22 +1705,14 @@ var CodeMirror = (function() {
|
|
1959
1705
|
changes = []; selectionChanged = false; callbacks = [];
|
1960
1706
|
}
|
1961
1707
|
function endOperation() {
|
1962
|
-
|
1963
|
-
if (
|
1964
|
-
|
1965
|
-
maxLineChanged = false;
|
1966
|
-
}
|
1967
|
-
var newScrollPos, updated;
|
1968
|
-
if (selectionChanged) {
|
1969
|
-
var coords = calculateCursorCoords();
|
1970
|
-
newScrollPos = calculateScrollPos(coords.x, coords.y, coords.x, coords.yBot);
|
1971
|
-
}
|
1972
|
-
if (changes.length) updated = updateDisplay(changes, true, (newScrollPos ? newScrollPos.scrollTop : null));
|
1708
|
+
var reScroll = false, updated;
|
1709
|
+
if (selectionChanged) reScroll = !scrollCursorIntoView();
|
1710
|
+
if (changes.length) updated = updateDisplay(changes, true);
|
1973
1711
|
else {
|
1974
1712
|
if (selectionChanged) updateSelection();
|
1975
1713
|
if (gutterDirty) updateGutter();
|
1976
1714
|
}
|
1977
|
-
if (
|
1715
|
+
if (reScroll) scrollCursorIntoView();
|
1978
1716
|
if (selectionChanged) {scrollEditorIntoView(); restartBlink();}
|
1979
1717
|
|
1980
1718
|
if (focused && !leaveInputAlone &&
|
@@ -1986,11 +1724,11 @@ var CodeMirror = (function() {
|
|
1986
1724
|
if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;}
|
1987
1725
|
if (posEq(sel.from, sel.to)) matchBrackets(false);
|
1988
1726
|
}), 20);
|
1989
|
-
var
|
1990
|
-
if (
|
1991
|
-
options.onChange(instance, textChanged);
|
1992
|
-
if (sc && options.onCursorActivity)
|
1727
|
+
var tc = textChanged, cbs = callbacks; // these can be reset by callbacks
|
1728
|
+
if (selectionChanged && options.onCursorActivity)
|
1993
1729
|
options.onCursorActivity(instance);
|
1730
|
+
if (tc && options.onChange && instance)
|
1731
|
+
options.onChange(instance, tc);
|
1994
1732
|
for (var i = 0; i < cbs.length; ++i) cbs[i](instance);
|
1995
1733
|
if (updated && options.onUpdate) options.onUpdate(instance);
|
1996
1734
|
}
|
@@ -2004,11 +1742,6 @@ var CodeMirror = (function() {
|
|
2004
1742
|
};
|
2005
1743
|
}
|
2006
1744
|
|
2007
|
-
function compoundChange(f) {
|
2008
|
-
history.startCompound();
|
2009
|
-
try { return f(); } finally { history.endCompound(); }
|
2010
|
-
}
|
2011
|
-
|
2012
1745
|
for (var ext in extensions)
|
2013
1746
|
if (extensions.propertyIsEnumerable(ext) &&
|
2014
1747
|
!instance.propertyIsEnumerable(ext))
|
@@ -2028,16 +1761,13 @@ var CodeMirror = (function() {
|
|
2028
1761
|
keyMap: "default",
|
2029
1762
|
extraKeys: null,
|
2030
1763
|
electricChars: true,
|
2031
|
-
autoClearEmptyLines: false,
|
2032
1764
|
onKeyEvent: null,
|
2033
|
-
onDragEvent: null,
|
2034
1765
|
lineWrapping: false,
|
2035
1766
|
lineNumbers: false,
|
2036
1767
|
gutter: false,
|
2037
1768
|
fixedGutter: false,
|
2038
1769
|
firstLineNumber: 1,
|
2039
1770
|
readOnly: false,
|
2040
|
-
dragDrop: true,
|
2041
1771
|
onChange: null,
|
2042
1772
|
onCursorActivity: null,
|
2043
1773
|
onGutterClick: null,
|
@@ -2050,7 +1780,7 @@ var CodeMirror = (function() {
|
|
2050
1780
|
pollInterval: 100,
|
2051
1781
|
undoDepth: 40,
|
2052
1782
|
tabindex: null,
|
2053
|
-
|
1783
|
+
document: window.document
|
2054
1784
|
};
|
2055
1785
|
|
2056
1786
|
var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
|
@@ -2058,31 +1788,27 @@ var CodeMirror = (function() {
|
|
2058
1788
|
var win = /Win/.test(navigator.platform);
|
2059
1789
|
|
2060
1790
|
// Known modes, by name and by MIME
|
2061
|
-
var modes =
|
1791
|
+
var modes = {}, mimeModes = {};
|
2062
1792
|
CodeMirror.defineMode = function(name, mode) {
|
2063
1793
|
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
|
2064
|
-
if (arguments.length > 2) {
|
2065
|
-
mode.dependencies = [];
|
2066
|
-
for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
|
2067
|
-
}
|
2068
1794
|
modes[name] = mode;
|
2069
1795
|
};
|
2070
1796
|
CodeMirror.defineMIME = function(mime, spec) {
|
2071
1797
|
mimeModes[mime] = spec;
|
2072
1798
|
};
|
2073
|
-
CodeMirror.
|
1799
|
+
CodeMirror.getMode = function(options, spec) {
|
2074
1800
|
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
|
2075
1801
|
spec = mimeModes[spec];
|
2076
|
-
|
2077
|
-
|
2078
|
-
if (
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
return mfactory(options,
|
1802
|
+
if (typeof spec == "string")
|
1803
|
+
var mname = spec, config = {};
|
1804
|
+
else if (spec != null)
|
1805
|
+
var mname = spec.name, config = spec;
|
1806
|
+
var mfactory = modes[mname];
|
1807
|
+
if (!mfactory) {
|
1808
|
+
if (window.console) console.warn("No mode " + mname + " found, falling back to plain text.");
|
1809
|
+
return CodeMirror.getMode(options, "text/plain");
|
1810
|
+
}
|
1811
|
+
return mfactory(options, config || {});
|
2086
1812
|
};
|
2087
1813
|
CodeMirror.listModes = function() {
|
2088
1814
|
var list = [];
|
@@ -2139,10 +1865,6 @@ var CodeMirror = (function() {
|
|
2139
1865
|
indentMore: function(cm) {cm.indentSelection("add");},
|
2140
1866
|
indentLess: function(cm) {cm.indentSelection("subtract");},
|
2141
1867
|
insertTab: function(cm) {cm.replaceSelection("\t", "end");},
|
2142
|
-
defaultTab: function(cm) {
|
2143
|
-
if (cm.somethingSelected()) cm.indentSelection("add");
|
2144
|
-
else cm.replaceSelection("\t", "end");
|
2145
|
-
},
|
2146
1868
|
transposeChars: function(cm) {
|
2147
1869
|
var cur = cm.getCursor(), line = cm.getLine(cur.line);
|
2148
1870
|
if (cur.ch > 0 && cur.ch < line.length - 1)
|
@@ -2160,7 +1882,7 @@ var CodeMirror = (function() {
|
|
2160
1882
|
keyMap.basic = {
|
2161
1883
|
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
|
2162
1884
|
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
|
2163
|
-
"Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "
|
1885
|
+
"Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "indentMore", "Shift-Tab": "indentLess",
|
2164
1886
|
"Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
|
2165
1887
|
};
|
2166
1888
|
// Note that the save and find-related commands aren't defined by
|
@@ -2171,7 +1893,6 @@ var CodeMirror = (function() {
|
|
2171
1893
|
"Ctrl-Left": "goWordLeft", "Ctrl-Right": "goWordRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
|
2172
1894
|
"Ctrl-Backspace": "delWordLeft", "Ctrl-Delete": "delWordRight", "Ctrl-S": "save", "Ctrl-F": "find",
|
2173
1895
|
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
|
2174
|
-
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
|
2175
1896
|
fallthrough: "basic"
|
2176
1897
|
};
|
2177
1898
|
keyMap.macDefault = {
|
@@ -2180,7 +1901,6 @@ var CodeMirror = (function() {
|
|
2180
1901
|
"Alt-Right": "goWordRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delWordLeft",
|
2181
1902
|
"Ctrl-Alt-Backspace": "delWordRight", "Alt-Delete": "delWordRight", "Cmd-S": "save", "Cmd-F": "find",
|
2182
1903
|
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
|
2183
|
-
"Cmd-[": "indentLess", "Cmd-]": "indentMore",
|
2184
1904
|
fallthrough: ["basic", "emacsy"]
|
2185
1905
|
};
|
2186
1906
|
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
|
@@ -2191,30 +1911,20 @@ var CodeMirror = (function() {
|
|
2191
1911
|
"Alt-D": "delWordRight", "Alt-Backspace": "delWordLeft", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
|
2192
1912
|
};
|
2193
1913
|
|
2194
|
-
function
|
2195
|
-
|
2196
|
-
else return val;
|
2197
|
-
}
|
2198
|
-
function lookupKey(name, extraMap, map, handle, stop) {
|
2199
|
-
function lookup(map) {
|
2200
|
-
map = getKeyMap(map);
|
1914
|
+
function lookupKey(name, extraMap, map) {
|
1915
|
+
function lookup(name, map, ft) {
|
2201
1916
|
var found = map[name];
|
2202
|
-
if (found != null
|
2203
|
-
if (map.
|
2204
|
-
|
2205
|
-
|
1917
|
+
if (found != null) return found;
|
1918
|
+
if (ft == null) ft = map.fallthrough;
|
1919
|
+
if (ft == null) return map.catchall;
|
1920
|
+
if (typeof ft == "string") return lookup(name, keyMap[ft]);
|
1921
|
+
for (var i = 0, e = ft.length; i < e; ++i) {
|
1922
|
+
found = lookup(name, keyMap[ft[i]]);
|
1923
|
+
if (found != null) return found;
|
2206
1924
|
}
|
2207
|
-
|
2208
|
-
if (fallthrough == null) return false;
|
2209
|
-
if (Object.prototype.toString.call(fallthrough) != "[object Array]")
|
2210
|
-
return lookup(fallthrough);
|
2211
|
-
for (var i = 0, e = fallthrough.length; i < e; ++i) {
|
2212
|
-
if (lookup(fallthrough[i])) return true;
|
2213
|
-
}
|
2214
|
-
return false;
|
1925
|
+
return null;
|
2215
1926
|
}
|
2216
|
-
|
2217
|
-
return lookup(map);
|
1927
|
+
return extraMap ? lookup(name, extraMap, map) : lookup(name, keyMap[map]);
|
2218
1928
|
}
|
2219
1929
|
function isModifierKey(event) {
|
2220
1930
|
var name = keyNames[e_prop(event, "keyCode")];
|
@@ -2226,8 +1936,6 @@ var CodeMirror = (function() {
|
|
2226
1936
|
options.value = textarea.value;
|
2227
1937
|
if (!options.tabindex && textarea.tabindex)
|
2228
1938
|
options.tabindex = textarea.tabindex;
|
2229
|
-
if (options.autofocus == null && textarea.getAttribute("autofocus") != null)
|
2230
|
-
options.autofocus = true;
|
2231
1939
|
|
2232
1940
|
function save() {textarea.value = instance.getValue();}
|
2233
1941
|
if (textarea.form) {
|
@@ -2328,7 +2036,8 @@ var CodeMirror = (function() {
|
|
2328
2036
|
if (consume !== false) this.pos += pattern.length;
|
2329
2037
|
return true;
|
2330
2038
|
}
|
2331
|
-
}
|
2039
|
+
}
|
2040
|
+
else {
|
2332
2041
|
var match = this.string.slice(this.pos).match(pattern);
|
2333
2042
|
if (match && consume !== false) this.pos += match[0].length;
|
2334
2043
|
return match;
|
@@ -2338,34 +2047,34 @@ var CodeMirror = (function() {
|
|
2338
2047
|
};
|
2339
2048
|
CodeMirror.StringStream = StringStream;
|
2340
2049
|
|
2341
|
-
function MarkedText(from, to, className,
|
2342
|
-
this.from = from; this.to = to; this.style = className; this.
|
2050
|
+
function MarkedText(from, to, className, set) {
|
2051
|
+
this.from = from; this.to = to; this.style = className; this.set = set;
|
2343
2052
|
}
|
2344
2053
|
MarkedText.prototype = {
|
2345
|
-
attach: function(line) { this.
|
2054
|
+
attach: function(line) { this.set.push(line); },
|
2346
2055
|
detach: function(line) {
|
2347
|
-
var ix = indexOf(this.
|
2348
|
-
if (ix > -1) this.
|
2056
|
+
var ix = indexOf(this.set, line);
|
2057
|
+
if (ix > -1) this.set.splice(ix, 1);
|
2349
2058
|
},
|
2350
2059
|
split: function(pos, lenBefore) {
|
2351
2060
|
if (this.to <= pos && this.to != null) return null;
|
2352
2061
|
var from = this.from < pos || this.from == null ? null : this.from - pos + lenBefore;
|
2353
2062
|
var to = this.to == null ? null : this.to - pos + lenBefore;
|
2354
|
-
return new MarkedText(from, to, this.style, this.
|
2063
|
+
return new MarkedText(from, to, this.style, this.set);
|
2355
2064
|
},
|
2356
|
-
dup: function() { return new MarkedText(null, null, this.style, this.
|
2065
|
+
dup: function() { return new MarkedText(null, null, this.style, this.set); },
|
2357
2066
|
clipTo: function(fromOpen, from, toOpen, to, diff) {
|
2067
|
+
if (this.from != null && this.from >= from)
|
2068
|
+
this.from = Math.max(to, this.from) + diff;
|
2069
|
+
if (this.to != null && this.to > from)
|
2070
|
+
this.to = to < this.to ? this.to + diff : from;
|
2358
2071
|
if (fromOpen && to > this.from && (to < this.to || this.to == null))
|
2359
2072
|
this.from = null;
|
2360
|
-
else if (this.from != null && this.from >= from)
|
2361
|
-
this.from = Math.max(to, this.from) + diff;
|
2362
2073
|
if (toOpen && (from < this.to || this.to == null) && (from > this.from || this.from == null))
|
2363
2074
|
this.to = null;
|
2364
|
-
else if (this.to != null && this.to > from)
|
2365
|
-
this.to = to < this.to ? this.to + diff : from;
|
2366
2075
|
},
|
2367
2076
|
isDead: function() { return this.from != null && this.to != null && this.from >= this.to; },
|
2368
|
-
sameSet: function(x) { return this.
|
2077
|
+
sameSet: function(x) { return this.set == x.set; }
|
2369
2078
|
};
|
2370
2079
|
|
2371
2080
|
function Bookmark(pos) {
|
@@ -2408,7 +2117,7 @@ var CodeMirror = (function() {
|
|
2408
2117
|
this.styles = styles || [text, null];
|
2409
2118
|
this.text = text;
|
2410
2119
|
this.height = 1;
|
2411
|
-
this.marked = this.gutterMarker = this.className = this.
|
2120
|
+
this.marked = this.gutterMarker = this.className = this.handlers = null;
|
2412
2121
|
this.stateAfter = this.parent = this.hidden = null;
|
2413
2122
|
}
|
2414
2123
|
Line.inheritMarks = function(text, orig) {
|
@@ -2454,7 +2163,6 @@ var CodeMirror = (function() {
|
|
2454
2163
|
if (newmark) {
|
2455
2164
|
if (!taken.marked) taken.marked = [];
|
2456
2165
|
taken.marked.push(newmark); newmark.attach(taken);
|
2457
|
-
if (newmark == mark) mk.splice(i--, 1);
|
2458
2166
|
}
|
2459
2167
|
}
|
2460
2168
|
}
|
@@ -2564,82 +2272,34 @@ var CodeMirror = (function() {
|
|
2564
2272
|
indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
|
2565
2273
|
// Produces an HTML fragment for the line, taking selection,
|
2566
2274
|
// marking, and highlighting into account.
|
2567
|
-
getHTML: function(
|
2568
|
-
var html = [], first = true
|
2569
|
-
function
|
2275
|
+
getHTML: function(tabText, endAt) {
|
2276
|
+
var html = [], first = true;
|
2277
|
+
function span(text, style) {
|
2570
2278
|
if (!text) return;
|
2571
2279
|
// Work around a bug where, in some compat modes, IE ignores leading spaces
|
2572
2280
|
if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
|
2573
2281
|
first = false;
|
2574
|
-
if (
|
2575
|
-
|
2576
|
-
var escaped = htmlEscape(text);
|
2577
|
-
} else {
|
2578
|
-
var escaped = "";
|
2579
|
-
for (var pos = 0;;) {
|
2580
|
-
var idx = text.indexOf("\t", pos);
|
2581
|
-
if (idx == -1) {
|
2582
|
-
escaped += htmlEscape(text.slice(pos));
|
2583
|
-
col += text.length - pos;
|
2584
|
-
break;
|
2585
|
-
} else {
|
2586
|
-
col += idx - pos;
|
2587
|
-
var tab = makeTab(col);
|
2588
|
-
escaped += htmlEscape(text.slice(pos, idx)) + tab.html;
|
2589
|
-
col += tab.width;
|
2590
|
-
pos = idx + 1;
|
2591
|
-
}
|
2592
|
-
}
|
2593
|
-
}
|
2594
|
-
if (style) html.push('<span class="', style, '">', escaped, "</span>");
|
2595
|
-
else html.push(escaped);
|
2596
|
-
}
|
2597
|
-
var span = span_;
|
2598
|
-
if (wrapAt != null) {
|
2599
|
-
var outPos = 0, open = "<span id=\"" + wrapId + "\">";
|
2600
|
-
span = function(text, style) {
|
2601
|
-
var l = text.length;
|
2602
|
-
if (wrapAt >= outPos && wrapAt < outPos + l) {
|
2603
|
-
if (wrapAt > outPos) {
|
2604
|
-
span_(text.slice(0, wrapAt - outPos), style);
|
2605
|
-
// See comment at the definition of spanAffectsWrapping
|
2606
|
-
if (wrapWBR) html.push("<wbr>");
|
2607
|
-
}
|
2608
|
-
html.push(open);
|
2609
|
-
var cut = wrapAt - outPos;
|
2610
|
-
span_(opera ? text.slice(cut, cut + 1) : text.slice(cut), style);
|
2611
|
-
html.push("</span>");
|
2612
|
-
if (opera) span_(text.slice(cut + 1), style);
|
2613
|
-
wrapAt--;
|
2614
|
-
outPos += l;
|
2615
|
-
} else {
|
2616
|
-
outPos += l;
|
2617
|
-
span_(text, style);
|
2618
|
-
// Output empty wrapper when at end of line
|
2619
|
-
if (outPos == wrapAt && outPos == len) html.push(open + " </span>");
|
2620
|
-
// Stop outputting HTML when gone sufficiently far beyond measure
|
2621
|
-
else if (outPos > wrapAt + 10 && /\s/.test(text)) span = function(){};
|
2622
|
-
}
|
2623
|
-
}
|
2282
|
+
if (style) html.push('<span class="', style, '">', htmlEscape(text).replace(/\t/g, tabText), "</span>");
|
2283
|
+
else html.push(htmlEscape(text).replace(/\t/g, tabText));
|
2624
2284
|
}
|
2625
|
-
|
2626
2285
|
var st = this.styles, allText = this.text, marked = this.marked;
|
2627
2286
|
var len = allText.length;
|
2287
|
+
if (endAt != null) len = Math.min(endAt, len);
|
2628
2288
|
function styleToClass(style) {
|
2629
2289
|
if (!style) return null;
|
2630
2290
|
return "cm-" + style.replace(/ +/g, " cm-");
|
2631
2291
|
}
|
2632
2292
|
|
2633
|
-
if (!allText &&
|
2293
|
+
if (!allText && endAt == null)
|
2634
2294
|
span(" ");
|
2635
|
-
|
2295
|
+
else if (!marked || !marked.length)
|
2636
2296
|
for (var i = 0, ch = 0; ch < len; i+=2) {
|
2637
2297
|
var str = st[i], style = st[i+1], l = str.length;
|
2638
2298
|
if (ch + l > len) str = str.slice(0, len - ch);
|
2639
2299
|
ch += l;
|
2640
2300
|
span(str, styleToClass(style));
|
2641
2301
|
}
|
2642
|
-
|
2302
|
+
else {
|
2643
2303
|
var pos = 0, i = 0, text = "", style, sg = 0;
|
2644
2304
|
var nextChange = marked[0].from || 0, marks = [], markpos = 0;
|
2645
2305
|
function advanceMarks() {
|
@@ -2689,7 +2349,8 @@ var CodeMirror = (function() {
|
|
2689
2349
|
if (state == 0) {
|
2690
2350
|
if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]);
|
2691
2351
|
if (end >= from) state = 1;
|
2692
|
-
}
|
2352
|
+
}
|
2353
|
+
else if (state == 1) {
|
2693
2354
|
if (end > to) dest.push(part.slice(0, to - pos), source[i+1]);
|
2694
2355
|
else dest.push(part, source[i+1]);
|
2695
2356
|
}
|
@@ -2724,7 +2385,7 @@ var CodeMirror = (function() {
|
|
2724
2385
|
},
|
2725
2386
|
insertHeight: function(at, lines, height) {
|
2726
2387
|
this.height += height;
|
2727
|
-
this.lines
|
2388
|
+
this.lines.splice.apply(this.lines, [at, 0].concat(lines));
|
2728
2389
|
for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
|
2729
2390
|
},
|
2730
2391
|
iterN: function(at, n, op) {
|
@@ -2890,36 +2551,33 @@ var CodeMirror = (function() {
|
|
2890
2551
|
function History() {
|
2891
2552
|
this.time = 0;
|
2892
2553
|
this.done = []; this.undone = [];
|
2893
|
-
this.compound = 0;
|
2894
|
-
this.closed = false;
|
2895
2554
|
}
|
2896
2555
|
History.prototype = {
|
2897
2556
|
addChange: function(start, added, old) {
|
2898
2557
|
this.undone.length = 0;
|
2899
2558
|
var time = +new Date, cur = this.done[this.done.length - 1], last = cur && cur[cur.length - 1];
|
2900
2559
|
var dtime = time - this.time;
|
2901
|
-
|
2902
|
-
if (this.compound && cur && !this.closed) {
|
2903
|
-
cur.push({start: start, added: added, old: old});
|
2904
|
-
} else if (dtime > 400 || !last || this.closed ||
|
2905
|
-
last.start > start + old.length || last.start + last.added < start) {
|
2560
|
+
if (dtime > 400 || !last) {
|
2906
2561
|
this.done.push([{start: start, added: added, old: old}]);
|
2907
|
-
|
2562
|
+
} else if (last.start > start + added || last.start + last.added < start - last.added + last.old.length) {
|
2563
|
+
cur.push({start: start, added: added, old: old});
|
2908
2564
|
} else {
|
2909
|
-
var
|
2910
|
-
|
2911
|
-
|
2912
|
-
|
2913
|
-
|
2914
|
-
|
2565
|
+
var oldoff = 0;
|
2566
|
+
if (start < last.start) {
|
2567
|
+
for (var i = last.start - start - 1; i >= 0; --i)
|
2568
|
+
last.old.unshift(old[i]);
|
2569
|
+
last.added += last.start - start;
|
2570
|
+
last.start = start;
|
2571
|
+
}
|
2572
|
+
else if (last.start < start) {
|
2573
|
+
oldoff = start - last.start;
|
2574
|
+
added += oldoff;
|
2575
|
+
}
|
2576
|
+
for (var i = last.added - oldoff, e = old.length; i < e; ++i)
|
2577
|
+
last.old.push(old[i]);
|
2578
|
+
if (last.added < added) last.added = added;
|
2915
2579
|
}
|
2916
2580
|
this.time = time;
|
2917
|
-
},
|
2918
|
-
startCompound: function() {
|
2919
|
-
if (!this.compound++) this.closed = true;
|
2920
|
-
},
|
2921
|
-
endCompound: function() {
|
2922
|
-
if (!--this.compound) this.closed = true;
|
2923
2581
|
}
|
2924
2582
|
};
|
2925
2583
|
|
@@ -2964,7 +2622,8 @@ var CodeMirror = (function() {
|
|
2964
2622
|
if (typeof node.addEventListener == "function") {
|
2965
2623
|
node.addEventListener(type, handler, false);
|
2966
2624
|
if (disconnect) return function() {node.removeEventListener(type, handler, false);};
|
2967
|
-
}
|
2625
|
+
}
|
2626
|
+
else {
|
2968
2627
|
var wrapHandler = function(event) {handler(event || window.event);};
|
2969
2628
|
node.attachEvent("on" + type, wrapHandler);
|
2970
2629
|
if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);};
|
@@ -2975,48 +2634,26 @@ var CodeMirror = (function() {
|
|
2975
2634
|
function Delayed() {this.id = null;}
|
2976
2635
|
Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
|
2977
2636
|
|
2978
|
-
var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
|
2979
|
-
|
2980
|
-
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
|
2981
|
-
var ie = /MSIE \d/.test(navigator.userAgent);
|
2982
|
-
var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent);
|
2983
|
-
var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
|
2984
|
-
var quirksMode = ie && document.documentMode == 5;
|
2985
|
-
var webkit = /WebKit\//.test(navigator.userAgent);
|
2986
|
-
var chrome = /Chrome\//.test(navigator.userAgent);
|
2987
|
-
var opera = /Opera\//.test(navigator.userAgent);
|
2988
|
-
var safari = /Apple Computer/.test(navigator.vendor);
|
2989
|
-
var khtml = /KHTML\//.test(navigator.userAgent);
|
2990
|
-
var mac_geLion = /Mac OS X 10\D([7-9]|\d\d)\D/.test(navigator.userAgent);
|
2991
|
-
|
2992
2637
|
// Detect drag-and-drop
|
2993
2638
|
var dragAndDrop = function() {
|
2994
|
-
//
|
2995
|
-
//
|
2996
|
-
if (
|
2639
|
+
// IE8 has ondragstart and ondrop properties, but doesn't seem to
|
2640
|
+
// actually support ondragstart the way it's supposed to work.
|
2641
|
+
if (/MSIE [1-8]\b/.test(navigator.userAgent)) return false;
|
2997
2642
|
var div = document.createElement('div');
|
2998
|
-
return "draggable" in div
|
2643
|
+
return "draggable" in div;
|
2999
2644
|
}();
|
3000
2645
|
|
2646
|
+
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
|
2647
|
+
var ie = /MSIE \d/.test(navigator.userAgent);
|
2648
|
+
var webkit = /WebKit\//.test(navigator.userAgent);
|
2649
|
+
|
2650
|
+
var lineSep = "\n";
|
3001
2651
|
// Feature-detect whether newlines in textareas are converted to \r\n
|
3002
|
-
|
2652
|
+
(function () {
|
3003
2653
|
var te = document.createElement("textarea");
|
3004
2654
|
te.value = "foo\nbar";
|
3005
|
-
if (te.value.indexOf("\r") > -1)
|
3006
|
-
|
3007
|
-
}();
|
3008
|
-
|
3009
|
-
// For a reason I have yet to figure out, some browsers disallow
|
3010
|
-
// word wrapping between certain characters *only* if a new inline
|
3011
|
-
// element is started between them. This makes it hard to reliably
|
3012
|
-
// measure the position of things, since that requires inserting an
|
3013
|
-
// extra span. This terribly fragile set of regexps matches the
|
3014
|
-
// character combinations that suffer from this phenomenon on the
|
3015
|
-
// various browsers.
|
3016
|
-
var spanAffectsWrapping = /^$/; // Won't match any two-character string
|
3017
|
-
if (gecko) spanAffectsWrapping = /$'/;
|
3018
|
-
else if (safari) spanAffectsWrapping = /\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/;
|
3019
|
-
else if (chrome) spanAffectsWrapping = /\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/;
|
2655
|
+
if (te.value.indexOf("\r") > -1) lineSep = "\r\n";
|
2656
|
+
}());
|
3020
2657
|
|
3021
2658
|
// Counts the column offset in a string, taking tabs into account.
|
3022
2659
|
// Used mostly to find indentation.
|
@@ -3097,19 +2734,18 @@ var CodeMirror = (function() {
|
|
3097
2734
|
}
|
3098
2735
|
// Recent (late 2011) Opera betas insert bogus newlines at the start
|
3099
2736
|
// of the textContent, so we strip those.
|
3100
|
-
if (htmlEscape("a") == "\na")
|
2737
|
+
if (htmlEscape("a") == "\na")
|
3101
2738
|
htmlEscape = function(str) {
|
3102
2739
|
escapeElement.textContent = str;
|
3103
2740
|
return escapeElement.innerHTML.slice(1);
|
3104
2741
|
};
|
3105
2742
|
// Some IEs don't preserve tabs through innerHTML
|
3106
|
-
|
2743
|
+
else if (htmlEscape("\t") != "\t")
|
3107
2744
|
htmlEscape = function(str) {
|
3108
2745
|
escapeElement.innerHTML = "";
|
3109
2746
|
escapeElement.appendChild(document.createTextNode(str));
|
3110
2747
|
return escapeElement.innerHTML;
|
3111
2748
|
};
|
3112
|
-
}
|
3113
2749
|
CodeMirror.htmlEscape = htmlEscape;
|
3114
2750
|
|
3115
2751
|
// Used to position the cursor after an undo/redo by finding the
|
@@ -3163,10 +2799,10 @@ var CodeMirror = (function() {
|
|
3163
2799
|
var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
|
3164
2800
|
19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
|
3165
2801
|
36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
|
3166
|
-
46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod",
|
3167
|
-
|
3168
|
-
|
3169
|
-
|
2802
|
+
46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 186: ";", 187: "=", 188: ",",
|
2803
|
+
189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", 63276: "PageUp",
|
2804
|
+
63277: "PageDown", 63275: "End", 63273: "Home", 63234: "Left", 63232: "Up", 63235: "Right",
|
2805
|
+
63233: "Down", 63302: "Insert", 63272: "Delete"};
|
3170
2806
|
CodeMirror.keyNames = keyNames;
|
3171
2807
|
(function() {
|
3172
2808
|
// Number keys
|