##// END OF EJS Templates
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
Bradley M. Kuhn -
r4120:bb9ef063 rhodecode-2.2.5-gpl
parent child Browse files
Show More
@@ -0,0 +1,54 b''
1 <!doctype html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>CodeMirror: Jade Templating Mode</title>
6 <link rel="stylesheet" href="../../lib/codemirror.css">
7 <script src="../../lib/codemirror.js"></script>
8 <script src="jade.js"></script>
9 <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
10 <link rel="stylesheet" href="../../doc/docs.css">
11 </head>
12 <body>
13 <h1>CodeMirror: Jade Templating Mode</h1>
14 <form><textarea id="code" name="code">
15 doctype 5
16 html
17 head
18 title= "Jade Templating CodeMirror Mode Example"
19 link(rel='stylesheet', href='/css/bootstrap.min.css')
20 link(rel='stylesheet', href='/css/index.css')
21 script(type='text/javascript', src='/js/jquery-1.9.1.min.js')
22 script(type='text/javascript', src='/js/bootstrap.min.js')
23 body
24 div.header
25 h1 Welcome to this Example
26 div.spots
27 if locals.spots
28 each spot in spots
29 div.spot.well
30 div
31 if spot.logo
32 img.img-rounded.logo(src=spot.logo)
33 else
34 img.img-rounded.logo(src="img/placeholder.png")
35 h3
36 a(href=spot.hash) ##{spot.hash}
37 if spot.title
38 span.title #{spot.title}
39 if spot.desc
40 div #{spot.desc}
41 else
42 h3 There are no spots currently available.
43 </textarea></form>
44 <script>
45 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
46 mode: {name: "jade", alignCDATA: true},
47 lineNumbers: true
48 });
49 </script>
50 <h3>The Jade Templating Mode</h3>
51 <p> Created by Drew Bratcher. Managed as part of an Adobe Brackets extension at <a href="https://github.com/dbratcher/brackets-jade">https://github.com/dbratcher/brackets-jade</a>.</p>
52 <p><strong>MIME type defined:</strong> <code>text/x-jade</code>.</p>
53 </body>
54 </html>
@@ -0,0 +1,90 b''
1 CodeMirror.defineMode("jade", function () {
2 var symbol_regex1 = /^(?:~|!|%|\^|\*|\+|=|\\|:|;|,|\/|\?|&|<|>|\|)/;
3 var open_paren_regex = /^(\(|\[)/;
4 var close_paren_regex = /^(\)|\])/;
5 var keyword_regex1 = /^(if|else|return|var|function|include|doctype|each)/;
6 var keyword_regex2 = /^(#|{|}|\.)/;
7 var keyword_regex3 = /^(in)/;
8 var html_regex1 = /^(html|head|title|meta|link|script|body|br|div|input|span|a|img)/;
9 var html_regex2 = /^(h1|h2|h3|h4|h5|p|strong|em)/;
10 return {
11 startState: function () {
12 return {
13 inString: false,
14 stringType: "",
15 beforeTag: true,
16 justMatchedKeyword: false,
17 afterParen: false
18 };
19 },
20 token: function (stream, state) {
21 //check for state changes
22 if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) {
23 state.stringType = stream.peek();
24 stream.next(); // Skip quote
25 state.inString = true; // Update state
26 }
27
28 //return state
29 if (state.inString) {
30 if (stream.skipTo(state.stringType)) { // Quote found on this line
31 stream.next(); // Skip quote
32 state.inString = false; // Clear flag
33 } else {
34 stream.skipToEnd(); // Rest of line is string
35 }
36 state.justMatchedKeyword = false;
37 return "string"; // Token style
38 } else if (stream.sol() && stream.eatSpace()) {
39 if (stream.match(keyword_regex1)) {
40 state.justMatchedKeyword = true;
41 stream.eatSpace();
42 return "keyword";
43 }
44 if (stream.match(html_regex1) || stream.match(html_regex2)) {
45 state.justMatchedKeyword = true;
46 return "variable";
47 }
48 } else if (stream.sol() && stream.match(keyword_regex1)) {
49 state.justMatchedKeyword = true;
50 stream.eatSpace();
51 return "keyword";
52 } else if (stream.sol() && (stream.match(html_regex1) || stream.match(html_regex2))) {
53 state.justMatchedKeyword = true;
54 return "variable";
55 } else if (stream.eatSpace()) {
56 state.justMatchedKeyword = false;
57 if (stream.match(keyword_regex3) && stream.eatSpace()) {
58 state.justMatchedKeyword = true;
59 return "keyword";
60 }
61 } else if (stream.match(symbol_regex1)) {
62 state.justMatchedKeyword = false;
63 return "atom";
64 } else if (stream.match(open_paren_regex)) {
65 state.afterParen = true;
66 state.justMatchedKeyword = true;
67 return "def";
68 } else if (stream.match(close_paren_regex)) {
69 state.afterParen = false;
70 state.justMatchedKeyword = true;
71 return "def";
72 } else if (stream.match(keyword_regex2)) {
73 state.justMatchedKeyword = true;
74 return "keyword";
75 } else if (stream.eatSpace()) {
76 state.justMatchedKeyword = false;
77 } else {
78 stream.next();
79 if (state.justMatchedKeyword) {
80 return "property";
81 } else if (state.afterParen) {
82 return "property";
83 }
84 }
85 return null;
86 }
87 };
88 });
89
90 CodeMirror.defineMIME('text/x-jade', 'jade');
@@ -0,0 +1,10 b''
1 (function() {
2 var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
3 function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
4
5 MT("locals",
6 "[keyword function] [variable foo]([def a], [def b]) { [keyword var] [def c] = [number 10]; [keyword return] [variable-2 a] + [variable-2 c] + [variable d]; }");
7
8 MT("comma-and-binop",
9 "[keyword function](){ [keyword var] [def x] = [number 1] + [number 2], [def y]; }");
10 })();
@@ -0,0 +1,167 b''
1 <!doctype html>
2 <html>
3 <head>
4 <title>CodeMirror: NGINX mode</title>
5 <link rel="stylesheet" href="../../lib/codemirror.css">
6 <script src="../../lib/codemirror.js"></script>
7 <script src="nginx.js"></script>
8 <style>.CodeMirror {background: #f8f8f8;}</style>
9 <link rel="stylesheet" href="../../doc/docs.css">
10 </head>
11
12 <style>
13 body {
14 margin: 0em auto;
15 }
16
17 .CodeMirror, .CodeMirror-scroll {
18 height: 600px;
19 }
20 </style>
21
22 <body>
23 <h1>CodeMirror: NGINX mode</h1>
24 <form><textarea id="code" name="code" style="height: 800px;">
25 server {
26 listen 173.255.219.235:80;
27 server_name website.com.au;
28 rewrite / $scheme://www.$host$request_uri permanent; ## Forcibly prepend a www
29 }
30
31 server {
32 listen 173.255.219.235:443;
33 server_name website.com.au;
34 rewrite / $scheme://www.$host$request_uri permanent; ## Forcibly prepend a www
35 }
36
37 server {
38
39 listen 173.255.219.235:80;
40 server_name www.website.com.au;
41
42
43
44 root /data/www;
45 index index.html index.php;
46
47 location / {
48 index index.html index.php; ## Allow a static html file to be shown first
49 try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
50 expires 30d; ## Assume all files are cachable
51 }
52
53 ## These locations would be hidden by .htaccess normally
54 location /app/ { deny all; }
55 location /includes/ { deny all; }
56 location /lib/ { deny all; }
57 location /media/downloadable/ { deny all; }
58 location /pkginfo/ { deny all; }
59 location /report/config.xml { deny all; }
60 location /var/ { deny all; }
61
62 location /var/export/ { ## Allow admins only to view export folder
63 auth_basic "Restricted"; ## Message shown in login window
64 auth_basic_user_file /rs/passwords/testfile; ## See /etc/nginx/htpassword
65 autoindex on;
66 }
67
68 location /. { ## Disable .htaccess and other hidden files
69 return 404;
70 }
71
72 location @handler { ## Magento uses a common front handler
73 rewrite / /index.php;
74 }
75
76 location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
77 rewrite ^/(.*.php)/ /$1 last;
78 }
79
80 location ~ \.php$ {
81 if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss
82
83 fastcgi_pass 127.0.0.1:9000;
84 fastcgi_index index.php;
85 fastcgi_param PATH_INFO $fastcgi_script_name;
86 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
87 include /rs/confs/nginx/fastcgi_params;
88 }
89
90 }
91
92
93 server {
94
95 listen 173.255.219.235:443;
96 server_name website.com.au www.website.com.au;
97
98 root /data/www;
99 index index.html index.php;
100
101 ssl on;
102 ssl_certificate /rs/ssl/ssl.crt;
103 ssl_certificate_key /rs/ssl/ssl.key;
104
105 ssl_session_timeout 5m;
106
107 ssl_protocols SSLv2 SSLv3 TLSv1;
108 ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
109 ssl_prefer_server_ciphers on;
110
111
112
113 location / {
114 index index.html index.php; ## Allow a static html file to be shown first
115 try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
116 expires 30d; ## Assume all files are cachable
117 }
118
119 ## These locations would be hidden by .htaccess normally
120 location /app/ { deny all; }
121 location /includes/ { deny all; }
122 location /lib/ { deny all; }
123 location /media/downloadable/ { deny all; }
124 location /pkginfo/ { deny all; }
125 location /report/config.xml { deny all; }
126 location /var/ { deny all; }
127
128 location /var/export/ { ## Allow admins only to view export folder
129 auth_basic "Restricted"; ## Message shown in login window
130 auth_basic_user_file htpasswd; ## See /etc/nginx/htpassword
131 autoindex on;
132 }
133
134 location /. { ## Disable .htaccess and other hidden files
135 return 404;
136 }
137
138 location @handler { ## Magento uses a common front handler
139 rewrite / /index.php;
140 }
141
142 location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
143 rewrite ^/(.*.php)/ /$1 last;
144 }
145
146 location ~ .php$ { ## Execute PHP scripts
147 if (!-e $request_filename) { rewrite /index.php last; } ## Catch 404s that try_files miss
148
149 fastcgi_pass 127.0.0.1:9000;
150 fastcgi_index index.php;
151 fastcgi_param PATH_INFO $fastcgi_script_name;
152 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
153 include /rs/confs/nginx/fastcgi_params;
154
155 fastcgi_param HTTPS on;
156 }
157
158 }
159 </textarea></form>
160 <script>
161 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
162 </script>
163
164 <p><strong>MIME types defined:</strong> <code>text/nginx</code>.</p>
165
166 </body>
167 </html>
@@ -0,0 +1,163 b''
1 CodeMirror.defineMode("nginx", function(config) {
2
3 function words(str) {
4 var obj = {}, words = str.split(" ");
5 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
6 return obj;
7 }
8
9 var keywords = words(
10 /* ngxDirectiveControl */ "break return rewrite set" +
11 /* ngxDirective */ " accept_mutex accept_mutex_delay access_log add_after_body add_before_body add_header addition_types aio alias allow ancient_browser ancient_browser_value auth_basic auth_basic_user_file auth_http auth_http_header auth_http_timeout autoindex autoindex_exact_size autoindex_localtime charset charset_types client_body_buffer_size client_body_in_file_only client_body_in_single_buffer client_body_temp_path client_body_timeout client_header_buffer_size client_header_timeout client_max_body_size connection_pool_size create_full_put_path daemon dav_access dav_methods debug_connection debug_points default_type degradation degrade deny devpoll_changes devpoll_events directio directio_alignment empty_gif env epoll_events error_log eventport_events expires fastcgi_bind fastcgi_buffer_size fastcgi_buffers fastcgi_busy_buffers_size fastcgi_cache fastcgi_cache_key fastcgi_cache_methods fastcgi_cache_min_uses fastcgi_cache_path fastcgi_cache_use_stale fastcgi_cache_valid fastcgi_catch_stderr fastcgi_connect_timeout fastcgi_hide_header fastcgi_ignore_client_abort fastcgi_ignore_headers fastcgi_index fastcgi_intercept_errors fastcgi_max_temp_file_size fastcgi_next_upstream fastcgi_param fastcgi_pass_header fastcgi_pass_request_body fastcgi_pass_request_headers fastcgi_read_timeout fastcgi_send_lowat fastcgi_send_timeout fastcgi_split_path_info fastcgi_store fastcgi_store_access fastcgi_temp_file_write_size fastcgi_temp_path fastcgi_upstream_fail_timeout fastcgi_upstream_max_fails flv geoip_city geoip_country google_perftools_profiles gzip gzip_buffers gzip_comp_level gzip_disable gzip_hash gzip_http_version gzip_min_length gzip_no_buffer gzip_proxied gzip_static gzip_types gzip_vary gzip_window if_modified_since ignore_invalid_headers image_filter image_filter_buffer image_filter_jpeg_quality image_filter_transparency imap_auth imap_capabilities imap_client_buffer index ip_hash keepalive_requests keepalive_timeout kqueue_changes kqueue_events large_client_header_buffers limit_conn limit_conn_log_level limit_rate limit_rate_after limit_req limit_req_log_level limit_req_zone limit_zone lingering_time lingering_timeout lock_file log_format log_not_found log_subrequest map_hash_bucket_size map_hash_max_size master_process memcached_bind memcached_buffer_size memcached_connect_timeout memcached_next_upstream memcached_read_timeout memcached_send_timeout memcached_upstream_fail_timeout memcached_upstream_max_fails merge_slashes min_delete_depth modern_browser modern_browser_value msie_padding msie_refresh multi_accept open_file_cache open_file_cache_errors open_file_cache_events open_file_cache_min_uses open_file_cache_valid open_log_file_cache output_buffers override_charset perl perl_modules perl_require perl_set pid pop3_auth pop3_capabilities port_in_redirect postpone_gzipping postpone_output protocol proxy proxy_bind proxy_buffer proxy_buffer_size proxy_buffering proxy_buffers proxy_busy_buffers_size proxy_cache proxy_cache_key proxy_cache_methods proxy_cache_min_uses proxy_cache_path proxy_cache_use_stale proxy_cache_valid proxy_connect_timeout proxy_headers_hash_bucket_size proxy_headers_hash_max_size proxy_hide_header proxy_ignore_client_abort proxy_ignore_headers proxy_intercept_errors proxy_max_temp_file_size proxy_method proxy_next_upstream proxy_pass_error_message proxy_pass_header proxy_pass_request_body proxy_pass_request_headers proxy_read_timeout proxy_redirect proxy_send_lowat proxy_send_timeout proxy_set_body proxy_set_header proxy_ssl_session_reuse proxy_store proxy_store_access proxy_temp_file_write_size proxy_temp_path proxy_timeout proxy_upstream_fail_timeout proxy_upstream_max_fails random_index read_ahead real_ip_header recursive_error_pages request_pool_size reset_timedout_connection resolver resolver_timeout rewrite_log rtsig_overflow_events rtsig_overflow_test rtsig_overflow_threshold rtsig_signo satisfy secure_link_secret send_lowat send_timeout sendfile sendfile_max_chunk server_name_in_redirect server_names_hash_bucket_size server_names_hash_max_size server_tokens set_real_ip_from smtp_auth smtp_capabilities smtp_client_buffer smtp_greeting_delay so_keepalive source_charset ssi ssi_ignore_recycled_buffers ssi_min_file_chunk ssi_silent_errors ssi_types ssi_value_length ssl ssl_certificate ssl_certificate_key ssl_ciphers ssl_client_certificate ssl_crl ssl_dhparam ssl_engine ssl_prefer_server_ciphers ssl_protocols ssl_session_cache ssl_session_timeout ssl_verify_client ssl_verify_depth starttls stub_status sub_filter sub_filter_once sub_filter_types tcp_nodelay tcp_nopush thread_stack_size timeout timer_resolution types_hash_bucket_size types_hash_max_size underscores_in_headers uninitialized_variable_warn use user userid userid_domain userid_expires userid_mark userid_name userid_p3p userid_path userid_service valid_referers variables_hash_bucket_size variables_hash_max_size worker_connections worker_cpu_affinity worker_priority worker_processes worker_rlimit_core worker_rlimit_nofile worker_rlimit_sigpending worker_threads working_directory xclient xml_entities xslt_stylesheet xslt_typesdrew@li229-23"
12 );
13
14 var keywords_block = words(
15 /* ngxDirectiveBlock */ "http mail events server types location upstream charset_map limit_except if geo map"
16 );
17
18 var keywords_important = words(
19 /* ngxDirectiveImportant */ "include root server server_name listen internal proxy_pass memcached_pass fastcgi_pass try_files"
20 );
21
22 var indentUnit = config.indentUnit, type;
23 function ret(style, tp) {type = tp; return style;}
24
25 function tokenBase(stream, state) {
26
27
28 stream.eatWhile(/[\w\$_]/);
29
30 var cur = stream.current();
31
32
33 if (keywords.propertyIsEnumerable(cur)) {
34 return "keyword";
35 }
36 else if (keywords_block.propertyIsEnumerable(cur)) {
37 return "variable-2";
38 }
39 else if (keywords_important.propertyIsEnumerable(cur)) {
40 return "string-2";
41 }
42 /**/
43
44 var ch = stream.next();
45 if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
46 else if (ch == "/" && stream.eat("*")) {
47 state.tokenize = tokenCComment;
48 return tokenCComment(stream, state);
49 }
50 else if (ch == "<" && stream.eat("!")) {
51 state.tokenize = tokenSGMLComment;
52 return tokenSGMLComment(stream, state);
53 }
54 else if (ch == "=") ret(null, "compare");
55 else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
56 else if (ch == "\"" || ch == "'") {
57 state.tokenize = tokenString(ch);
58 return state.tokenize(stream, state);
59 }
60 else if (ch == "#") {
61 stream.skipToEnd();
62 return ret("comment", "comment");
63 }
64 else if (ch == "!") {
65 stream.match(/^\s*\w*/);
66 return ret("keyword", "important");
67 }
68 else if (/\d/.test(ch)) {
69 stream.eatWhile(/[\w.%]/);
70 return ret("number", "unit");
71 }
72 else if (/[,.+>*\/]/.test(ch)) {
73 return ret(null, "select-op");
74 }
75 else if (/[;{}:\[\]]/.test(ch)) {
76 return ret(null, ch);
77 }
78 else {
79 stream.eatWhile(/[\w\\\-]/);
80 return ret("variable", "variable");
81 }
82 }
83
84 function tokenCComment(stream, state) {
85 var maybeEnd = false, ch;
86 while ((ch = stream.next()) != null) {
87 if (maybeEnd && ch == "/") {
88 state.tokenize = tokenBase;
89 break;
90 }
91 maybeEnd = (ch == "*");
92 }
93 return ret("comment", "comment");
94 }
95
96 function tokenSGMLComment(stream, state) {
97 var dashes = 0, ch;
98 while ((ch = stream.next()) != null) {
99 if (dashes >= 2 && ch == ">") {
100 state.tokenize = tokenBase;
101 break;
102 }
103 dashes = (ch == "-") ? dashes + 1 : 0;
104 }
105 return ret("comment", "comment");
106 }
107
108 function tokenString(quote) {
109 return function(stream, state) {
110 var escaped = false, ch;
111 while ((ch = stream.next()) != null) {
112 if (ch == quote && !escaped)
113 break;
114 escaped = !escaped && ch == "\\";
115 }
116 if (!escaped) state.tokenize = tokenBase;
117 return ret("string", "string");
118 };
119 }
120
121 return {
122 startState: function(base) {
123 return {tokenize: tokenBase,
124 baseIndent: base || 0,
125 stack: []};
126 },
127
128 token: function(stream, state) {
129 if (stream.eatSpace()) return null;
130 type = null;
131 var style = state.tokenize(stream, state);
132
133 var context = state.stack[state.stack.length-1];
134 if (type == "hash" && context == "rule") style = "atom";
135 else if (style == "variable") {
136 if (context == "rule") style = "number";
137 else if (!context || context == "@media{") style = "tag";
138 }
139
140 if (context == "rule" && /^[\{\};]$/.test(type))
141 state.stack.pop();
142 if (type == "{") {
143 if (context == "@media") state.stack[state.stack.length-1] = "@media{";
144 else state.stack.push("{");
145 }
146 else if (type == "}") state.stack.pop();
147 else if (type == "@media") state.stack.push("@media");
148 else if (context == "{" && type != "comment") state.stack.push("rule");
149 return style;
150 },
151
152 indent: function(state, textAfter) {
153 var n = state.stack.length;
154 if (/^\}/.test(textAfter))
155 n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
156 return state.baseIndent + n * indentUnit;
157 },
158
159 electricChars: "}"
160 };
161 });
162
163 CodeMirror.defineMIME("text/nginx", "text/x-nginx-conf");
@@ -0,0 +1,107 b''
1 <!doctype html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>CodeMirror: Smarty mixed mode</title>
6 <link rel="stylesheet" href="../../lib/codemirror.css">
7 <script src="../../lib/codemirror.js"></script>
8 <link rel="stylesheet" href="../../doc/docs.css">
9
10 <!-- smartymixed dependencies -->
11 <script src="../../mode/xml/xml.js"></script>
12 <script src="../../mode/javascript/javascript.js"></script>
13 <script src="../../mode/css/css.js"></script>
14 <script src="../../mode/htmlmixed/htmlmixed.js"></script>
15 <script src="../../mode/smarty/smarty.js"></script>
16
17 <!-- smartymixed -->
18 <script src="../../mode/smartymixed/smartymixed.js"></script>
19 </head>
20 <body>
21 <h1>CodeMirror: Smarty mixed mode</h1>
22 <form><textarea id="code" name="code">
23 {**
24 * @brief Smarty mixed mode
25 * @author Ruslan Osmanov
26 * @date 29.06.2013
27 *}
28 <html>
29 <head>
30 <title>{$title|htmlspecialchars|truncate:30}</title>
31 </head>
32 <body>
33 {* Multiline smarty
34 * comment, no {$variables} here
35 *}
36 {literal}
37 {literal} is just an HTML text.
38 <script type="text/javascript">//<![CDATA[
39 var a = {$just_a_normal_js_object : "value"};
40 var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("code"), {
41 mode : "smartymixed",
42 tabSize : 2,
43 indentUnit : 2,
44 indentWithTabs : false,
45 lineNumbers : true,
46 smartyVersion : 3
47 });
48 // ]]>
49 </script>
50 <style>
51 /* CSS content
52 {$no_smarty} */
53 .some-class { font-weight: bolder; color: "orange"; }
54 </style>
55 {/literal}
56
57 {extends file="parent.tpl"}
58 {include file="template.tpl"}
59
60 {* some example Smarty content *}
61 {if isset($name) && $name == 'Blog'}
62 This is a {$var}.
63 {$integer = 4511}, {$array[] = "a"}, {$stringvar = "string"}
64 {$integer = 4512} {$array[] = "a"} {$stringvar = "string"}
65 {assign var='bob' value=$var.prop}
66 {elseif $name == $foo}
67 {function name=menu level=0}
68 {foreach $data as $entry}
69 {if is_array($entry)}
70 - {$entry@key}
71 {menu data=$entry level=$level+1}
72 {else}
73 {$entry}
74 {* One
75 * Two
76 * Three
77 *}
78 {/if}
79 {/foreach}
80 {/function}
81 {/if}
82 </body>
83 <!-- R.O. -->
84 </html>
85 </textarea></form>
86
87 <script type="text/javascript">
88 var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("code"), {
89 mode : "smartymixed",
90 tabSize : 2,
91 indentUnit : 2,
92 indentWithTabs : false,
93 lineNumbers : true,
94 smartyVersion : 3,
95 matchBrackets : true,
96 });
97 </script>
98
99 <p>The Smarty mixed mode depends on the Smarty and HTML mixed modes. HTML
100 mixed mode itself depends on XML, JavaScript, and CSS modes.</p>
101
102 <p>It takes the same options, as Smarty and HTML mixed modes.</p>
103
104 <p><strong>MIME types defined:</strong> <code>text/x-smarty</code>.</p>
105 </body>
106 </html>
107 <!-- vim: set ft=html ts=2 sts=2 sw=2 et: -->
@@ -0,0 +1,170 b''
1 /**
2 * @file smartymixed.js
3 * @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML)
4 * @author Ruslan Osmanov <rrosmanov at gmail dot com>
5 * @version 3.0
6 * @date 05.07.2013
7 */
8 CodeMirror.defineMode("smartymixed", function(config) {
9 var settings, regs, helpers, parsers,
10 htmlMixedMode = CodeMirror.getMode(config, "htmlmixed"),
11 smartyMode = CodeMirror.getMode(config, "smarty"),
12
13 settings = {
14 rightDelimiter: '}',
15 leftDelimiter: '{'
16 };
17
18 if (config.hasOwnProperty("leftDelimiter")) {
19 settings.leftDelimiter = config.leftDelimiter;
20 }
21 if (config.hasOwnProperty("rightDelimiter")) {
22 settings.rightDelimiter = config.rightDelimiter;
23 }
24
25 regs = {
26 smartyComment: new RegExp("^" + settings.leftDelimiter + "\\*"),
27 literalOpen: new RegExp(settings.leftDelimiter + "literal" + settings.rightDelimiter),
28 literalClose: new RegExp(settings.leftDelimiter + "\/literal" + settings.rightDelimiter),
29 hasLeftDelimeter: new RegExp(".*" + settings.leftDelimiter),
30 htmlHasLeftDelimeter: new RegExp("[^<>]*" + settings.leftDelimiter)
31 };
32
33 helpers = {
34 chain: function(stream, state, parser) {
35 state.tokenize = parser;
36 return parser(stream, state);
37 },
38
39 cleanChain: function(stream, state, parser) {
40 state.tokenize = null;
41 state.localState = null;
42 state.localMode = null;
43 return (typeof parser == "string") ? (parser ? parser : null) : parser(stream, state);
44 },
45
46 maybeBackup: function(stream, pat, style) {
47 var cur = stream.current();
48 var close = cur.search(pat),
49 m;
50 if (close > - 1) stream.backUp(cur.length - close);
51 else if (m = cur.match(/<\/?$/)) {
52 stream.backUp(cur.length);
53 if (!stream.match(pat, false)) stream.match(cur[0]);
54 }
55 return style;
56 }
57 };
58
59 parsers = {
60 html: function(stream, state) {
61 if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false)) {
62 state.tokenize = parsers.smarty;
63 state.localMode = smartyMode;
64 state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
65 return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
66 }
67 return htmlMixedMode.token(stream, state.htmlMixedState);
68 },
69
70 smarty: function(stream, state) {
71 if (stream.match(settings.leftDelimiter, false)) {
72 if (stream.match(regs.smartyComment, false)) {
73 return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
74 }
75 } else if (stream.match(settings.rightDelimiter, false)) {
76 stream.eat(settings.rightDelimiter);
77 state.tokenize = parsers.html;
78 state.localMode = htmlMixedMode;
79 state.localState = state.htmlMixedState;
80 return "tag";
81 }
82
83 return helpers.maybeBackup(stream, settings.rightDelimiter, smartyMode.token(stream, state.localState));
84 },
85
86 inBlock: function(style, terminator) {
87 return function(stream, state) {
88 while (!stream.eol()) {
89 if (stream.match(terminator)) {
90 helpers.cleanChain(stream, state, "");
91 break;
92 }
93 stream.next();
94 }
95 return style;
96 };
97 }
98 };
99
100 return {
101 startState: function() {
102 var state = htmlMixedMode.startState();
103 return {
104 token: parsers.html,
105 localMode: null,
106 localState: null,
107 htmlMixedState: state,
108 tokenize: null,
109 inLiteral: false
110 };
111 },
112
113 copyState: function(state) {
114 var local = null, tok = (state.tokenize || state.token);
115 if (state.localState) {
116 local = CodeMirror.copyState((tok != parsers.html ? smartyMode : htmlMixedMode), state.localState);
117 }
118 return {
119 token: state.token,
120 tokenize: state.tokenize,
121 localMode: state.localMode,
122 localState: local,
123 htmlMixedState: CodeMirror.copyState(htmlMixedMode, state.htmlMixedState),
124 inLiteral: state.inLiteral
125 };
126 },
127
128 token: function(stream, state) {
129 if (stream.match(settings.leftDelimiter, false)) {
130 if (!state.inLiteral && stream.match(regs.literalOpen, true)) {
131 state.inLiteral = true;
132 return "keyword";
133 } else if (state.inLiteral && stream.match(regs.literalClose, true)) {
134 state.inLiteral = false;
135 return "keyword";
136 }
137 }
138 if (state.inLiteral && state.localState != state.htmlMixedState) {
139 state.tokenize = parsers.html;
140 state.localMode = htmlMixedMode;
141 state.localState = state.htmlMixedState;
142 }
143
144 var style = (state.tokenize || state.token)(stream, state);
145 return style;
146 },
147
148 indent: function(state, textAfter) {
149 if (state.localMode == smartyMode
150 || (state.inLiteral && !state.localMode)
151 || regs.hasLeftDelimeter.test(textAfter)) {
152 return CodeMirror.Pass;
153 }
154 return htmlMixedMode.indent(state.htmlMixedState, textAfter);
155 },
156
157 electricChars: "/{}:",
158
159 innerMode: function(state) {
160 return {
161 state: state.localState || state.htmlMixedState,
162 mode: state.localMode || htmlMixedMode
163 };
164 }
165 };
166 },
167 "htmlmixed");
168
169 CodeMirror.defineMIME("text/x-smarty", "smartymixed");
170 // vim: et ts=2 sts=2 sw=2
@@ -192,6 +192,16 b' div.CodeMirror span.CodeMirror-nonmatchi'
192 white-space: pre-wrap;
192 white-space: pre-wrap;
193 word-break: normal;
193 word-break: normal;
194 }
194 }
195 .CodeMirror-code pre {
196 border-right: 30px solid transparent;
197 width: -webkit-fit-content;
198 width: -moz-fit-content;
199 width: fit-content;
200 }
201 .CodeMirror-wrap .CodeMirror-code pre {
202 border-right: none;
203 width: auto;
204 }
195 .CodeMirror-linebackground {
205 .CodeMirror-linebackground {
196 position: absolute;
206 position: absolute;
197 left: 0; right: 0; top: 0; bottom: 0;
207 left: 0; right: 0; top: 0; bottom: 0;
@@ -1,4 +1,4 b''
1 // CodeMirror version 3.14
1 // CodeMirror version 3.15
2 //
2 //
3 // CodeMirror is the only global var we claim
3 // CodeMirror is the only global var we claim
4 window.CodeMirror = (function() {
4 window.CodeMirror = (function() {
@@ -30,6 +30,7 b' window.CodeMirror = (function() {'
30
30
31 var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
31 var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
32 if (opera_version) opera_version = Number(opera_version[1]);
32 if (opera_version) opera_version = Number(opera_version[1]);
33 if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
33 // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
34 // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
34 var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
35 var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
35 var captureMiddleClick = gecko || (ie && !ie_lt9);
36 var captureMiddleClick = gecko || (ie && !ie_lt9);
@@ -403,11 +404,12 b' window.CodeMirror = (function() {'
403
404
404 // DISPLAY DRAWING
405 // DISPLAY DRAWING
405
406
406 function updateDisplay(cm, changes, viewPort) {
407 function updateDisplay(cm, changes, viewPort, forced) {
407 var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
408 var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
408 var visible = visibleLines(cm.display, cm.doc, viewPort);
409 var visible = visibleLines(cm.display, cm.doc, viewPort);
409 for (;;) {
410 for (;;) {
410 if (!updateDisplayInner(cm, changes, visible)) break;
411 if (!updateDisplayInner(cm, changes, visible, forced)) break;
412 forced = false;
411 updated = true;
413 updated = true;
412 updateSelection(cm);
414 updateSelection(cm);
413 updateScrollbars(cm);
415 updateScrollbars(cm);
@@ -433,7 +435,7 b' window.CodeMirror = (function() {'
433 // Uses a set of changes plus the current scroll position to
435 // Uses a set of changes plus the current scroll position to
434 // determine which DOM updates have to be made, and makes the
436 // determine which DOM updates have to be made, and makes the
435 // updates.
437 // updates.
436 function updateDisplayInner(cm, changes, visible) {
438 function updateDisplayInner(cm, changes, visible, forced) {
437 var display = cm.display, doc = cm.doc;
439 var display = cm.display, doc = cm.doc;
438 if (!display.wrapper.clientWidth) {
440 if (!display.wrapper.clientWidth) {
439 display.showingFrom = display.showingTo = doc.first;
441 display.showingFrom = display.showingTo = doc.first;
@@ -442,7 +444,7 b' window.CodeMirror = (function() {'
442 }
444 }
443
445
444 // Bail out if the visible area is already rendered and nothing changed.
446 // Bail out if the visible area is already rendered and nothing changed.
445 if (changes.length == 0 &&
447 if (!forced && changes.length == 0 &&
446 visible.from > display.showingFrom && visible.to < display.showingTo)
448 visible.from > display.showingFrom && visible.to < display.showingTo)
447 return;
449 return;
448
450
@@ -495,7 +497,7 b' window.CodeMirror = (function() {'
495 if (range.from >= range.to) intact.splice(i--, 1);
497 if (range.from >= range.to) intact.splice(i--, 1);
496 else intactLines += range.to - range.from;
498 else intactLines += range.to - range.from;
497 }
499 }
498 if (intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
500 if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
499 updateViewOffset(cm);
501 updateViewOffset(cm);
500 return;
502 return;
501 }
503 }
@@ -520,6 +522,14 b' window.CodeMirror = (function() {'
520 }
522 }
521 display.showingFrom = from; display.showingTo = to;
523 display.showingFrom = from; display.showingTo = to;
522
524
525 updateHeightsInViewport(cm);
526 updateViewOffset(cm);
527
528 return true;
529 }
530
531 function updateHeightsInViewport(cm) {
532 var display = cm.display;
523 var prevBottom = display.lineDiv.offsetTop;
533 var prevBottom = display.lineDiv.offsetTop;
524 for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
534 for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
525 if (ie_lt8) {
535 if (ie_lt8) {
@@ -539,9 +549,6 b' window.CodeMirror = (function() {'
539 widgets[i].height = widgets[i].node.offsetHeight;
549 widgets[i].height = widgets[i].node.offsetHeight;
540 }
550 }
541 }
551 }
542 updateViewOffset(cm);
543
544 return true;
545 }
552 }
546
553
547 function updateViewOffset(cm) {
554 function updateViewOffset(cm) {
@@ -670,10 +677,10 b' window.CodeMirror = (function() {'
670 if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
677 if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
671 reuse.removeChild(n);
678 reuse.removeChild(n);
672 } else {
679 } else {
673 for (var i = 0, first = true; i < line.widgets.length; ++i) {
680 for (var i = 0; i < line.widgets.length; ++i) {
674 var widget = line.widgets[i];
681 var widget = line.widgets[i];
675 if (!widget.above) { insertBefore = n; first = false; }
676 if (widget.node == n.firstChild) {
682 if (widget.node == n.firstChild) {
683 if (!widget.above && !insertBefore) insertBefore = n;
677 positionLineWidget(widget, n, reuse, dims);
684 positionLineWidget(widget, n, reuse, dims);
678 ++widgetsSeen;
685 ++widgetsSeen;
679 break;
686 break;
@@ -966,11 +973,13 b' window.CodeMirror = (function() {'
966 if (r) break;
973 if (r) break;
967 if (dir < 0 && pos == 0) dir = 1;
974 if (dir < 0 && pos == 0) dir = 1;
968 }
975 }
969 var rightV = (pos < ch || bias == "right") && r.topRight != null;
976 bias = pos > ch ? "left" : pos < ch ? "right" : bias;
977 if (bias == "left" && r.leftSide) r = r.leftSide;
978 else if (bias == "right" && r.rightSide) r = r.rightSide;
970 return {left: pos < ch ? r.right : r.left,
979 return {left: pos < ch ? r.right : r.left,
971 right: pos > ch ? r.left : r.right,
980 right: pos > ch ? r.left : r.right,
972 top: rightV ? r.topRight : r.top,
981 top: r.top,
973 bottom: rightV ? r.bottomRight : r.bottom};
982 bottom: r.bottom};
974 }
983 }
975
984
976 function findCachedMeasurement(cm, line) {
985 function findCachedMeasurement(cm, line) {
@@ -1007,7 +1016,7 b' window.CodeMirror = (function() {'
1007
1016
1008 function measureLineInner(cm, line) {
1017 function measureLineInner(cm, line) {
1009 var display = cm.display, measure = emptyArray(line.text.length);
1018 var display = cm.display, measure = emptyArray(line.text.length);
1010 var pre = lineContent(cm, line, measure);
1019 var pre = lineContent(cm, line, measure, true);
1011
1020
1012 // IE does not cache element positions of inline elements between
1021 // IE does not cache element positions of inline elements between
1013 // calls to getBoundingClientRect. This makes the loop below,
1022 // calls to getBoundingClientRect. This makes the loop below,
@@ -1043,48 +1052,50 b' window.CodeMirror = (function() {'
1043 if (ie_lt9 && display.measure.first != pre)
1052 if (ie_lt9 && display.measure.first != pre)
1044 removeChildrenAndAdd(display.measure, pre);
1053 removeChildrenAndAdd(display.measure, pre);
1045
1054
1046 function categorizeVSpan(top, bot) {
1055 function measureRect(rect) {
1056 var top = rect.top - outer.top, bot = rect.bottom - outer.top;
1047 if (bot > maxBot) bot = maxBot;
1057 if (bot > maxBot) bot = maxBot;
1048 if (top < 0) top = 0;
1058 if (top < 0) top = 0;
1049 for (var j = 0; j < vranges.length; j += 2) {
1059 for (var i = vranges.length - 2; i >= 0; i -= 2) {
1050 var rtop = vranges[j], rbot = vranges[j+1];
1060 var rtop = vranges[i], rbot = vranges[i+1];
1051 if (rtop > bot || rbot < top) continue;
1061 if (rtop > bot || rbot < top) continue;
1052 if (rtop <= top && rbot >= bot ||
1062 if (rtop <= top && rbot >= bot ||
1053 top <= rtop && bot >= rbot ||
1063 top <= rtop && bot >= rbot ||
1054 Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
1064 Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
1055 vranges[j] = Math.min(top, rtop);
1065 vranges[i] = Math.min(top, rtop);
1056 vranges[j+1] = Math.max(bot, rbot);
1066 vranges[i+1] = Math.max(bot, rbot);
1057 return j;
1067 break;
1058 }
1068 }
1059 }
1069 }
1060 vranges.push(top, bot);
1070 if (i < 0) { i = vranges.length; vranges.push(top, bot); }
1061 return j;
1071 return {left: rect.left - outer.left,
1072 right: rect.right - outer.left,
1073 top: i, bottom: null};
1074 }
1075 function finishRect(rect) {
1076 rect.bottom = vranges[rect.top+1];
1077 rect.top = vranges[rect.top];
1062 }
1078 }
1063
1079
1064 for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
1080 for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
1065 var size, node = cur;
1081 var node = cur, rect = null;
1066 // A widget might wrap, needs special care
1082 // A widget might wrap, needs special care
1067 if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
1083 if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
1068 if (cur.firstChild.nodeType == 1) node = cur.firstChild;
1084 if (cur.firstChild.nodeType == 1) node = cur.firstChild;
1069 var rects = node.getClientRects(), rLeft = rects[0], rRight = rects[rects.length - 1];
1085 var rects = node.getClientRects();
1070 if (rects.length > 1) {
1086 if (rects.length > 1) {
1071 var vCatLeft = categorizeVSpan(rLeft.top - outer.top, rLeft.bottom - outer.top);
1087 rect = data[i] = measureRect(rects[0]);
1072 var vCatRight = categorizeVSpan(rRight.top - outer.top, rRight.bottom - outer.top);
1088 rect.rightSide = measureRect(rects[rects.length - 1]);
1073 data[i] = {left: rLeft.left - outer.left, right: rRight.right - outer.left,
1074 top: vCatLeft, topRight: vCatRight};
1075 continue;
1076 }
1089 }
1077 }
1090 }
1078 size = getRect(node);
1091 if (!rect) rect = data[i] = measureRect(getRect(node));
1079 var vCat = categorizeVSpan(size.top - outer.top, size.bottom - outer.top);
1092 if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
1080 var right = size.right;
1093 if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
1081 if (cur.measureRight) right = getRect(cur.measureRight).left;
1082 data[i] = {left: size.left - outer.left, right: right - outer.left, top: vCat};
1083 }
1094 }
1084 for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
1095 for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
1085 var vr = cur.top, vrRight = cur.topRight;
1096 finishRect(cur);
1086 cur.top = vranges[vr]; cur.bottom = vranges[vr+1];
1097 if (cur.leftSide) finishRect(cur.leftSide);
1087 if (vrRight != null) { cur.topRight = vranges[vrRight]; cur.bottomRight = vranges[vrRight+1]; }
1098 if (cur.rightSide) finishRect(cur.rightSide);
1088 }
1099 }
1089 return data;
1100 return data;
1090 }
1101 }
@@ -1098,7 +1109,7 b' window.CodeMirror = (function() {'
1098 var cached = !hasBadSpan && findCachedMeasurement(cm, line);
1109 var cached = !hasBadSpan && findCachedMeasurement(cm, line);
1099 if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
1110 if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
1100
1111
1101 var pre = lineContent(cm, line);
1112 var pre = lineContent(cm, line, null, true);
1102 var end = pre.appendChild(zeroWidthElement(cm.display.measure));
1113 var end = pre.appendChild(zeroWidthElement(cm.display.measure));
1103 removeChildrenAndAdd(cm.display.measure, pre);
1114 removeChildrenAndAdd(cm.display.measure, pre);
1104 return getRect(end).right - getRect(cm.display.lineDiv).left;
1115 return getRect(end).right - getRect(cm.display.lineDiv).left;
@@ -1302,6 +1313,7 b' window.CodeMirror = (function() {'
1302 // An array of ranges of lines that have to be updated. See
1313 // An array of ranges of lines that have to be updated. See
1303 // updateDisplay.
1314 // updateDisplay.
1304 changes: [],
1315 changes: [],
1316 forceUpdate: false,
1305 updateInput: null,
1317 updateInput: null,
1306 userSelChange: null,
1318 userSelChange: null,
1307 textChanged: null,
1319 textChanged: null,
@@ -1334,8 +1346,8 b' window.CodeMirror = (function() {'
1334 var coords = cursorCoords(cm, doc.sel.head);
1346 var coords = cursorCoords(cm, doc.sel.head);
1335 newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
1347 newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
1336 }
1348 }
1337 if (op.changes.length || newScrollPos && newScrollPos.scrollTop != null) {
1349 if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) {
1338 updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop);
1350 updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
1339 if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
1351 if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
1340 }
1352 }
1341 if (!updated && op.selectionChanged) updateSelection(cm);
1353 if (!updated && op.selectionChanged) updateSelection(cm);
@@ -2105,6 +2117,7 b' window.CodeMirror = (function() {'
2105
2117
2106 var detectingSelectAll;
2118 var detectingSelectAll;
2107 function onContextMenu(cm, e) {
2119 function onContextMenu(cm, e) {
2120 if (signalDOMEvent(cm, e, "contextmenu")) return;
2108 var display = cm.display, sel = cm.doc.sel;
2121 var display = cm.display, sel = cm.doc.sel;
2109 if (eventInWidget(display, e)) return;
2122 if (eventInWidget(display, e)) return;
2110
2123
@@ -2755,7 +2768,7 b' window.CodeMirror = (function() {'
2755 function findWordAt(line, pos) {
2768 function findWordAt(line, pos) {
2756 var start = pos.ch, end = pos.ch;
2769 var start = pos.ch, end = pos.ch;
2757 if (line) {
2770 if (line) {
2758 if (pos.xRel < 0 || end == line.length) --start; else ++end;
2771 if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
2759 var startChar = line.charAt(start);
2772 var startChar = line.charAt(start);
2760 var check = isWordChar(startChar) ? isWordChar
2773 var check = isWordChar(startChar) ? isWordChar
2761 : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
2774 : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
@@ -2796,7 +2809,7 b' window.CodeMirror = (function() {'
2796 removeKeyMap: function(map) {
2809 removeKeyMap: function(map) {
2797 var maps = this.state.keyMaps;
2810 var maps = this.state.keyMaps;
2798 for (var i = 0; i < maps.length; ++i)
2811 for (var i = 0; i < maps.length; ++i)
2799 if ((typeof map == "string" ? maps[i].name : maps[i]) == map) {
2812 if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
2800 maps.splice(i, 1);
2813 maps.splice(i, 1);
2801 return true;
2814 return true;
2802 }
2815 }
@@ -2860,6 +2873,7 b' window.CodeMirror = (function() {'
2860 pos = clipPos(this.doc, pos);
2873 pos = clipPos(this.doc, pos);
2861 var styles = getLineStyles(this, getLine(this.doc, pos.line));
2874 var styles = getLineStyles(this, getLine(this.doc, pos.line));
2862 var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
2875 var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
2876 if (ch == 0) return styles[2];
2863 for (;;) {
2877 for (;;) {
2864 var mid = (before + after) >> 1;
2878 var mid = (before + after) >> 1;
2865 if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
2879 if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
@@ -2868,6 +2882,20 b' window.CodeMirror = (function() {'
2868 }
2882 }
2869 },
2883 },
2870
2884
2885 getModeAt: function(pos) {
2886 var mode = this.doc.mode;
2887 if (!mode.innerMode) return mode;
2888 return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
2889 },
2890
2891 getHelper: function(pos, type) {
2892 if (!helpers.hasOwnProperty(type)) return;
2893 var help = helpers[type], mode = this.getModeAt(pos);
2894 return mode[type] && help[mode[type]] ||
2895 mode.helperType && help[mode.helperType] ||
2896 help[mode.name];
2897 },
2898
2871 getStateAfter: function(line, precise) {
2899 getStateAfter: function(line, precise) {
2872 var doc = this.doc;
2900 var doc = this.doc;
2873 line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
2901 line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
@@ -3097,17 +3125,16 b' window.CodeMirror = (function() {'
3097 updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
3125 updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
3098 }),
3126 }),
3099
3127
3100 setSize: function(width, height) {
3128 setSize: operation(null, function(width, height) {
3101 function interpret(val) {
3129 function interpret(val) {
3102 return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
3130 return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
3103 }
3131 }
3104 if (width != null) this.display.wrapper.style.width = interpret(width);
3132 if (width != null) this.display.wrapper.style.width = interpret(width);
3105 if (height != null) this.display.wrapper.style.height = interpret(height);
3133 if (height != null) this.display.wrapper.style.height = interpret(height);
3106 this.refresh();
3134 if (this.options.lineWrapping)
3107 },
3135 this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
3108
3136 this.curOp.forceUpdate = true;
3109 on: function(type, f) {on(this, type, f);},
3137 }),
3110 off: function(type, f) {off(this, type, f);},
3111
3138
3112 operation: function(f){return runInOp(this, f);},
3139 operation: function(f){return runInOp(this, f);},
3113
3140
@@ -3132,6 +3159,7 b' window.CodeMirror = (function() {'
3132 getScrollerElement: function(){return this.display.scroller;},
3159 getScrollerElement: function(){return this.display.scroller;},
3133 getGutterElement: function(){return this.display.gutters;}
3160 getGutterElement: function(){return this.display.gutters;}
3134 };
3161 };
3162 eventMixin(CodeMirror);
3135
3163
3136 // OPTION DEFAULTS
3164 // OPTION DEFAULTS
3137
3165
@@ -3256,7 +3284,7 b' window.CodeMirror = (function() {'
3256 };
3284 };
3257
3285
3258 CodeMirror.getMode = function(options, spec) {
3286 CodeMirror.getMode = function(options, spec) {
3259 spec = CodeMirror.resolveMode(spec);
3287 var spec = CodeMirror.resolveMode(spec);
3260 var mfactory = modes[spec.name];
3288 var mfactory = modes[spec.name];
3261 if (!mfactory) return CodeMirror.getMode(options, "text/plain");
3289 if (!mfactory) return CodeMirror.getMode(options, "text/plain");
3262 var modeObj = mfactory(options, spec);
3290 var modeObj = mfactory(options, spec);
@@ -3269,6 +3297,7 b' window.CodeMirror = (function() {'
3269 }
3297 }
3270 }
3298 }
3271 modeObj.name = spec.name;
3299 modeObj.name = spec.name;
3300
3272 return modeObj;
3301 return modeObj;
3273 };
3302 };
3274
3303
@@ -3296,6 +3325,16 b' window.CodeMirror = (function() {'
3296 var initHooks = [];
3325 var initHooks = [];
3297 CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
3326 CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
3298
3327
3328 var helpers = CodeMirror.helpers = {};
3329 CodeMirror.registerHelper = function(type, name, value) {
3330 if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {};
3331 helpers[type][name] = value;
3332 };
3333
3334 // UTILITIES
3335
3336 CodeMirror.isWordChar = isWordChar;
3337
3299 // MODE STATE HANDLING
3338 // MODE STATE HANDLING
3300
3339
3301 // Utility functions for working with state. Exported because modes
3340 // Utility functions for working with state. Exported because modes
@@ -3321,6 +3360,7 b' window.CodeMirror = (function() {'
3321 CodeMirror.innerMode = function(mode, state) {
3360 CodeMirror.innerMode = function(mode, state) {
3322 while (mode.innerMode) {
3361 while (mode.innerMode) {
3323 var info = mode.innerMode(state);
3362 var info = mode.innerMode(state);
3363 if (!info || info.mode == mode) break;
3324 state = info.state;
3364 state = info.state;
3325 mode = info.mode;
3365 mode = info.mode;
3326 }
3366 }
@@ -3633,11 +3673,16 b' window.CodeMirror = (function() {'
3633 this.doc = doc;
3673 this.doc = doc;
3634 }
3674 }
3635 CodeMirror.TextMarker = TextMarker;
3675 CodeMirror.TextMarker = TextMarker;
3676 eventMixin(TextMarker);
3636
3677
3637 TextMarker.prototype.clear = function() {
3678 TextMarker.prototype.clear = function() {
3638 if (this.explicitlyCleared) return;
3679 if (this.explicitlyCleared) return;
3639 var cm = this.doc.cm, withOp = cm && !cm.curOp;
3680 var cm = this.doc.cm, withOp = cm && !cm.curOp;
3640 if (withOp) startOperation(cm);
3681 if (withOp) startOperation(cm);
3682 if (hasHandler(this, "clear")) {
3683 var found = this.find();
3684 if (found) signalLater(this, "clear", found.from, found.to);
3685 }
3641 var min = null, max = null;
3686 var min = null, max = null;
3642 for (var i = 0; i < this.lines.length; ++i) {
3687 for (var i = 0; i < this.lines.length; ++i) {
3643 var line = this.lines[i];
3688 var line = this.lines[i];
@@ -3666,7 +3711,6 b' window.CodeMirror = (function() {'
3666 if (cm) reCheckSelection(cm);
3711 if (cm) reCheckSelection(cm);
3667 }
3712 }
3668 if (withOp) endOperation(cm);
3713 if (withOp) endOperation(cm);
3669 signalLater(this, "clear");
3670 };
3714 };
3671
3715
3672 TextMarker.prototype.find = function() {
3716 TextMarker.prototype.find = function() {
@@ -3694,7 +3738,9 b' window.CodeMirror = (function() {'
3694 if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
3738 if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
3695 break;
3739 break;
3696 }
3740 }
3697 runInOp(cm, function() { cm.curOp.selectionChanged = true; });
3741 runInOp(cm, function() {
3742 cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true;
3743 });
3698 }
3744 }
3699 };
3745 };
3700
3746
@@ -3767,7 +3813,7 b' window.CodeMirror = (function() {'
3767 }
3813 }
3768 if (cm) {
3814 if (cm) {
3769 if (updateMaxLine) cm.curOp.updateMaxLine = true;
3815 if (updateMaxLine) cm.curOp.updateMaxLine = true;
3770 if (marker.className || marker.startStyle || marker.endStyle || marker.collapsed)
3816 if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
3771 regChange(cm, from.line, to.line + 1);
3817 regChange(cm, from.line, to.line + 1);
3772 if (marker.atomic) reCheckSelection(cm);
3818 if (marker.atomic) reCheckSelection(cm);
3773 }
3819 }
@@ -3785,6 +3831,7 b' window.CodeMirror = (function() {'
3785 }
3831 }
3786 }
3832 }
3787 CodeMirror.SharedTextMarker = SharedTextMarker;
3833 CodeMirror.SharedTextMarker = SharedTextMarker;
3834 eventMixin(SharedTextMarker);
3788
3835
3789 SharedTextMarker.prototype.clear = function() {
3836 SharedTextMarker.prototype.clear = function() {
3790 if (this.explicitlyCleared) return;
3837 if (this.explicitlyCleared) return;
@@ -4037,11 +4084,12 b' window.CodeMirror = (function() {'
4037 // LINE WIDGETS
4084 // LINE WIDGETS
4038
4085
4039 var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
4086 var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
4040 for (var opt in options) if (options.hasOwnProperty(opt))
4087 if (options) for (var opt in options) if (options.hasOwnProperty(opt))
4041 this[opt] = options[opt];
4088 this[opt] = options[opt];
4042 this.cm = cm;
4089 this.cm = cm;
4043 this.node = node;
4090 this.node = node;
4044 };
4091 };
4092 eventMixin(LineWidget);
4045 function widgetOperation(f) {
4093 function widgetOperation(f) {
4046 return function() {
4094 return function() {
4047 var withOp = !this.cm.curOp;
4095 var withOp = !this.cm.curOp;
@@ -4056,7 +4104,9 b' window.CodeMirror = (function() {'
4056 if (no == null || !ws) return;
4104 if (no == null || !ws) return;
4057 for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
4105 for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
4058 if (!ws.length) this.line.widgets = null;
4106 if (!ws.length) this.line.widgets = null;
4107 var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
4059 updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
4108 updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
4109 if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
4060 regChange(this.cm, no, no + 1);
4110 regChange(this.cm, no, no + 1);
4061 });
4111 });
4062 LineWidget.prototype.changed = widgetOperation(function() {
4112 LineWidget.prototype.changed = widgetOperation(function() {
@@ -4080,10 +4130,12 b' window.CodeMirror = (function() {'
4080 var widget = new LineWidget(cm, node, options);
4130 var widget = new LineWidget(cm, node, options);
4081 if (widget.noHScroll) cm.display.alignWidgets = true;
4131 if (widget.noHScroll) cm.display.alignWidgets = true;
4082 changeLine(cm, handle, function(line) {
4132 changeLine(cm, handle, function(line) {
4083 (line.widgets || (line.widgets = [])).push(widget);
4133 var widgets = line.widgets || (line.widgets = []);
4134 if (widget.insertAt == null) widgets.push(widget);
4135 else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
4084 widget.line = line;
4136 widget.line = line;
4085 if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
4137 if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
4086 var aboveVisible = heightAtLine(cm, line) < cm.display.scroller.scrollTop;
4138 var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
4087 updateLineHeight(line, line.height + widgetHeight(widget));
4139 updateLineHeight(line, line.height + widgetHeight(widget));
4088 if (aboveVisible) addToScrollPos(cm, 0, widget.height);
4140 if (aboveVisible) addToScrollPos(cm, 0, widget.height);
4089 }
4141 }
@@ -4096,12 +4148,12 b' window.CodeMirror = (function() {'
4096
4148
4097 // Line objects. These hold state related to a line, including
4149 // Line objects. These hold state related to a line, including
4098 // highlighting info (the styles array).
4150 // highlighting info (the styles array).
4099 function makeLine(text, markedSpans, estimateHeight) {
4151 var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
4100 var line = {text: text};
4152 this.text = text;
4101 attachMarkedSpans(line, markedSpans);
4153 attachMarkedSpans(this, markedSpans);
4102 line.height = estimateHeight ? estimateHeight(line) : 1;
4154 this.height = estimateHeight ? estimateHeight(this) : 1;
4103 return line;
4155 };
4104 }
4156 eventMixin(Line);
4105
4157
4106 function updateLine(line, text, markedSpans, estimateHeight) {
4158 function updateLine(line, text, markedSpans, estimateHeight) {
4107 line.text = text;
4159 line.text = text;
@@ -4207,13 +4259,14 b' window.CodeMirror = (function() {'
4207 (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
4259 (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
4208 }
4260 }
4209
4261
4210 function lineContent(cm, realLine, measure) {
4262 function lineContent(cm, realLine, measure, copyWidgets) {
4211 var merged, line = realLine, empty = true;
4263 var merged, line = realLine, empty = true;
4212 while (merged = collapsedSpanAtStart(line))
4264 while (merged = collapsedSpanAtStart(line))
4213 line = getLine(cm.doc, merged.find().from.line);
4265 line = getLine(cm.doc, merged.find().from.line);
4214
4266
4215 var builder = {pre: elt("pre"), col: 0, pos: 0, display: !measure,
4267 var builder = {pre: elt("pre"), col: 0, pos: 0,
4216 measure: null, measuredSomething: false, cm: cm};
4268 measure: null, measuredSomething: false, cm: cm,
4269 copyWidgets: copyWidgets};
4217 if (line.textClass) builder.pre.className = line.textClass;
4270 if (line.textClass) builder.pre.className = line.textClass;
4218
4271
4219 do {
4272 do {
@@ -4256,7 +4309,7 b' window.CodeMirror = (function() {'
4256 }
4309 }
4257
4310
4258 var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
4311 var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
4259 function buildToken(builder, text, style, startStyle, endStyle) {
4312 function buildToken(builder, text, style, startStyle, endStyle, title) {
4260 if (!text) return;
4313 if (!text) return;
4261 if (!tokenSpecialChars.test(text)) {
4314 if (!tokenSpecialChars.test(text)) {
4262 builder.col += text.length;
4315 builder.col += text.length;
@@ -4289,7 +4342,9 b' window.CodeMirror = (function() {'
4289 var fullStyle = style || "";
4342 var fullStyle = style || "";
4290 if (startStyle) fullStyle += startStyle;
4343 if (startStyle) fullStyle += startStyle;
4291 if (endStyle) fullStyle += endStyle;
4344 if (endStyle) fullStyle += endStyle;
4292 return builder.pre.appendChild(elt("span", [content], fullStyle));
4345 var token = elt("span", [content], fullStyle);
4346 if (title) token.title = title;
4347 return builder.pre.appendChild(token);
4293 }
4348 }
4294 builder.pre.appendChild(content);
4349 builder.pre.appendChild(content);
4295 }
4350 }
@@ -4304,9 +4359,11 b' window.CodeMirror = (function() {'
4304 } else if (i && wrapping && spanAffectsWrapping(text, i)) {
4359 } else if (i && wrapping && spanAffectsWrapping(text, i)) {
4305 builder.pre.appendChild(elt("wbr"));
4360 builder.pre.appendChild(elt("wbr"));
4306 }
4361 }
4362 var old = builder.measure[builder.pos];
4307 var span = builder.measure[builder.pos] =
4363 var span = builder.measure[builder.pos] =
4308 buildToken(builder, ch, style,
4364 buildToken(builder, ch, style,
4309 start && startStyle, i == text.length - 1 && endStyle);
4365 start && startStyle, i == text.length - 1 && endStyle);
4366 if (old) span.leftSide = old.leftSide || old;
4310 // In IE single-space nodes wrap differently than spaces
4367 // In IE single-space nodes wrap differently than spaces
4311 // embedded in larger text nodes, except when set to
4368 // embedded in larger text nodes, except when set to
4312 // white-space: normal (issue #1268).
4369 // white-space: normal (issue #1268).
@@ -4325,20 +4382,28 b' window.CodeMirror = (function() {'
4325 out += " ";
4382 out += " ";
4326 return out;
4383 return out;
4327 }
4384 }
4328 return function(builder, text, style, startStyle, endStyle) {
4385 return function(builder, text, style, startStyle, endStyle, title) {
4329 return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle);
4386 return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title);
4330 };
4387 };
4331 }
4388 }
4332
4389
4333 function buildCollapsedSpan(builder, size, widget) {
4390 function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
4391 var widget = !ignoreWidget && marker.replacedWith;
4334 if (widget) {
4392 if (widget) {
4335 if (!builder.display) widget = widget.cloneNode(true);
4393 if (builder.copyWidgets) widget = widget.cloneNode(true);
4394 builder.pre.appendChild(widget);
4336 if (builder.measure) {
4395 if (builder.measure) {
4337 builder.measure[builder.pos] = size ? widget
4396 if (size) {
4338 : builder.pre.appendChild(zeroWidthElement(builder.cm.display.measure));
4397 builder.measure[builder.pos] = widget;
4398 } else {
4399 var elt = builder.measure[builder.pos] = zeroWidthElement(builder.cm.display.measure);
4400 if (marker.type != "bookmark" || marker.insertLeft)
4401 builder.pre.insertBefore(elt, widget);
4402 else
4403 builder.pre.appendChild(elt);
4404 }
4339 builder.measuredSomething = true;
4405 builder.measuredSomething = true;
4340 }
4406 }
4341 builder.pre.appendChild(widget);
4342 }
4407 }
4343 builder.pos += size;
4408 builder.pos += size;
4344 }
4409 }
@@ -4354,10 +4419,10 b' window.CodeMirror = (function() {'
4354 }
4419 }
4355
4420
4356 var len = allText.length, pos = 0, i = 1, text = "", style;
4421 var len = allText.length, pos = 0, i = 1, text = "", style;
4357 var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, collapsed;
4422 var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
4358 for (;;) {
4423 for (;;) {
4359 if (nextChange == pos) { // Update current marker set
4424 if (nextChange == pos) { // Update current marker set
4360 spanStyle = spanEndStyle = spanStartStyle = "";
4425 spanStyle = spanEndStyle = spanStartStyle = title = "";
4361 collapsed = null; nextChange = Infinity;
4426 collapsed = null; nextChange = Infinity;
4362 var foundBookmark = null;
4427 var foundBookmark = null;
4363 for (var j = 0; j < spans.length; ++j) {
4428 for (var j = 0; j < spans.length; ++j) {
@@ -4367,17 +4432,17 b' window.CodeMirror = (function() {'
4367 if (m.className) spanStyle += " " + m.className;
4432 if (m.className) spanStyle += " " + m.className;
4368 if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
4433 if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
4369 if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
4434 if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
4435 if (m.title && !title) title = m.title;
4370 if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
4436 if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
4371 collapsed = sp;
4437 collapsed = sp;
4372 } else if (sp.from > pos && nextChange > sp.from) {
4438 } else if (sp.from > pos && nextChange > sp.from) {
4373 nextChange = sp.from;
4439 nextChange = sp.from;
4374 }
4440 }
4375 if (m.type == "bookmark" && sp.from == pos && m.replacedWith)
4441 if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmark = m;
4376 foundBookmark = m.replacedWith;
4377 }
4442 }
4378 if (collapsed && (collapsed.from || 0) == pos) {
4443 if (collapsed && (collapsed.from || 0) == pos) {
4379 buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
4444 buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
4380 collapsed.from != null && collapsed.marker.replacedWith);
4445 collapsed.marker, collapsed.from == null);
4381 if (collapsed.to == null) return collapsed.marker.find();
4446 if (collapsed.to == null) return collapsed.marker.find();
4382 }
4447 }
4383 if (foundBookmark && !collapsed) buildCollapsedSpan(builder, 0, foundBookmark);
4448 if (foundBookmark && !collapsed) buildCollapsedSpan(builder, 0, foundBookmark);
@@ -4391,7 +4456,7 b' window.CodeMirror = (function() {'
4391 if (!collapsed) {
4456 if (!collapsed) {
4392 var tokenText = end > upto ? text.slice(0, upto - pos) : text;
4457 var tokenText = end > upto ? text.slice(0, upto - pos) : text;
4393 builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
4458 builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
4394 spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "");
4459 spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
4395 }
4460 }
4396 if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
4461 if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
4397 pos = end;
4462 pos = end;
@@ -4421,7 +4486,7 b' window.CodeMirror = (function() {'
4421 // This is a whole-line replace. Treated specially to make
4486 // This is a whole-line replace. Treated specially to make
4422 // sure line objects move the way they are supposed to.
4487 // sure line objects move the way they are supposed to.
4423 for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
4488 for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
4424 added.push(makeLine(text[i], spansFor(i), estimateHeight));
4489 added.push(new Line(text[i], spansFor(i), estimateHeight));
4425 update(lastLine, lastLine.text, lastSpans);
4490 update(lastLine, lastLine.text, lastSpans);
4426 if (nlines) doc.remove(from.line, nlines);
4491 if (nlines) doc.remove(from.line, nlines);
4427 if (added.length) doc.insert(from.line, added);
4492 if (added.length) doc.insert(from.line, added);
@@ -4430,8 +4495,8 b' window.CodeMirror = (function() {'
4430 update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
4495 update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
4431 } else {
4496 } else {
4432 for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
4497 for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
4433 added.push(makeLine(text[i], spansFor(i), estimateHeight));
4498 added.push(new Line(text[i], spansFor(i), estimateHeight));
4434 added.push(makeLine(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
4499 added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
4435 update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4500 update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4436 doc.insert(from.line + 1, added);
4501 doc.insert(from.line + 1, added);
4437 }
4502 }
@@ -4442,7 +4507,7 b' window.CodeMirror = (function() {'
4442 update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4507 update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4443 update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
4508 update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
4444 for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
4509 for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
4445 added.push(makeLine(text[i], spansFor(i), estimateHeight));
4510 added.push(new Line(text[i], spansFor(i), estimateHeight));
4446 if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
4511 if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
4447 doc.insert(from.line + 1, added);
4512 doc.insert(from.line + 1, added);
4448 }
4513 }
@@ -4585,7 +4650,7 b' window.CodeMirror = (function() {'
4585 if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
4650 if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
4586 if (firstLine == null) firstLine = 0;
4651 if (firstLine == null) firstLine = 0;
4587
4652
4588 BranchChunk.call(this, [new LeafChunk([makeLine("", null)])]);
4653 BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
4589 this.first = firstLine;
4654 this.first = firstLine;
4590 this.scrollTop = this.scrollLeft = 0;
4655 this.scrollTop = this.scrollLeft = 0;
4591 this.cantEdit = false;
4656 this.cantEdit = false;
@@ -4650,6 +4715,11 b' window.CodeMirror = (function() {'
4650 getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
4715 getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
4651 getLineNumber: function(line) {return lineNo(line);},
4716 getLineNumber: function(line) {return lineNo(line);},
4652
4717
4718 getLineHandleVisualStart: function(line) {
4719 if (typeof line == "number") line = getLine(this, line);
4720 return visualLine(this, line);
4721 },
4722
4653 lineCount: function() {return this.size;},
4723 lineCount: function() {return this.size;},
4654 firstLine: function() {return this.first;},
4724 firstLine: function() {return this.first;},
4655 lastLine: function() {return this.first + this.size - 1;},
4725 lastLine: function() {return this.first + this.size - 1;},
@@ -4820,6 +4890,8 b' window.CodeMirror = (function() {'
4820 return function() {return method.apply(this.doc, arguments);};
4890 return function() {return method.apply(this.doc, arguments);};
4821 })(Doc.prototype[prop]);
4891 })(Doc.prototype[prop]);
4822
4892
4893 eventMixin(Doc);
4894
4823 function linkedDocs(doc, f, sharedHistOnly) {
4895 function linkedDocs(doc, f, sharedHistOnly) {
4824 function propagate(doc, skip, sharedHist) {
4896 function propagate(doc, skip, sharedHist) {
4825 if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
4897 if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
@@ -4963,7 +5035,8 b' window.CodeMirror = (function() {'
4963 }
5035 }
4964
5036
4965 function historyChangeFromChange(doc, change) {
5037 function historyChangeFromChange(doc, change) {
4966 var histChange = {from: change.from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
5038 var from = { line: change.from.line, ch: change.from.ch };
5039 var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
4967 attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
5040 attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
4968 linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
5041 linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
4969 return histChange;
5042 return histChange;
@@ -5183,9 +5256,9 b' window.CodeMirror = (function() {'
5183 delayedCallbacks.push(bnd(arr[i]));
5256 delayedCallbacks.push(bnd(arr[i]));
5184 }
5257 }
5185
5258
5186 function signalDOMEvent(cm, e) {
5259 function signalDOMEvent(cm, e, override) {
5187 signal(cm, e.type, cm, e);
5260 signal(cm, override || e.type, cm, e);
5188 return e_defaultPrevented(e);
5261 return e_defaultPrevented(e) || e.codemirrorIgnore;
5189 }
5262 }
5190
5263
5191 function fireDelayed() {
5264 function fireDelayed() {
@@ -5202,6 +5275,11 b' window.CodeMirror = (function() {'
5202
5275
5203 CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
5276 CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
5204
5277
5278 function eventMixin(ctor) {
5279 ctor.prototype.on = function(type, f) {on(this, type, f);};
5280 ctor.prototype.off = function(type, f) {off(this, type, f);};
5281 }
5282
5205 // MISC UTILITIES
5283 // MISC UTILITIES
5206
5284
5207 // Number of pixels added to scroller and sizer to hide scrollbar
5285 // Number of pixels added to scroller and sizer to hide scrollbar
@@ -5353,10 +5431,12 b' window.CodeMirror = (function() {'
5353 spanAffectsWrapping = function(str, i) {
5431 spanAffectsWrapping = function(str, i) {
5354 return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
5432 return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
5355 };
5433 };
5356 else if (webkit)
5434 else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
5357 spanAffectsWrapping = function(str, i) {
5435 spanAffectsWrapping = function(str, i) {
5358 if (i > 1 && str.charCodeAt(i - 1) == 45 && /\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i)))
5436 if (i > 1 && str.charCodeAt(i - 1) == 45) {
5359 return true;
5437 if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
5438 if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
5439 }
5360 return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
5440 return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
5361 };
5441 };
5362
5442
@@ -5443,11 +5523,15 b' window.CodeMirror = (function() {'
5443
5523
5444 function iterateBidiSections(order, from, to, f) {
5524 function iterateBidiSections(order, from, to, f) {
5445 if (!order) return f(from, to, "ltr");
5525 if (!order) return f(from, to, "ltr");
5526 var found = false;
5446 for (var i = 0; i < order.length; ++i) {
5527 for (var i = 0; i < order.length; ++i) {
5447 var part = order[i];
5528 var part = order[i];
5448 if (part.from < to && part.to > from || from == to && part.to == from)
5529 if (part.from < to && part.to > from || from == to && part.to == from) {
5449 f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
5530 f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
5450 }
5531 found = true;
5532 }
5533 }
5534 if (!found) f(from, to, "ltr");
5451 }
5535 }
5452
5536
5453 function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
5537 function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
@@ -5709,7 +5793,7 b' window.CodeMirror = (function() {'
5709
5793
5710 // THE END
5794 // THE END
5711
5795
5712 CodeMirror.version = "3.14.0";
5796 CodeMirror.version = "3.15.0";
5713
5797
5714 return CodeMirror;
5798 return CodeMirror;
5715 })();
5799 })();
@@ -158,7 +158,8 b' CodeMirror.defineMode("clike", function('
158 electricChars: "{}",
158 electricChars: "{}",
159 blockCommentStart: "/*",
159 blockCommentStart: "/*",
160 blockCommentEnd: "*/",
160 blockCommentEnd: "*/",
161 lineComment: "//"
161 lineComment: "//",
162 fold: "brace"
162 };
163 };
163 });
164 });
164
165
@@ -339,7 +339,8 b" CodeMirror.defineMode('coffeescript', fu"
339 return state.scopes[0].offset;
339 return state.scopes[0].offset;
340 },
340 },
341
341
342 lineComment: "#"
342 lineComment: "#",
343 fold: "indent"
343 };
344 };
344 return external;
345 return external;
345 });
346 });
@@ -103,7 +103,8 b' CodeMirror.defineMode("css-base", functi'
103 startState: function(base) {
103 startState: function(base) {
104 return {tokenize: tokenBase,
104 return {tokenize: tokenBase,
105 baseIndent: base || 0,
105 baseIndent: base || 0,
106 stack: []};
106 stack: [],
107 lastToken: null};
107 },
108 },
108
109
109 token: function(stream, state) {
110 token: function(stream, state) {
@@ -163,7 +164,7 b' CodeMirror.defineMode("css-base", functi'
163 var context = state.stack[state.stack.length-1];
164 var context = state.stack[state.stack.length-1];
164 if (style == "variable") {
165 if (style == "variable") {
165 if (type == "variable-definition") state.stack.push("propertyValue");
166 if (type == "variable-definition") state.stack.push("propertyValue");
166 return "variable-2";
167 return state.lastToken = "variable-2";
167 } else if (style == "property") {
168 } else if (style == "property") {
168 var word = stream.current().toLowerCase();
169 var word = stream.current().toLowerCase();
169 if (context == "propertyValue") {
170 if (context == "propertyValue") {
@@ -251,7 +252,6 b' CodeMirror.defineMode("css-base", functi'
251 // Push/pop context stack
252 // Push/pop context stack
252 if (type == "{") {
253 if (type == "{") {
253 if (context == "@media" || context == "@mediaType") {
254 if (context == "@media" || context == "@mediaType") {
254 state.stack.pop();
255 state.stack[state.stack.length-1] = "@media{";
255 state.stack[state.stack.length-1] = "@media{";
256 }
256 }
257 else {
257 else {
@@ -260,8 +260,7 b' CodeMirror.defineMode("css-base", functi'
260 }
260 }
261 }
261 }
262 else if (type == "}") {
262 else if (type == "}") {
263 var lastState = state.stack[state.stack.length - 1];
263 if (context == "interpolation") style = "operator";
264 if (lastState == "interpolation") style = "operator";
265 state.stack.pop();
264 state.stack.pop();
266 if (context == "propertyValue") state.stack.pop();
265 if (context == "propertyValue") state.stack.pop();
267 }
266 }
@@ -269,26 +268,44 b' CodeMirror.defineMode("css-base", functi'
269 else if (type == "@media") state.stack.push("@media");
268 else if (type == "@media") state.stack.push("@media");
270 else if (type == "@import") state.stack.push("@import");
269 else if (type == "@import") state.stack.push("@import");
271 else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
270 else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
272 state.stack.push("@mediaType");
271 state.stack[state.stack.length-1] = "@mediaType";
273 else if (context == "@mediaType" && stream.current() == ",") state.stack.pop();
272 else if (context == "@mediaType" && stream.current() == ",")
274 else if (context == "@mediaType" && type == "(") state.stack.push("@mediaType(");
273 state.stack[state.stack.length-1] = "@media";
275 else if (context == "@mediaType(" && type == ")") state.stack.pop();
274 else if (type == "(") {
276 else if ((context == "rule" || context == "block") && type == ":") state.stack.push("propertyValue");
275 if (context == "@media" || context == "@mediaType") {
276 // Make sure @mediaType is used to avoid error on {
277 state.stack[state.stack.length-1] = "@mediaType";
278 state.stack.push("@mediaType(");
279 }
280 }
281 else if (type == ")") {
282 if (context == "propertyValue" && state.stack[state.stack.length-2] == "@mediaType(") {
283 // In @mediaType( without closing ; after propertyValue
284 state.stack.pop();
285 state.stack.pop();
286 }
287 else if (context == "@mediaType(") {
288 state.stack.pop();
289 }
290 }
291 else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
277 else if (context == "propertyValue" && type == ";") state.stack.pop();
292 else if (context == "propertyValue" && type == ";") state.stack.pop();
278 else if (context == "@import" && type == ";") state.stack.pop();
293 else if (context == "@import" && type == ";") state.stack.pop();
279 return style;
294
295 return state.lastToken = style;
280 },
296 },
281
297
282 indent: function(state, textAfter) {
298 indent: function(state, textAfter) {
283 var n = state.stack.length;
299 var n = state.stack.length;
284 if (/^\}/.test(textAfter))
300 if (/^\}/.test(textAfter))
285 n -= state.stack[state.stack.length-1] == "propertyValue" ? 2 : 1;
301 n -= state.stack[n-1] == "propertyValue" ? 2 : 1;
286 return state.baseIndent + n * indentUnit;
302 return state.baseIndent + n * indentUnit;
287 },
303 },
288
304
289 electricChars: "}",
305 electricChars: "}",
290 blockCommentStart: "/*",
306 blockCommentStart: "/*",
291 blockCommentEnd: "*/"
307 blockCommentEnd: "*/",
308 fold: "brace"
292 };
309 };
293 });
310 });
294
311
@@ -384,15 +401,15 b' CodeMirror.defineMode("css-base", functi'
384 "text-decoration-color", "text-decoration-line", "text-decoration-skip",
401 "text-decoration-color", "text-decoration-line", "text-decoration-skip",
385 "text-decoration-style", "text-emphasis", "text-emphasis-color",
402 "text-decoration-style", "text-emphasis", "text-emphasis-color",
386 "text-emphasis-position", "text-emphasis-style", "text-height",
403 "text-emphasis-position", "text-emphasis-style", "text-height",
387 "text-indent", "text-justify", "text-outline", "text-shadow",
404 "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
388 "text-space-collapse", "text-transform", "text-underline-position",
405 "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
389 "text-wrap", "top", "transform", "transform-origin", "transform-style",
406 "text-wrap", "top", "transform", "transform-origin", "transform-style",
390 "transition", "transition-delay", "transition-duration",
407 "transition", "transition-delay", "transition-duration",
391 "transition-property", "transition-timing-function", "unicode-bidi",
408 "transition-property", "transition-timing-function", "unicode-bidi",
392 "vertical-align", "visibility", "voice-balance", "voice-duration",
409 "vertical-align", "visibility", "voice-balance", "voice-duration",
393 "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
410 "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
394 "voice-volume", "volume", "white-space", "widows", "width", "word-break",
411 "voice-volume", "volume", "white-space", "widows", "width", "word-break",
395 "word-spacing", "word-wrap", "z-index",
412 "word-spacing", "word-wrap", "z-index", "zoom",
396 // SVG-specific
413 // SVG-specific
397 "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
414 "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
398 "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
415 "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
@@ -64,7 +64,7 b''
64 "[tag p] { [tag a] { [property color][operator :][atom #000]; } }");
64 "[tag p] { [tag a] { [property color][operator :][atom #000]; } }");
65
65
66 MT('interpolation_in_property',
66 MT('interpolation_in_property',
67 "[tag foo] { [operator #{][variable-2 $hello][operator }:][atom #000]; }");
67 "[tag foo] { [operator #{][variable-2 $hello][operator }:][number 2]; }");
68
68
69 MT('interpolation_in_selector',
69 MT('interpolation_in_selector',
70 "[tag foo][operator #{][variable-2 $hello][operator }] { [property color][operator :][atom #000]; }");
70 "[tag foo][operator #{][variable-2 $hello][operator }] { [property color][operator :][atom #000]; }");
@@ -15,6 +15,12 b''
15 MT("atMediaCheckStack",
15 MT("atMediaCheckStack",
16 "[def @media] [attribute screen] ([property color]) { } [tag foo] { }");
16 "[def @media] [attribute screen] ([property color]) { } [tag foo] { }");
17
17
18 MT("atMediaPropertyOnly",
19 "[def @media] ([property color]) { } [tag foo] { }");
20
21 MT("atMediaCheckStackInvalidAttribute",
22 "[def @media] [attribute&error foobarhello] { [tag foo] { } }");
23
18 MT("atMediaCheckStackInvalidAttribute",
24 MT("atMediaCheckStackInvalidAttribute",
19 "[def @media] [attribute&error foobarhello] { } [tag foo] { }");
25 "[def @media] [attribute&error foobarhello] { } [tag foo] { }");
20
26
@@ -53,6 +59,10 b''
53 MT("atMediaUnknownProperty",
59 MT("atMediaUnknownProperty",
54 "[def @media] [attribute screen] [operator and] ([property&error foobarhello]) { }");
60 "[def @media] [attribute screen] [operator and] ([property&error foobarhello]) { }");
55
61
62 // Make sure nesting works with media queries
63 MT("atMediaMaxWidthNested",
64 "[def @media] [attribute screen] [operator and] ([property max-width][operator :] [number 25px]) { [tag foo] { } }");
65
56 MT("tagSelector",
66 MT("tagSelector",
57 "[tag foo] { }");
67 "[tag foo] { }");
58
68
@@ -108,6 +118,9 b''
108 MT("tagTwoProperties",
118 MT("tagTwoProperties",
109 "[tag foo] { [property margin][operator :] [number 0]; [property padding][operator :] [number 0]; }");
119 "[tag foo] { [property margin][operator :] [number 0]; [property padding][operator :] [number 0]; }");
110
120
121 MT("tagTwoPropertiesURL",
122 "[tag foo] { [property background][operator :] [string-2 url]([string //example.com/foo.png]); [property padding][operator :] [number 0]; }");
123
111 MT("commentSGML",
124 MT("commentSGML",
112 "[comment <!--comment-->]");
125 "[comment <!--comment-->]");
113 })();
126 })();
@@ -203,7 +203,8 b' CodeMirror.defineMode("groovy", function'
203 else return ctx.indented + (closing ? 0 : config.indentUnit);
203 else return ctx.indented + (closing ? 0 : config.indentUnit);
204 },
204 },
205
205
206 electricChars: "{}"
206 electricChars: "{}",
207 fold: "brace"
207 };
208 };
208 });
209 });
209
210
@@ -258,17 +258,17 b' CodeMirror.defineMode("javascript", func'
258 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
258 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
259 if (type == "{") return cont(pushlex("}"), block, poplex);
259 if (type == "{") return cont(pushlex("}"), block, poplex);
260 if (type == ";") return cont();
260 if (type == ";") return cont();
261 if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse(cx.state.indented));
261 if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
262 if (type == "function") return cont(functiondef);
262 if (type == "function") return cont(functiondef);
263 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
263 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
264 poplex, statement, poplex);
264 poplex, statement, poplex);
265 if (type == "variable") return cont(pushlex("stat"), maybelabel);
265 if (type == "variable") return cont(pushlex("stat"), maybelabel);
266 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
266 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
267 block, poplex, poplex);
267 block, poplex, poplex);
268 if (type == "case") return cont(expression, expect(":"));
268 if (type == "case") return cont(expression, expect(":"));
269 if (type == "default") return cont(expect(":"));
269 if (type == "default") return cont(expect(":"));
270 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
270 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
271 statement, poplex, popcontext);
271 statement, poplex, popcontext);
272 return pass(pushlex("stat"), expression, expect(";"), poplex);
272 return pass(pushlex("stat"), expression, expect(";"), poplex);
273 }
273 }
274 function expression(type) {
274 function expression(type) {
@@ -299,19 +299,20 b' CodeMirror.defineMode("javascript", func'
299
299
300 function maybeoperatorComma(type, value) {
300 function maybeoperatorComma(type, value) {
301 if (type == ",") return cont(expression);
301 if (type == ",") return cont(expression);
302 return maybeoperatorNoComma(type, value, maybeoperatorComma);
302 return maybeoperatorNoComma(type, value, false);
303 }
303 }
304 function maybeoperatorNoComma(type, value, me) {
304 function maybeoperatorNoComma(type, value, noComma) {
305 if (!me) me = maybeoperatorNoComma;
305 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
306 var expr = noComma == false ? expression : expressionNoComma;
306 if (type == "operator") {
307 if (type == "operator") {
307 if (/\+\+|--/.test(value)) return cont(me);
308 if (/\+\+|--/.test(value)) return cont(me);
308 if (value == "?") return cont(expression, expect(":"), expression);
309 if (value == "?") return cont(expression, expect(":"), expr);
309 return cont(expression);
310 return cont(expr);
310 }
311 }
311 if (type == ";") return;
312 if (type == ";") return;
312 if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);
313 if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);
313 if (type == ".") return cont(property, me);
314 if (type == ".") return cont(property, me);
314 if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, me);
315 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
315 }
316 }
316 function maybelabel(type) {
317 function maybelabel(type) {
317 if (type == ":") return cont(poplex, statement);
318 if (type == ":") return cont(poplex, statement);
@@ -373,14 +374,8 b' CodeMirror.defineMode("javascript", func'
373 if (value == "=") return cont(expressionNoComma, vardef2);
374 if (value == "=") return cont(expressionNoComma, vardef2);
374 if (type == ",") return cont(vardef1);
375 if (type == ",") return cont(vardef1);
375 }
376 }
376 function maybeelse(indent) {
377 function maybeelse(type, value) {
377 return function(type, value) {
378 if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
378 if (type == "keyword b" && value == "else") {
379 cx.state.lexical = new JSLexical(indent, 0, "form", null, cx.state.lexical);
380 return cont(statement, poplex);
381 }
382 return pass();
383 };
384 }
379 }
385 function forspec1(type) {
380 function forspec1(type) {
386 if (type == "var") return cont(vardef1, expect(";"), forspec2);
381 if (type == "var") return cont(vardef1, expect(";"), forspec2);
@@ -441,6 +436,12 b' CodeMirror.defineMode("javascript", func'
441 if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
436 if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
442 if (state.tokenize != jsTokenBase) return 0;
437 if (state.tokenize != jsTokenBase) return 0;
443 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
438 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
439 // Kludge to prevent 'maybelse' from blocking lexical scope pops
440 for (var i = state.cc.length - 1; i >= 0; --i) {
441 var c = state.cc[i];
442 if (c == poplex) lexical = lexical.prev;
443 else if (c != maybeelse || /^else\b/.test(textAfter)) break;
444 }
444 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
445 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
445 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
446 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
446 lexical = lexical.prev;
447 lexical = lexical.prev;
@@ -461,7 +462,9 b' CodeMirror.defineMode("javascript", func'
461 blockCommentStart: jsonMode ? null : "/*",
462 blockCommentStart: jsonMode ? null : "/*",
462 blockCommentEnd: jsonMode ? null : "*/",
463 blockCommentEnd: jsonMode ? null : "*/",
463 lineComment: jsonMode ? null : "//",
464 lineComment: jsonMode ? null : "//",
465 fold: "brace",
464
466
467 helperType: jsonMode ? "json" : "javascript",
465 jsonMode: jsonMode
468 jsonMode: jsonMode
466 };
469 };
467 });
470 });
@@ -8,7 +8,12 b''
8 <script src="../../addon/edit/continuelist.js"></script>
8 <script src="../../addon/edit/continuelist.js"></script>
9 <script src="../xml/xml.js"></script>
9 <script src="../xml/xml.js"></script>
10 <script src="markdown.js"></script>
10 <script src="markdown.js"></script>
11 <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
11 <style type="text/css">
12 .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
13 .cm-s-default .cm-trailing-space-a:before,
14 .cm-s-default .cm-trailing-space-b:before {position: absolute; content: "\00B7"; color: #777;}
15 .cm-s-default .cm-trailing-space-new-line:before {position: absolute; content: "\21B5"; color: #777;}
16 </style>
12 <link rel="stylesheet" href="../../doc/docs.css">
17 <link rel="stylesheet" href="../../doc/docs.css">
13 </head>
18 </head>
14 <body>
19 <body>
@@ -71,7 +76,7 b' Markdown:'
71
76
72 A First Level Header
77 A First Level Header
73 ====================
78 ====================
74
79
75 A Second Level Header
80 A Second Level Header
76 ---------------------
81 ---------------------
77
82
@@ -81,11 +86,11 b' Markdown:'
81
86
82 The quick brown fox jumped over the lazy
87 The quick brown fox jumped over the lazy
83 dog's back.
88 dog's back.
84
89
85 ### Header 3
90 ### Header 3
86
91
87 &gt; This is a blockquote.
92 &gt; This is a blockquote.
88 &gt;
93 &gt;
89 &gt; This is the second paragraph in the blockquote.
94 &gt; This is the second paragraph in the blockquote.
90 &gt;
95 &gt;
91 &gt; ## This is an H2 in a blockquote
96 &gt; ## This is an H2 in a blockquote
@@ -94,23 +99,23 b' Markdown:'
94 Output:
99 Output:
95
100
96 &lt;h1&gt;A First Level Header&lt;/h1&gt;
101 &lt;h1&gt;A First Level Header&lt;/h1&gt;
97
102
98 &lt;h2&gt;A Second Level Header&lt;/h2&gt;
103 &lt;h2&gt;A Second Level Header&lt;/h2&gt;
99
104
100 &lt;p&gt;Now is the time for all good men to come to
105 &lt;p&gt;Now is the time for all good men to come to
101 the aid of their country. This is just a
106 the aid of their country. This is just a
102 regular paragraph.&lt;/p&gt;
107 regular paragraph.&lt;/p&gt;
103
108
104 &lt;p&gt;The quick brown fox jumped over the lazy
109 &lt;p&gt;The quick brown fox jumped over the lazy
105 dog's back.&lt;/p&gt;
110 dog's back.&lt;/p&gt;
106
111
107 &lt;h3&gt;Header 3&lt;/h3&gt;
112 &lt;h3&gt;Header 3&lt;/h3&gt;
108
113
109 &lt;blockquote&gt;
114 &lt;blockquote&gt;
110 &lt;p&gt;This is a blockquote.&lt;/p&gt;
115 &lt;p&gt;This is a blockquote.&lt;/p&gt;
111
116
112 &lt;p&gt;This is the second paragraph in the blockquote.&lt;/p&gt;
117 &lt;p&gt;This is the second paragraph in the blockquote.&lt;/p&gt;
113
118
114 &lt;h2&gt;This is an H2 in a blockquote&lt;/h2&gt;
119 &lt;h2&gt;This is an H2 in a blockquote&lt;/h2&gt;
115 &lt;/blockquote&gt;
120 &lt;/blockquote&gt;
116
121
@@ -124,7 +129,7 b' Markdown:'
124
129
125 Some of these words *are emphasized*.
130 Some of these words *are emphasized*.
126 Some of these words _are emphasized also_.
131 Some of these words _are emphasized also_.
127
132
128 Use two asterisks for **strong emphasis**.
133 Use two asterisks for **strong emphasis**.
129 Or, if you prefer, __use two underscores instead__.
134 Or, if you prefer, __use two underscores instead__.
130
135
@@ -132,10 +137,10 b' Output:'
132
137
133 &lt;p&gt;Some of these words &lt;em&gt;are emphasized&lt;/em&gt;.
138 &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;
139 Some of these words &lt;em&gt;are emphasized also&lt;/em&gt;.&lt;/p&gt;
135
140
136 &lt;p&gt;Use two asterisks for &lt;strong&gt;strong emphasis&lt;/strong&gt;.
141 &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;
142 Or, if you prefer, &lt;strong&gt;use two underscores instead&lt;/strong&gt;.&lt;/p&gt;
138
143
139
144
140
145
141 ## Lists ##
146 ## Lists ##
@@ -188,7 +193,7 b' list item text. You can create multi-par'
188 the paragraphs by 4 spaces or 1 tab:
193 the paragraphs by 4 spaces or 1 tab:
189
194
190 * A list item.
195 * A list item.
191
196
192 With multiple paragraphs.
197 With multiple paragraphs.
193
198
194 * Another item in the list.
199 * Another item in the list.
@@ -200,7 +205,7 b' Output:'
200 &lt;p&gt;With multiple paragraphs.&lt;/p&gt;&lt;/li&gt;
205 &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;
206 &lt;li&gt;&lt;p&gt;Another item in the list.&lt;/p&gt;&lt;/li&gt;
202 &lt;/ul&gt;
207 &lt;/ul&gt;
203
208
204
209
205
210
206 ### Links ###
211 ### Links ###
@@ -295,7 +300,7 b' Output:'
295
300
296 &lt;p&gt;I strongly recommend against using any
301 &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;
302 &lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;
298
303
299 &lt;p&gt;I wish SmartyPants used named entities like
304 &lt;p&gt;I wish SmartyPants used named entities like
300 &lt;code&gt;&amp;amp;mdash;&lt;/code&gt; instead of decimal-encoded
305 &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;
306 entites like &lt;code&gt;&amp;amp;#8212;&lt;/code&gt;.&lt;/p&gt;
@@ -318,7 +323,7 b' Output:'
318
323
319 &lt;p&gt;If you want your page to validate under XHTML 1.0 Strict,
324 &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;
325 you've got to put paragraph tags in your blockquotes:&lt;/p&gt;
321
326
322 &lt;pre&gt;&lt;code&gt;&amp;lt;blockquote&amp;gt;
327 &lt;pre&gt;&lt;code&gt;&amp;lt;blockquote&amp;gt;
323 &amp;lt;p&amp;gt;For example.&amp;lt;/p&amp;gt;
328 &amp;lt;p&amp;gt;For example.&amp;lt;/p&amp;gt;
324 &amp;lt;/blockquote&amp;gt;
329 &amp;lt;/blockquote&amp;gt;
@@ -103,6 +103,9 b' CodeMirror.defineMode("markdown", functi'
103 state.f = inlineNormal;
103 state.f = inlineNormal;
104 state.block = blockNormal;
104 state.block = blockNormal;
105 }
105 }
106 // Reset state.trailingSpace
107 state.trailingSpace = 0;
108 state.trailingSpaceNewLine = false;
106 // Mark this line as blank
109 // Mark this line as blank
107 state.thisLineHasContent = false;
110 state.thisLineHasContent = false;
108 return null;
111 return null;
@@ -217,6 +220,12 b' CodeMirror.defineMode("markdown", functi'
217 }
220 }
218 }
221 }
219
222
223 if (state.trailingSpaceNewLine) {
224 styles.push("trailing-space-new-line");
225 } else if (state.trailingSpace) {
226 styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
227 }
228
220 return styles.length ? styles.join(' ') : null;
229 return styles.length ? styles.join(' ') : null;
221 }
230 }
222
231
@@ -369,6 +378,14 b' CodeMirror.defineMode("markdown", functi'
369 }
378 }
370 }
379 }
371
380
381 if (ch === ' ') {
382 if (stream.match(/ +$/, false)) {
383 state.trailingSpace++;
384 } else if (state.trailingSpace) {
385 state.trailingSpaceNewLine = true;
386 }
387 }
388
372 return getType(state);
389 return getType(state);
373 }
390 }
374
391
@@ -453,7 +470,9 b' CodeMirror.defineMode("markdown", functi'
453 taskList: false,
470 taskList: false,
454 list: false,
471 list: false,
455 listDepth: 0,
472 listDepth: 0,
456 quote: 0
473 quote: 0,
474 trailingSpace: 0,
475 trailingSpaceNewLine: false
457 };
476 };
458 },
477 },
459
478
@@ -481,6 +500,8 b' CodeMirror.defineMode("markdown", functi'
481 list: s.list,
500 list: s.list,
482 listDepth: s.listDepth,
501 listDepth: s.listDepth,
483 quote: s.quote,
502 quote: s.quote,
503 trailingSpace: s.trailingSpace,
504 trailingSpaceNewLine: s.trailingSpaceNewLine,
484 md_inside: s.md_inside
505 md_inside: s.md_inside
485 };
506 };
486 },
507 },
@@ -504,6 +525,10 b' CodeMirror.defineMode("markdown", functi'
504 // Reset state.code
525 // Reset state.code
505 state.code = false;
526 state.code = false;
506
527
528 // Reset state.trailingSpace
529 state.trailingSpace = 0;
530 state.trailingSpaceNewLine = false;
531
507 state.f = state.block;
532 state.f = state.block;
508 var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
533 var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
509 var difference = Math.floor((indentation - state.indentation) / 4) * 4;
534 var difference = Math.floor((indentation - state.indentation) / 4) * 4;
@@ -5,6 +5,20 b''
5 MT("plainText",
5 MT("plainText",
6 "foo");
6 "foo");
7
7
8 // Don't style single trailing space
9 MT("trailingSpace1",
10 "foo ");
11
12 // Two or more trailing spaces should be styled with line break character
13 MT("trailingSpace2",
14 "foo[trailing-space-a ][trailing-space-new-line ]");
15
16 MT("trailingSpace3",
17 "foo[trailing-space-a ][trailing-space-b ][trailing-space-new-line ]");
18
19 MT("trailingSpace4",
20 "foo[trailing-space-a ][trailing-space-b ][trailing-space-a ][trailing-space-new-line ]");
21
8 // Code blocks using 4 spaces (regardless of CodeMirror.tabSize value)
22 // Code blocks using 4 spaces (regardless of CodeMirror.tabSize value)
9 MT("codeBlocksUsing4Spaces",
23 MT("codeBlocksUsing4Spaces",
10 " [comment foo]");
24 " [comment foo]");
@@ -16,7 +16,7 b' CodeMirror.modeInfo = ['
16 {name: 'ECL', mime: 'text/x-ecl', mode: 'ecl'},
16 {name: 'ECL', mime: 'text/x-ecl', mode: 'ecl'},
17 {name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'},
17 {name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'},
18 {name: 'Gas', mime: 'text/x-gas', mode: 'gas'},
18 {name: 'Gas', mime: 'text/x-gas', mode: 'gas'},
19 {name: 'GitHub Flavored Markdown', mode: 'gfm'},
19 {name: 'GitHub Flavored Markdown', mime: 'text/x-gfm', mode: 'gfm'},
20 {name: 'GO', mime: 'text/x-go', mode: 'go'},
20 {name: 'GO', mime: 'text/x-go', mode: 'go'},
21 {name: 'Groovy', mime: 'text/x-groovy', mode: 'groovy'},
21 {name: 'Groovy', mime: 'text/x-groovy', mode: 'groovy'},
22 {name: 'Haskell', mime: 'text/x-haskell', mode: 'haskell'},
22 {name: 'Haskell', mime: 'text/x-haskell', mode: 'haskell'},
@@ -26,7 +26,9 b' CodeMirror.modeInfo = ['
26 {name: 'JavaServer Pages', mime: 'application/x-jsp', mode: 'htmlembedded'},
26 {name: 'JavaServer Pages', mime: 'application/x-jsp', mode: 'htmlembedded'},
27 {name: 'HTML', mime: 'text/html', mode: 'htmlmixed'},
27 {name: 'HTML', mime: 'text/html', mode: 'htmlmixed'},
28 {name: 'HTTP', mime: 'message/http', mode: 'http'},
28 {name: 'HTTP', mime: 'message/http', mode: 'http'},
29 {name: 'Jade', mime: 'text/x-jade', mode: 'jade'},
29 {name: 'JavaScript', mime: 'text/javascript', mode: 'javascript'},
30 {name: 'JavaScript', mime: 'text/javascript', mode: 'javascript'},
31 {name: 'JSON', mime: 'application/x-json', mode: 'javascript'},
30 {name: 'JSON', mime: 'application/json', mode: 'javascript'},
32 {name: 'JSON', mime: 'application/json', mode: 'javascript'},
31 {name: 'TypeScript', mime: 'application/typescript', mode: 'javascript'},
33 {name: 'TypeScript', mime: 'application/typescript', mode: 'javascript'},
32 {name: 'Jinja2', mime: 'jinja2', mode: 'jinja2'},
34 {name: 'Jinja2', mime: 'jinja2', mode: 'jinja2'},
@@ -35,6 +37,7 b' CodeMirror.modeInfo = ['
35 {name: 'Lua', mime: 'text/x-lua', mode: 'lua'},
37 {name: 'Lua', mime: 'text/x-lua', mode: 'lua'},
36 {name: 'Markdown (GitHub-flavour)', mime: 'text/x-markdown', mode: 'markdown'},
38 {name: 'Markdown (GitHub-flavour)', mime: 'text/x-markdown', mode: 'markdown'},
37 {name: 'mIRC', mime: 'text/mirc', mode: 'mirc'},
39 {name: 'mIRC', mime: 'text/mirc', mode: 'mirc'},
40 {name: 'Nginx', mime: 'text/x-nginx-conf', mode: 'nginx'},
38 {name: 'NTriples', mime: 'text/n-triples', mode: 'ntriples'},
41 {name: 'NTriples', mime: 'text/n-triples', mode: 'ntriples'},
39 {name: 'OCaml', mime: 'text/x-ocaml', mode: 'ocaml'},
42 {name: 'OCaml', mime: 'text/x-ocaml', mode: 'ocaml'},
40 {name: 'Pascal', mime: 'text/x-pascal', mode: 'pascal'},
43 {name: 'Pascal', mime: 'text/x-pascal', mode: 'pascal'},
@@ -45,6 +48,7 b' CodeMirror.modeInfo = ['
45 {name: 'Plain Text', mime: 'text/plain', mode: 'null'},
48 {name: 'Plain Text', mime: 'text/plain', mode: 'null'},
46 {name: 'Properties files', mime: 'text/x-properties', mode: 'clike'},
49 {name: 'Properties files', mime: 'text/x-properties', mode: 'clike'},
47 {name: 'Python', mime: 'text/x-python', mode: 'python'},
50 {name: 'Python', mime: 'text/x-python', mode: 'python'},
51 {name: 'Cython', mime: 'text/x-cython', mode: 'python'},
48 {name: 'R', mime: 'text/x-rsrc', mode: 'r'},
52 {name: 'R', mime: 'text/x-rsrc', mode: 'r'},
49 {name: 'reStructuredText', mime: 'text/x-rst', mode: 'rst'},
53 {name: 'reStructuredText', mime: 'text/x-rst', mode: 'rst'},
50 {name: 'Ruby', mime: 'text/x-ruby', mode: 'ruby'},
54 {name: 'Ruby', mime: 'text/x-ruby', mode: 'ruby'},
@@ -56,6 +60,7 b' CodeMirror.modeInfo = ['
56 {name: 'Sieve', mime: 'application/sieve', mode: 'sieve'},
60 {name: 'Sieve', mime: 'application/sieve', mode: 'sieve'},
57 {name: 'Smalltalk', mime: 'text/x-stsrc', mode: 'smalltalk'},
61 {name: 'Smalltalk', mime: 'text/x-stsrc', mode: 'smalltalk'},
58 {name: 'Smarty', mime: 'text/x-smarty', mode: 'smarty'},
62 {name: 'Smarty', mime: 'text/x-smarty', mode: 'smarty'},
63 {name: 'SmartyMixed', mime: 'text/x-smarty', mode: 'smartymixed'},
59 {name: 'SPARQL', mime: 'application/x-sparql-query', mode: 'sparql'},
64 {name: 'SPARQL', mime: 'application/x-sparql-query', mode: 'sparql'},
60 {name: 'SQL', mime: 'text/x-sql', mode: 'sql'},
65 {name: 'SQL', mime: 'text/x-sql', mode: 'sql'},
61 {name: 'MariaDB', mime: 'text/x-mariadb', mode: 'sql'},
66 {name: 'MariaDB', mime: 'text/x-mariadb', mode: 'sql'},
@@ -12,7 +12,7 b''
12 </head>
12 </head>
13 <body>
13 <body>
14 <h1>CodeMirror: Python mode</h1>
14 <h1>CodeMirror: Python mode</h1>
15
15 <h2>Python mode</h2>
16 <div><textarea id="code" name="code">
16 <div><textarea id="code" name="code">
17 # Literals
17 # Literals
18 1234
18 1234
@@ -102,6 +102,34 b' class ExampleClass(ParentClass):'
102 self.mixin = mixin
102 self.mixin = mixin
103
103
104 </textarea></div>
104 </textarea></div>
105
106
107 <h2>Cython mode</h2>
108
109 <div><textarea id="code-cython" name="code-cython">
110
111 import numpy as np
112 cimport cython
113 from libc.math cimport sqrt
114
115 @cython.boundscheck(False)
116 @cython.wraparound(False)
117 def pairwise_cython(double[:, ::1] X):
118 cdef int M = X.shape[0]
119 cdef int N = X.shape[1]
120 cdef double tmp, d
121 cdef double[:, ::1] D = np.empty((M, M), dtype=np.float64)
122 for i in range(M):
123 for j in range(M):
124 d = 0.0
125 for k in range(N):
126 tmp = X[i, k] - X[j, k]
127 d += tmp * tmp
128 D[i, j] = sqrt(d)
129 return np.asarray(D)
130
131 </textarea></div>
132
105 <script>
133 <script>
106 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
134 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
107 mode: {name: "python",
135 mode: {name: "python",
@@ -111,9 +139,19 b' class ExampleClass(ParentClass):'
111 indentUnit: 4,
139 indentUnit: 4,
112 tabMode: "shift",
140 tabMode: "shift",
113 matchBrackets: true
141 matchBrackets: true
142 });
143
144 CodeMirror.fromTextArea(document.getElementById("code-cython"), {
145 mode: {name: "text/x-cython",
146 version: 2,
147 singleLineStringErrors: false},
148 lineNumbers: true,
149 indentUnit: 4,
150 tabMode: "shift",
151 matchBrackets: true
114 });
152 });
115 </script>
153 </script>
116 <h2>Configuration Options:</h2>
154 <h2>Configuration Options for Python mode:</h2>
117 <ul>
155 <ul>
118 <li>version - 2/3 - The version of Python to recognize. Default is 2.</li>
156 <li>version - 2/3 - The version of Python to recognize. Default is 2.</li>
119 <li>singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.</li>
157 <li>singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.</li>
@@ -127,9 +165,11 b' class ExampleClass(ParentClass):'
127 <li>doubleDelimiters - RegEx - Regular Expressoin for double delimiters matching, default : <pre>^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&amp;=)|(\\|=)|(\\^=))</pre></li>
165 <li>doubleDelimiters - RegEx - Regular Expressoin for double delimiters matching, default : <pre>^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&amp;=)|(\\|=)|(\\^=))</pre></li>
128 <li>tripleDelimiters - RegEx - Regular Expression for triple delimiters matching, default : <pre>^((//=)|(&gt;&gt;=)|(&lt;&lt;=)|(\\*\\*=))</pre></li>
166 <li>tripleDelimiters - RegEx - Regular Expression for triple delimiters matching, default : <pre>^((//=)|(&gt;&gt;=)|(&lt;&lt;=)|(\\*\\*=))</pre></li>
129 <li>identifiers - RegEx - Regular Expression for identifier, default : <pre>^[_A-Za-z][_A-Za-z0-9]*</pre></li>
167 <li>identifiers - RegEx - Regular Expression for identifier, default : <pre>^[_A-Za-z][_A-Za-z0-9]*</pre></li>
168 <li>extra_keywords - list of string - List of extra words ton consider as keywords</li>
169 <li>extra_builtins - list of string - List of extra words ton consider as builtins</li>
130 </ul>
170 </ul>
131
171
132
172
133 <p><strong>MIME types defined:</strong> <code>text/x-python</code>.</p>
173 <p><strong>MIME types defined:</strong> <code>text/x-python</code> and <code>text/x-cython</code>.</p>
134 </body>
174 </body>
135 </html>
175 </html>
@@ -36,6 +36,12 b' CodeMirror.defineMode("python", function'
36 var py3 = {'builtins': ['ascii', 'bytes', 'exec', 'print'],
36 var py3 = {'builtins': ['ascii', 'bytes', 'exec', 'print'],
37 'keywords': ['nonlocal', 'False', 'True', 'None']};
37 'keywords': ['nonlocal', 'False', 'True', 'None']};
38
38
39 if(parserConf.extra_keywords != undefined){
40 commonkeywords = commonkeywords.concat(parserConf.extra_keywords);
41 }
42 if(parserConf.extra_builtins != undefined){
43 commonBuiltins = commonBuiltins.concat(parserConf.extra_builtins);
44 }
39 if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) {
45 if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) {
40 commonkeywords = commonkeywords.concat(py3.keywords);
46 commonkeywords = commonkeywords.concat(py3.keywords);
41 commonBuiltins = commonBuiltins.concat(py3.builtins);
47 commonBuiltins = commonBuiltins.concat(py3.builtins);
@@ -318,7 +324,7 b' CodeMirror.defineMode("python", function'
318
324
319 state.lastToken = style;
325 state.lastToken = style;
320
326
321 if (stream.eol() && stream.lambda) {
327 if (stream.eol() && state.lambda) {
322 state.lambda = false;
328 state.lambda = false;
323 }
329 }
324
330
@@ -333,9 +339,20 b' CodeMirror.defineMode("python", function'
333 return state.scopes[0].offset;
339 return state.scopes[0].offset;
334 },
340 },
335
341
336 lineComment: "#"
342 lineComment: "#",
343 fold: "indent"
337 };
344 };
338 return external;
345 return external;
339 });
346 });
340
347
341 CodeMirror.defineMIME("text/x-python", "python");
348 CodeMirror.defineMIME("text/x-python", "python");
349
350 var words = function(str){return str.split(' ');};
351
352
353 CodeMirror.defineMIME("text/x-cython", {
354 name: "python",
355 extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
356 "extern gil include nogil property public"+
357 "readonly struct union DEF IF ELIF ELSE")
358 });
@@ -1,6 +1,6 b''
1 The MIT License
1 The MIT License
2
2
3 Copyright (c) 2013 Hasan Karahan
3 Copyright (c) 2013 Hasan Karahan <hasan.karahan81@gmail.com>
4
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
6 of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 b' FITNESS FOR A PARTICULAR PURPOSE AND NON'
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
21 THE SOFTWARE. No newline at end of file
@@ -36,9 +36,11 b" CodeMirror.defineMode('rst-base', functi"
36 var TAIL = "(?:\\s*|\\W|$)",
36 var TAIL = "(?:\\s*|\\W|$)",
37 rx_TAIL = new RegExp(format('^{0}', TAIL));
37 rx_TAIL = new RegExp(format('^{0}', TAIL));
38
38
39 var NAME = "(?:[^\\W\\d_](?:[\\w\\+\\.\\-:]*[^\\W_])?)",
39 var NAME =
40 "(?:[^\\W\\d_](?:[\\w!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)",
40 rx_NAME = new RegExp(format('^{0}', NAME));
41 rx_NAME = new RegExp(format('^{0}', NAME));
41 var NAME_WWS = "(?:[^\\W\\d_](?:[\\w\\s\\+\\.\\-:]*[^\\W_])?)";
42 var NAME_WWS =
43 "(?:[^\\W\\d_](?:[\\w\\s!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)";
42 var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS);
44 var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS);
43
45
44 var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)";
46 var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)";
@@ -480,7 +482,9 b" CodeMirror.defineMode('rst-base', functi"
480 },
482 },
481
483
482 innerMode: function (state) {
484 innerMode: function (state) {
483 return {state: state.ctx.local, mode: state.ctx.mode};
485 return state.tmp ? {state: state.tmp.local, mode: state.tmp.mode}
486 : state.ctx ? {state: state.ctx.local, mode: state.ctx.mode}
487 : null;
484 },
488 },
485
489
486 token: function (stream, state) {
490 token: function (stream, state) {
@@ -494,6 +498,14 b" CodeMirror.defineMode('rst-base', functi"
494
498
495 CodeMirror.defineMode('rst', function (config, options) {
499 CodeMirror.defineMode('rst', function (config, options) {
496
500
501 var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/;
502 var rx_emphasis = /^\*[^\*\s](?:[^\*]*[^\*\s])?\*/;
503 var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``/;
504
505 var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/;
506 var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/;
507 var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/;
508
497 var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://";
509 var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://";
498 var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})";
510 var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})";
499 var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*";
511 var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*";
@@ -501,33 +513,32 b" CodeMirror.defineMode('rst', function (c"
501 rx_uri_protocol + rx_uri_domain + rx_uri_path
513 rx_uri_protocol + rx_uri_domain + rx_uri_path
502 );
514 );
503
515
504 var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*(\s+|$)/;
505 var rx_emphasis = /^[^\*]\*[^\*\s](?:[^\*]*[^\*\s])?\*(\s+|$)/;
506 var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``(\s+|$)/;
507
508 var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/;
509 var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/;
510 var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/;
511
512 var overlay = {
516 var overlay = {
513 token: function (stream) {
517 token: function (stream) {
514
518
515 if (stream.match(rx_uri)) return 'link';
519 if (stream.match(rx_strong) && stream.match (/\W+|$/, false))
516 if (stream.match(rx_strong)) return 'strong';
520 return 'strong';
517 if (stream.match(rx_emphasis)) return 'em';
521 if (stream.match(rx_emphasis) && stream.match (/\W+|$/, false))
518 if (stream.match(rx_literal)) return 'string-2';
522 return 'em';
519 if (stream.match(rx_number)) return 'number';
523 if (stream.match(rx_literal) && stream.match (/\W+|$/, false))
520 if (stream.match(rx_positive)) return 'positive';
524 return 'string-2';
521 if (stream.match(rx_negative)) return 'negative';
525 if (stream.match(rx_number))
526 return 'number';
527 if (stream.match(rx_positive))
528 return 'positive';
529 if (stream.match(rx_negative))
530 return 'negative';
531 if (stream.match(rx_uri))
532 return 'link';
522
533
523 while (stream.next() != null) {
534 while (stream.next() != null) {
524 if (stream.match(rx_uri, false)) break;
525 if (stream.match(rx_strong, false)) break;
535 if (stream.match(rx_strong, false)) break;
526 if (stream.match(rx_emphasis, false)) break;
536 if (stream.match(rx_emphasis, false)) break;
527 if (stream.match(rx_literal, false)) break;
537 if (stream.match(rx_literal, false)) break;
528 if (stream.match(rx_number, false)) break;
538 if (stream.match(rx_number, false)) break;
529 if (stream.match(rx_positive, false)) break;
539 if (stream.match(rx_positive, false)) break;
530 if (stream.match(rx_negative, false)) break;
540 if (stream.match(rx_negative, false)) break;
541 if (stream.match(rx_uri, false)) break;
531 }
542 }
532
543
533 return null;
544 return null;
@@ -36,11 +36,11 b' CodeMirror.defineMode("ruby", function(c'
36 } else if (ch == "/" && !stream.eol() && stream.peek() != " ") {
36 } else if (ch == "/" && !stream.eol() && stream.peek() != " ") {
37 return chain(readQuoted(ch, "string-2", true), stream, state);
37 return chain(readQuoted(ch, "string-2", true), stream, state);
38 } else if (ch == "%") {
38 } else if (ch == "%") {
39 var style = "string", embed = false;
39 var style = "string", embed = true;
40 if (stream.eat("s")) style = "atom";
40 if (stream.eat("s")) style = "atom";
41 else if (stream.eat(/[WQ]/)) { style = "string"; embed = true; }
41 else if (stream.eat(/[WQ]/)) style = "string";
42 else if (stream.eat(/[r]/)) { style = "string-2"; embed = true; }
42 else if (stream.eat(/[r]/)) style = "string-2";
43 else if (stream.eat(/[wxq]/)) style = "string";
43 else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
44 var delim = stream.eat(/[^\w\s]/);
44 var delim = stream.eat(/[^\w\s]/);
45 if (!delim) return "operator";
45 if (!delim) return "operator";
46 if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
46 if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
@@ -428,7 +428,8 b' CodeMirror.defineMode("rust", function()'
428 electricChars: "{}",
428 electricChars: "{}",
429 blockCommentStart: "/*",
429 blockCommentStart: "/*",
430 blockCommentEnd: "*/",
430 blockCommentEnd: "*/",
431 lineComment: "//"
431 lineComment: "//",
432 fold: "brace"
432 };
433 };
433 });
434 });
434
435
@@ -36,8 +36,13 b" CodeMirror.defineMode('smalltalk', funct"
36 token = nextString(stream, new Context(nextString, context));
36 token = nextString(stream, new Context(nextString, context));
37
37
38 } else if (aChar === '#') {
38 } else if (aChar === '#') {
39 stream.eatWhile(/[^ .\[\]()]/);
39 if (stream.peek() === '\'') {
40 token.name = 'string-2';
40 stream.next();
41 token = nextSymbol(stream, new Context(nextSymbol, context));
42 } else {
43 stream.eatWhile(/[^ .\[\]()]/);
44 token.name = 'string-2';
45 }
41
46
42 } else if (aChar === '$') {
47 } else if (aChar === '$') {
43 if (stream.next() === '<') {
48 if (stream.next() === '<') {
@@ -89,6 +94,11 b" CodeMirror.defineMode('smalltalk', funct"
89 return new Token('string', stream.eat('\'') ? context.parent : context, false);
94 return new Token('string', stream.eat('\'') ? context.parent : context, false);
90 };
95 };
91
96
97 var nextSymbol = function(stream, context) {
98 stream.eatWhile(/[^']/);
99 return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
100 };
101
92 var nextTemporaries = function(stream, context) {
102 var nextTemporaries = function(stream, context) {
93 var token = new Token(null, context, false);
103 var token = new Token(null, context, false);
94 var aChar = stream.next();
104 var aChar = stream.next();
@@ -6,10 +6,12 b' CodeMirror.defineMode("sparql", function'
6 return new RegExp("^(?:" + words.join("|") + ")$", "i");
6 return new RegExp("^(?:" + words.join("|") + ")$", "i");
7 }
7 }
8 var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
8 var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
9 "isblank", "isliteral", "union", "a"]);
9 "isblank", "isliteral", "a"]);
10 var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
10 var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
11 "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
11 "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
12 "graph", "by", "asc", "desc"]);
12 "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group",
13 "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union",
14 "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]);
13 var operatorChars = /[*+\-<>=&|]/;
15 var operatorChars = /[*+\-<>=&|]/;
14
16
15 function tokenBase(stream, state) {
17 function tokenBase(stream, state) {
@@ -23,19 +23,21 b' Const ForReading = 1, ForWriting = 2, Fo'
23 Call Sub020_PostBroadcastToUrbanAirship(strUserName, strPassword, intTransmitID, strResponse)
23 Call Sub020_PostBroadcastToUrbanAirship(strUserName, strPassword, intTransmitID, strResponse)
24
24
25 If Not IsNull(strResponse) AND Len(strResponse) = 0 Then
25 If Not IsNull(strResponse) AND Len(strResponse) = 0 Then
26 boolTransmitOkYN = False
26 boolTransmitOkYN = False
27 Else
27 Else
28 ' WScript.Echo "Oh Happy Day! Oh Happy DAY!"
28 ' WScript.Echo "Oh Happy Day! Oh Happy DAY!"
29 boolTransmitOkYN = True
29 boolTransmitOkYN = True
30 End If
30 End If
31 </textarea></div>
31 </textarea></div>
32
32
33 <script>
33 <script>
34 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
34 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
35 lineNumbers: true
35 lineNumbers: true,
36 indentUnit: 4
36 });
37 });
37 </script>
38 </script>
38
39
39 <p><strong>MIME types defined:</strong> <code>text/vbscript</code>.</p>
40 <p><strong>MIME types defined:</strong> <code>text/vbscript</code>.</p>
40 </body>
41 </body>
41 </html>
42 </html>
43
@@ -1,26 +1,334 b''
1 CodeMirror.defineMode("vbscript", function() {
1 /*
2 var regexVBScriptKeyword = /^(?:Call|Case|CDate|Clear|CInt|CLng|Const|CStr|Description|Dim|Do|Each|Else|ElseIf|End|Err|Error|Exit|False|For|Function|If|LCase|Loop|LTrim|Next|Nothing|Now|Number|On|Preserve|Quit|ReDim|Resume|RTrim|Select|Set|Sub|Then|To|Trim|True|UBound|UCase|Until|VbCr|VbCrLf|VbLf|VbTab)$/im;
2 For extra ASP classic objects, initialize CodeMirror instance with this option:
3 isASP: true
4
5 E.G.:
6 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
7 lineNumbers: true,
8 isASP: true
9 });
10 */
11 CodeMirror.defineMode("vbscript", function(conf, parserConf) {
12 var ERRORCLASS = 'error';
13
14 function wordRegexp(words) {
15 return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
16 }
17
18 var singleOperators = new RegExp("^[\\+\\-\\*/&\\\\\\^<>=]");
19 var doubleOperators = new RegExp("^((<>)|(<=)|(>=))");
20 var singleDelimiters = new RegExp('^[\\.,]');
21 var brakets = new RegExp('^[\\(\\)]');
22 var identifiers = new RegExp("^[A-Za-z][_A-Za-z0-9]*");
23
24 var openingKeywords = ['class','sub','select','while','if','function', 'property', 'with', 'for'];
25 var middleKeywords = ['else','elseif','case'];
26 var endKeywords = ['next','loop','wend'];
27
28 var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'is', 'mod', 'eqv', 'imp']);
29 var commonkeywords = ['dim', 'redim', 'then', 'until', 'randomize',
30 'byval','byref','new','property', 'exit', 'in',
31 'const','private', 'public',
32 'get','set','let', 'stop', 'on error resume next', 'on error goto 0', 'option explicit', 'call', 'me'];
33
34 //This list was from: http://msdn.microsoft.com/en-us/library/f8tbc79x(v=vs.84).aspx
35 var atomWords = ['true', 'false', 'nothing', 'empty', 'null'];
36 //This list was from: http://msdn.microsoft.com/en-us/library/3ca8tfek(v=vs.84).aspx
37 var builtinFuncsWords = ['abs', 'array', 'asc', 'atn', 'cbool', 'cbyte', 'ccur', 'cdate', 'cdbl', 'chr', 'cint', 'clng', 'cos', 'csng', 'cstr', 'date', 'dateadd', 'datediff', 'datepart',
38 'dateserial', 'datevalue', 'day', 'escape', 'eval', 'execute', 'exp', 'filter', 'formatcurrency', 'formatdatetime', 'formatnumber', 'formatpercent', 'getlocale', 'getobject',
39 'getref', 'hex', 'hour', 'inputbox', 'instr', 'instrrev', 'int', 'fix', 'isarray', 'isdate', 'isempty', 'isnull', 'isnumeric', 'isobject', 'join', 'lbound', 'lcase', 'left',
40 'len', 'loadpicture', 'log', 'ltrim', 'rtrim', 'trim', 'maths', 'mid', 'minute', 'month', 'monthname', 'msgbox', 'now', 'oct', 'replace', 'rgb', 'right', 'rnd', 'round',
41 'scriptengine', 'scriptenginebuildversion', 'scriptenginemajorversion', 'scriptengineminorversion', 'second', 'setlocale', 'sgn', 'sin', 'space', 'split', 'sqr', 'strcomp',
42 'string', 'strreverse', 'tan', 'time', 'timer', 'timeserial', 'timevalue', 'typename', 'ubound', 'ucase', 'unescape', 'vartype', 'weekday', 'weekdayname', 'year'];
43
44 //This list was from: http://msdn.microsoft.com/en-us/library/ydz4cfk3(v=vs.84).aspx
45 var builtinConsts = ['vbBlack', 'vbRed', 'vbGreen', 'vbYellow', 'vbBlue', 'vbMagenta', 'vbCyan', 'vbWhite', 'vbBinaryCompare', 'vbTextCompare',
46 'vbSunday', 'vbMonday', 'vbTuesday', 'vbWednesday', 'vbThursday', 'vbFriday', 'vbSaturday', 'vbUseSystemDayOfWeek', 'vbFirstJan1', 'vbFirstFourDays', 'vbFirstFullWeek',
47 'vbGeneralDate', 'vbLongDate', 'vbShortDate', 'vbLongTime', 'vbShortTime', 'vbObjectError',
48 'vbOKOnly', 'vbOKCancel', 'vbAbortRetryIgnore', 'vbYesNoCancel', 'vbYesNo', 'vbRetryCancel', 'vbCritical', 'vbQuestion', 'vbExclamation', 'vbInformation', 'vbDefaultButton1', 'vbDefaultButton2',
49 'vbDefaultButton3', 'vbDefaultButton4', 'vbApplicationModal', 'vbSystemModal', 'vbOK', 'vbCancel', 'vbAbort', 'vbRetry', 'vbIgnore', 'vbYes', 'vbNo',
50 'vbCr', 'VbCrLf', 'vbFormFeed', 'vbLf', 'vbNewLine', 'vbNullChar', 'vbNullString', 'vbTab', 'vbVerticalTab', 'vbUseDefault', 'vbTrue', 'vbFalse',
51 'vbEmpty', 'vbNull', 'vbInteger', 'vbLong', 'vbSingle', 'vbDouble', 'vbCurrency', 'vbDate', 'vbString', 'vbObject', 'vbError', 'vbBoolean', 'vbVariant', 'vbDataObject', 'vbDecimal', 'vbByte', 'vbArray'];
52 //This list was from: http://msdn.microsoft.com/en-us/library/hkc375ea(v=vs.84).aspx
53 var builtinObjsWords = ['WScript', 'err', 'debug', 'RegExp'];
54 var knownProperties = ['description', 'firstindex', 'global', 'helpcontext', 'helpfile', 'ignorecase', 'length', 'number', 'pattern', 'source', 'value', 'count'];
55 var knownMethods = ['clear', 'execute', 'raise', 'replace', 'test', 'write', 'writeline', 'close', 'open', 'state', 'eof', 'update', 'addnew', 'end', 'createobject', 'quit'];
56
57 var aspBuiltinObjsWords = ['server', 'response', 'request', 'session', 'application'];
58 var aspKnownProperties = ['buffer', 'cachecontrol', 'charset', 'contenttype', 'expires', 'expiresabsolute', 'isclientconnected', 'pics', 'status', //response
59 'clientcertificate', 'cookies', 'form', 'querystring', 'servervariables', 'totalbytes', //request
60 'contents', 'staticobjects', //application
61 'codepage', 'lcid', 'sessionid', 'timeout', //session
62 'scripttimeout']; //server
63 var aspKnownMethods = ['addheader', 'appendtolog', 'binarywrite', 'end', 'flush', 'redirect', //response
64 'binaryread', //request
65 'remove', 'removeall', 'lock', 'unlock', //application
66 'abandon', //session
67 'getlasterror', 'htmlencode', 'mappath', 'transfer', 'urlencode']; //server
68
69 var knownWords = knownMethods.concat(knownProperties);
70
71 builtinObjsWords = builtinObjsWords.concat(builtinConsts);
72
73 if (conf.isASP){
74 builtinObjsWords = builtinObjsWords.concat(aspBuiltinObjsWords);
75 knownWords = knownWords.concat(aspKnownMethods, aspKnownProperties);
76 };
77
78 var keywords = wordRegexp(commonkeywords);
79 var atoms = wordRegexp(atomWords);
80 var builtinFuncs = wordRegexp(builtinFuncsWords);
81 var builtinObjs = wordRegexp(builtinObjsWords);
82 var known = wordRegexp(knownWords);
83 var stringPrefixes = '"';
84
85 var opening = wordRegexp(openingKeywords);
86 var middle = wordRegexp(middleKeywords);
87 var closing = wordRegexp(endKeywords);
88 var doubleClosing = wordRegexp(['end']);
89 var doOpening = wordRegexp(['do']);
90 var noIndentWords = wordRegexp(['on error resume next', 'exit']);
91 var comment = wordRegexp(['rem']);
92
93
94 function indent(_stream, state) {
95 state.currentIndent++;
96 }
97
98 function dedent(_stream, state) {
99 state.currentIndent--;
100 }
101 // tokenizers
102 function tokenBase(stream, state) {
103 if (stream.eatSpace()) {
104 return 'space';
105 //return null;
106 }
107
108 var ch = stream.peek();
109
110 // Handle Comments
111 if (ch === "'") {
112 stream.skipToEnd();
113 return 'comment';
114 }
115 if (stream.match(comment)){
116 stream.skipToEnd();
117 return 'comment';
118 }
119
120
121 // Handle Number Literals
122 if (stream.match(/^((&H)|(&O))?[0-9\.]/i, false) && !stream.match(/^((&H)|(&O))?[0-9\.]+[a-z_]/i, false)) {
123 var floatLiteral = false;
124 // Floats
125 if (stream.match(/^\d*\.\d+/i)) { floatLiteral = true; }
126 else if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
127 else if (stream.match(/^\.\d+/)) { floatLiteral = true; }
128
129 if (floatLiteral) {
130 // Float literals may be "imaginary"
131 stream.eat(/J/i);
132 return 'number';
133 }
134 // Integers
135 var intLiteral = false;
136 // Hex
137 if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; }
138 // Octal
139 else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; }
140 // Decimal
141 else if (stream.match(/^[1-9]\d*F?/)) {
142 // Decimal literals may be "imaginary"
143 stream.eat(/J/i);
144 // TODO - Can you have imaginary longs?
145 intLiteral = true;
146 }
147 // Zero by itself with no other piece of number.
148 else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
149 if (intLiteral) {
150 // Integer literals may be "long"
151 stream.eat(/L/i);
152 return 'number';
153 }
154 }
155
156 // Handle Strings
157 if (stream.match(stringPrefixes)) {
158 state.tokenize = tokenStringFactory(stream.current());
159 return state.tokenize(stream, state);
160 }
3
161
4 return {
162 // Handle operators and Delimiters
5 token: function(stream) {
163 if (stream.match(doubleOperators)
6 if (stream.eatSpace()) return null;
164 || stream.match(singleOperators)
7 var ch = stream.next();
165 || stream.match(wordOperators)) {
8 if (ch == "'") {
166 return 'operator';
9 stream.skipToEnd();
167 }
10 return "comment";
168 if (stream.match(singleDelimiters)) {
11 }
169 return null;
12 if (ch == '"') {
170 }
13 stream.skipTo('"');
171
14 return "string";
172 if (stream.match(brakets)) {
15 }
173 return "bracket";
174 }
175
176 if (stream.match(noIndentWords)) {
177 state.doInCurrentLine = true;
178
179 return 'keyword';
180 }
181
182 if (stream.match(doOpening)) {
183 indent(stream,state);
184 state.doInCurrentLine = true;
185
186 return 'keyword';
187 }
188 if (stream.match(opening)) {
189 if (! state.doInCurrentLine)
190 indent(stream,state);
191 else
192 state.doInCurrentLine = false;
193
194 return 'keyword';
195 }
196 if (stream.match(middle)) {
197 return 'keyword';
198 }
199
200
201 if (stream.match(doubleClosing)) {
202 dedent(stream,state);
203 dedent(stream,state);
204
205 return 'keyword';
206 }
207 if (stream.match(closing)) {
208 if (! state.doInCurrentLine)
209 dedent(stream,state);
210 else
211 state.doInCurrentLine = false;
212
213 return 'keyword';
214 }
215
216 if (stream.match(keywords)) {
217 return 'keyword';
218 }
219
220 if (stream.match(atoms)) {
221 return 'atom';
222 }
223
224 if (stream.match(known)) {
225 return 'variable-2';
226 }
227
228 if (stream.match(builtinFuncs)) {
229 return 'builtin';
230 }
231
232 if (stream.match(builtinObjs)){
233 return 'variable-2';
234 }
235
236 if (stream.match(identifiers)) {
237 return 'variable';
238 }
239
240 // Handle non-detected items
241 stream.next();
242 return ERRORCLASS;
243 }
16
244
17 if (/\w/.test(ch)) {
245 function tokenStringFactory(delimiter) {
18 stream.eatWhile(/\w/);
246 var singleline = delimiter.length == 1;
19 if (regexVBScriptKeyword.test(stream.current())) return "keyword";
247 var OUTCLASS = 'string';
20 }
248
21 return null;
249 return function(stream, state) {
250 while (!stream.eol()) {
251 stream.eatWhile(/[^'"]/);
252 if (stream.match(delimiter)) {
253 state.tokenize = tokenBase;
254 return OUTCLASS;
255 } else {
256 stream.eat(/['"]/);
257 }
258 }
259 if (singleline) {
260 if (parserConf.singleLineStringErrors) {
261 return ERRORCLASS;
262 } else {
263 state.tokenize = tokenBase;
264 }
265 }
266 return OUTCLASS;
267 };
22 }
268 }
23 };
269
270
271 function tokenLexer(stream, state) {
272 var style = state.tokenize(stream, state);
273 var current = stream.current();
274
275 // Handle '.' connected identifiers
276 if (current === '.') {
277 style = state.tokenize(stream, state);
278
279 current = stream.current();
280 if (style.substr(0, 8) === 'variable' || style==='builtin' || style==='keyword'){//|| knownWords.indexOf(current.substring(1)) > -1) {
281 if (style === 'builtin' || style === 'keyword') style='variable';
282 if (knownWords.indexOf(current.substr(1)) > -1) style='variable-2';
283
284 return style;
285 } else {
286 return ERRORCLASS;
287 }
288 }
289
290 return style;
291 }
292
293 var external = {
294 electricChars:"dDpPtTfFeE ",
295 startState: function() {
296 return {
297 tokenize: tokenBase,
298 lastToken: null,
299 currentIndent: 0,
300 nextLineIndent: 0,
301 doInCurrentLine: false,
302 ignoreKeyword: false
303
304
305 };
306 },
307
308 token: function(stream, state) {
309 if (stream.sol()) {
310 state.currentIndent += state.nextLineIndent;
311 state.nextLineIndent = 0;
312 state.doInCurrentLine = 0;
313 }
314 var style = tokenLexer(stream, state);
315
316 state.lastToken = {style:style, content: stream.current()};
317
318 if (style==='space') style=null;
319
320 return style;
321 },
322
323 indent: function(state, textAfter) {
324 var trueText = textAfter.replace(/^\s+|\s+$/g, '') ;
325 if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1);
326 if(state.currentIndent < 0) return 0;
327 return state.currentIndent * conf.indentUnit;
328 }
329
330 };
331 return external;
24 });
332 });
25
333
26 CodeMirror.defineMIME("text/vbscript", "vbscript");
334 CodeMirror.defineMIME("text/vbscript", "vbscript");
@@ -1,6 +1,7 b''
1 CodeMirror.defineMode("xml", function(config, parserConfig) {
1 CodeMirror.defineMode("xml", function(config, parserConfig) {
2 var indentUnit = config.indentUnit;
2 var indentUnit = config.indentUnit;
3 var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
3 var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
4 var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true;
4
5
5 var Kludges = parserConfig.htmlMode ? {
6 var Kludges = parserConfig.htmlMode ? {
6 autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
7 autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
@@ -111,6 +112,7 b' CodeMirror.defineMode("xml", function(co'
111 return "error";
112 return "error";
112 } else if (/[\'\"]/.test(ch)) {
113 } else if (/[\'\"]/.test(ch)) {
113 state.tokenize = inAttribute(ch);
114 state.tokenize = inAttribute(ch);
115 state.stringStartCol = stream.column();
114 return state.tokenize(stream, state);
116 return state.tokenize(stream, state);
115 } else {
117 } else {
116 stream.eatWhile(/[^\s\u00a0=<>\"\']/);
118 stream.eatWhile(/[^\s\u00a0=<>\"\']/);
@@ -119,7 +121,7 b' CodeMirror.defineMode("xml", function(co'
119 }
121 }
120
122
121 function inAttribute(quote) {
123 function inAttribute(quote) {
122 return function(stream, state) {
124 var closure = function(stream, state) {
123 while (!stream.eol()) {
125 while (!stream.eol()) {
124 if (stream.next() == quote) {
126 if (stream.next() == quote) {
125 state.tokenize = inTag;
127 state.tokenize = inTag;
@@ -128,6 +130,8 b' CodeMirror.defineMode("xml", function(co'
128 }
130 }
129 return "string";
131 return "string";
130 };
132 };
133 closure.isInAttribute = true;
134 return closure;
131 }
135 }
132
136
133 function inBlock(style, terminator) {
137 function inBlock(style, terminator) {
@@ -299,10 +303,20 b' CodeMirror.defineMode("xml", function(co'
299
303
300 indent: function(state, textAfter, fullLine) {
304 indent: function(state, textAfter, fullLine) {
301 var context = state.context;
305 var context = state.context;
306 // Indent multi-line strings (e.g. css).
307 if (state.tokenize.isInAttribute) {
308 return state.stringStartCol + 1;
309 }
302 if ((state.tokenize != inTag && state.tokenize != inText) ||
310 if ((state.tokenize != inTag && state.tokenize != inText) ||
303 context && context.noIndent)
311 context && context.noIndent)
304 return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
312 return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
305 if (state.tagName) return state.tagStart + indentUnit * multilineTagIndentFactor;
313 // Indent the starts of attribute names.
314 if (state.tagName) {
315 if (multilineTagIndentPastTag)
316 return state.tagStart + state.tagName.length + 2;
317 else
318 return state.tagStart + indentUnit * multilineTagIndentFactor;
319 }
306 if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
320 if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
307 if (context && /^<\//.test(textAfter))
321 if (context && /^<\//.test(textAfter))
308 context = context.prev;
322 context = context.prev;
@@ -316,7 +330,8 b' CodeMirror.defineMode("xml", function(co'
316 blockCommentStart: "<!--",
330 blockCommentStart: "<!--",
317 blockCommentEnd: "-->",
331 blockCommentEnd: "-->",
318
332
319 configuration: parserConfig.htmlMode ? "html" : "xml"
333 configuration: parserConfig.htmlMode ? "html" : "xml",
334 helperType: parserConfig.htmlMode ? "html" : "xml"
320 };
335 };
321 });
336 });
322
337
General Comments 0
You need to be logged in to leave comments. Login now