codemirror-rails 2.24 → 2.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
});
|