| 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 |