ent.documentElement || document.body.parentNode; if (t.scrollTop == null) t = document.body; box.top += t.scrollTop; box.left += t.scrollLeft; } else { box.top += window.pageYOffset; box.left += window.pageXOffset; } } return box; }; // Get a node's text content. function eltText(node) { return node.textContent || node.innerText || node.nodeValue || ""; } // Operations on {line, ch} objects. function posEq(a, b) {return a.line == b.line && a.ch == b.ch;} function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);} function copyPos(x) {return {line: x.line, ch: x.ch};} var escapeElement = document.createElement("pre"); function htmlEscape(str) { escapeElement.textContent = str; return escapeElement.innerHTML; } // Recent (late 2011) Opera betas insert bogus newlines at the start // of the textContent, so we strip those. if (htmlEscape("a") == "\na") htmlEscape = function(str) { escapeElement.textContent = str; return escapeElement.innerHTML.slice(1); }; // Some IEs don't preserve tabs through innerHTML else if (htmlEscape("\t") != "\t") htmlEscape = function(str) { escapeElement.innerHTML = ""; escapeElement.appendChild(document.createTextNode(str)); return escapeElement.innerHTML; }; CodeMirror.htmlEscape = htmlEscape; // Used to position the cursor after an undo/redo by finding the // last edited character. function editEnd(from, to) { if (!to) return from ? from.length : 0; if (!from) return to.length; for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j) if (from.charAt(i) != to.charAt(j)) break; return j + 1; } function indexOf(collection, elt) { if (collection.indexOf) return collection.indexOf(elt); for (var i = 0, e = collection.length; i < e; ++i) if (collection[i] == elt) return i; return -1; } function isWordChar(ch) { return /\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase(); } // See if "".split is the broken IE version, if so, provide an // alternative way to split lines. var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { var pos = 0, nl, result = []; while ((nl = string.indexOf("\n", pos)) > -1) { result.push(string.slice(pos, string.charAt(nl-1) == "\r" ? nl - 1 : nl)); pos = nl + 1; } result.push(string.slice(pos)); return result; } : function(string){return string.split(/\r?\n/);}; CodeMirror.splitLines = splitLines; var hasSelection = window.getSelection ? function(te) { try { return te.selectionStart != te.selectionEnd; } catch(e) { return false; } } : function(te) { try {var range = te.ownerDocument.selection.createRange();} catch(e) {} if (!range || range.parentElement() != te) return false; return range.compareEndPoints("StartToEnd", range) != 0; }; CodeMirror.defineMode("null", function() { return {token: function(stream) {stream.skipToEnd();}}; }); CodeMirror.defineMIME("text/plain", "null"); var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home", 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"}; CodeMirror.keyNames = keyNames; (function() { // Number keys for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i); // Alphabetic keys for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); // Function keys for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; })(); return CodeMirror; })(); CodeMirror.defineMode("xml", function(config, parserConfig) { var indentUnit = config.indentUnit; var Kludges = parserConfig.htmlMode ? { autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true, "meta": true, "col": true, "frame": true, "base": true, "area": true}, doNotIndent: {"pre": true}, allowUnquoted: true } : {autoSelfClosers: {}, doNotIndent: {}, allowUnquoted: false}; var alignCDATA = parserConfig.alignCDATA; // Return variables for tokenizers 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 { type = stream.eat("/") ? "closeTag" : "openTag"; stream.eatSpace(); tagName = ""; var c; while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; state.tokenize = inTag; return "tag"; } } else if (ch == "&") { stream.eatWhile(/[^;]/); stream.eat(";"); return "atom"; } 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 (/[\'\"]/.test(ch)) { state.tokenize = inAttribute(ch); return state.tokenize(stream, state); } else { stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/); return "word"; } } function inAttribute(quote) { return function(stream, state) { while (!stream.eol()) { if (stream.next() == quote) { state.tokenize = inTag; break; } } return "string"; }; } 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 == "<") {