aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/lib/codemirror.js
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/lib/codemirror.js')
-rw-r--r--imports/codemirror/lib/codemirror.js619
1 files changed, 414 insertions, 205 deletions
diff --git a/imports/codemirror/lib/codemirror.js b/imports/codemirror/lib/codemirror.js
index 5434a8dd..250d5b18 100644
--- a/imports/codemirror/lib/codemirror.js
+++ b/imports/codemirror/lib/codemirror.js
@@ -1,4 +1,4 @@
1// CodeMirror version 2.23 1// CodeMirror version 2.3
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,
@@ -23,14 +23,19 @@ var CodeMirror = (function() {
23 '<div style="overflow: hidden; position: relative; width: 3px; height: 0px;">' + // Wraps and hides input textarea 23 '<div style="overflow: hidden; position: relative; width: 3px; height: 0px;">' + // Wraps and hides input textarea
24 '<textarea style="position: absolute; padding: 0; width: 1px; height: 1em" wrap="off" ' + 24 '<textarea style="position: absolute; padding: 0; width: 1px; height: 1em" wrap="off" ' +
25 'autocorrect="off" autocapitalize="off"></textarea></div>' + 25 '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.
26 '<div class="CodeMirror-scroll" tabindex="-1">' + 29 '<div class="CodeMirror-scroll" tabindex="-1">' +
27 '<div style="position: relative">' + // Set to the height of the text, causes scrolling 30 '<div style="position: relative">' + // Set to the height of the text, causes scrolling
28 '<div style="position: relative">' + // Moved around its parent to cover visible view 31 '<div style="position: relative">' + // Moved around its parent to cover visible view
29 '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' + 32 '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
30 // Provides positioning relative to (visible) text origin 33 // Provides positioning relative to (visible) text origin
31 '<div class="CodeMirror-lines"><div style="position: relative; z-index: 0">' + 34 '<div class="CodeMirror-lines"><div style="position: relative; z-index: 0">' +
35 // Used to measure text size
32 '<div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden;"></div>' + 36 '<div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden;"></div>' +
33 '<pre class="CodeMirror-cursor">&#160;</pre>' + // Absolutely positioned blinky cursor 37 '<pre class="CodeMirror-cursor">&#160;</pre>' + // Absolutely positioned blinky cursor
38 '<pre class="CodeMirror-cursor" style="visibility: hidden">&#160;</pre>' + // Used to force a width
34 '<div style="position: relative; z-index: -1"></div><div></div>' + // DIVs containing the selection and the actual code 39 '<div style="position: relative; z-index: -1"></div><div></div>' + // DIVs containing the selection and the actual code
35 '</div></div></div></div></div>'; 40 '</div></div></div></div></div>';
36 if (place.appendChild) place.appendChild(wrapper); else place(wrapper); 41 if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
@@ -39,12 +44,13 @@ var CodeMirror = (function() {
39 scroller = wrapper.lastChild, code = scroller.firstChild, 44 scroller = wrapper.lastChild, code = scroller.firstChild,
40 mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild, 45 mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild,
41 lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild, 46 lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,
42 cursor = measure.nextSibling, selectionDiv = cursor.nextSibling, 47 cursor = measure.nextSibling, widthForcer = cursor.nextSibling,
43 lineDiv = selectionDiv.nextSibling; 48 selectionDiv = widthForcer.nextSibling, lineDiv = selectionDiv.nextSibling,
44 themeChanged(); 49 scrollbar = inputDiv.nextSibling, scrollbarInner = scrollbar.firstChild;
50 themeChanged(); keyMapChanged();
45 // Needed to hide big blue blinking cursor on Mobile Safari 51 // Needed to hide big blue blinking cursor on Mobile Safari
46 if (ios) input.style.width = "0px"; 52 if (ios) input.style.width = "0px";
47 if (!webkit) lineSpace.draggable = true; 53 if (!webkit) scroller.draggable = true;
48 lineSpace.style.outline = "none"; 54 lineSpace.style.outline = "none";
49 if (options.tabindex != null) input.tabIndex = options.tabindex; 55 if (options.tabindex != null) input.tabIndex = options.tabindex;
50 if (options.autofocus) focusInput(); 56 if (options.autofocus) focusInput();
@@ -52,6 +58,17 @@ var CodeMirror = (function() {
52 // Needed to handle Tab key in KHTML 58 // Needed to handle Tab key in KHTML
53 if (khtml) inputDiv.style.height = "1px", inputDiv.style.position = "absolute"; 59 if (khtml) inputDiv.style.height = "1px", inputDiv.style.position = "absolute";
54 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
55 // Check for problem with IE innerHTML not working when we have a 72 // Check for problem with IE innerHTML not working when we have a
56 // P (or similar) parent node. 73 // P (or similar) parent node.
57 try { stringWidth("x"); } 74 try { stringWidth("x"); }
@@ -75,7 +92,7 @@ var CodeMirror = (function() {
75 var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false}; 92 var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
76 // Selection-related flags. shiftSelecting obviously tracks 93 // Selection-related flags. shiftSelecting obviously tracks
77 // whether the user is holding shift. 94 // whether the user is holding shift.
78 var shiftSelecting, lastClick, lastDoubleClick, lastScrollPos = 0, draggingText, 95 var shiftSelecting, lastClick, lastDoubleClick, lastScrollTop = 0, lastScrollLeft = 0, draggingText,
79 overwrite = false, suppressEdits = false; 96 overwrite = false, suppressEdits = false;
80 // Variables used by startOperation/endOperation to track what 97 // Variables used by startOperation/endOperation to track what
81 // happened during the operation. 98 // happened during the operation.
@@ -88,7 +105,7 @@ var CodeMirror = (function() {
88 var bracketHighlighted; 105 var bracketHighlighted;
89 // Tracks the maximum line length so that the horizontal scrollbar 106 // Tracks the maximum line length so that the horizontal scrollbar
90 // can be kept static when scrolling. 107 // can be kept static when scrolling.
91 var maxLine = "", maxWidth; 108 var maxLine = "", updateMaxLine = false, maxLineChanged = true;
92 var tabCache = {}; 109 var tabCache = {};
93 110
94 // Initialize the content. 111 // Initialize the content.
@@ -98,18 +115,16 @@ var CodeMirror = (function() {
98 // Register our event handlers. 115 // Register our event handlers.
99 connect(scroller, "mousedown", operation(onMouseDown)); 116 connect(scroller, "mousedown", operation(onMouseDown));
100 connect(scroller, "dblclick", operation(onDoubleClick)); 117 connect(scroller, "dblclick", operation(onDoubleClick));
101 connect(lineSpace, "dragstart", onDragStart);
102 connect(lineSpace, "selectstart", e_preventDefault); 118 connect(lineSpace, "selectstart", e_preventDefault);
103 // Gecko browsers fire contextmenu *after* opening the menu, at 119 // Gecko browsers fire contextmenu *after* opening the menu, at
104 // which point we can't mess with it anymore. Context menu is 120 // which point we can't mess with it anymore. Context menu is
105 // handled in onMouseDown for Gecko. 121 // handled in onMouseDown for Gecko.
106 if (!gecko) connect(scroller, "contextmenu", onContextMenu); 122 if (!gecko) connect(scroller, "contextmenu", onContextMenu);
107 connect(scroller, "scroll", function() { 123 connect(scroller, "scroll", onScroll);
108 lastScrollPos = scroller.scrollTop; 124 connect(scrollbar, "scroll", onScroll);
109 updateDisplay([]); 125 connect(scrollbar, "mousedown", function() {setTimeout(focusInput, 0);});
110 if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px"; 126 connect(scroller, "mousewheel", onMouseWheel);
111 if (options.onScroll) options.onScroll(instance); 127 connect(scroller, "DOMMouseScroll", onMouseWheel);
112 });
113 connect(window, "resize", function() {updateDisplay(true);}); 128 connect(window, "resize", function() {updateDisplay(true);});
114 connect(input, "keyup", operation(onKeyUp)); 129 connect(input, "keyup", operation(onKeyUp));
115 connect(input, "input", fastPoll); 130 connect(input, "input", fastPoll);
@@ -118,9 +133,16 @@ var CodeMirror = (function() {
118 connect(input, "focus", onFocus); 133 connect(input, "focus", onFocus);
119 connect(input, "blur", onBlur); 134 connect(input, "blur", onBlur);
120 135
121 connect(scroller, "dragenter", e_stop); 136 if (options.dragDrop) {
122 connect(scroller, "dragover", e_stop); 137 connect(scroller, "dragstart", onDragStart);
123 connect(scroller, "drop", operation(onDrop)); 138 function drag_(e) {
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 }
124 connect(scroller, "paste", function(){focusInput(); fastPoll();}); 146 connect(scroller, "paste", function(){focusInput(); fastPoll();});
125 connect(input, "paste", fastPoll); 147 connect(input, "paste", fastPoll);
126 connect(input, "cut", operation(function(){ 148 connect(input, "cut", operation(function(){
@@ -160,6 +182,7 @@ var CodeMirror = (function() {
160 else if (option == "theme") themeChanged(); 182 else if (option == "theme") themeChanged();
161 else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)(); 183 else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
162 else if (option == "tabSize") updateDisplay(true); 184 else if (option == "tabSize") updateDisplay(true);
185 else if (option == "keyMap") keyMapChanged();
163 if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme") { 186 if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme") {
164 gutterChanged(); 187 gutterChanged();
165 updateDisplay(true); 188 updateDisplay(true);
@@ -307,15 +330,20 @@ var CodeMirror = (function() {
307 }, 330 },
308 scrollTo: function(x, y) { 331 scrollTo: function(x, y) {
309 if (x != null) scroller.scrollLeft = x; 332 if (x != null) scroller.scrollLeft = x;
310 if (y != null) scroller.scrollTop = y; 333 if (y != null) scrollbar.scrollTop = y;
311 updateDisplay([]); 334 updateDisplay([]);
312 }, 335 },
336 getScrollInfo: function() {
337 return {x: scroller.scrollLeft, y: scrollbar.scrollTop,
338 height: scrollbar.scrollHeight, width: scroller.scrollWidth};
339 },
313 340
314 operation: function(f){return operation(f)();}, 341 operation: function(f){return operation(f)();},
342 compoundChange: function(f){return compoundChange(f);},
315 refresh: function(){ 343 refresh: function(){
316 updateDisplay(true); 344 updateDisplay(true);
317 if (scroller.scrollHeight > lastScrollPos) 345 if (scrollbar.scrollHeight > lastScrollTop)
318 scroller.scrollTop = lastScrollPos; 346 scrollbar.scrollTop = lastScrollTop;
319 }, 347 },
320 getInputField: function(){return input;}, 348 getInputField: function(){return input;},
321 getWrapperElement: function(){return wrapper;}, 349 getWrapperElement: function(){return wrapper;},
@@ -336,12 +364,22 @@ var CodeMirror = (function() {
336 splitLines(code), top, top); 364 splitLines(code), top, top);
337 updateInput = true; 365 updateInput = true;
338 } 366 }
339 function getValue(code) { 367 function getValue() {
340 var text = []; 368 var text = [];
341 doc.iter(0, doc.size, function(line) { text.push(line.text); }); 369 doc.iter(0, doc.size, function(line) { text.push(line.text); });
342 return text.join("\n"); 370 return text.join("\n");
343 } 371 }
344 372
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
345 function onMouseDown(e) { 383 function onMouseDown(e) {