diff options
Diffstat (limited to 'imports/codemirror/lib/codemirror.js')
-rw-r--r--[-rwxr-xr-x] | imports/codemirror/lib/codemirror.js | 554 |
1 files changed, 342 insertions, 212 deletions
diff --git a/imports/codemirror/lib/codemirror.js b/imports/codemirror/lib/codemirror.js index 79eb457d..9c6e65e4 100755..100644 --- a/imports/codemirror/lib/codemirror.js +++ b/imports/codemirror/lib/codemirror.js | |||
@@ -1,4 +1,4 @@ | |||
1 | // CodeMirror version 2.2 | 1 | // CodeMirror version 2.22 |
2 | // | 2 | // |
3 | // All functions that need access to the editor's state live inside | 3 | // All functions that need access to the editor's state live inside |
4 | // the CodeMirror function. Below that, at the bottom of the file, | 4 | // the CodeMirror function. Below that, at the bottom of the file, |
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | // CodeMirror is the only global var we claim | 7 | // CodeMirror is the only global var we claim |
8 | var CodeMirror = (function() { | 8 | var CodeMirror = (function() { |
9 | // This is the function that produces an editor instance. It's | 9 | // This is the function that produces an editor instance. Its |
10 | // closure is used to store the editor state. | 10 | // closure is used to store the editor state. |
11 | function CodeMirror(place, givenOptions) { | 11 | function CodeMirror(place, givenOptions) { |
12 | // Determine effective options based on given values and defaults. | 12 | // Determine effective options based on given values and defaults. |
@@ -22,17 +22,17 @@ var CodeMirror = (function() { | |||
22 | // This mess creates the base DOM structure for the editor. | 22 | // This mess creates the base DOM structure for the editor. |
23 | wrapper.innerHTML = | 23 | wrapper.innerHTML = |
24 | '<div style="overflow: hidden; position: relative; width: 3px; height: 0px;">' + // Wraps and hides input textarea | 24 | '<div style="overflow: hidden; position: relative; width: 3px; height: 0px;">' + // Wraps and hides input textarea |
25 | '<textarea style="position: absolute; padding: 0; width: 1px;" wrap="off" ' + | 25 | '<textarea style="position: absolute; padding: 0; width: 1px; height: 1em" wrap="off" ' + |
26 | 'autocorrect="off" autocapitalize="off"></textarea></div>' + | 26 | 'autocorrect="off" autocapitalize="off"></textarea></div>' + |
27 | '<div class="CodeMirror-scroll" tabindex="-1">' + | 27 | '<div class="CodeMirror-scroll" tabindex="-1">' + |
28 | '<div style="position: relative">' + // Set to the height of the text, causes scrolling | 28 | '<div style="position: relative">' + // Set to the height of the text, causes scrolling |
29 | '<div style="position: relative">' + // Moved around its parent to cover visible view | 29 | '<div style="position: relative">' + // Moved around its parent to cover visible view |
30 | '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' + | 30 | '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' + |
31 | // Provides positioning relative to (visible) text origin | 31 | // Provides positioning relative to (visible) text origin |
32 | '<div class="CodeMirror-lines"><div style="position: relative">' + | 32 | '<div class="CodeMirror-lines"><div style="position: relative; z-index: 0">' + |
33 | '<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;"></div>' + |
34 | '<pre class="CodeMirror-cursor"> </pre>' + // Absolutely positioned blinky cursor | 34 | '<pre class="CodeMirror-cursor"> </pre>' + // Absolutely positioned blinky cursor |
35 | '<div></div>' + // This DIV contains the actual code | 35 | '<div style="position: relative; z-index: -1"></div><div></div>' + // DIVs containing the selection and the actual code |
36 | '</div></div></div></div></div>'; | 36 | '</div></div></div></div></div>'; |
37 | if (place.appendChild) place.appendChild(wrapper); else place(wrapper); | 37 | if (place.appendChild) place.appendChild(wrapper); else place(wrapper); |
38 | // I've never seen more elegant code in my life. | 38 | // I've never seen more elegant code in my life. |
@@ -40,11 +40,13 @@ var CodeMirror = (function() { | |||
40 | scroller = wrapper.lastChild, code = scroller.firstChild, | 40 | scroller = wrapper.lastChild, code = scroller.firstChild, |
41 | mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild, | 41 | mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild, |
42 | lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild, | 42 | lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild, |
43 | cursor = measure.nextSibling, lineDiv = cursor.nextSibling; | 43 | cursor = measure.nextSibling, selectionDiv = cursor.nextSibling, |
44 | lineDiv = selectionDiv.nextSibling; | ||
44 | themeChanged(); | 45 | themeChanged(); |
45 | // Needed to hide big blue blinking cursor on Mobile Safari | 46 | // Needed to hide big blue blinking cursor on Mobile Safari |
46 | if (/AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent)) input.style.width = "0px"; | 47 | if (ios) input.style.width = "0px"; |
47 | if (!webkit) lineSpace.draggable = true; | 48 | if (!webkit) lineSpace.draggable = true; |
49 | lineSpace.style.outline = "none"; | ||
48 | if (options.tabindex != null) input.tabIndex = options.tabindex; | 50 | if (options.tabindex != null) input.tabIndex = options.tabindex; |
49 | if (!options.gutter && !options.lineNumbers) gutter.style.display = "none"; | 51 | if (!options.gutter && !options.lineNumbers) gutter.style.display = "none"; |
50 | 52 | ||
@@ -71,7 +73,8 @@ var CodeMirror = (function() { | |||
71 | var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false}; | 73 | var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false}; |
72 | // Selection-related flags. shiftSelecting obviously tracks | 74 | // Selection-related flags. shiftSelecting obviously tracks |
73 | // whether the user is holding shift. | 75 | // whether the user is holding shift. |
74 | var shiftSelecting, lastClick, lastDoubleClick, draggingText, overwrite = false; | 76 | var shiftSelecting, lastClick, lastDoubleClick, lastScrollPos = 0, draggingText, |
77 | overwrite = false, suppressEdits = false; | ||
75 | // Variables used by startOperation/endOperation to track what | 78 | // Variables used by startOperation/endOperation to track what |
76 | // happened during the operation. | 79 | // happened during the operation. |
77 | var updateInput, userSelChange, changes, textChanged, selectionChanged, leaveInputAlone, | 80 | var updateInput, userSelChange, changes, textChanged, selectionChanged, leaveInputAlone, |
@@ -83,7 +86,7 @@ var CodeMirror = (function() { | |||
83 | var bracketHighlighted; | 86 | var bracketHighlighted; |
84 | // Tracks the maximum line length so that the horizontal scrollbar | 87 | // Tracks the maximum line length so that the horizontal scrollbar |
85 | // can be kept static when scrolling. | 88 | // can be kept static when scrolling. |
86 | var maxLine = "", maxWidth, tabText = computeTabText(); | 89 | var maxLine = "", maxWidth; |
87 | 90 | ||
88 | // Initialize the content. | 91 | // Initialize the content. |
89 | operation(function(){setValue(options.value || ""); updateInput = false;})(); | 92 | operation(function(){setValue(options.value || ""); updateInput = false;})(); |
@@ -99,6 +102,7 @@ var CodeMirror = (function() { | |||
99 | // handled in onMouseDown for Gecko. | 102 | // handled in onMouseDown for Gecko. |
100 | if (!gecko) connect(scroller, "contextmenu", onContextMenu); | 103 | if (!gecko) connect(scroller, "contextmenu", onContextMenu); |
101 | connect(scroller, "scroll", function() { | 104 | connect(scroller, "scroll", function() { |
105 | lastScrollPos = scroller.scrollTop; | ||
102 | updateDisplay([]); | 106 | updateDisplay([]); |
103 | if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px"; | 107 | if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px"; |
104 | if (options.onScroll) options.onScroll(instance); | 108 | if (options.onScroll) options.onScroll(instance); |
@@ -116,7 +120,9 @@ var CodeMirror = (function() { | |||
116 | connect(scroller, "drop", operation(onDrop)); | 120 | connect(scroller, "drop", operation(onDrop)); |
117 | connect(scroller, "paste", function(){focusInput(); fastPoll();}); | 121 | connect(scroller, "paste", function(){focusInput(); fastPoll();}); |
118 | connect(input, "paste", fastPoll); | 122 | connect(input, "paste", fastPoll); |
119 | connect(input, "cut", operation(function(){replaceSelection("");})); | 123 | connect(input, "cut", operation(function(){ |
124 | if (!options.readOnly) replaceSelection(""); | ||
125 | })); | ||
120 | 126 | ||
121 | // IE throws unspecified error in certain cases, when | 127 | // IE throws unspecified error in certain cases, when |
122 | // trying to access activeElement before onload | 128 | // trying to access activeElement before onload |
@@ -135,23 +141,30 @@ var CodeMirror = (function() { | |||
135 | setValue: operation(setValue), | 141 | setValue: operation(setValue), |
136 | getSelection: getSelection, | 142 | getSelection: getSelection, |
137 | replaceSelection: operation(replaceSelection), | 143 | replaceSelection: operation(replaceSelection), |
138 | focus: function(){focusInput(); onFocus(); fastPoll();}, | 144 | focus: function(){window.focus(); focusInput(); onFocus(); fastPoll();}, |
139 | setOption: function(option, value) { | 145 | setOption: function(option, value) { |
140 | var oldVal = options[option]; | 146 | var oldVal = options[option]; |
141 | options[option] = value; | 147 | options[option] = value; |
142 | if (option == "mode" || option == "indentUnit") loadMode(); | 148 | if (option == "mode" || option == "indentUnit") loadMode(); |
143 | else if (option == "readOnly" && value) {onBlur(); input.blur();} | 149 | else if (option == "readOnly" && value == "nocursor") {onBlur(); input.blur();} |
150 | else if (option == "readOnly" && !value) {resetInput(true);} | ||
144 | else if (option == "theme") themeChanged(); | 151 | else if (option == "theme") themeChanged(); |
145 | else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)(); | 152 | else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)(); |
146 | else if (option == "tabSize") operation(tabsChanged)(); | 153 | else if (option == "tabSize") updateDisplay(true); |
147 | if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme") | 154 | if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme") { |
148 | operation(gutterChanged)(); | 155 | gutterChanged(); |
156 | updateDisplay(true); | ||
157 | } | ||
149 | }, | 158 | }, |
150 | getOption: function(option) {return options[option];}, | 159 | getOption: function(option) {return options[option];}, |
151 | undo: operation(undo), | 160 | undo: operation(undo), |
152 | redo: operation(redo), | 161 | redo: operation(redo), |
153 | indentLine: operation(function(n, dir) { | 162 | indentLine: operation(function(n, dir) { |
154 | if (isLine(n)) indentLine(n, dir == null ? "smart" : dir ? "add" : "subtract"); | 163 | if (typeof dir != "string") { |
164 | if (dir == null) dir = options.smartIndent ? "smart" : "prev"; | ||
165 | else dir = dir ? "add" : "subtract"; | ||
166 | } | ||
167 | if (isLine(n)) indentLine(n, dir); | ||
155 | }), | 168 | }), |
156 | indentSelection: operation(indentSelected), | 169 | indentSelection: operation(indentSelected), |
157 | historySize: function() {return {undo: history.done.length, redo: history.undone.length};}, | 170 | historySize: function() {return {undo: history.done.length, redo: history.undone.length};}, |
@@ -248,7 +261,15 @@ var CodeMirror = (function() { | |||
248 | moveH: operation(moveH), | 261 | moveH: operation(moveH), |
249 | deleteH: operation(deleteH), | 262 | deleteH: operation(deleteH), |
250 | moveV: operation(moveV), | 263 | moveV: operation(moveV), |
251 | toggleOverwrite: function() {overwrite = !overwrite;}, | 264 | toggleOverwrite: function() { |
265 | if(overwrite){ | ||
266 | overwrite = false; | ||
267 | cursor.className = cursor.className.replace(" CodeMirror-overwrite", ""); | ||
268 | } else { | ||
269 | overwrite = true; | ||
270 | cursor.className += " CodeMirror-overwrite"; | ||
271 | } | ||
272 | }, | ||
252 | 273 | ||
253 | posFromIndex: function(off) { | 274 | posFromIndex: function(off) { |
254 | var lineNo = 0, ch; | 275 | var lineNo = 0, ch; |
@@ -268,9 +289,18 @@ var CodeMirror = (function() { | |||
268 | }); | 289 | }); |
269 | return index; | 290 | return index; |
270 | }, | 291 | }, |
292 | scrollTo: function(x, y) { | ||
293 | if (x != null) scroller.scrollLeft = x; | ||
294 | if (y != null) scroller.scrollTop = y; | ||
295 | updateDisplay([]); | ||
296 | }, | ||
271 | 297 | ||
272 | operation: function(f){return operation(f)();}, | 298 | operation: function(f){return operation(f)();}, |
273 | refresh: function(){updateDisplay(true);}, | 299 | refresh: function(){ |
300 | updateDisplay(true); | ||
301 | if (scroller.scrollHeight > lastScrollPos) | ||
302 | scroller.scrollTop = lastScrollPos; | ||
303 | }, | ||
274 | getInputField: function(){return input;}, | 304 | getInputField: function(){return input;}, |
275 | getWrapperElement: function(){return wrapper;}, | 305 | getWrapperElement: function(){return wrapper;}, |
276 | getScrollerElement: function(){return scroller;}, | 306 | getScrollerElement: function(){return scroller;}, |
@@ -297,7 +327,7 @@ var CodeMirror = (function() { | |||
297 | } | 327 | } |
298 | 328 | ||
299 | function onMouseDown(e) { | 329 | function onMouseDown(e) { |
300 | setShift(e.shiftKey); | 330 | setShift(e_prop(e, "shiftKey")); |
301 | // Check whether this is a click in a widget | 331 | // Check whether this is a click in a widget |
302 | for (var n = e_target(e); n != wrapper; n = n.parentNode) | 332 | for (var n = e_target(e); n != wrapper; n = n.parentNode) |
303 | if (n.parentNode == code && n != mover) return; | 333 | if (n.parentNode == code && n != mover) return; |
@@ -339,7 +369,7 @@ var CodeMirror = (function() { | |||
339 | } else { lastClick = {time: now, pos: start}; } | 369 | } else { lastClick = {time: now, pos: start}; } |
340 | 370 | ||
341 | var last = start, going; |