codemirror-rails 2.24 → 2.32
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Rakefile +19 -0
- data/codemirror-rails.gemspec +6 -1
- data/lib/codemirror/rails/version.rb +2 -2
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/.gitkeep +0 -0
- data/test/dummy/app/models/.gitkeep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +56 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/lib/assets/.gitkeep +0 -0
- data/test/dummy/log/.gitkeep +0 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/codemirror_rails_integration_test.rb +13 -0
- data/test/test_helper.rb +13 -0
- data/vendor/assets/javascripts/codemirror.js +381 -197
- data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +1 -1
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +649 -94
- data/vendor/assets/javascripts/codemirror/modes/clike.js +53 -7
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +12 -7
- data/vendor/assets/javascripts/codemirror/modes/diff.js +24 -5
- data/vendor/assets/javascripts/codemirror/modes/ecl.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/erlang.js +463 -0
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +38 -2
- data/vendor/assets/javascripts/codemirror/modes/go.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/groovy.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/haxe.js +432 -0
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/less.js +93 -93
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +29 -6
- data/vendor/assets/javascripts/codemirror/modes/mysql.js +6 -8
- data/vendor/assets/javascripts/codemirror/modes/ocaml.js +114 -0
- data/vendor/assets/javascripts/codemirror/modes/pascal.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/pig.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/plsql.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/python.js +13 -16
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +3 -8
- data/vendor/assets/javascripts/codemirror/modes/scheme.js +74 -46
- data/vendor/assets/javascripts/codemirror/modes/shell.js +22 -7
- data/vendor/assets/javascripts/codemirror/modes/stex.js +7 -5
- data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +14 -14
- data/vendor/assets/javascripts/codemirror/modes/vb.js +260 -0
- data/vendor/assets/javascripts/codemirror/modes/verilog.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/xml.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/xquery.js +3 -3
- data/vendor/assets/javascripts/codemirror/utils/closetag.js +24 -34
- data/vendor/assets/javascripts/codemirror/utils/dialog.js +5 -1
- data/vendor/assets/javascripts/codemirror/utils/foldcode.js +10 -5
- data/vendor/assets/javascripts/codemirror/utils/formatting.js +8 -3
- data/vendor/assets/javascripts/codemirror/utils/loadmode.js +2 -1
- data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +1 -1
- data/vendor/assets/javascripts/codemirror/utils/multiplex.js +81 -0
- data/vendor/assets/javascripts/codemirror/utils/overlay.js +2 -1
- data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +123 -0
- data/vendor/assets/javascripts/codemirror/utils/search.js +16 -12
- data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +1 -1
- data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +4 -0
- data/vendor/assets/javascripts/codemirror/utils/xml-hint.js +137 -0
- data/vendor/assets/stylesheets/codemirror.css +59 -4
- data/vendor/assets/stylesheets/codemirror/modes/tiddlywiki.css +14 -21
- data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +1 -2
- data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +21 -0
- data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +2 -3
- data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +27 -0
- data/vendor/assets/stylesheets/codemirror/utils/dialog.css +4 -0
- metadata +98 -5
- data/vendor/assets/javascripts/codemirror/modes/rpm-spec.css +0 -5
@@ -0,0 +1,260 @@
|
|
1
|
+
CodeMirror.defineMode("vb", function(conf, parserConf) {
|
2
|
+
var ERRORCLASS = 'error';
|
3
|
+
|
4
|
+
function wordRegexp(words) {
|
5
|
+
return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
|
6
|
+
}
|
7
|
+
|
8
|
+
var singleOperators = new RegExp("^[\\+\\-\\*/%&\\\\|\\^~<>!]");
|
9
|
+
var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
|
10
|
+
var doubleOperators = new RegExp("^((==)|(<>)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
|
11
|
+
var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
|
12
|
+
var tripleDelimiters = new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
|
13
|
+
var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
|
14
|
+
|
15
|
+
var openingKeywords = ['class','module', 'sub','enum','select','while','if','function', 'get','set','property'];
|
16
|
+
var middleKeywords = ['else','elseif','case'];
|
17
|
+
var endKeywords = ['next','loop'];
|
18
|
+
|
19
|
+
var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'in']);
|
20
|
+
var commonkeywords = ['as', 'dim', 'break', 'continue','optional', 'then', 'until',
|
21
|
+
'goto', 'byval','byref','new','handles','property', 'return',
|
22
|
+
'const','private', 'protected', 'friend', 'public', 'shared', 'static', 'true','false'];
|
23
|
+
var commontypes = ['integer','string','double','decimal','boolean','short','char', 'float','single'];
|
24
|
+
|
25
|
+
var keywords = wordRegexp(commonkeywords);
|
26
|
+
var types = wordRegexp(commontypes);
|
27
|
+
var stringPrefixes = '"';
|
28
|
+
|
29
|
+
var opening = wordRegexp(openingKeywords);
|
30
|
+
var middle = wordRegexp(middleKeywords);
|
31
|
+
var closing = wordRegexp(endKeywords);
|
32
|
+
var doubleClosing = wordRegexp(['end']);
|
33
|
+
var doOpening = wordRegexp(['do']);
|
34
|
+
|
35
|
+
var indentInfo = null;
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
function indent(stream, state) {
|
41
|
+
state.currentIndent++;
|
42
|
+
}
|
43
|
+
|
44
|
+
function dedent(stream, state) {
|
45
|
+
state.currentIndent--;
|
46
|
+
}
|
47
|
+
// tokenizers
|
48
|
+
function tokenBase(stream, state) {
|
49
|
+
if (stream.eatSpace()) {
|
50
|
+
return null;
|
51
|
+
}
|
52
|
+
|
53
|
+
var ch = stream.peek();
|
54
|
+
|
55
|
+
// Handle Comments
|
56
|
+
if (ch === "'") {
|
57
|
+
stream.skipToEnd();
|
58
|
+
return 'comment';
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
// Handle Number Literals
|
63
|
+
if (stream.match(/^((&H)|(&O))?[0-9\.a-f]/i, false)) {
|
64
|
+
var floatLiteral = false;
|
65
|
+
// Floats
|
66
|
+
if (stream.match(/^\d*\.\d+F?/i)) { floatLiteral = true; }
|
67
|
+
else if (stream.match(/^\d+\.\d*F?/)) { floatLiteral = true; }
|
68
|
+
else if (stream.match(/^\.\d+F?/)) { floatLiteral = true; }
|
69
|
+
|
70
|
+
if (floatLiteral) {
|
71
|
+
// Float literals may be "imaginary"
|
72
|
+
stream.eat(/J/i);
|
73
|
+
return 'number';
|
74
|
+
}
|
75
|
+
// Integers
|
76
|
+
var intLiteral = false;
|
77
|
+
// Hex
|
78
|
+
if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; }
|
79
|
+
// Octal
|
80
|
+
else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; }
|
81
|
+
// Decimal
|
82
|
+
else if (stream.match(/^[1-9]\d*F?/)) {
|
83
|
+
// Decimal literals may be "imaginary"
|
84
|
+
stream.eat(/J/i);
|
85
|
+
// TODO - Can you have imaginary longs?
|
86
|
+
intLiteral = true;
|
87
|
+
}
|
88
|
+
// Zero by itself with no other piece of number.
|
89
|
+
else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
|
90
|
+
if (intLiteral) {
|
91
|
+
// Integer literals may be "long"
|
92
|
+
stream.eat(/L/i);
|
93
|
+
return 'number';
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
// Handle Strings
|
98
|
+
if (stream.match(stringPrefixes)) {
|
99
|
+
state.tokenize = tokenStringFactory(stream.current());
|
100
|
+
return state.tokenize(stream, state);
|
101
|
+
}
|
102
|
+
|
103
|
+
// Handle operators and Delimiters
|
104
|
+
if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
|
105
|
+
return null;
|
106
|
+
}
|
107
|
+
if (stream.match(doubleOperators)
|
108
|
+
|| stream.match(singleOperators)
|
109
|
+
|| stream.match(wordOperators)) {
|
110
|
+
return 'operator';
|
111
|
+
}
|
112
|
+
if (stream.match(singleDelimiters)) {
|
113
|
+
return null;
|
114
|
+
}
|
115
|
+
if (stream.match(doOpening)) {
|
116
|
+
indent(stream,state);
|
117
|
+
state.doInCurrentLine = true;
|
118
|
+
return 'keyword';
|
119
|
+
}
|
120
|
+
if (stream.match(opening)) {
|
121
|
+
if (! state.doInCurrentLine)
|
122
|
+
indent(stream,state);
|
123
|
+
else
|
124
|
+
state.doInCurrentLine = false;
|
125
|
+
return 'keyword';
|
126
|
+
}
|
127
|
+
if (stream.match(middle)) {
|
128
|
+
return 'keyword';
|
129
|
+
}
|
130
|
+
|
131
|
+
if (stream.match(doubleClosing)) {
|
132
|
+
dedent(stream,state);
|
133
|
+
dedent(stream,state);
|
134
|
+
return 'keyword';
|
135
|
+
}
|
136
|
+
if (stream.match(closing)) {
|
137
|
+
dedent(stream,state);
|
138
|
+
return 'keyword';
|
139
|
+
}
|
140
|
+
|
141
|
+
if (stream.match(types)) {
|
142
|
+
return 'keyword';
|
143
|
+
}
|
144
|
+
|
145
|
+
if (stream.match(keywords)) {
|
146
|
+
return 'keyword';
|
147
|
+
}
|
148
|
+
|
149
|
+
if (stream.match(identifiers)) {
|
150
|
+
return 'variable';
|
151
|
+
}
|
152
|
+
|
153
|
+
// Handle non-detected items
|
154
|
+
stream.next();
|
155
|
+
return ERRORCLASS;
|
156
|
+
}
|
157
|
+
|
158
|
+
function tokenStringFactory(delimiter) {
|
159
|
+
var singleline = delimiter.length == 1;
|
160
|
+
var OUTCLASS = 'string';
|
161
|
+
|
162
|
+
return function tokenString(stream, state) {
|
163
|
+
while (!stream.eol()) {
|
164
|
+
stream.eatWhile(/[^'"]/);
|
165
|
+
if (stream.match(delimiter)) {
|
166
|
+
state.tokenize = tokenBase;
|
167
|
+
return OUTCLASS;
|
168
|
+
} else {
|
169
|
+
stream.eat(/['"]/);
|
170
|
+
}
|
171
|
+
}
|
172
|
+
if (singleline) {
|
173
|
+
if (parserConf.singleLineStringErrors) {
|
174
|
+
return ERRORCLASS;
|
175
|
+
} else {
|
176
|
+
state.tokenize = tokenBase;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
return OUTCLASS;
|
180
|
+
};
|
181
|
+
}
|
182
|
+
|
183
|
+
|
184
|
+
function tokenLexer(stream, state) {
|
185
|
+
var style = state.tokenize(stream, state);
|
186
|
+
var current = stream.current();
|
187
|
+
|
188
|
+
// Handle '.' connected identifiers
|
189
|
+
if (current === '.') {
|
190
|
+
style = state.tokenize(stream, state);
|
191
|
+
current = stream.current();
|
192
|
+
if (style === 'variable') {
|
193
|
+
return 'variable';
|
194
|
+
} else {
|
195
|
+
return ERRORCLASS;
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
|
200
|
+
var delimiter_index = '[({'.indexOf(current);
|
201
|
+
if (delimiter_index !== -1) {
|
202
|
+
indent(stream, state );
|
203
|
+
}
|
204
|
+
if (indentInfo === 'dedent') {
|
205
|
+
if (dedent(stream, state)) {
|
206
|
+
return ERRORCLASS;
|
207
|
+
}
|
208
|
+
}
|
209
|
+
delimiter_index = '])}'.indexOf(current);
|
210
|
+
if (delimiter_index !== -1) {
|
211
|
+
if (dedent(stream, state)) {
|
212
|
+
return ERRORCLASS;
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
return style;
|
217
|
+
}
|
218
|
+
|
219
|
+
var external = {
|
220
|
+
electricChars:"dDpPtTfFeE ",
|
221
|
+
startState: function(basecolumn) {
|
222
|
+
return {
|
223
|
+
tokenize: tokenBase,
|
224
|
+
lastToken: null,
|
225
|
+
currentIndent: 0,
|
226
|
+
nextLineIndent: 0,
|
227
|
+
doInCurrentLine: false
|
228
|
+
|
229
|
+
|
230
|
+
};
|
231
|
+
},
|
232
|
+
|
233
|
+
token: function(stream, state) {
|
234
|
+
if (stream.sol()) {
|
235
|
+
state.currentIndent += state.nextLineIndent;
|
236
|
+
state.nextLineIndent = 0;
|
237
|
+
state.doInCurrentLine = 0;
|
238
|
+
}
|
239
|
+
var style = tokenLexer(stream, state);
|
240
|
+
|
241
|
+
state.lastToken = {style:style, content: stream.current()};
|
242
|
+
|
243
|
+
|
244
|
+
|
245
|
+
return style;
|
246
|
+
},
|
247
|
+
|
248
|
+
indent: function(state, textAfter) {
|
249
|
+
var trueText = textAfter.replace(/^\s+|\s+$/g, '') ;
|
250
|
+
if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1);
|
251
|
+
if(state.currentIndent < 0) return 0;
|
252
|
+
return state.currentIndent * conf.indentUnit;
|
253
|
+
}
|
254
|
+
|
255
|
+
};
|
256
|
+
return external;
|
257
|
+
});
|
258
|
+
|
259
|
+
CodeMirror.defineMIME("text/x-vb", "vb");
|
260
|
+
|
@@ -312,7 +312,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
|
312
312
|
if (a.indented != b.indented || a.tokenize != b.tokenize) return false;
|
313
313
|
for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
|
314
314
|
if (!ca || !cb) return ca == cb;
|
315
|
-
if (ca.tagName != cb.tagName) return false;
|
315
|
+
if (ca.tagName != cb.tagName || ca.indent != cb.indent) return false;
|
316
316
|
}
|
317
317
|
},
|
318
318
|
|
@@ -320,6 +320,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
|
320
320
|
};
|
321
321
|
});
|
322
322
|
|
323
|
+
CodeMirror.defineMIME("text/xml", "xml");
|
323
324
|
CodeMirror.defineMIME("application/xml", "xml");
|
324
325
|
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
|
325
326
|
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
|
@@ -137,7 +137,7 @@ CodeMirror.defineMode("xquery", function(config, parserConfig) {
|
|
137
137
|
return ret("tag", "tag");
|
138
138
|
}
|
139
139
|
else
|
140
|
-
return ret("word", "
|
140
|
+
return ret("word", "variable");
|
141
141
|
}
|
142
142
|
// if a number
|
143
143
|
else if (/\d/.test(ch)) {
|
@@ -213,7 +213,7 @@ CodeMirror.defineMode("xquery", function(config, parserConfig) {
|
|
213
213
|
// if the previous word was element, attribute, axis specifier, this word should be the name of that
|
214
214
|
if(isInXmlConstructor(state)) {
|
215
215
|
popStateStack(state);
|
216
|
-
return ret("word", "
|
216
|
+
return ret("word", "variable", word);
|
217
217
|
}
|
218
218
|
// as previously checked, if the word is element,attribute, axis specifier, call it an "xmlconstructor" and
|
219
219
|
// push the stack so we know to look for it on the next word
|
@@ -221,7 +221,7 @@ CodeMirror.defineMode("xquery", function(config, parserConfig) {
|
|
221
221
|
|
222
222
|
// if the word is known, return the details of that else just call this a generic 'word'
|
223
223
|
return known ? ret(known.type, known.style, word) :
|
224
|
-
ret("word", "
|
224
|
+
ret("word", "variable", word);
|
225
225
|
}
|
226
226
|
}
|
227
227
|
|
@@ -10,7 +10,6 @@
|
|
10
10
|
* following CodeMirror modes and will ignore all others:
|
11
11
|
* - htmlmixed
|
12
12
|
* - xml
|
13
|
-
* - xmlpure
|
14
13
|
*
|
15
14
|
* See demos/closetag.html for a usage example.
|
16
15
|
*
|
@@ -24,21 +23,25 @@
|
|
24
23
|
/** Array of tag names to add indentation after the start tag for. Default is the list of block-level html tags. */
|
25
24
|
CodeMirror.defaults['closeTagIndent'] = ['applet', 'blockquote', 'body', 'button', 'div', 'dl', 'fieldset', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html', 'iframe', 'layer', 'legend', 'object', 'ol', 'p', 'select', 'table', 'ul'];
|
26
25
|
|
26
|
+
/** Array of tag names where an end tag is forbidden. */
|
27
|
+
CodeMirror.defaults['closeTagVoid'] = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
|
28
|
+
|
27
29
|
/**
|
28
30
|
* Call during key processing to close tags. Handles the key event if the tag is closed, otherwise throws CodeMirror.Pass.
|
29
31
|
* - cm: The editor instance.
|
30
32
|
* - ch: The character being processed.
|
31
|
-
* - indent: Optional. Omit or pass true to use the default indentation tag list defined in the 'closeTagIndent' option.
|
33
|
+
* - indent: Optional. An array of tag names to indent when closing. Omit or pass true to use the default indentation tag list defined in the 'closeTagIndent' option.
|
32
34
|
* Pass false to disable indentation. Pass an array to override the default list of tag names.
|
35
|
+
* - vd: Optional. An array of tag names that should not be closed. Omit to use the default void (end tag forbidden) tag list defined in the 'closeTagVoid' option. Ignored in xml mode.
|
33
36
|
*/
|
34
|
-
CodeMirror.defineExtension("closeTag", function(cm, ch, indent) {
|
37
|
+
CodeMirror.defineExtension("closeTag", function(cm, ch, indent, vd) {
|
35
38
|
if (!cm.getOption('closeTagEnabled')) {
|
36
39
|
throw CodeMirror.Pass;
|
37
40
|
}
|
38
41
|
|
39
42
|
var mode = cm.getOption('mode');
|
40
43
|
|
41
|
-
if (mode == 'text/html') {
|
44
|
+
if (mode == 'text/html' || mode == 'xml') {
|
42
45
|
|
43
46
|
/*
|
44
47
|
* Relevant structure of token:
|
@@ -48,6 +51,7 @@
|
|
48
51
|
* state
|
49
52
|
* htmlState
|
50
53
|
* type
|
54
|
+
* tagName
|
51
55
|
* context
|
52
56
|
* tagName
|
53
57
|
* mode
|
@@ -83,8 +87,8 @@
|
|
83
87
|
type = state.htmlState ? state.htmlState.type : state.type; // htmlmixed : xml
|
84
88
|
|
85
89
|
if (tok.className == 'tag' && type != 'selfcloseTag') {
|
86
|
-
var tagName = state.htmlState ? state.htmlState.
|
87
|
-
if (tagName.length > 0) {
|
90
|
+
var tagName = state.htmlState ? state.htmlState.tagName : state.tagName; // htmlmixed : xml
|
91
|
+
if (tagName.length > 0 && shouldClose(cm, vd, tagName)) {
|
88
92
|
insertEndTag(cm, indent, pos, tagName);
|
89
93
|
}
|
90
94
|
return;
|
@@ -96,7 +100,7 @@
|
|
96
100
|
|
97
101
|
} else if (ch == '/') {
|
98
102
|
if (tok.className == 'tag' && tok.string == '<') {
|
99
|
-
var tagName = state.htmlState ? (state.htmlState.context ? state.htmlState.context.tagName : '') : state.context.tagName; // htmlmixed : xml
|
103
|
+
var tagName = state.htmlState ? (state.htmlState.context ? state.htmlState.context.tagName : '') : (state.context ? state.context.tagName : ''); // htmlmixed : xml
|
100
104
|
if (tagName.length > 0) {
|
101
105
|
completeEndTag(cm, pos, tagName);
|
102
106
|
return;
|
@@ -104,33 +108,6 @@
|
|
104
108
|
}
|
105
109
|
}
|
106
110
|
|
107
|
-
} else if (mode == 'xmlpure') {
|
108
|
-
|
109
|
-
var pos = cm.getCursor();
|
110
|
-
var tok = cm.getTokenAt(pos);
|
111
|
-
var tagName = tok.state.context.tagName;
|
112
|
-
|
113
|
-
if (ch == '>') {
|
114
|
-
// <foo> tagName=foo, string=foo
|
115
|
-
// <foo /> tagName=foo, string=/ # ignore
|
116
|
-
// <foo></foo> tagName=foo, string=/foo # ignore
|
117
|
-
if (tok.string == tagName) {
|
118
|
-
cm.replaceSelection('>'); // parity w/html modes
|
119
|
-
pos = {line: pos.line, ch: pos.ch + 1};
|
120
|
-
cm.setCursor(pos);
|
121
|
-
|
122
|
-
insertEndTag(cm, indent, pos, tagName);
|
123
|
-
return;
|
124
|
-
}
|
125
|
-
|
126
|
-
} else if (ch == '/') {
|
127
|
-
// <foo / tagName=foo, string= # ignore
|
128
|
-
// <foo></ tagName=foo, string=<
|
129
|
-
if (tok.string == '<') {
|
130
|
-
completeEndTag(cm, pos, tagName);
|
131
|
-
return;
|
132
|
-
}
|
133
|
-
}
|
134
111
|
}
|
135
112
|
|
136
113
|
throw CodeMirror.Pass; // Bubble if not handled
|
@@ -158,6 +135,19 @@
|
|
158
135
|
return indexOf(indent, tagName.toLowerCase()) != -1;
|
159
136
|
}
|
160
137
|
|
138
|
+
function shouldClose(cm, vd, tagName) {
|
139
|
+
if (cm.getOption('mode') == 'xml') {
|
140
|
+
return true; // always close xml tags
|
141
|
+
}
|
142
|
+
if (typeof vd == 'undefined' || vd == null) {
|
143
|
+
vd = cm.getOption('closeTagVoid');
|
144
|
+
}
|
145
|
+
if (!vd) {
|
146
|
+
vd = [];
|
147
|
+
}
|
148
|
+
return indexOf(vd, tagName.toLowerCase()) == -1;
|
149
|
+
}
|
150
|
+
|
161
151
|
// C&P from codemirror.js...would be nice if this were visible to utilities.
|
162
152
|
function indexOf(collection, elt) {
|
163
153
|
if (collection.indexOf) return collection.indexOf(elt);
|
@@ -17,7 +17,7 @@
|
|
17
17
|
closed = true;
|
18
18
|
dialog.parentNode.removeChild(dialog);
|
19
19
|
}
|
20
|
-
var inp = dialog.getElementsByTagName("input")[0];
|
20
|
+
var inp = dialog.getElementsByTagName("input")[0], button;
|
21
21
|
if (inp) {
|
22
22
|
CodeMirror.connect(inp, "keydown", function(e) {
|
23
23
|
if (e.keyCode == 13 || e.keyCode == 27) {
|
@@ -29,6 +29,10 @@
|
|
29
29
|
});
|
30
30
|
inp.focus();
|
31
31
|
CodeMirror.connect(inp, "blur", close);
|
32
|
+
} else if (button = dialog.getElementsByTagName("button")[0]) {
|
33
|
+
CodeMirror.connect(button, "click", close);
|
34
|
+
button.focus();
|
35
|
+
CodeMirror.connect(button, "blur", close);
|
32
36
|
}
|
33
37
|
return close;
|
34
38
|
});
|