vendor/assets/javascripts/codemirror/modes/xml.js in codemirror-rails-4.0 vs vendor/assets/javascripts/codemirror/modes/xml.js in codemirror-rails-4.1

- old
+ new

@@ -56,11 +56,11 @@ caseFold: false }; var alignCDATA = parserConfig.alignCDATA; // Return variables for tokenizers - var tagName, type, setStyle; + var type, setStyle; function inText(stream, state) { function chain(parser) { state.tokenize = parser; return parser(stream, state); @@ -83,19 +83,13 @@ } 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 (Kludges.caseFold) tagName = tagName.toLowerCase(); - if (!tagName) return "tag error"; - type = isClose ? "closeTag" : "openTag"; + type = stream.eat("/") ? "closeTag" : "openTag"; state.tokenize = inTag; - return "tag"; + return "tag bracket"; } } else if (ch == "&") { var ok; if (stream.eat("#")) { if (stream.eat("x")) { @@ -116,11 +110,11 @@ function inTag(stream, state) { var ch = stream.next(); if (ch == ">" || (ch == "/" && stream.eat(">"))) { state.tokenize = inText; type = ch == ">" ? "endTag" : "selfcloseTag"; - return "tag"; + return "tag bracket"; } else if (ch == "=") { type = "equals"; return null; } else if (ch == "<") { state.tokenize = inText; @@ -131,11 +125,11 @@ } else if (/[\'\"]/.test(ch)) { state.tokenize = inAttribute(ch); state.stringStartCol = stream.column(); return state.tokenize(stream, state); } else { - stream.eatWhile(/[^\s\u00a0=<>\"\']/); + stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/); return "word"; } } function inAttribute(quote) { @@ -211,28 +205,44 @@ } } function baseState(type, stream, state) { if (type == "openTag") { - state.tagName = tagName; state.tagStart = stream.column(); - return attrState; + return tagNameState; } else if (type == "closeTag") { - var err = false; - if (state.context) { - if (state.context.tagName != tagName) { - if (Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName)) - popContext(state); - err = !state.context || state.context.tagName != tagName; - } + return closeTagNameState; + } else { + return baseState; + } + } + function tagNameState(type, stream, state) { + if (type == "word") { + state.tagName = stream.current(); + setStyle = "tag"; + return attrState; + } else { + setStyle = "error"; + return tagNameState; + } + } + function closeTagNameState(type, stream, state) { + if (type == "word") { + var tagName = stream.current(); + if (state.context && state.context.tagName != tagName && + Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName)) + popContext(state); + if (state.context && state.context.tagName == tagName) { + setStyle = "tag"; + return closeState; } else { - err = true; + setStyle = "tag error"; + return closeStateErr; } - if (err) setStyle = "error"; - return err ? closeStateErr : closeState; } else { - return baseState; + setStyle = "error"; + return closeStateErr; } } function closeState(type, _stream, state) { if (type != "endTag") { @@ -294,11 +304,11 @@ token: function(stream, state) { if (!state.tagName && stream.sol()) state.indented = stream.indentation(); if (stream.eatSpace()) return null; - tagName = type = null; + type = null; var style = state.tokenize(stream, state); if ((style || type) && style != "comment") { setStyle = null; state.state = state.state(type || style, stream, state); if (setStyle) @@ -309,11 +319,14 @@ indent: function(state, textAfter, fullLine) { var context = state.context; // Indent multi-line strings (e.g. css). if (state.tokenize.isInAttribute) { - return state.stringStartCol + 1; + if (state.tagStart == state.indented) + return state.stringStartCol + 1; + else + return state.indented + indentUnit; } if (context && context.noIndent) return CodeMirror.Pass; if (state.tokenize != inTag && state.tokenize != inText) return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; // Indent the starts of attribute names. @@ -322,18 +335,37 @@ return state.tagStart + state.tagName.length + 2; else return state.tagStart + indentUnit * multilineTagIndentFactor; } if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0; - if (context && /^<\//.test(textAfter)) - context = context.prev; + var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter); + if (tagAfter && tagAfter[1]) { // Closing tag spotted + while (context) { + if (context.tagName == tagAfter[2]) { + context = context.prev; + break; + } else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) { + context = context.prev; + } else { + break; + } + } + } else if (tagAfter) { // Opening tag spotted + while (context) { + var grabbers = Kludges.contextGrabbers[context.tagName]; + if (grabbers && grabbers.hasOwnProperty(tagAfter[2])) + context = context.prev; + else + break; + } + } while (context && !context.startOfLine) context = context.prev; if (context) return context.indent + indentUnit; else return 0; }, - electricChars: "/", + electricInput: /<\/[\s\w:]+>$/, blockCommentStart: "<!--", blockCommentEnd: "-->", configuration: parserConfig.htmlMode ? "html" : "xml", helperType: parserConfig.htmlMode ? "html" : "xml"