CodeMirror.defineMode("xml", function (config, parserConfig){ var indentUnit = config.indentUnit; var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1; var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true ; var Kludges = parserConfig.htmlMode? { autoSelfClosers: { 'area': true , 'base': true , 'br': true , 'col': true , 'command': true , 'embed': true , 'frame': true , 'hr': true , 'img': true , 'input': true , 'keygen': true , 'link': true , 'meta': true , 'param': true , 'source': true , 'track': true , 'wbr': true } , implicitlyClosed: { 'dd': true , 'li': true , 'optgroup': true , 'option': true , 'p': true , 'rp': true , 'rt': true , 'tbody': true , 'td': true , 'tfoot': true , 'th': true , 'tr': true } , contextGrabbers: { 'dd': { 'dd': true , 'dt': true } , 'dt': { 'dd': true , 'dt': true } , 'li': { 'li': true } , 'option': { 'option': true , 'optgroup': true } , 'optgroup': { 'optgroup': true } , 'p': { 'address': true , 'article': true , 'aside': true , 'blockquote': true , 'dir': true , 'div': true , 'dl': true , 'fieldset': true , 'footer': true , 'form': true , 'h1': true , 'h2': true , 'h3': true , 'h4': true , 'h5': true , 'h6': true , 'header': true , 'hgroup': true , 'hr': true , 'menu': true , 'nav': true , 'ol': true , 'p': true , 'pre': true , 'section': true , 'table': true , 'ul': true } , 'rp': { 'rp': true , 'rt': true } , 'rt': { 'rp': true , 'rt': true } , 'tbody': { 'tbody': true , 'tfoot': true } , 'td': { 'td': true , 'th': true } , 'tfoot': { 'tbody': true } , 'th': { 'td': true , 'th': true } , 'thead': { 'tbody': true , 'tfoot': true } , 'tr': { 'tr': true } } , doNotIndent: { "pre": true } , allowUnquoted: true , allowMissing: true } : { autoSelfClosers: { } , implicitlyClosed: { } , contextGrabbers: { } , doNotIndent: { } , allowUnquoted: false , allowMissing: false } ; var alignCDATA = parserConfig.alignCDATA; var tagName, type; function inText(stream, state){ function chain(parser){ state.tokenize = parser; return parser(stream, state); } var ch = stream.next(); if (ch == "<") { if (stream.eat("!")) { if (stream.eat("[")) { if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); else return null ; } else if (stream.match("--")) { return chain(inBlock("comment", "-->")); } else if (stream.match("DOCTYPE", true , true )) { stream.eatWhile(/[\w\._\-]/); return chain(doctype(1)); } else { return null ; } } else if (stream.eat("?")) { stream.eatWhile(/[\w\._\-]/); state.tokenize = inBlock("meta", "?>"); return "meta"; } else { var isClose = stream.eat("/"); tagName = ""; var c; while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/)))tagName += c; if (!tagName) return "tag error"; type = isClose? "closeTag": "openTag"; state.tokenize = inTag; return "tag"; } } else if (ch == "&") { var ok; if (stream.eat("#")) { if (stream.eat("x")) { ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); } else { ok = stream.eatWhile(/[\d]/) && stream.eat(";"); } } else { ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); } return ok? "atom": "error"; } else { stream.eatWhile(/[^&<]/); return null ; } } function inTag(stream, state){ var ch = stream.next(); if (ch == ">" || (ch == "/" && stream.eat(">"))) { state.tokenize = inText; type = ch == ">"? "endTag": "selfcloseTag"; return "tag"; } else if (ch == "=") { type = "equals"; return null ; } else if (ch == "<") { state.tokenize = inText; var next = state.tokenize(stream, state); return next? next + " error": "error"; } else if (/[\'\"]/.test(ch)) { state.tokenize = inAttribute(ch); state.stringStartCol = stream.column(); return state.tokenize(stream, state); } else { stream.eatWhile(/[^\s\u00a0=<>\"\']/); return "word"; } } function inAttribute(quote){ var closure = function (stream, state){ while (!stream.eol()){ if (stream.next() == quote) { state.tokenize = inTag; break ; } } return "string"; } ; closure.isInAttribute = true ; return closure; } function inBlock(style, terminator){ return function (stream, state){ while (!stream.eol()){ if (stream.match(terminator)) { state.tokenize = inText; break ; } stream.next(); } return style; } ; } function doctype(depth){ return function (stream, state){ var ch; while ((ch = stream.next()) != null ){ if (ch == "<") { state.tokenize = doctype(depth + 1); return state.tokenize(stream, state); } else if (ch == ">") { if (depth == 1) { state.tokenize = inText; break ; } else { state.tokenize = doctype(depth - 1); return state.tokenize(stream, state); } } } return "meta"; } ; } var curState, curStream, setStyle; function pass(){ for (var i = _AN_Read_length("length", arguments) - 1; i >= 0; i-- )curState.cc.push(arguments[i]); } function cont(){ pass.apply(null , arguments); return true ; } function pushContext(tagName, startOfLine){ var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent); curState.context = { prev: curState.context, tagName: tagName, indent: curState.indented, startOfLine: startOfLine, noIndent: noIndent} ; } function popContext(){ if (curState.context) curState.context = curState.context.prev; } function element(type){ if (type == "openTag") { curState.tagName = tagName; curState.tagStart = curStream.column(); return cont(attributes, endtag(curState.startOfLine)); } else if (type == "closeTag") { var err = false ; if (curState.context) { if (curState.context.tagName != tagName) { if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) { popContext(); } err = !curState.context || curState.context.tagName != tagName; } } else { err = true ; } if (err) setStyle = "error"; return cont(endclosetag(err)); } return cont(); } function endtag(startOfLine){ return function (type){ var tagName = curState.tagName; curState.tagName = curState.tagStart = null ; if (type == "selfcloseTag" || (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) { maybePopContext(tagName.toLowerCase()); return cont(); } if (type == "endTag") { maybePopContext(tagName.toLowerCase()); pushContext(tagName, startOfLine); return cont(); } return cont(); } ; } function endclosetag(err){ return function (type){ if (err) setStyle = "error"; if (type == "endTag") { popContext(); return cont(); } setStyle = "error"; return cont(arguments.callee); } ; } function maybePopContext(nextTagName){ var parentTagName; while (true ){ if (!curState.context) { return ; } parentTagName = curState.context.tagName.toLowerCase(); if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { return ; } popContext(); } } function attributes(type){ if (type == "word") { setStyle = "attribute"; return cont(attribute, attributes); } if (type == "endTag" || type == "selfcloseTag") return pass(); setStyle = "error"; return cont(attributes); } function attribute(type){ if (type == "equals") return cont(attvalue, attributes); if (!Kludges.allowMissing) setStyle = "error"; else if (type == "word") { setStyle = "attribute"; return cont(attribute, attributes); } return (type == "endTag" || type == "selfcloseTag")? pass(): cont(); } function attvalue(type){ if (type == "string") return cont(attvaluemaybe); if (type == "word" && Kludges.allowUnquoted) { setStyle = "string"; return cont(); } setStyle = "error"; return (type == "endTag" || type == "selfCloseTag")? pass(): cont(); } function attvaluemaybe(type){ if (type == "string") return cont(attvaluemaybe); else return pass(); } return { startState: function (){ return { tokenize: inText, cc: [] , indented: 0, startOfLine: true , tagName: null , tagStart: null , context: null } ; } , token: function (stream, state){ if (!state.tagName && stream.sol()) { state.startOfLine = true ; state.indented = stream.indentation(); } if (stream.eatSpace()) return null ; setStyle = type = tagName = null ; var style = state.tokenize(stream, state); state.type = type; if ((style || type) && style != "comment") { curState = state; curStream = stream; while (true ){ var comb = state.cc.pop() || element; if (comb(type || style)) break ; } } state.startOfLine = false ; if (setStyle) style = setStyle == "error"? style + " error": setStyle; return style; } , indent: function (state, textAfter, fullLine){ var context = state.context; if (state.tokenize.isInAttribute) { return state.stringStartCol + 1; } if ((state.tokenize != inTag && state.tokenize != inText) || context && context.noIndent) return fullLine? _AN_Read_length("length", fullLine.match(/^(\s*)/)[0]): 0; if (state.tagName) { if (multilineTagIndentPastTag) return state.tagStart + _AN_Read_length("length", state.tagName) + 2; else return state.tagStart + indentUnit * multilineTagIndentFactor; } if (alignCDATA && /", configuration: parserConfig.htmlMode? "html": "xml", helperType: parserConfig.htmlMode? "html": "xml"} ; } ); CodeMirror.defineMIME("text/xml", "xml"); CodeMirror.defineMIME("application/xml", "xml"); if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) CodeMirror.defineMIME("text/html", { name: "xml", htmlMode: true } );