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"