1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/dew/src/main/resources/org/apidesign/bck2brwsr/dew/js/codemirror/mode/xml.js Wed Jan 23 13:18:46 2013 +0100
1.3 @@ -0,0 +1,324 @@
1.4 +CodeMirror.defineMode("xml", function(config, parserConfig) {
1.5 + var indentUnit = config.indentUnit;
1.6 + var Kludges = parserConfig.htmlMode ? {
1.7 + autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
1.8 + 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
1.9 + 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
1.10 + 'track': true, 'wbr': true},
1.11 + implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
1.12 + 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
1.13 + 'th': true, 'tr': true},
1.14 + contextGrabbers: {
1.15 + 'dd': {'dd': true, 'dt': true},
1.16 + 'dt': {'dd': true, 'dt': true},
1.17 + 'li': {'li': true},
1.18 + 'option': {'option': true, 'optgroup': true},
1.19 + 'optgroup': {'optgroup': true},
1.20 + 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
1.21 + 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
1.22 + 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
1.23 + 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
1.24 + 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
1.25 + 'rp': {'rp': true, 'rt': true},
1.26 + 'rt': {'rp': true, 'rt': true},
1.27 + 'tbody': {'tbody': true, 'tfoot': true},
1.28 + 'td': {'td': true, 'th': true},
1.29 + 'tfoot': {'tbody': true},
1.30 + 'th': {'td': true, 'th': true},
1.31 + 'thead': {'tbody': true, 'tfoot': true},
1.32 + 'tr': {'tr': true}
1.33 + },
1.34 + doNotIndent: {"pre": true},
1.35 + allowUnquoted: true,
1.36 + allowMissing: true
1.37 + } : {
1.38 + autoSelfClosers: {},
1.39 + implicitlyClosed: {},
1.40 + contextGrabbers: {},
1.41 + doNotIndent: {},
1.42 + allowUnquoted: false,
1.43 + allowMissing: false
1.44 + };
1.45 + var alignCDATA = parserConfig.alignCDATA;
1.46 +
1.47 + // Return variables for tokenizers
1.48 + var tagName, type;
1.49 +
1.50 + function inText(stream, state) {
1.51 + function chain(parser) {
1.52 + state.tokenize = parser;
1.53 + return parser(stream, state);
1.54 + }
1.55 +
1.56 + var ch = stream.next();
1.57 + if (ch == "<") {
1.58 + if (stream.eat("!")) {
1.59 + if (stream.eat("[")) {
1.60 + if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
1.61 + else return null;
1.62 + }
1.63 + else if (stream.match("--")) return chain(inBlock("comment", "-->"));
1.64 + else if (stream.match("DOCTYPE", true, true)) {
1.65 + stream.eatWhile(/[\w\._\-]/);
1.66 + return chain(doctype(1));
1.67 + }
1.68 + else return null;
1.69 + }
1.70 + else if (stream.eat("?")) {
1.71 + stream.eatWhile(/[\w\._\-]/);
1.72 + state.tokenize = inBlock("meta", "?>");
1.73 + return "meta";
1.74 + }
1.75 + else {
1.76 + var isClose = stream.eat("/");
1.77 + tagName = "";
1.78 + var c;
1.79 + while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
1.80 + if (!tagName) return "error";
1.81 + type = isClose ? "closeTag" : "openTag";
1.82 + state.tokenize = inTag;
1.83 + return "tag";
1.84 + }
1.85 + }
1.86 + else if (ch == "&") {
1.87 + var ok;
1.88 + if (stream.eat("#")) {
1.89 + if (stream.eat("x")) {
1.90 + ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
1.91 + } else {
1.92 + ok = stream.eatWhile(/[\d]/) && stream.eat(";");
1.93 + }
1.94 + } else {
1.95 + ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
1.96 + }
1.97 + return ok ? "atom" : "error";
1.98 + }
1.99 + else {
1.100 + stream.eatWhile(/[^&<]/);
1.101 + return null;
1.102 + }
1.103 + }
1.104 +
1.105 + function inTag(stream, state) {
1.106 + var ch = stream.next();
1.107 + if (ch == ">" || (ch == "/" && stream.eat(">"))) {
1.108 + state.tokenize = inText;
1.109 + type = ch == ">" ? "endTag" : "selfcloseTag";
1.110 + return "tag";
1.111 + }
1.112 + else if (ch == "=") {
1.113 + type = "equals";
1.114 + return null;
1.115 + }
1.116 + else if (/[\'\"]/.test(ch)) {
1.117 + state.tokenize = inAttribute(ch);
1.118 + return state.tokenize(stream, state);
1.119 + }
1.120 + else {
1.121 + stream.eatWhile(/[^\s\u00a0=<>\"\']/);
1.122 + return "word";
1.123 + }
1.124 + }
1.125 +
1.126 + function inAttribute(quote) {
1.127 + return function(stream, state) {
1.128 + while (!stream.eol()) {
1.129 + if (stream.next() == quote) {
1.130 + state.tokenize = inTag;
1.131 + break;
1.132 + }
1.133 + }
1.134 + return "string";
1.135 + };
1.136 + }
1.137 +
1.138 + function inBlock(style, terminator) {
1.139 + return function(stream, state) {
1.140 + while (!stream.eol()) {
1.141 + if (stream.match(terminator)) {
1.142 + state.tokenize = inText;
1.143 + break;
1.144 + }
1.145 + stream.next();
1.146 + }
1.147 + return style;
1.148 + };
1.149 + }
1.150 + function doctype(depth) {
1.151 + return function(stream, state) {
1.152 + var ch;
1.153 + while ((ch = stream.next()) != null) {
1.154 + if (ch == "<") {
1.155 + state.tokenize = doctype(depth + 1);
1.156 + return state.tokenize(stream, state);
1.157 + } else if (ch == ">") {
1.158 + if (depth == 1) {
1.159 + state.tokenize = inText;
1.160 + break;
1.161 + } else {
1.162 + state.tokenize = doctype(depth - 1);
1.163 + return state.tokenize(stream, state);
1.164 + }
1.165 + }
1.166 + }
1.167 + return "meta";
1.168 + };
1.169 + }
1.170 +
1.171 + var curState, setStyle;
1.172 + function pass() {
1.173 + for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
1.174 + }
1.175 + function cont() {
1.176 + pass.apply(null, arguments);
1.177 + return true;
1.178 + }
1.179 +
1.180 + function pushContext(tagName, startOfLine) {
1.181 + var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
1.182 + curState.context = {
1.183 + prev: curState.context,
1.184 + tagName: tagName,
1.185 + indent: curState.indented,
1.186 + startOfLine: startOfLine,
1.187 + noIndent: noIndent
1.188 + };
1.189 + }
1.190 + function popContext() {
1.191 + if (curState.context) curState.context = curState.context.prev;
1.192 + }
1.193 +
1.194 + function element(type) {
1.195 + if (type == "openTag") {
1.196 + curState.tagName = tagName;
1.197 + return cont(attributes, endtag(curState.startOfLine));
1.198 + } else if (type == "closeTag") {
1.199 + var err = false;
1.200 + if (curState.context) {
1.201 + if (curState.context.tagName != tagName) {
1.202 + if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
1.203 + popContext();
1.204 + }
1.205 + err = !curState.context || curState.context.tagName != tagName;
1.206 + }
1.207 + } else {
1.208 + err = true;
1.209 + }
1.210 + if (err) setStyle = "error";
1.211 + return cont(endclosetag(err));
1.212 + }
1.213 + return cont();
1.214 + }
1.215 + function endtag(startOfLine) {
1.216 + return function(type) {
1.217 + var tagName = curState.tagName;
1.218 + curState.tagName = null;
1.219 + if (type == "selfcloseTag" ||
1.220 + (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) {
1.221 + maybePopContext(tagName.toLowerCase());
1.222 + return cont();
1.223 + }
1.224 + if (type == "endTag") {
1.225 + maybePopContext(tagName.toLowerCase());
1.226 + pushContext(tagName, startOfLine);
1.227 + return cont();
1.228 + }
1.229 + return cont();
1.230 + };
1.231 + }
1.232 + function endclosetag(err) {
1.233 + return function(type) {
1.234 + if (err) setStyle = "error";
1.235 + if (type == "endTag") { popContext(); return cont(); }
1.236 + setStyle = "error";
1.237 + return cont(arguments.callee);
1.238 + };
1.239 + }
1.240 + function maybePopContext(nextTagName) {
1.241 + var parentTagName;
1.242 + while (true) {
1.243 + if (!curState.context) {
1.244 + return;
1.245 + }
1.246 + parentTagName = curState.context.tagName.toLowerCase();
1.247 + if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
1.248 + !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
1.249 + return;
1.250 + }
1.251 + popContext();
1.252 + }
1.253 + }
1.254 +
1.255 + function attributes(type) {
1.256 + if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
1.257 + if (type == "endTag" || type == "selfcloseTag") return pass();
1.258 + setStyle = "error";
1.259 + return cont(attributes);
1.260 + }
1.261 + function attribute(type) {
1.262 + if (type == "equals") return cont(attvalue, attributes);
1.263 + if (!Kludges.allowMissing) setStyle = "error";
1.264 + else if (type == "word") setStyle = "attribute";
1.265 + return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
1.266 + }
1.267 + function attvalue(type) {
1.268 + if (type == "string") return cont(attvaluemaybe);
1.269 + if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
1.270 + setStyle = "error";
1.271 + return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
1.272 + }
1.273 + function attvaluemaybe(type) {
1.274 + if (type == "string") return cont(attvaluemaybe);
1.275 + else return pass();
1.276 + }
1.277 +
1.278 + return {
1.279 + startState: function() {
1.280 + return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
1.281 + },
1.282 +
1.283 + token: function(stream, state) {
1.284 + if (stream.sol()) {
1.285 + state.startOfLine = true;
1.286 + state.indented = stream.indentation();
1.287 + }
1.288 + if (stream.eatSpace()) return null;
1.289 +
1.290 + setStyle = type = tagName = null;
1.291 + var style = state.tokenize(stream, state);
1.292 + state.type = type;
1.293 + if ((style || type) && style != "comment") {
1.294 + curState = state;
1.295 + while (true) {
1.296 + var comb = state.cc.pop() || element;
1.297 + if (comb(type || style)) break;
1.298 + }
1.299 + }
1.300 + state.startOfLine = false;
1.301 + return setStyle || style;
1.302 + },
1.303 +
1.304 + indent: function(state, textAfter, fullLine) {
1.305 + var context = state.context;
1.306 + if ((state.tokenize != inTag && state.tokenize != inText) ||
1.307 + context && context.noIndent)
1.308 + return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
1.309 + if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
1.310 + if (context && /^<\//.test(textAfter))
1.311 + context = context.prev;
1.312 + while (context && !context.startOfLine)
1.313 + context = context.prev;
1.314 + if (context) return context.indent + indentUnit;
1.315 + else return 0;
1.316 + },
1.317 +
1.318 + electricChars: "/",
1.319 +
1.320 + configuration: parserConfig.htmlMode ? "html" : "xml"
1.321 + };
1.322 +});
1.323 +
1.324 +CodeMirror.defineMIME("text/xml", "xml");
1.325 +CodeMirror.defineMIME("application/xml", "xml");
1.326 +if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
1.327 + CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});