diff options
Diffstat (limited to 'js/codemirror/lib')
-rw-r--r-- | js/codemirror/lib/codemirror.css | 67 | ||||
-rw-r--r-- | js/codemirror/lib/codemirror.js | 2144 | ||||
-rw-r--r-- | js/codemirror/lib/overlay.js | 51 | ||||
-rw-r--r-- | js/codemirror/lib/runmode.js | 27 |
4 files changed, 2289 insertions, 0 deletions
diff --git a/js/codemirror/lib/codemirror.css b/js/codemirror/lib/codemirror.css new file mode 100644 index 00000000..d93e72d7 --- /dev/null +++ b/js/codemirror/lib/codemirror.css | |||
@@ -0,0 +1,67 @@ | |||
1 | .CodeMirror { | ||
2 | line-height: 1em; | ||
3 | font-family: monospace; | ||
4 | } | ||
5 | |||
6 | .CodeMirror-scroll { | ||
7 | overflow: auto; | ||
8 | height: 300px; | ||
9 | /* This is needed to prevent an IE[67] bug where the scrolled content | ||
10 | is visible outside of the scrolling box. */ | ||
11 | position: relative; | ||
12 | } | ||
13 | |||
14 | .CodeMirror-gutter { | ||
15 | position: absolute; left: 0; top: 0; | ||
16 | background-color: #f7f7f7; | ||
17 | border-right: 1px solid #eee; | ||
18 | min-width: 2em; | ||
19 | height: 100%; | ||
20 | } | ||
21 | .CodeMirror-gutter-text { | ||
22 | color: #aaa; | ||
23 | text-align: right; | ||
24 | padding: .4em .2em .4em .4em; | ||
25 | } | ||
26 | .CodeMirror-lines { | ||
27 | padding: .4em; | ||
28 | } | ||
29 | |||
30 | .CodeMirror pre { | ||
31 | -moz-border-radius: 0; | ||
32 | -webkit-border-radius: 0; | ||
33 | -o-border-radius: 0; | ||
34 | border-radius: 0; | ||
35 | border-width: 0; margin: 0; padding: 0; background: transparent; | ||
36 | font-family: inherit; | ||
37 | font-size: inherit; | ||
38 | padding: 0; margin: 0; | ||
39 | white-space: pre; | ||
40 | word-wrap: normal; | ||
41 | } | ||
42 | |||
43 | .CodeMirror textarea { | ||
44 | font-family: inherit !important; | ||
45 | font-size: inherit !important; | ||
46 | } | ||
47 | |||
48 | .CodeMirror-cursor { | ||
49 | z-index: 10; | ||
50 | position: absolute; | ||
51 | visibility: hidden; | ||
52 | border-left: 1px solid black !important; | ||
53 | } | ||
54 | .CodeMirror-focused .CodeMirror-cursor { | ||
55 | visibility: visible; | ||
56 | } | ||
57 | |||
58 | span.CodeMirror-selected { | ||
59 | background: #ccc !important; | ||
60 | color: HighlightText !important; | ||
61 | } | ||
62 | .CodeMirror-focused span.CodeMirror-selected { | ||
63 | background: Highlight !important; | ||
64 | } | ||
65 | |||
66 | .CodeMirror-matchingbracket {color: #0f0 !important;} | ||
67 | .CodeMirror-nonmatchingbracket {color: #f22 !important;} | ||
diff --git a/js/codemirror/lib/codemirror.js b/js/codemirror/lib/codemirror.js new file mode 100644 index 00000000..27bec72f --- /dev/null +++ b/js/codemirror/lib/codemirror.js | |||
@@ -0,0 +1,2144 @@ | |||
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) { | ||