##// END OF EJS Templates
Update CodeMirror code to v2.15
Fernando Perez -
Show More
@@ -0,0 +1,340 b''
1 <!doctype html>
2 <html>
3 <head>
4 <title>CodeMirror 2: Markdown mode</title>
5 <link rel="stylesheet" href="../../lib/codemirror.css">
6 <script src="../../lib/codemirror.js"></script>
7 <script src="../xml/xml.js"></script>
8 <script src="markdown.js"></script>
9 <link rel="stylesheet" href="../../theme/default.css">
10 <link rel="stylesheet" href="markdown.css">
11 <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
12 <link rel="stylesheet" href="../../css/docs.css">
13 </head>
14 <body>
15 <h1>CodeMirror 2: Markdown mode</h1>
16
17 <!-- source: http://daringfireball.net/projects/markdown/basics.text -->
18 <form><textarea id="code" name="code">
19 Markdown: Basics
20 ================
21
22 &lt;ul id="ProjectSubmenu"&gt;
23 &lt;li&gt;&lt;a href="/projects/markdown/" title="Markdown Project Page"&gt;Main&lt;/a&gt;&lt;/li&gt;
24 &lt;li&gt;&lt;a class="selected" title="Markdown Basics"&gt;Basics&lt;/a&gt;&lt;/li&gt;
25 &lt;li&gt;&lt;a href="/projects/markdown/syntax" title="Markdown Syntax Documentation"&gt;Syntax&lt;/a&gt;&lt;/li&gt;
26 &lt;li&gt;&lt;a href="/projects/markdown/license" title="Pricing and License Information"&gt;License&lt;/a&gt;&lt;/li&gt;
27 &lt;li&gt;&lt;a href="/projects/markdown/dingus" title="Online Markdown Web Form"&gt;Dingus&lt;/a&gt;&lt;/li&gt;
28 &lt;/ul&gt;
29
30
31 Getting the Gist of Markdown's Formatting Syntax
32 ------------------------------------------------
33
34 This page offers a brief overview of what it's like to use Markdown.
35 The [syntax page] [s] provides complete, detailed documentation for
36 every feature, but Markdown should be very easy to pick up simply by
37 looking at a few examples of it in action. The examples on this page
38 are written in a before/after style, showing example syntax and the
39 HTML output produced by Markdown.
40
41 It's also helpful to simply try Markdown out; the [Dingus] [d] is a
42 web application that allows you type your own Markdown-formatted text
43 and translate it to XHTML.
44
45 **Note:** This document is itself written using Markdown; you
46 can [see the source for it by adding '.text' to the URL] [src].
47
48 [s]: /projects/markdown/syntax "Markdown Syntax"
49 [d]: /projects/markdown/dingus "Markdown Dingus"
50 [src]: /projects/markdown/basics.text
51
52
53 ## Paragraphs, Headers, Blockquotes ##
54
55 A paragraph is simply one or more consecutive lines of text, separated
56 by one or more blank lines. (A blank line is any line that looks like
57 a blank line -- a line containing nothing but spaces or tabs is
58 considered blank.) Normal paragraphs should not be indented with
59 spaces or tabs.
60
61 Markdown offers two styles of headers: *Setext* and *atx*.
62 Setext-style headers for `&lt;h1&gt;` and `&lt;h2&gt;` are created by
63 "underlining" with equal signs (`=`) and hyphens (`-`), respectively.
64 To create an atx-style header, you put 1-6 hash marks (`#`) at the
65 beginning of the line -- the number of hashes equals the resulting
66 HTML header level.
67
68 Blockquotes are indicated using email-style '`&gt;`' angle brackets.
69
70 Markdown:
71
72 A First Level Header
73 ====================
74
75 A Second Level Header
76 ---------------------
77
78 Now is the time for all good men to come to
79 the aid of their country. This is just a
80 regular paragraph.
81
82 The quick brown fox jumped over the lazy
83 dog's back.
84
85 ### Header 3
86
87 &gt; This is a blockquote.
88 &gt;
89 &gt; This is the second paragraph in the blockquote.
90 &gt;
91 &gt; ## This is an H2 in a blockquote
92
93
94 Output:
95
96 &lt;h1&gt;A First Level Header&lt;/h1&gt;
97
98 &lt;h2&gt;A Second Level Header&lt;/h2&gt;
99
100 &lt;p&gt;Now is the time for all good men to come to
101 the aid of their country. This is just a
102 regular paragraph.&lt;/p&gt;
103
104 &lt;p&gt;The quick brown fox jumped over the lazy
105 dog's back.&lt;/p&gt;
106
107 &lt;h3&gt;Header 3&lt;/h3&gt;
108
109 &lt;blockquote&gt;
110 &lt;p&gt;This is a blockquote.&lt;/p&gt;
111
112 &lt;p&gt;This is the second paragraph in the blockquote.&lt;/p&gt;
113
114 &lt;h2&gt;This is an H2 in a blockquote&lt;/h2&gt;
115 &lt;/blockquote&gt;
116
117
118
119 ### Phrase Emphasis ###
120
121 Markdown uses asterisks and underscores to indicate spans of emphasis.
122
123 Markdown:
124
125 Some of these words *are emphasized*.
126 Some of these words _are emphasized also_.
127
128 Use two asterisks for **strong emphasis**.
129 Or, if you prefer, __use two underscores instead__.
130
131 Output:
132
133 &lt;p&gt;Some of these words &lt;em&gt;are emphasized&lt;/em&gt;.
134 Some of these words &lt;em&gt;are emphasized also&lt;/em&gt;.&lt;/p&gt;
135
136 &lt;p&gt;Use two asterisks for &lt;strong&gt;strong emphasis&lt;/strong&gt;.
137 Or, if you prefer, &lt;strong&gt;use two underscores instead&lt;/strong&gt;.&lt;/p&gt;
138
139
140
141 ## Lists ##
142
143 Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
144 `+`, and `-`) as list markers. These three markers are
145 interchangable; this:
146
147 * Candy.
148 * Gum.
149 * Booze.
150
151 this:
152
153 + Candy.
154 + Gum.
155 + Booze.
156
157 and this:
158
159 - Candy.
160 - Gum.
161 - Booze.
162
163 all produce the same output:
164
165 &lt;ul&gt;
166 &lt;li&gt;Candy.&lt;/li&gt;
167 &lt;li&gt;Gum.&lt;/li&gt;
168 &lt;li&gt;Booze.&lt;/li&gt;
169 &lt;/ul&gt;
170
171 Ordered (numbered) lists use regular numbers, followed by periods, as
172 list markers:
173
174 1. Red
175 2. Green
176 3. Blue
177
178 Output:
179
180 &lt;ol&gt;
181 &lt;li&gt;Red&lt;/li&gt;
182 &lt;li&gt;Green&lt;/li&gt;
183 &lt;li&gt;Blue&lt;/li&gt;
184 &lt;/ol&gt;
185
186 If you put blank lines between items, you'll get `&lt;p&gt;` tags for the
187 list item text. You can create multi-paragraph list items by indenting
188 the paragraphs by 4 spaces or 1 tab:
189
190 * A list item.
191
192 With multiple paragraphs.
193
194 * Another item in the list.
195
196 Output:
197
198 &lt;ul&gt;
199 &lt;li&gt;&lt;p&gt;A list item.&lt;/p&gt;
200 &lt;p&gt;With multiple paragraphs.&lt;/p&gt;&lt;/li&gt;
201 &lt;li&gt;&lt;p&gt;Another item in the list.&lt;/p&gt;&lt;/li&gt;
202 &lt;/ul&gt;
203
204
205
206 ### Links ###
207
208 Markdown supports two styles for creating links: *inline* and
209 *reference*. With both styles, you use square brackets to delimit the
210 text you want to turn into a link.
211
212 Inline-style links use parentheses immediately after the link text.
213 For example:
214
215 This is an [example link](http://example.com/).
216
217 Output:
218
219 &lt;p&gt;This is an &lt;a href="http://example.com/"&gt;
220 example link&lt;/a&gt;.&lt;/p&gt;
221
222 Optionally, you may include a title attribute in the parentheses:
223
224 This is an [example link](http://example.com/ "With a Title").
225
226 Output:
227
228 &lt;p&gt;This is an &lt;a href="http://example.com/" title="With a Title"&gt;
229 example link&lt;/a&gt;.&lt;/p&gt;
230
231 Reference-style links allow you to refer to your links by names, which
232 you define elsewhere in your document:
233
234 I get 10 times more traffic from [Google][1] than from
235 [Yahoo][2] or [MSN][3].
236
237 [1]: http://google.com/ "Google"
238 [2]: http://search.yahoo.com/ "Yahoo Search"
239 [3]: http://search.msn.com/ "MSN Search"
240
241 Output:
242
243 &lt;p&gt;I get 10 times more traffic from &lt;a href="http://google.com/"
244 title="Google"&gt;Google&lt;/a&gt; than from &lt;a href="http://search.yahoo.com/"
245 title="Yahoo Search"&gt;Yahoo&lt;/a&gt; or &lt;a href="http://search.msn.com/"
246 title="MSN Search"&gt;MSN&lt;/a&gt;.&lt;/p&gt;
247
248 The title attribute is optional. Link names may contain letters,
249 numbers and spaces, but are *not* case sensitive:
250
251 I start my morning with a cup of coffee and
252 [The New York Times][NY Times].
253
254 [ny times]: http://www.nytimes.com/
255
256 Output:
257
258 &lt;p&gt;I start my morning with a cup of coffee and
259 &lt;a href="http://www.nytimes.com/"&gt;The New York Times&lt;/a&gt;.&lt;/p&gt;
260
261
262 ### Images ###
263
264 Image syntax is very much like link syntax.
265
266 Inline (titles are optional):
267
268 ![alt text](/path/to/img.jpg "Title")
269
270 Reference-style:
271
272 ![alt text][id]
273
274 [id]: /path/to/img.jpg "Title"
275
276 Both of the above examples produce the same output:
277
278 &lt;img src="/path/to/img.jpg" alt="alt text" title="Title" /&gt;
279
280
281
282 ### Code ###
283
284 In a regular paragraph, you can create code span by wrapping text in
285 backtick quotes. Any ampersands (`&amp;`) and angle brackets (`&lt;` or
286 `&gt;`) will automatically be translated into HTML entities. This makes
287 it easy to use Markdown to write about HTML example code:
288
289 I strongly recommend against using any `&lt;blink&gt;` tags.
290
291 I wish SmartyPants used named entities like `&amp;mdash;`
292 instead of decimal-encoded entites like `&amp;#8212;`.
293
294 Output:
295
296 &lt;p&gt;I strongly recommend against using any
297 &lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;
298
299 &lt;p&gt;I wish SmartyPants used named entities like
300 &lt;code&gt;&amp;amp;mdash;&lt;/code&gt; instead of decimal-encoded
301 entites like &lt;code&gt;&amp;amp;#8212;&lt;/code&gt;.&lt;/p&gt;
302
303
304 To specify an entire block of pre-formatted code, indent every line of
305 the block by 4 spaces or 1 tab. Just like with code spans, `&amp;`, `&lt;`,
306 and `&gt;` characters will be escaped automatically.
307
308 Markdown:
309
310 If you want your page to validate under XHTML 1.0 Strict,
311 you've got to put paragraph tags in your blockquotes:
312
313 &lt;blockquote&gt;
314 &lt;p&gt;For example.&lt;/p&gt;
315 &lt;/blockquote&gt;
316
317 Output:
318
319 &lt;p&gt;If you want your page to validate under XHTML 1.0 Strict,
320 you've got to put paragraph tags in your blockquotes:&lt;/p&gt;
321
322 &lt;pre&gt;&lt;code&gt;&amp;lt;blockquote&amp;gt;
323 &amp;lt;p&amp;gt;For example.&amp;lt;/p&amp;gt;
324 &amp;lt;/blockquote&amp;gt;
325 &lt;/code&gt;&lt;/pre&gt;
326 </textarea></form>
327
328 <script>
329 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
330 mode: 'markdown',
331 lineNumbers: true,
332 matchBrackets: true,
333 theme: "default"
334 });
335 </script>
336
337 <p><strong>MIME types defined:</strong> <code>text/x-markdown</code>.</p>
338
339 </body>
340 </html>
@@ -0,0 +1,10 b''
1 .cm-s-default span.cm-header {color: #2f2f4f; font-weight:bold;}
2 .cm-s-default span.cm-code {color: #666;}
3 .cm-s-default span.cm-quote {color: #090;}
4 .cm-s-default span.cm-list {color: #a50;}
5 .cm-s-default span.cm-hr {color: #999;}
6 .cm-s-default span.cm-linktext {color: #00c; text-decoration: underline;}
7 .cm-s-default span.cm-linkhref {color: #00c;}
8 .cm-s-default span.cm-em {font-style: italic;}
9 .cm-s-default span.cm-strong {font-weight: bold;}
10 .cm-s-default span.cm-emstrong {font-style: italic; font-weight: bold;}
@@ -0,0 +1,230 b''
1 CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
2
3 var htmlMode = CodeMirror.getMode(cmCfg, { name: 'xml', htmlMode: true });
4
5 var header = 'header'
6 , code = 'code'
7 , quote = 'quote'
8 , list = 'list'
9 , hr = 'hr'
10 , linktext = 'linktext'
11 , linkhref = 'linkhref'
12 , em = 'em'
13 , strong = 'strong'
14 , emstrong = 'emstrong';
15
16 var hrRE = /^[*-=_]/
17 , ulRE = /^[*-+]\s+/
18 , olRE = /^[0-9]\.\s+/
19 , headerRE = /^(?:\={3,}|-{3,})$/
20 , codeRE = /^(k:\t|\s{4,})/
21 , textRE = /^[^\[*_\\<>`]+/;
22
23 function switchInline(stream, state, f) {
24 state.f = state.inline = f;
25 return f(stream, state);
26 }
27
28 function switchBlock(stream, state, f) {
29 state.f = state.block = f;
30 return f(stream, state);
31 }
32
33
34 // Blocks
35
36 function blockNormal(stream, state) {
37 if (stream.match(codeRE)) {
38 stream.skipToEnd();
39 return code;
40 }
41
42 if (stream.eatSpace()) {
43 return null;
44 }
45
46 if (stream.peek() === '#' || stream.match(headerRE)) {
47 stream.skipToEnd();
48 return header;
49 }
50 if (stream.eat('>')) {
51 state.indentation++;
52 return quote;
53 }
54 if (stream.peek() === '<') {
55 return switchBlock(stream, state, htmlBlock);
56 }
57 if (stream.peek() === '[') {
58 return switchInline(stream, state, footnoteLink);
59 }
60 if (hrRE.test(stream.peek())) {
61 var re = new RegExp('(?:\s*['+stream.peek()+']){3,}$');
62 if (stream.match(re, true)) {
63 return hr;
64 }
65 }
66
67 var match;
68 if (match = stream.match(ulRE, true) || stream.match(olRE, true)) {
69 state.indentation += match[0].length;
70 return list;
71 }
72
73 return switchInline(stream, state, state.inline);
74 }
75
76 function htmlBlock(stream, state) {
77 var type = htmlMode.token(stream, state.htmlState);
78 if (stream.eol() && !state.htmlState.context) {
79 state.block = blockNormal;
80 }
81 return type;
82 }
83
84
85 // Inline
86
87 function inlineNormal(stream, state) {
88 function getType() {
89 return state.strong ? (state.em ? emstrong : strong)
90 : (state.em ? em : null);
91 }
92
93 if (stream.match(textRE, true)) {
94 return getType();
95 }
96
97 var ch = stream.next();
98
99 if (ch === '\\') {
100 stream.next();
101 return getType();
102 }
103 if (ch === '`') {
104 return switchInline(stream, state, inlineElement(code, '`'));
105 }
106 if (ch === '<') {
107 return switchInline(stream, state, inlineElement(linktext, '>'));
108 }
109 if (ch === '[') {
110 return switchInline(stream, state, linkText);
111 }
112
113 var t = getType();
114 if (ch === '*' || ch === '_') {
115 if (stream.eat(ch)) {
116 return (state.strong = !state.strong) ? getType() : t;
117 }
118 return (state.em = !state.em) ? getType() : t;
119 }
120
121 return getType();
122 }
123
124 function linkText(stream, state) {
125 while (!stream.eol()) {
126 var ch = stream.next();
127 if (ch === '\\') stream.next();
128 if (ch === ']') {
129 state.inline = state.f = linkHref;
130 return linktext;
131 }
132 }
133 return linktext;
134 }
135
136 function linkHref(stream, state) {
137 stream.eatSpace();
138 var ch = stream.next();
139 if (ch === '(' || ch === '[') {
140 return switchInline(stream, state, inlineElement(linkhref, ch === '(' ? ')' : ']'));
141 }
142 return 'error';
143 }
144
145 function footnoteLink(stream, state) {
146 if (stream.match(/^[^\]]*\]:/, true)) {
147 state.f = footnoteUrl;
148 return linktext;
149 }
150 return switchInline(stream, state, inlineNormal);
151 }
152
153 function footnoteUrl(stream, state) {
154 stream.eatSpace();
155 stream.match(/^[^\s]+/, true);
156 state.f = state.inline = inlineNormal;
157 return linkhref;
158 }
159
160 function inlineElement(type, endChar, next) {
161 next = next || inlineNormal;
162 return function(stream, state) {
163 while (!stream.eol()) {
164 var ch = stream.next();
165 if (ch === '\\') stream.next();
166 if (ch === endChar) {
167 state.inline = state.f = next;
168 return type;
169 }
170 }
171 return type;
172 };
173 }
174
175 return {
176 startState: function() {
177 return {
178 f: blockNormal,
179
180 block: blockNormal,
181 htmlState: htmlMode.startState(),
182 indentation: 0,
183
184 inline: inlineNormal,
185 em: false,
186 strong: false
187 };
188 },
189
190 copyState: function(s) {
191 return {
192 f: s.f,
193
194 block: s.block,
195 htmlState: CodeMirror.copyState(htmlMode, s.htmlState),
196 indentation: s.indentation,
197
198 inline: s.inline,
199 em: s.em,
200 strong: s.strong
201 };
202 },
203
204 token: function(stream, state) {
205 if (stream.sol()) {
206 state.f = state.block;
207 var previousIndentation = state.indentation
208 , currentIndentation = 0;
209 while (previousIndentation > 0) {
210 if (stream.eat(' ')) {
211 previousIndentation--;
212 currentIndentation++;
213 } else if (previousIndentation >= 4 && stream.eat('\t')) {
214 previousIndentation -= 4;
215 currentIndentation += 4;
216 } else {
217 break;
218 }
219 }
220 state.indentation = currentIndentation;
221
222 if (currentIndentation > 0) return null;
223 }
224 return state.f(stream, state);
225 }
226 };
227
228 });
229
230 CodeMirror.defineMIME("text/x-markdown", "markdown");
@@ -13,6 +13,7 b''
13
13
14 .CodeMirror-gutter {
14 .CodeMirror-gutter {
15 position: absolute; left: 0; top: 0;
15 position: absolute; left: 0; top: 0;
16 z-index: 10;
16 background-color: #f7f7f7;
17 background-color: #f7f7f7;
17 border-right: 1px solid #eee;
18 border-right: 1px solid #eee;
18 min-width: 2em;
19 min-width: 2em;
@@ -20,14 +20,15 b' var CodeMirror = (function() {'
20 // This mess creates the base DOM structure for the editor.
20 // This mess creates the base DOM structure for the editor.
21 wrapper.innerHTML =
21 wrapper.innerHTML =
22 '<div style="overflow: hidden; position: relative; width: 1px; height: 0px;">' + // Wraps and hides input textarea
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>' +
23 '<textarea style="position: absolute; width: 2px;" wrap="off" ' +
24 'autocorrect="off" autocapitalize="off"></textarea></div>' +
24 '<div class="CodeMirror-scroll cm-s-' + options.theme + '">' +
25 '<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: 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: absolute; height: 0; width: 0; overflow: hidden;"></div>' +
27 '<div style="position: relative">' + // Moved around its parent to cover visible view
28 '<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 '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
29 // Provides positioning relative to (visible) text origin
30 // Provides positioning relative to (visible) text origin
30 '<div class="CodeMirror-lines"><div style="position: relative">' +
31 '<div class="CodeMirror-lines"><div style="position: relative" draggable="true">' +
31 '<pre class="CodeMirror-cursor">&#160;</pre>' + // Absolutely positioned blinky cursor
32 '<pre class="CodeMirror-cursor">&#160;</pre>' + // Absolutely positioned blinky cursor
32 '<div></div>' + // This DIV contains the actual code
33 '<div></div>' + // This DIV contains the actual code
33 '</div></div></div></div></div>';
34 '</div></div></div></div></div>';
@@ -59,10 +60,10 b' var CodeMirror = (function() {'
59 // whether the user is holding shift. reducedSelection is a hack
60 // whether the user is holding shift. reducedSelection is a hack
60 // to get around the fact that we can't create inverted
61 // to get around the fact that we can't create inverted
61 // selections. See below.
62 // selections. See below.
62 var shiftSelecting, reducedSelection, lastDoubleClick;
63 var shiftSelecting, reducedSelection, lastClick, lastDoubleClick;
63 // Variables used by startOperation/endOperation to track what
64 // Variables used by startOperation/endOperation to track what
64 // happened during the operation.
65 // happened during the operation.
65 var updateInput, changes, textChanged, selectionChanged, leaveInputAlone;
66 var updateInput, changes, textChanged, selectionChanged, leaveInputAlone, gutterDirty;
66 // Current visible range (may be bigger than the view window).
67 // Current visible range (may be bigger than the view window).
67 var showingFrom = 0, showingTo = 0, lastHeight = 0, curKeyId = null;
68 var showingFrom = 0, showingTo = 0, lastHeight = 0, curKeyId = null;
68 // editing will hold an object describing the things we put in the
69 // editing will hold an object describing the things we put in the
@@ -79,12 +80,16 b' var CodeMirror = (function() {'
79
80
80 // Register our event handlers.
81 // Register our event handlers.
81 connect(scroller, "mousedown", operation(onMouseDown));
82 connect(scroller, "mousedown", operation(onMouseDown));
83 connect(lineSpace, "dragstart", onDragStart);
82 // Gecko browsers fire contextmenu *after* opening the menu, at
84 // Gecko browsers fire contextmenu *after* opening the menu, at
83 // which point we can't mess with it anymore. Context menu is
85 // which point we can't mess with it anymore. Context menu is
84 // handled in onMouseDown for Gecko.
86 // handled in onMouseDown for Gecko.
85 if (!gecko) connect(scroller, "contextmenu", onContextMenu);
87 if (!gecko) connect(scroller, "contextmenu", onContextMenu);
86 connect(code, "dblclick", operation(onDblClick));
88 connect(scroller, "scroll", function() {
87 connect(scroller, "scroll", function() {updateDisplay([]); if (options.onScroll) options.onScroll(instance);});
89 updateDisplay([]);
90 if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
91 if (options.onScroll) options.onScroll(instance);
92 });
88 connect(window, "resize", function() {updateDisplay(true);});
93 connect(window, "resize", function() {updateDisplay(true);});
89 connect(input, "keyup", operation(onKeyUp));
94 connect(input, "keyup", operation(onKeyUp));
90 connect(input, "keydown", operation(onKeyDown));
95 connect(input, "keydown", operation(onKeyDown));
@@ -111,7 +116,7 b' var CodeMirror = (function() {'
111 // range checking and/or clipping. operation is used to wrap the
116 // range checking and/or clipping. operation is used to wrap the
112 // call so that changes it makes are tracked, and the display is
117 // call so that changes it makes are tracked, and the display is
113 // updated afterwards.
118 // updated afterwards.
114 var instance = {
119 var instance = wrapper.CodeMirror = {
115 getValue: getValue,
120 getValue: getValue,
116 setValue: operation(setValue),
121 setValue: operation(setValue),
117 getSelection: getSelection,
122 getSelection: getSelection,
@@ -119,7 +124,8 b' var CodeMirror = (function() {'
119 focus: function(){focusInput(); onFocus(); fastPoll();},
124 focus: function(){focusInput(); onFocus(); fastPoll();},
120 setOption: function(option, value) {
125 setOption: function(option, value) {
121 options[option] = value;
126 options[option] = value;
122 if (option == "lineNumbers" || option == "gutter") gutterChanged();
127 if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber")
128 operation(gutterChanged)();
123 else if (option == "mode" || option == "indentUnit") loadMode();
129 else if (option == "mode" || option == "indentUnit") loadMode();
124 else if (option == "readOnly" && value == "nocursor") input.blur();
130 else if (option == "readOnly" && value == "nocursor") input.blur();
125 else if (option == "theme") scroller.className = scroller.className.replace(/cm-s-\w+/, "cm-s-" + value);
131 else if (option == "theme") scroller.className = scroller.className.replace(/cm-s-\w+/, "cm-s-" + value);
@@ -127,7 +133,9 b' var CodeMirror = (function() {'
127 getOption: function(option) {return options[option];},
133 getOption: function(option) {return options[option];},
128 undo: operation(undo),
134 undo: operation(undo),
129 redo: operation(redo),
135 redo: operation(redo),
130 indentLine: operation(function(n) {if (isLine(n)) indentLine(n, "smart");}),
136 indentLine: operation(function(n, dir) {
137 if (isLine(n)) indentLine(n, dir == null ? "smart" : dir ? "add" : "subtract");
138 }),
131 historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
139 historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
132 matchBrackets: operation(function(){matchBrackets(true);}),
140 matchBrackets: operation(function(){matchBrackets(true);}),
133 getTokenAt: function(pos) {
141 getTokenAt: function(pos) {
@@ -150,18 +158,17 b' var CodeMirror = (function() {'
150 },
158 },
151 getSearchCursor: function(query, pos, caseFold) {return new SearchCursor(query, pos, caseFold);},
159 getSearchCursor: function(query, pos, caseFold) {return new SearchCursor(query, pos, caseFold);},
152 markText: operation(function(a, b, c){return operation(markText(a, b, c));}),
160 markText: operation(function(a, b, c){return operation(markText(a, b, c));}),
153 setMarker: addGutterMarker,
161 setMarker: operation(addGutterMarker),
154 clearMarker: removeGutterMarker,
162 clearMarker: operation(removeGutterMarker),
155 setLineClass: operation(setLineClass),
163 setLineClass: operation(setLineClass),
156 lineInfo: lineInfo,
164 lineInfo: lineInfo,
157 addWidget: function(pos, node, scroll, where) {
165 addWidget: function(pos, node, scroll, vert, horiz) {
158 pos = localCoords(clipPos(pos));
166 pos = localCoords(clipPos(pos));
159 var top = pos.yBot, left = pos.x;
167 var top = pos.yBot, left = pos.x;
160 node.style.position = "absolute";
168 node.style.position = "absolute";
161 code.appendChild(node);
169 code.appendChild(node);
162 node.style.left = left + "px";
170 if (vert == "over") top = pos.y;
163 if (where == "over") top = pos.y;
171 else if (vert == "near") {
164 else if (where == "near") {
165 var vspace = Math.max(scroller.offsetHeight, lines.length * lineHeight()),
172 var vspace = Math.max(scroller.offsetHeight, lines.length * lineHeight()),
166 hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();
173 hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();
167 if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
174 if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
@@ -170,7 +177,15 b' var CodeMirror = (function() {'
170 left = hspace - node.offsetWidth;
177 left = hspace - node.offsetWidth;
171 }
178 }
172 node.style.top = (top + paddingTop()) + "px";
179 node.style.top = (top + paddingTop()) + "px";
173 node.style.left = (left + paddingLeft()) + "px";
180 node.style.left = node.style.right = "";
181 if (horiz == "right") {
182 left = code.clientWidth - node.offsetWidth;
183 node.style.right = "0px";
184 } else {
185 if (horiz == "left") left = 0;
186 else if (horiz == "middle") left = (code.clientWidth - node.offsetWidth) / 2;
187 node.style.left = (left + paddingLeft()) + "px";
188 }
174 if (scroll)
189 if (scroll)
175 scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
190 scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
176 },
191 },
@@ -200,7 +215,8 b' var CodeMirror = (function() {'
200 refresh: function(){updateDisplay(true);},
215 refresh: function(){updateDisplay(true);},
201 getInputField: function(){return input;},
216 getInputField: function(){return input;},
202 getWrapperElement: function(){return wrapper;},
217 getWrapperElement: function(){return wrapper;},
203 getScrollerElement: function(){return scroller;}
218 getScrollerElement: function(){return scroller;},
219 getGutterElement: function(){return gutter;}
204 };
220 };
205
221
206 function setValue(code) {
222 function setValue(code) {
@@ -209,6 +225,7 b' var CodeMirror = (function() {'
209 updateLines(top, {line: lines.length - 1, ch: lines[lines.length-1].text.length},
225 updateLines(top, {line: lines.length - 1, ch: lines[lines.length-1].text.length},
210 splitLines(code), top, top);
226 splitLines(code), top, top);
211 history = new History();
227 history = new History();
228 updateInput = true;
212 }
229 }
213 function getValue(code) {
230 function getValue(code) {
214 var text = [];
231 var text = [];
@@ -221,12 +238,12 b' var CodeMirror = (function() {'
221 // Check whether this is a click in a widget
238 // Check whether this is a click in a widget
222 for (var n = e_target(e); n != wrapper; n = n.parentNode)
239 for (var n = e_target(e); n != wrapper; n = n.parentNode)
223 if (n.parentNode == code && n != mover) return;
240 if (n.parentNode == code && n != mover) return;
224 var ld = lastDoubleClick; lastDoubleClick = null;
241
225 // First, see if this is a click in the gutter
242 // First, see if this is a click in the gutter
226 for (var n = e_target(e); n != wrapper; n = n.parentNode)
243 for (var n = e_target(e); n != wrapper; n = n.parentNode)
227 if (n.parentNode == gutterText) {
244 if (n.parentNode == gutterText) {
228 if (options.onGutterClick)
245 if (options.onGutterClick)
229 options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom);
246 options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);
230 return e_preventDefault(e);
247 return e_preventDefault(e);
231 }
248 }
232
249
@@ -246,18 +263,26 b' var CodeMirror = (function() {'
246 if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
263 if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
247
264
248 if (!focused) onFocus();
265 if (!focused) onFocus();
249 e_preventDefault(e);
250 if (ld && +new Date - ld < 400) return selectLine(start.line);
251
266
252 setCursor(start.line, start.ch, true);
267 var now = +new Date;
268 if (lastDoubleClick > now - 400) {
269 e_preventDefault(e);
270 return selectLine(start.line);
271 } else if (lastClick > now - 400) {
272 lastDoubleClick = now;
273 e_preventDefault(e);
274 return selectWordAt(start);
275 } else { lastClick = now; }
276
253 var last = start, going;
277 var last = start, going;
254 // And then we have to see if it's a drag event, in which case
278 if (dragAndDrop && !posEq(sel.from, sel.to) &&
255 // the dragged-over text must be selected.
279 !posLess(start, sel.from) && !posLess(sel.to, start)) {
256 function end() {
280 // Let the drag handler handle this.
257 focusInput();
281 return;
258 updateInput = true;
259 move(); up();
260 }
282 }
283 e_preventDefault(e);
284 setCursor(start.line, start.ch, true);
285
261 function extend(e) {
286 function extend(e) {
262 var cur = posFromMouse(e, true);
287 var cur = posFromMouse(e, true);
263 if (cur && !posEq(cur, last)) {
288 if (cur && !posEq(cur, last)) {
@@ -281,16 +306,11 b' var CodeMirror = (function() {'
281 var cur = posFromMouse(e);
306 var cur = posFromMouse(e);
282 if (cur) setSelectionUser(start, cur);
307 if (cur) setSelectionUser(start, cur);
283 e_preventDefault(e);
308 e_preventDefault(e);
284 end();
309 focusInput();
310 updateInput = true;
311 move(); up();
285 }), true);
312 }), true);
286 }
313 }
287 function onDblClick(e) {
288 var pos = posFromMouse(e);
289 if (!pos) return;
290 selectWordAt(pos);
291 e_preventDefault(e);
292 lastDoubleClick = +new Date;
293 }
294 function onDrop(e) {
314 function onDrop(e) {
295 e.preventDefault();
315 e.preventDefault();
296 var pos = posFromMouse(e, true), files = e.dataTransfer.files;
316 var pos = posFromMouse(e, true), files = e.dataTransfer.files;
@@ -315,6 +335,13 b' var CodeMirror = (function() {'
315 catch(e){}
335 catch(e){}
316 }
336 }
317 }
337 }
338 function onDragStart(e) {
339 var txt = getSelection();
340 // This will reset escapeElement
341 htmlEscape(txt);
342 e.dataTransfer.setDragImage(escapeElement, 0, 0);
343 e.dataTransfer.setData("Text", txt);
344 }
318 function onKeyDown(e) {
345 function onKeyDown(e) {
319 if (!focused) onFocus();
346 if (!focused) onFocus();
320
347
@@ -340,6 +367,7 b' var CodeMirror = (function() {'
340 if (mod && code == 90) {undo(); return e_preventDefault(e);} // ctrl-z
367 if (mod && code == 90) {undo(); return e_preventDefault(e);} // ctrl-z
341 if (mod && ((e.shiftKey && code == 90) || code == 89)) {redo(); return e_preventDefault(e);} // ctrl-shift-z, ctrl-y
368 if (mod && ((e.shiftKey && code == 90) || code == 89)) {redo(); return e_preventDefault(e);} // ctrl-shift-z, ctrl-y
342 }
369 }
370 if (code == 36) { if (options.smartHome) { smartHome(); return e_preventDefault(e); } }
343
371
344 // Key id to use in the movementKeys map. We also pass it to
372 // Key id to use in the movementKeys map. We also pass it to
345 // fastPoll in order to 'self learn'. We need this because
373 // fastPoll in order to 'self learn'. We need this because
@@ -347,14 +375,16 b' var CodeMirror = (function() {'
347 // its start when it is inverted and a movement key is pressed
375 // its start when it is inverted and a movement key is pressed
348 // (and later restore it again), shouldn't be used for
376 // (and later restore it again), shouldn't be used for
349 // non-movement keys.
377 // non-movement keys.
350 curKeyId = (mod ? "c" : "") + code;
378 curKeyId = (mod ? "c" : "") + (e.altKey ? "a" : "") + code;
351 if (sel.inverted && movementKeys.hasOwnProperty(curKeyId)) {
379 if (sel.inverted && movementKeys[curKeyId] === true) {
352 var range = selRange(input);
380 var range = selRange(input);
353 if (range) {
381 if (range) {
354 reducedSelection = {anchor: range.start};
382 reducedSelection = {anchor: range.start};
355 setSelRange(input, range.start, range.start);
383 setSelRange(input, range.start, range.start);
356 }
384 }
357 }
385 }
386 // Don't save the key as a movementkey unless it had a modifier
387 if (!mod && !e.altKey) curKeyId = null;
358 fastPoll(curKeyId);
388 fastPoll(curKeyId);
359 }
389 }
360 function onKeyUp(e) {
390 function onKeyUp(e) {
@@ -566,7 +596,10 b' var CodeMirror = (function() {'
566 function p() {
596 function p() {
567 startOperation();
597 startOperation();
568 var changed = readInput();
598 var changed = readInput();
569 if (changed == "moved" && keyId) movementKeys[keyId] = true;
599 if (changed && keyId) {
600 if (changed == "moved" && movementKeys[keyId] == null) movementKeys[keyId] = true;
601 if (changed == "changed") movementKeys[keyId] = false;
602 }
570 if (!changed && !missed) {missed = true; poll.set(80, p);}
603 if (!changed && !missed) {missed = true; poll.set(80, p);}
571 else {pollingFast = false; slowPoll();}
604 else {pollingFast = false; slowPoll();}
572 endOperation();
605 endOperation();
@@ -663,6 +696,12 b' var CodeMirror = (function() {'
663 if (options.readOnly != "nocursor") input.focus();
696 if (options.readOnly != "nocursor") input.focus();
664 }
697 }
665
698
699 function scrollEditorIntoView() {
700 if (!cursor.getBoundingClientRect) return;
701 var rect = cursor.getBoundingClientRect();
702 var winH = window.innerHeight || document.body.offsetHeight || document.documentElement.offsetHeight;
703 if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();
704 }
666 function scrollCursorIntoView() {
705 function scrollCursorIntoView() {
667 var cursor = localCoords(sel.inverted ? sel.from : sel.to);
706 var cursor = localCoords(sel.inverted ? sel.from : sel.to);
668 return scrollIntoView(cursor.x, cursor.y, cursor.x, cursor.yBot);
707 return scrollIntoView(cursor.x, cursor.y, cursor.x, cursor.yBot);
@@ -675,9 +714,10 b' var CodeMirror = (function() {'
675 else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
714 else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
676
715
677 var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
716 var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
678 if (x1 < screenleft) {
717 var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
718 if (x1 < screenleft + gutterw) {
679 if (x1 < 50) x1 = 0;
719 if (x1 < 50) x1 = 0;
680 scroller.scrollLeft = Math.max(0, x1 - 10);
720 scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
681 scrolled = true;
721 scrolled = true;
682 }
722 }
683 else if (x2 > screenw + screenleft) {
723 else if (x2 > screenw + screenleft) {
@@ -745,6 +785,7 b' var CodeMirror = (function() {'
745 if (domPos != domEnd || pos != to) {
785 if (domPos != domEnd || pos != to) {
746 changedLines += Math.abs(to - pos);
786 changedLines += Math.abs(to - pos);
747 updates.push({from: pos, to: to, domSize: domEnd - domPos, domStart: domPos});
787 updates.push({from: pos, to: to, domSize: domEnd - domPos, domStart: domPos});
788 if (to - pos != domEnd - domPos) gutterDirty = true;
748 }
789 }
749
790
750 if (!updates.length) return;
791 if (!updates.length) return;
@@ -766,8 +807,8 b' var CodeMirror = (function() {'
766 if (different) {
807 if (different) {
767 lastHeight = scroller.clientHeight;
808 lastHeight = scroller.clientHeight;
768 code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px";
809 code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px";
769 updateGutter();
770 }
810 }
811 if (different || gutterDirty) updateGutter();
771
812
772 if (maxWidth == null) maxWidth = stringWidth(maxLine);
813 if (maxWidth == null) maxWidth = stringWidth(maxLine);
773 if (maxWidth > scroller.clientWidth) {
814 if (maxWidth > scroller.clientWidth) {
@@ -868,13 +909,17 b' var CodeMirror = (function() {'
868 if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
909 if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
869 gutter.style.display = "";
910 gutter.style.display = "";
870 lineSpace.style.marginLeft = gutter.offsetWidth + "px";
911 lineSpace.style.marginLeft = gutter.offsetWidth + "px";
912 gutterDirty = false;
871 }
913 }
872 function updateCursor() {
914 function updateCursor() {
873 var head = sel.inverted ? sel.from : sel.to, lh = lineHeight();
915 var head = sel.inverted ? sel.from : sel.to, lh = lineHeight();
874 var x = charX(head.line, head.ch) + "px", y = (head.line - showingFrom) * lh + "px";
916 var x = charX(head.line, head.ch);
875 inputDiv.style.top = (head.line * lh - scroller.scrollTop) + "px";
917 var top = head.line * lh - scroller.scrollTop;
918 inputDiv.style.top = Math.max(Math.min(top, scroller.offsetHeight), 0) + "px";
919 inputDiv.style.left = (x - scroller.scrollLeft) + "px";
876 if (posEq(sel.from, sel.to)) {
920 if (posEq(sel.from, sel.to)) {
877 cursor.style.top = y; cursor.style.left = x;
921 cursor.style.top = (head.line - showingFrom) * lh + "px";
922 cursor.style.left = x + "px";
878 cursor.style.display = "";
923 cursor.style.display = "";
879 }
924 }
880 else cursor.style.display = "none";
925 else cursor.style.display = "none";
@@ -994,6 +1039,10 b' var CodeMirror = (function() {'
994 }
1039 }
995 return true;
1040 return true;
996 }
1041 }
1042 function smartHome() {
1043 var firstNonWS = Math.max(0, lines[sel.from.line].text.search(/\S/));
1044 setCursor(sel.from.line, sel.from.ch <= firstNonWS && sel.from.ch ? 0 : firstNonWS, true);
1045 }
997
1046
998 function indentLine(n, how) {
1047 function indentLine(n, how) {
999 if (how == "smart") {
1048 if (how == "smart") {
@@ -1036,7 +1085,7 b' var CodeMirror = (function() {'
1036 function gutterChanged() {
1085 function gutterChanged() {
1037 var visible = options.gutter || options.lineNumbers;
1086 var visible = options.gutter || options.lineNumbers;
1038 gutter.style.display = visible ? "" : "none";
1087 gutter.style.display = visible ? "" : "none";
1039 if (visible) updateGutter();
1088 if (visible) gutterDirty = true;
1040 else lineDiv.parentNode.style.marginLeft = 0;
1089 else lineDiv.parentNode.style.marginLeft = 0;
1041 }
1090 }
1042
1091
@@ -1073,13 +1122,13 b' var CodeMirror = (function() {'
1073 function addGutterMarker(line, text, className) {
1122 function addGutterMarker(line, text, className) {
1074 if (typeof line == "number") line = lines[clipLine(line)];
1123 if (typeof line == "number") line = lines[clipLine(line)];
1075 line.gutterMarker = {text: text, style: className};
1124 line.gutterMarker = {text: text, style: className};
1076 updateGutter();
1125 gutterDirty = true;
1077 return line;
1126 return line;
1078 }
1127 }
1079 function removeGutterMarker(line) {
1128 function removeGutterMarker(line) {
1080 if (typeof line == "number") line = lines[clipLine(line)];
1129 if (typeof line == "number") line = lines[clipLine(line)];
1081 line.gutterMarker = null;
1130 line.gutterMarker = null;
1082 updateGutter();
1131 gutterDirty = true;
1083 }
1132 }
1084 function setLineClass(line, className) {
1133 function setLineClass(line, className) {
1085 if (typeof line == "number") {
1134 if (typeof line == "number") {
@@ -1190,8 +1239,8 b' var CodeMirror = (function() {'
1190
1239
1191 var oldCSS = input.style.cssText;
1240 var oldCSS = input.style.cssText;
1192 inputDiv.style.position = "absolute";
1241 inputDiv.style.position = "absolute";
1193 input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e_pageY(e) - 1) +
1242 input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
1194 "px; left: " + (e_pageX(e) - 1) + "px; z-index: 1000; background: white; " +
1243 "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
1195 "border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
1244 "border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
1196 leaveInputAlone = true;
1245 leaveInputAlone = true;
1197 var val = input.value = getSelection();
1246 var val = input.value = getSelection();
@@ -1284,7 +1333,7 b' var CodeMirror = (function() {'
1284 if (line.stateAfter) return search;
1333 if (line.stateAfter) return search;
1285 var indented = line.indentation();
1334 var indented = line.indentation();
1286 if (minline == null || minindent > indented) {
1335 if (minline == null || minindent > indented) {
1287 minline = search;
1336 minline = search - 1;
1288 minindent = indented;
1337 minindent = indented;
1289 }
1338 }
1290 }
1339 }
@@ -1321,25 +1370,26 b' var CodeMirror = (function() {'
1321 if (state) state = copyState(mode, state);
1370 if (state) state = copyState(mode, state);
1322 else state = startState(mode);
1371 else state = startState(mode);
1323
1372
1324 var unchanged = 0, compare = mode.compareStates;
1373 var unchanged = 0, compare = mode.compareStates, realChange = false;
1325 for (var i = start, l = lines.length; i < l; ++i) {
1374 for (var i = start, l = lines.length; i < l; ++i) {
1326 var line = lines[i], hadState = line.stateAfter;
1375 var line = lines[i], hadState = line.stateAfter;
1327 if (+new Date > end) {
1376 if (+new Date > end) {
1328 work.push(i);
1377 work.push(i);
1329 startWorker(options.workDelay);
1378 startWorker(options.workDelay);
1330 changes.push({from: task, to: i + 1});
1379 if (realChange) changes.push({from: task, to: i + 1});
1331 return;
1380 return;
1332 }
1381 }
1333 var changed = line.highlight(mode, state);
1382 var changed = line.highlight(mode, state);
1383 if (changed) realChange = true;
1334 line.stateAfter = copyState(mode, state);
1384 line.stateAfter = copyState(mode, state);
1335 if (compare) {
1385 if (compare) {
1336 if (hadState && compare(hadState, state)) break;
1386 if (hadState && compare(hadState, state)) break;
1337 } else {
1387 } else {
1338 if (changed || !hadState) unchanged = 0;
1388 if (changed !== false || !hadState) unchanged = 0;
1339 else if (++unchanged > 3) break;
1389 else if (++unchanged > 3) break;
1340 }
1390 }
1341 }
1391 }
1342 changes.push({from: task, to: i + 1});
1392 if (realChange) changes.push({from: task, to: i + 1});
1343 }
1393 }
1344 if (foundWork && options.onHighlightComplete)
1394 if (foundWork && options.onHighlightComplete)
1345 options.onHighlightComplete(instance);
1395 options.onHighlightComplete(instance);
@@ -1360,9 +1410,12 b' var CodeMirror = (function() {'
1360 var reScroll = false;
1410 var reScroll = false;
1361 if (selectionChanged) reScroll = !scrollCursorIntoView();
1411 if (selectionChanged) reScroll = !scrollCursorIntoView();
1362 if (changes.length) updateDisplay(changes);
1412 if (changes.length) updateDisplay(changes);
1363 else if (selectionChanged) updateCursor();
1413 else {
1414 if (selectionChanged) updateCursor();
1415 if (gutterDirty) updateGutter();
1416 }
1364 if (reScroll) scrollCursorIntoView();
1417 if (reScroll) scrollCursorIntoView();
1365 if (selectionChanged) restartBlink();
1418 if (selectionChanged) {scrollEditorIntoView(); restartBlink();}
1366
1419
1367 // updateInput can be set to a boolean value to force/prevent an
1420 // updateInput can be set to a boolean value to force/prevent an
1368 // update.
1421 // update.
@@ -1525,8 +1578,10 b' var CodeMirror = (function() {'
1525 onKeyEvent: null,
1578 onKeyEvent: null,
1526 lineNumbers: false,
1579 lineNumbers: false,
1527 gutter: false,
1580 gutter: false,
1581 fixedGutter: false,
1528 firstLineNumber: 1,
1582 firstLineNumber: 1,
1529 readOnly: false,
1583 readOnly: false,
1584 smartHome: true,
1530 onChange: null,
1585 onChange: null,
1531 onCursorActivity: null,
1586 onCursorActivity: null,
1532 onGutterClick: null,
1587 onGutterClick: null,
@@ -1572,7 +1627,7 b' var CodeMirror = (function() {'
1572 CodeMirror.listMIMEs = function() {
1627 CodeMirror.listMIMEs = function() {
1573 var list = [];
1628 var list = [];
1574 for (var m in mimeModes)
1629 for (var m in mimeModes)
1575 if (mimeModes.propertyIsEnumerable(m)) list.push(m);
1630 if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});
1576 return list;
1631 return list;
1577 };
1632 };
1578
1633
@@ -1660,7 +1715,7 b' var CodeMirror = (function() {'
1660 if (ok) {++this.pos; return ch;}
1715 if (ok) {++this.pos; return ch;}
1661 },
1716 },
1662 eatWhile: function(match) {
1717 eatWhile: function(match) {
1663 var start = this.start;
1718 var start = this.pos;
1664 while (this.eat(match)){}
1719 while (this.eat(match)){}
1665 return this.pos > start;
1720 return this.pos > start;
1666 },
1721 },
@@ -1769,10 +1824,10 b' var CodeMirror = (function() {'
1769 }
1824 }
1770 if (st.length != pos) {st.length = pos; changed = true;}
1825 if (st.length != pos) {st.length = pos; changed = true;}
1771 if (pos && st[pos-2] != prevWord) changed = true;
1826 if (pos && st[pos-2] != prevWord) changed = true;
1772 // Short lines with simple highlights always count as changed,
1827 // Short lines with simple highlights return null, and are
1773 // because they are likely to highlight the same way in various
1828 // counted as changed by the driver because they are likely to
1774 // contexts.
1829 // highlight the same way in various contexts.
1775 return changed || (st.length < 5 && this.text.length < 10);
1830 return changed || (st.length < 5 && this.text.length < 10 ? null : false);
1776 },
1831 },
1777 // Fetch the parser token for a given character. Useful for hacks
1832 // Fetch the parser token for a given character. Useful for hacks
1778 // that want to inspect the mode state (say, for completion).
1833 // that want to inspect the mode state (say, for completion).
@@ -1930,16 +1985,6 b' var CodeMirror = (function() {'
1930 else if (e.button & 2) return 3;
1985 else if (e.button & 2) return 3;
1931 else if (e.button & 4) return 2;
1986 else if (e.button & 4) return 2;
1932 }
1987 }
1933 function e_pageX(e) {
1934 if (e.pageX != null) return e.pageX;
1935 var doc = e_target(e).ownerDocument;
1936 return e.clientX + doc.body.scrollLeft + doc.documentElement.scrollLeft;
1937 }
1938 function e_pageY(e) {
1939 if (e.pageY != null) return e.pageY;
1940 var doc = e_target(e).ownerDocument;
1941 return e.clientY + doc.body.scrollTop + doc.documentElement.scrollTop;
1942 }
1943
1988
1944 // Event handler registration. If disconnect is true, it'll return a
1989 // Event handler registration. If disconnect is true, it'll return a
1945 // function that unregisters the handler.
1990 // function that unregisters the handler.
@@ -1965,6 +2010,15 b' var CodeMirror = (function() {'
1965 pre.innerHTML = " "; return !pre.innerHTML;
2010 pre.innerHTML = " "; return !pre.innerHTML;
1966 })();
2011 })();
1967
2012
2013 // Detect drag-and-drop
2014 var dragAndDrop = (function() {
2015 // IE8 has ondragstart and ondrop properties, but doesn't seem to
2016 // actually support ondragstart the way it's supposed to work.
2017 if (/MSIE [1-8]\b/.test(navigator.userAgent)) return false;
2018 var div = document.createElement('div');
2019 return "ondragstart" in div && "ondrop" in div;
2020 })();
2021
1968 var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
2022 var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
1969 var ie = /MSIE \d/.test(navigator.userAgent);
2023 var ie = /MSIE \d/.test(navigator.userAgent);
1970 var safari = /Apple Computer/.test(navigator.vendor);
2024 var safari = /Apple Computer/.test(navigator.vendor);
@@ -2140,5 +2194,4 b' var CodeMirror = (function() {'
2140 CodeMirror.defineMIME("text/plain", "null");
2194 CodeMirror.defineMIME("text/plain", "null");
2141
2195
2142 return CodeMirror;
2196 return CodeMirror;
2143 })()
2197 })();
2144 ; No newline at end of file
@@ -4,7 +4,7 b' CodeMirror.defineMode("css", function(config) {'
4
4
5 function tokenBase(stream, state) {
5 function tokenBase(stream, state) {
6 var ch = stream.next();
6 var ch = stream.next();
7 if (ch == "@") {stream.eatWhile(/\w/); return ret("meta", stream.current());}
7 if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
8 else if (ch == "/" && stream.eat("*")) {
8 else if (ch == "/" && stream.eat("*")) {
9 state.tokenize = tokenCComment;
9 state.tokenize = tokenCComment;
10 return tokenCComment(stream, state);
10 return tokenCComment(stream, state);
@@ -20,7 +20,7 b' CodeMirror.defineMode("css", function(config) {'
20 return state.tokenize(stream, state);
20 return state.tokenize(stream, state);
21 }
21 }
22 else if (ch == "#") {
22 else if (ch == "#") {
23 stream.eatWhile(/\w/);
23 stream.eatWhile(/[\w\\\-]/);
24 return ret("atom", "hash");
24 return ret("atom", "hash");
25 }
25 }
26 else if (ch == "!") {
26 else if (ch == "!") {
@@ -38,7 +38,7 b' CodeMirror.defineMode("css", function(config) {'
38 return ret(null, ch);
38 return ret(null, ch);
39 }
39 }
40 else {
40 else {
41 stream.eatWhile(/[\w\\\-_]/);
41 stream.eatWhile(/[\w\\\-]/);
42 return ret("variable", "variable");
42 return ret("variable", "variable");
43 }
43 }
44 }
44 }
@@ -75,6 +75,10 b' CodeMirror.defineMode("javascript", function(config, parserConfig) {'
75 return ret("operator", null, stream.current());
75 return ret("operator", null, stream.current());
76 }
76 }
77 }
77 }
78 else if (ch == "#") {
79 stream.skipToEnd();
80 return ret("error", "error");
81 }
78 else if (isOperatorChar.test(ch)) {
82 else if (isOperatorChar.test(ch)) {
79 stream.eatWhile(isOperatorChar);
83 stream.eatWhile(isOperatorChar);
80 return ret("operator", null, stream.current());
84 return ret("operator", null, stream.current());
@@ -1,11 +1,11 b''
1 CodeMirror.defineMode("python", function(conf) {
1 CodeMirror.defineMode("python", function(conf, parserConf) {
2 var ERRORCLASS = 'error';
2 var ERRORCLASS = 'error';
3
3
4 function wordRegexp(words) {
4 function wordRegexp(words) {
5 return new RegExp("^((" + words.join(")|(") + "))\\b");
5 return new RegExp("^((" + words.join(")|(") + "))\\b");
6 }
6 }
7
7
8 var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\\?]");
8 var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
9 var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
9 var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
10 var doubleOperators = new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
10 var doubleOperators = new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
11 var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
11 var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
@@ -29,7 +29,7 b' CodeMirror.defineMode("python", function(conf) {'
29 'open', 'range', 'zip'],
29 'open', 'range', 'zip'],
30 'keywords': ['nonlocal']};
30 'keywords': ['nonlocal']};
31
31
32 if (!!conf.mode.version && parseInt(conf.mode.version, 10) === 3) {
32 if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) {
33 commonkeywords = commonkeywords.concat(py3.keywords);
33 commonkeywords = commonkeywords.concat(py3.keywords);
34 commontypes = commontypes.concat(py3.types);
34 commontypes = commontypes.concat(py3.types);
35 var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
35 var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
@@ -147,10 +147,9 b' CodeMirror.defineMode("python", function(conf) {'
147 }
147 }
148
148
149 function tokenStringFactory(delimiter) {
149 function tokenStringFactory(delimiter) {
150 while ('rub'.indexOf(delimiter[0].toLowerCase()) >= 0) {
150 while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
151 delimiter = delimiter.substr(1);
151 delimiter = delimiter.substr(1);
152 }
152 }
153 var delim_re = new RegExp(delimiter);
154 var singleline = delimiter.length == 1;
153 var singleline = delimiter.length == 1;
155 var OUTCLASS = 'string';
154 var OUTCLASS = 'string';
156
155
@@ -162,7 +161,7 b' CodeMirror.defineMode("python", function(conf) {'
162 if (singleline && stream.eol()) {
161 if (singleline && stream.eol()) {
163 return OUTCLASS;
162 return OUTCLASS;
164 }
163 }
165 } else if (stream.match(delim_re)) {
164 } else if (stream.match(delimiter)) {
166 state.tokenize = tokenBase;
165 state.tokenize = tokenBase;
167 return OUTCLASS;
166 return OUTCLASS;
168 } else {
167 } else {
@@ -170,8 +169,8 b' CodeMirror.defineMode("python", function(conf) {'
170 }
169 }
171 }
170 }
172 if (singleline) {
171 if (singleline) {
173 if (conf.mode.singleLineStringErrors) {
172 if (parserConf.singleLineStringErrors) {
174 OUTCLASS = ERRORCLASS
173 return ERRORCLASS;
175 } else {
174 } else {
176 state.tokenize = tokenBase;
175 state.tokenize = tokenBase;
177 }
176 }
@@ -132,7 +132,6 b' CodeMirror.defineMode("xml", function(config, parserConfig) {'
132 var err = false;
132 var err = false;
133 if (curState.context) {
133 if (curState.context) {
134 err = curState.context.tagName != tagName;
134 err = curState.context.tagName != tagName;
135 popContext();
136 } else {
135 } else {
137 err = true;
136 err = true;
138 }
137 }
@@ -158,8 +157,9 b' CodeMirror.defineMode("xml", function(config, parserConfig) {'
158 function endclosetag(err) {
157 function endclosetag(err) {
159 return function(type) {
158 return function(type) {
160 if (err) setStyle = "error";
159 if (err) setStyle = "error";
161 if (type == "endTag") return cont();
160 if (type == "endTag") { popContext(); return cont(); }
162 return pass();
161 setStyle = "error";
162 return cont(arguments.callee);
163 }
163 }
164 }
164 }
165
165
@@ -216,7 +216,7 b' CodeMirror.defineMode("xml", function(config, parserConfig) {'
216 },
216 },
217
217
218 compareStates: function(a, b) {
218 compareStates: function(a, b) {
219 if (a.indented != b.indented || a.tagName != b.tagName) return false;
219 if (a.indented != b.indented) return false;
220 for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
220 for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
221 if (!ca || !cb) return ca == cb;
221 if (!ca || !cb) return ca == cb;
222 if (ca.tagName != cb.tagName) return false;
222 if (ca.tagName != cb.tagName) return false;
@@ -9,6 +9,7 b''
9 .cm-s-default span.cm-operator {color: black;}
9 .cm-s-default span.cm-operator {color: black;}
10 .cm-s-default span.cm-comment {color: #a50;}
10 .cm-s-default span.cm-comment {color: #a50;}
11 .cm-s-default span.cm-string {color: #a11;}
11 .cm-s-default span.cm-string {color: #a11;}
12 .cm-s-default span.cm-string-2 {color: #f50;}
12 .cm-s-default span.cm-meta {color: #555;}
13 .cm-s-default span.cm-meta {color: #555;}
13 .cm-s-default span.cm-error {color: #f00;}
14 .cm-s-default span.cm-error {color: #f00;}
14 .cm-s-default span.cm-qualifier {color: #555;}
15 .cm-s-default span.cm-qualifier {color: #555;}
General Comments 0
You need to be logged in to leave comments. Login now