OLD | NEW |
| 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others |
| 2 // Distributed under an MIT license: http://codemirror.net/LICENSE |
| 3 |
| 4 (function(mod) { |
| 5 if (typeof exports == "object" && typeof module == "object") // CommonJS |
| 6 mod(require("../../lib/codemirror")); |
| 7 else if (typeof define == "function" && define.amd) // AMD |
| 8 define(["../../lib/codemirror"], mod); |
| 9 else // Plain browser env |
| 10 mod(CodeMirror); |
| 11 })(function(CodeMirror) { |
| 12 "use strict"; |
| 13 |
1 CodeMirror.defineMode("xml", function(config, parserConfig) { | 14 CodeMirror.defineMode("xml", function(config, parserConfig) { |
2 var indentUnit = config.indentUnit; | 15 var indentUnit = config.indentUnit; |
3 var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1; | 16 var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1; |
4 var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true
; | 17 var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag; |
| 18 if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true; |
5 | 19 |
6 var Kludges = parserConfig.htmlMode ? { | 20 var Kludges = parserConfig.htmlMode ? { |
7 autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'comm
and': true, | 21 autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'comm
and': true, |
8 'embed': true, 'frame': true, 'hr': true, 'img': true, 'in
put': true, | 22 'embed': true, 'frame': true, 'hr': true, 'img': true, 'in
put': true, |
9 'keygen': true, 'link': true, 'meta': true, 'param': true,
'source': true, | 23 'keygen': true, 'link': true, 'meta': true, 'param': true,
'source': true, |
10 'track': true, 'wbr': true}, | 24 'track': true, 'wbr': true}, |
11 implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true,
'p': true, | 25 implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true,
'p': true, |
12 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot
': true, | 26 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot
': true, |
13 'th': true, 'tr': true}, | 27 'th': true, 'tr': true}, |
14 contextGrabbers: { | 28 contextGrabbers: { |
(...skipping 11 matching lines...) Expand all Loading... |
26 'rt': {'rp': true, 'rt': true}, | 40 'rt': {'rp': true, 'rt': true}, |
27 'tbody': {'tbody': true, 'tfoot': true}, | 41 'tbody': {'tbody': true, 'tfoot': true}, |
28 'td': {'td': true, 'th': true}, | 42 'td': {'td': true, 'th': true}, |
29 'tfoot': {'tbody': true}, | 43 'tfoot': {'tbody': true}, |
30 'th': {'td': true, 'th': true}, | 44 'th': {'td': true, 'th': true}, |
31 'thead': {'tbody': true, 'tfoot': true}, | 45 'thead': {'tbody': true, 'tfoot': true}, |
32 'tr': {'tr': true} | 46 'tr': {'tr': true} |
33 }, | 47 }, |
34 doNotIndent: {"pre": true}, | 48 doNotIndent: {"pre": true}, |
35 allowUnquoted: true, | 49 allowUnquoted: true, |
36 allowMissing: true | 50 allowMissing: true, |
| 51 caseFold: true |
37 } : { | 52 } : { |
38 autoSelfClosers: {}, | 53 autoSelfClosers: {}, |
39 implicitlyClosed: {}, | 54 implicitlyClosed: {}, |
40 contextGrabbers: {}, | 55 contextGrabbers: {}, |
41 doNotIndent: {}, | 56 doNotIndent: {}, |
42 allowUnquoted: false, | 57 allowUnquoted: false, |
43 allowMissing: false | 58 allowMissing: false, |
| 59 caseFold: false |
44 }; | 60 }; |
45 var alignCDATA = parserConfig.alignCDATA; | 61 var alignCDATA = parserConfig.alignCDATA; |
46 | 62 |
47 // Return variables for tokenizers | 63 // Return variables for tokenizers |
48 var tagName, type; | 64 var type, setStyle; |
49 | 65 |
50 function inText(stream, state) { | 66 function inText(stream, state) { |
51 function chain(parser) { | 67 function chain(parser) { |
52 state.tokenize = parser; | 68 state.tokenize = parser; |
53 return parser(stream, state); | 69 return parser(stream, state); |
54 } | 70 } |
55 | 71 |
56 var ch = stream.next(); | 72 var ch = stream.next(); |
57 if (ch == "<") { | 73 if (ch == "<") { |
58 if (stream.eat("!")) { | 74 if (stream.eat("!")) { |
59 if (stream.eat("[")) { | 75 if (stream.eat("[")) { |
60 if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); | 76 if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); |
61 else return null; | 77 else return null; |
62 } else if (stream.match("--")) { | 78 } else if (stream.match("--")) { |
63 return chain(inBlock("comment", "-->")); | 79 return chain(inBlock("comment", "-->")); |
64 } else if (stream.match("DOCTYPE", true, true)) { | 80 } else if (stream.match("DOCTYPE", true, true)) { |
65 stream.eatWhile(/[\w\._\-]/); | 81 stream.eatWhile(/[\w\._\-]/); |
66 return chain(doctype(1)); | 82 return chain(doctype(1)); |
67 } else { | 83 } else { |
68 return null; | 84 return null; |
69 } | 85 } |
70 } else if (stream.eat("?")) { | 86 } else if (stream.eat("?")) { |
71 stream.eatWhile(/[\w\._\-]/); | 87 stream.eatWhile(/[\w\._\-]/); |
72 state.tokenize = inBlock("meta", "?>"); | 88 state.tokenize = inBlock("meta", "?>"); |
73 return "meta"; | 89 return "meta"; |
74 } else { | 90 } else { |
75 var isClose = stream.eat("/"); | 91 type = stream.eat("/") ? "closeTag" : "openTag"; |
76 tagName = ""; | |
77 var c; | |
78 while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; | |
79 if (!tagName) return "tag error"; | |
80 type = isClose ? "closeTag" : "openTag"; | |
81 state.tokenize = inTag; | 92 state.tokenize = inTag; |
82 return "tag"; | 93 return "tag bracket"; |
83 } | 94 } |
84 } else if (ch == "&") { | 95 } else if (ch == "&") { |
85 var ok; | 96 var ok; |
86 if (stream.eat("#")) { | 97 if (stream.eat("#")) { |
87 if (stream.eat("x")) { | 98 if (stream.eat("x")) { |
88 ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); | 99 ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); |
89 } else { | 100 } else { |
90 ok = stream.eatWhile(/[\d]/) && stream.eat(";"); | 101 ok = stream.eatWhile(/[\d]/) && stream.eat(";"); |
91 } | 102 } |
92 } else { | 103 } else { |
93 ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); | 104 ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); |
94 } | 105 } |
95 return ok ? "atom" : "error"; | 106 return ok ? "atom" : "error"; |
96 } else { | 107 } else { |
97 stream.eatWhile(/[^&<]/); | 108 stream.eatWhile(/[^&<]/); |
98 return null; | 109 return null; |
99 } | 110 } |
100 } | 111 } |
101 | 112 |
102 function inTag(stream, state) { | 113 function inTag(stream, state) { |
103 var ch = stream.next(); | 114 var ch = stream.next(); |
104 if (ch == ">" || (ch == "/" && stream.eat(">"))) { | 115 if (ch == ">" || (ch == "/" && stream.eat(">"))) { |
105 state.tokenize = inText; | 116 state.tokenize = inText; |
106 type = ch == ">" ? "endTag" : "selfcloseTag"; | 117 type = ch == ">" ? "endTag" : "selfcloseTag"; |
107 return "tag"; | 118 return "tag bracket"; |
108 } else if (ch == "=") { | 119 } else if (ch == "=") { |
109 type = "equals"; | 120 type = "equals"; |
110 return null; | 121 return null; |
111 } else if (ch == "<") { | 122 } else if (ch == "<") { |
112 state.tokenize = inText; | 123 state.tokenize = inText; |
| 124 state.state = baseState; |
| 125 state.tagName = state.tagStart = null; |
113 var next = state.tokenize(stream, state); | 126 var next = state.tokenize(stream, state); |
114 return next ? next + " error" : "error"; | 127 return next ? next + " tag error" : "tag error"; |
115 } else if (/[\'\"]/.test(ch)) { | 128 } else if (/[\'\"]/.test(ch)) { |
116 state.tokenize = inAttribute(ch); | 129 state.tokenize = inAttribute(ch); |
117 state.stringStartCol = stream.column(); | 130 state.stringStartCol = stream.column(); |
118 return state.tokenize(stream, state); | 131 return state.tokenize(stream, state); |
119 } else { | 132 } else { |
120 stream.eatWhile(/[^\s\u00a0=<>\"\']/); | 133 stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/); |
121 return "word"; | 134 return "word"; |
122 } | 135 } |
123 } | 136 } |
124 | 137 |
125 function inAttribute(quote) { | 138 function inAttribute(quote) { |
126 var closure = function(stream, state) { | 139 var closure = function(stream, state) { |
127 while (!stream.eol()) { | 140 while (!stream.eol()) { |
128 if (stream.next() == quote) { | 141 if (stream.next() == quote) { |
129 state.tokenize = inTag; | 142 state.tokenize = inTag; |
130 break; | 143 break; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } else { | 175 } else { |
163 state.tokenize = doctype(depth - 1); | 176 state.tokenize = doctype(depth - 1); |
164 return state.tokenize(stream, state); | 177 return state.tokenize(stream, state); |
165 } | 178 } |
166 } | 179 } |
167 } | 180 } |
168 return "meta"; | 181 return "meta"; |
169 }; | 182 }; |
170 } | 183 } |
171 | 184 |
172 var curState, curStream, setStyle; | 185 function Context(state, tagName, startOfLine) { |
173 function pass() { | 186 this.prev = state.context; |
174 for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i
]); | 187 this.tagName = tagName; |
| 188 this.indent = state.indented; |
| 189 this.startOfLine = startOfLine; |
| 190 if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.c
ontext.noIndent)) |
| 191 this.noIndent = true; |
175 } | 192 } |
176 function cont() { | 193 function popContext(state) { |
177 pass.apply(null, arguments); | 194 if (state.context) state.context = state.context.prev; |
178 return true; | |
179 } | 195 } |
180 | 196 function maybePopContext(state, nextTagName) { |
181 function pushContext(tagName, startOfLine) { | |
182 var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.cont
ext && curState.context.noIndent); | |
183 curState.context = { | |
184 prev: curState.context, | |
185 tagName: tagName, | |
186 indent: curState.indented, | |
187 startOfLine: startOfLine, | |
188 noIndent: noIndent | |
189 }; | |
190 } | |
191 function popContext() { | |
192 if (curState.context) curState.context = curState.context.prev; | |
193 } | |
194 | |
195 function element(type) { | |
196 if (type == "openTag") { | |
197 curState.tagName = tagName; | |
198 curState.tagStart = curStream.column(); | |
199 return cont(attributes, endtag(curState.startOfLine)); | |
200 } else if (type == "closeTag") { | |
201 var err = false; | |
202 if (curState.context) { | |
203 if (curState.context.tagName != tagName) { | |
204 if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.t
oLowerCase())) { | |
205 popContext(); | |
206 } | |
207 err = !curState.context || curState.context.tagName != tagName; | |
208 } | |
209 } else { | |
210 err = true; | |
211 } | |
212 if (err) setStyle = "error"; | |
213 return cont(endclosetag(err)); | |
214 } | |
215 return cont(); | |
216 } | |
217 function endtag(startOfLine) { | |
218 return function(type) { | |
219 var tagName = curState.tagName; | |
220 curState.tagName = curState.tagStart = null; | |
221 if (type == "selfcloseTag" || | |
222 (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.to
LowerCase()))) { | |
223 maybePopContext(tagName.toLowerCase()); | |
224 return cont(); | |
225 } | |
226 if (type == "endTag") { | |
227 maybePopContext(tagName.toLowerCase()); | |
228 pushContext(tagName, startOfLine); | |
229 return cont(); | |
230 } | |
231 return cont(); | |
232 }; | |
233 } | |
234 function endclosetag(err) { | |
235 return function(type) { | |
236 if (err) setStyle = "error"; | |
237 if (type == "endTag") { popContext(); return cont(); } | |
238 setStyle = "error"; | |
239 return cont(arguments.callee); | |
240 }; | |
241 } | |
242 function maybePopContext(nextTagName) { | |
243 var parentTagName; | 197 var parentTagName; |
244 while (true) { | 198 while (true) { |
245 if (!curState.context) { | 199 if (!state.context) { |
246 return; | 200 return; |
247 } | 201 } |
248 parentTagName = curState.context.tagName.toLowerCase(); | 202 parentTagName = state.context.tagName; |
249 if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || | 203 if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || |
250 !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { | 204 !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { |
251 return; | 205 return; |
252 } | 206 } |
253 popContext(); | 207 popContext(state); |
254 } | 208 } |
255 } | 209 } |
256 | 210 |
257 function attributes(type) { | 211 function baseState(type, stream, state) { |
258 if (type == "word") {setStyle = "attribute"; return cont(attribute, attribut
es);} | 212 if (type == "openTag") { |
259 if (type == "endTag" || type == "selfcloseTag") return pass(); | 213 state.tagStart = stream.column(); |
| 214 return tagNameState; |
| 215 } else if (type == "closeTag") { |
| 216 return closeTagNameState; |
| 217 } else { |
| 218 return baseState; |
| 219 } |
| 220 } |
| 221 function tagNameState(type, stream, state) { |
| 222 if (type == "word") { |
| 223 state.tagName = stream.current(); |
| 224 setStyle = "tag"; |
| 225 return attrState; |
| 226 } else { |
| 227 setStyle = "error"; |
| 228 return tagNameState; |
| 229 } |
| 230 } |
| 231 function closeTagNameState(type, stream, state) { |
| 232 if (type == "word") { |
| 233 var tagName = stream.current(); |
| 234 if (state.context && state.context.tagName != tagName && |
| 235 Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName)) |
| 236 popContext(state); |
| 237 if (state.context && state.context.tagName == tagName) { |
| 238 setStyle = "tag"; |
| 239 return closeState; |
| 240 } else { |
| 241 setStyle = "tag error"; |
| 242 return closeStateErr; |
| 243 } |
| 244 } else { |
| 245 setStyle = "error"; |
| 246 return closeStateErr; |
| 247 } |
| 248 } |
| 249 |
| 250 function closeState(type, _stream, state) { |
| 251 if (type != "endTag") { |
| 252 setStyle = "error"; |
| 253 return closeState; |
| 254 } |
| 255 popContext(state); |
| 256 return baseState; |
| 257 } |
| 258 function closeStateErr(type, stream, state) { |
260 setStyle = "error"; | 259 setStyle = "error"; |
261 return cont(attributes); | 260 return closeState(type, stream, state); |
262 } | 261 } |
263 function attribute(type) { | 262 |
264 if (type == "equals") return cont(attvalue, attributes); | 263 function attrState(type, _stream, state) { |
| 264 if (type == "word") { |
| 265 setStyle = "attribute"; |
| 266 return attrEqState; |
| 267 } else if (type == "endTag" || type == "selfcloseTag") { |
| 268 var tagName = state.tagName, tagStart = state.tagStart; |
| 269 state.tagName = state.tagStart = null; |
| 270 if (type == "selfcloseTag" || |
| 271 Kludges.autoSelfClosers.hasOwnProperty(tagName)) { |
| 272 maybePopContext(state, tagName); |
| 273 } else { |
| 274 maybePopContext(state, tagName); |
| 275 state.context = new Context(state, tagName, tagStart == state.indented); |
| 276 } |
| 277 return baseState; |
| 278 } |
| 279 setStyle = "error"; |
| 280 return attrState; |
| 281 } |
| 282 function attrEqState(type, stream, state) { |
| 283 if (type == "equals") return attrValueState; |
265 if (!Kludges.allowMissing) setStyle = "error"; | 284 if (!Kludges.allowMissing) setStyle = "error"; |
266 else if (type == "word") {setStyle = "attribute"; return cont(attribute, att
ributes);} | 285 return attrState(type, stream, state); |
267 return (type == "endTag" || type == "selfcloseTag") ? pass() : cont(); | |
268 } | 286 } |
269 function attvalue(type) { | 287 function attrValueState(type, stream, state) { |
270 if (type == "string") return cont(attvaluemaybe); | 288 if (type == "string") return attrContinuedState; |
271 if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return co
nt();} | 289 if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return at
trState;} |
272 setStyle = "error"; | 290 setStyle = "error"; |
273 return (type == "endTag" || type == "selfCloseTag") ? pass() : cont(); | 291 return attrState(type, stream, state); |
274 } | 292 } |
275 function attvaluemaybe(type) { | 293 function attrContinuedState(type, stream, state) { |
276 if (type == "string") return cont(attvaluemaybe); | 294 if (type == "string") return attrContinuedState; |
277 else return pass(); | 295 return attrState(type, stream, state); |
278 } | 296 } |
279 | 297 |
280 return { | 298 return { |
281 startState: function() { | 299 startState: function() { |
282 return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName:
null, tagStart: null, context: null}; | 300 return {tokenize: inText, |
| 301 state: baseState, |
| 302 indented: 0, |
| 303 tagName: null, tagStart: null, |
| 304 context: null}; |
283 }, | 305 }, |
284 | 306 |
285 token: function(stream, state) { | 307 token: function(stream, state) { |
286 if (!state.tagName && stream.sol()) { | 308 if (!state.tagName && stream.sol()) |
287 state.startOfLine = true; | |
288 state.indented = stream.indentation(); | 309 state.indented = stream.indentation(); |
| 310 |
| 311 if (stream.eatSpace()) return null; |
| 312 type = null; |
| 313 var style = state.tokenize(stream, state); |
| 314 if ((style || type) && style != "comment") { |
| 315 setStyle = null; |
| 316 state.state = state.state(type || style, stream, state); |
| 317 if (setStyle) |
| 318 style = setStyle == "error" ? style + " error" : setStyle; |
289 } | 319 } |
290 if (stream.eatSpace()) return null; | |
291 | |
292 setStyle = type = tagName = null; | |
293 var style = state.tokenize(stream, state); | |
294 state.type = type; | |
295 if ((style || type) && style != "comment") { | |
296 curState = state; curStream = stream; | |
297 while (true) { | |
298 var comb = state.cc.pop() || element; | |
299 if (comb(type || style)) break; | |
300 } | |
301 } | |
302 state.startOfLine = false; | |
303 if (setStyle) | |
304 style = setStyle == "error" ? style + " error" : setStyle; | |
305 return style; | 320 return style; |
306 }, | 321 }, |
307 | 322 |
308 indent: function(state, textAfter, fullLine) { | 323 indent: function(state, textAfter, fullLine) { |
309 var context = state.context; | 324 var context = state.context; |
310 // Indent multi-line strings (e.g. css). | 325 // Indent multi-line strings (e.g. css). |
311 if (state.tokenize.isInAttribute) { | 326 if (state.tokenize.isInAttribute) { |
312 return state.stringStartCol + 1; | 327 if (state.tagStart == state.indented) |
| 328 return state.stringStartCol + 1; |
| 329 else |
| 330 return state.indented + indentUnit; |
313 } | 331 } |
314 if ((state.tokenize != inTag && state.tokenize != inText) || | 332 if (context && context.noIndent) return CodeMirror.Pass; |
315 context && context.noIndent) | 333 if (state.tokenize != inTag && state.tokenize != inText) |
316 return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; | 334 return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; |
317 // Indent the starts of attribute names. | 335 // Indent the starts of attribute names. |
318 if (state.tagName) { | 336 if (state.tagName) { |
319 if (multilineTagIndentPastTag) | 337 if (multilineTagIndentPastTag) |
320 return state.tagStart + state.tagName.length + 2; | 338 return state.tagStart + state.tagName.length + 2; |
321 else | 339 else |
322 return state.tagStart + indentUnit * multilineTagIndentFactor; | 340 return state.tagStart + indentUnit * multilineTagIndentFactor; |
323 } | 341 } |
324 if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0; | 342 if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0; |
325 if (context && /^<\//.test(textAfter)) | 343 var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter); |
326 context = context.prev; | 344 if (tagAfter && tagAfter[1]) { // Closing tag spotted |
| 345 while (context) { |
| 346 if (context.tagName == tagAfter[2]) { |
| 347 context = context.prev; |
| 348 break; |
| 349 } else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) { |
| 350 context = context.prev; |
| 351 } else { |
| 352 break; |
| 353 } |
| 354 } |
| 355 } else if (tagAfter) { // Opening tag spotted |
| 356 while (context) { |
| 357 var grabbers = Kludges.contextGrabbers[context.tagName]; |
| 358 if (grabbers && grabbers.hasOwnProperty(tagAfter[2])) |
| 359 context = context.prev; |
| 360 else |
| 361 break; |
| 362 } |
| 363 } |
327 while (context && !context.startOfLine) | 364 while (context && !context.startOfLine) |
328 context = context.prev; | 365 context = context.prev; |
329 if (context) return context.indent + indentUnit; | 366 if (context) return context.indent + indentUnit; |
330 else return 0; | 367 else return 0; |
331 }, | 368 }, |
332 | 369 |
333 electricChars: "/", | 370 electricInput: /<\/[\s\w:]+>$/, |
334 blockCommentStart: "<!--", | 371 blockCommentStart: "<!--", |
335 blockCommentEnd: "-->", | 372 blockCommentEnd: "-->", |
336 | 373 |
337 configuration: parserConfig.htmlMode ? "html" : "xml", | 374 configuration: parserConfig.htmlMode ? "html" : "xml", |
338 helperType: parserConfig.htmlMode ? "html" : "xml" | 375 helperType: parserConfig.htmlMode ? "html" : "xml" |
339 }; | 376 }; |
340 }); | 377 }); |
341 | 378 |
342 CodeMirror.defineMIME("text/xml", "xml"); | 379 CodeMirror.defineMIME("text/xml", "xml"); |
343 CodeMirror.defineMIME("application/xml", "xml"); | 380 CodeMirror.defineMIME("application/xml", "xml"); |
344 if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) | 381 if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) |
345 CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); | 382 CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); |
| 383 |
| 384 }); |
OLD | NEW |