diff options
author | Valerio Virgillito | 2012-02-15 17:04:39 -0800 |
---|---|---|
committer | Valerio Virgillito | 2012-02-15 17:04:39 -0800 |
commit | fe71cb9aa1700199c0089166ad54fc56eb760644 (patch) | |
tree | b0c7c24b1f45a079e1c09312ca716e3d35aecad4 /js/codemirror/lib/codemirror.js | |
parent | 747616980cad14f0b65fbcc7f497ed9680a39d29 (diff) | |
parent | d366c0bd1af6471511217ed574083e15059519b5 (diff) | |
download | ninja-fe71cb9aa1700199c0089166ad54fc56eb760644.tar.gz |
Merge branch 'refs/heads/master' into components
Diffstat (limited to 'js/codemirror/lib/codemirror.js')
-rw-r--r-- | js/codemirror/lib/codemirror.js | 2144 |
1 files changed, 0 insertions, 2144 deletions
diff --git a/js/codemirror/lib/codemirror.js b/js/codemirror/lib/codemirror.js deleted file mode 100644 index 27bec72f..00000000 --- a/js/codemirror/lib/codemirror.js +++ /dev/null | |||
@@ -1,2144 +0,0 @@ | |||
1 | // All functions that need access to the editor's state live inside | ||
2 | // the CodeMirror function. Below that, at the bottom of the file, | ||
3 | // some utilities are defined. | ||
4 | |||
5 | // CodeMirror is the only global var we claim | ||
6 | var CodeMirror = (function() { | ||
7 | // This is the function that produces an editor instance. It's | ||
8 | // closure is used to store the editor state. | ||
9 | function CodeMirror(place, givenOptions) { | ||
10 | // Determine effective options based on given values and defaults. | ||
11 | var options = {}, defaults = CodeMirror.defaults; | ||
12 | for (var opt in defaults) | ||
13 | if (defaults.hasOwnProperty(opt)) | ||
14 | options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt]; | ||
15 | |||
16 | var targetDocument = options["document"]; | ||
17 | // The element in which the editor lives. | ||
18 | var wrapper = targetDocument.createElement("div"); | ||
19 | wrapper.className = "CodeMirror"; | ||
20 | // This mess creates the base DOM structure for the editor. | ||
21 | wrapper.innerHTML = | ||
22 | '<div style="overflow: hidden; position: relative; width: 1px; height: 0px;">' + // Wraps and hides input textarea | ||
23 | '<textarea style="position: absolute; width: 2px;" wrap="off"></textarea></div>' + | ||
24 | '<div class="CodeMirror-scroll cm-s-' + options.theme + '">' + | ||
25 | '<div style="position: relative">' + // Set to the height of the text, causes scrolling | ||
26 | '<div style="position: absolute; height: 0; width: 0; overflow: hidden;"></div>' + | ||
27 | '<div style="position: relative">' + // Moved around its parent to cover visible view | ||
28 | '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' + | ||
29 | // Provides positioning relative to (visible) text origin | ||
30 | '<div class="CodeMirror-lines"><div style="position: relative">' + | ||
31 | '<pre class="CodeMirror-cursor"> </pre>' + // Absolutely positioned blinky cursor | ||
32 | '<div></div>' + // This DIV contains the actual code | ||
33 | '</div></div></div></div></div>'; | ||
34 | if (place.appendChild) place.appendChild(wrapper); else place(wrapper); | ||
35 | // I've never seen more elegant code in my life. | ||
36 | var inputDiv = wrapper.firstChild, input = inputDiv.firstChild, | ||
37 | scroller = wrapper.lastChild, code = scroller.firstChild, | ||
38 | measure = code.firstChild, mover = measure.nextSibling, | ||
39 | gutter = mover.firstChild, gutterText = gutter.firstChild, | ||
40 | lineSpace = gutter.nextSibling.firstChild, | ||
41 | cursor = lineSpace.firstChild, lineDiv = cursor.nextSibling; | ||
42 | if (options.tabindex != null) input.tabindex = options.tabindex; | ||
43 | if (!options.gutter && !options.lineNumbers) gutter.style.display = "none"; | ||
44 | |||
45 | // Delayed object wrap timeouts, making sure only one is active. blinker holds an interval. | ||
46 | var poll = new Delayed(), highlight = new Delayed(), blinker; | ||
47 | |||
48 | // mode holds a mode API object. lines an array of Line objects | ||
49 | // (see Line constructor), work an array of lines that should be | ||
50 | // parsed, and history the undo history (instance of History | ||
51 | // constructor). | ||
52 | var mode, lines = [new Line("")], work, history = new History(), focused; | ||
53 | loadMode(); | ||
54 | // The selection. These are always maintained to point at valid | ||
55 | // positions. Inverted is used to remember that the user is | ||
56 | // selecting bottom-to-top. | ||
57 | var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false}; | ||
58 | // Selection-related flags. shiftSelecting obviously tracks | ||
59 | // whether the user is holding shift. reducedSelection is a hack | ||
60 | // to get around the fact that we can't create inverted | ||
61 | // selections. See below. | ||
62 | var shiftSelecting, reducedSelection, lastDoubleClick; | ||
63 | // Variables used by startOperation/endOperation to track what | ||
64 | // happened during the operation. | ||
65 | var updateInput, changes, textChanged, selectionChanged, leaveInputAlone; | ||
66 | // Current visible range (may be bigger than the view window). | ||
67 | var showingFrom = 0, showingTo = 0, lastHeight = 0, curKeyId = null; | ||
68 | // editing will hold an object describing the things we put in the | ||
69 | // textarea, to help figure out whether something changed. | ||
70 | // bracketHighlighted is used to remember that a backet has been | ||
71 | // marked. | ||
72 | var editing, bracketHighlighted; | ||
73 | // Tracks the maximum line length so that the horizontal scrollbar | ||
74 | // can be kept static when scrolling. | ||
75 | var maxLine = "", maxWidth; | ||
76 | |||
77 | // Initialize the content. | ||
78 | operation(function(){setValue(options.value || ""); updateInput = false;})(); | ||
79 | |||
80 | // Register our event handlers. | ||
81 | connect(scroller, "mousedown", operation(onMouseDown)); | ||
82 | // Gecko browsers fire contextmenu *after* opening the menu, at | ||
83 | // which point we can't mess with it anymore. Context menu is | ||
84 | // handled in onMouseDown for Gecko. | ||
85 | if (!gecko) connect(scroller, "contextmenu", onContextMenu); | ||
86 | connect(code, "dblclick", operation(onDblClick)); | ||
87 | connect(scroller, "scroll", function() {updateDisplay([]); if (options.onScroll) options.onScroll(instance);}); | ||
88 | connect(window, "resize", function() {updateDisplay(true);}); | ||
89 | connect(input, "keyup", operation(onKeyUp)); | ||
90 | connect(input, "keydown", operation(onKeyDown)); | ||
91 | connect(input, "keypress", operation(onKeyPress)); | ||
92 | connect(input, "focus", onFocus); | ||
93 | connect(input, "blur", onBlur); | ||
94 | |||
95 | connect(scroller, "dragenter", e_stop); | ||
96 | connect(scroller, "dragover", e_stop); | ||
97 | connect(scroller, "drop", operation(onDrop)); | ||
98 | connect(scroller, "paste", function(){focusInput(); fastPoll();}); | ||
99 | connect(input, "paste", function(){fastPoll();}); | ||
100 | connect(input, "cut", function(){fastPoll();}); | ||
101 | |||
102 | // IE throws unspecified error in certain cases, when | ||
103 | // trying to access activeElement before onload | ||
104 | var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { } | ||
105 | if (hasFocus) setTimeout(onFocus, 20); | ||
106 | else onBlur(); | ||
107 | |||
108 | function isLine(l) {return l >= 0 && l < lines.length;} | ||
109 | // The instance object that we'll return. Mostly calls out to | ||
110 | // local functions in the CodeMirror function. Some do some extra | ||
111 | // range checking and/or clipping. operation is used to wrap the | ||
112 | // call so that changes it makes are tracked, and the display is | ||
113 | // updated afterwards. | ||
114 | var instance = { | ||
115 | getValue: getValue, | ||
116 | setValue: operation(setValue), | ||
117 | getSelection: getSelection, | ||
118 | replaceSelection: operation(replaceSelection), | ||
119 | focus: function(){focusInput(); onFocus(); fastPoll();}, | ||
120 | setOption: function(option, value) { | ||
121 | options[option] = value; | ||
122 | if (option == "lineNumbers" || option == "gutter") gutterChanged(); | ||
123 | else if (option == "mode" || option == "indentUnit") loadMode(); | ||
124 | else if (option == "readOnly" && value == "nocursor") input.blur(); | ||
125 | else if (option == "theme") scroller.className = scroller.className.replace(/cm-s-\w+/, "cm-s-" + value); | ||
126 | }, | ||
127 | getOption: function(option) {return options[option];}, | ||
128 | undo: operation(undo), | ||
129 | redo: operation(redo), | ||
130 | indentLine: operation(function(n) {if (isLine(n)) indentLine(n, "smart");}), | ||
131 | historySize: function() {return {undo: history.done.length, redo: history.undone.length};}, | ||
132 | matchBrackets: operation(function(){matchBrackets(true);}), | ||
133 | getTokenAt: function(pos) { | ||
134 | pos = clipPos(pos); | ||
135 | return lines[pos.line].getTokenAt(mode, getStateBefore(pos.line), pos.ch); | ||
136 | }, | ||
137 | getStateAfter: function(line) { | ||
138 | line = clipLine(line == null ? lines.length - 1: line); | ||
139 | return getStateBefore(line + 1); | ||
140 | }, | ||
141 | cursorCoords: function(start){ | ||
142 | if (start == null) start = sel.inverted; | ||
143 | return pageCoords(start ? sel.from : sel.to); | ||
144 | }, | ||
145 | charCoords: function(pos){return pageCoords(clipPos(pos));}, | ||
146 | coordsChar: function(coords) { | ||
147 | var off = eltOffset(lineSpace); | ||
148 | var line = clipLine(Math.min(lines.length - 1, showingFrom + Math.floor((coords.y - off.top) / lineHeight()))); | ||
149 | return clipPos({line: line, ch: charFromX(clipLine(line), coords.x - off.left)}); | ||
150 | }, | ||
151 | getSearchCursor: function(query, pos, caseFold) {return new SearchCursor(query, pos, caseFold);}, | ||
152 | markText: operation(function(a, b, c){return operation(markText(a, b, c));}), | ||
153 | setMarker: addGutterMarker, | ||
154 | clearMarker: removeGutterMarker, | ||
155 | setLineClass: operation(setLineClass), | ||
156 | lineInfo: lineInfo, | ||
157 | addWidget: function(pos, node, scroll, where) { | ||
158 | pos = localCoords(clipPos(pos)); | ||
159 | var top = pos.yBot, left = pos.x; | ||
160 | node.style.position = "absolute"; | ||
161 | code.appendChild(node); | ||
162 | node.style.left = left + "px"; | ||
163 | if (where == "over") top = pos.y; | ||
164 | else if (where == "near") { | ||
165 | var vspace = Math.max(scroller.offsetHeight, lines.length * lineHeight()), | ||
166 | hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft(); | ||
167 | if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight) | ||
168 | top = pos.y - node.offsetHeight; | ||
169 | if (left + node.offsetWidth > hspace) | ||
170 | left = hspace - node.offsetWidth; | ||
171 | } | ||
172 | node.style.top = (top + paddingTop()) + "px"; | ||
173 | node.style.left = (left + paddingLeft()) + "px"; | ||
174 | if (scroll) | ||
175 | scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight); | ||
176 | }, | ||
177 | |||
178 | lineCount: function() {return lines.length;}, | ||
179 | getCursor: function(start) { | ||
180 | if (start == null) start = sel.inverted; | ||
181 | return copyPos(start ? sel.from : sel.to); | ||
182 | }, | ||
183 | somethingSelected: function() {return !posEq(sel.from, sel.to);}, | ||
184 | setCursor: operation(function(line, ch) { | ||
185 | if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch); | ||
186 | else setCursor(line, ch); | ||
187 | }), | ||
188 | setSelection: operation(function(from, to) {setSelection(clipPos(from), clipPos(to || from));}), | ||
189 | getLine: function(line) {if (isLine(line)) return lines[line].text;}, | ||
190 | setLine: operation(function(line, text) { | ||
191 | if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: lines[line].text.length}); | ||
192 | }), | ||
193 | removeLine: operation(function(line) { | ||
194 | if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0})); | ||
195 | }), | ||
196 | replaceRange: operation(replaceRange), | ||
197 | getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));}, | ||
198 | |||
199 | operation: function(f){return operation(f)();}, | ||
200 | refresh: function(){updateDisplay(true);}, | ||
201 | getInputField: function(){return input;}, | ||
202 | getWrapperElement: function(){return wrapper;}, | ||
203 | getScrollerElement: function(){return scroller;} | ||
204 | }; | ||
205 | |||
206 | function setValue(code) { | ||
207 | history = null; | ||
208 | var top = {line: 0, ch: 0}; | ||
209 | updateLines(top, {line: lines.length - 1, ch: lines[lines.length-1].text.length}, | ||
210 | splitLines(code), top, top); | ||
211 | history = new History(); | ||
212 | } | ||
213 | function getValue(code) { | ||
214 | var text = []; | ||
215 | for (var i = 0, l = lines.length; i < l; ++i) | ||
216 | text.push(lines[i].text); | ||
217 | return text.join("\n"); | ||
218 | } |