11CodeMirror . defineMode ( "xml" , function ( config , parserConfig ) {
22 var indentUnit = config . indentUnit ;
33 var multilineTagIndentFactor = parserConfig . multilineTagIndentFactor || 1 ;
4+ var multilineTagIndentPastTag = parserConfig . multilineTagIndentPastTag || true ;
45
56 var Kludges = parserConfig . htmlMode ? {
67 autoSelfClosers : { 'area' : true , 'base' : true , 'br' : true , 'col' : true , 'command' : true ,
@@ -111,6 +112,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
111112 return "error" ;
112113 } else if ( / [ \' \" ] / . test ( ch ) ) {
113114 state . tokenize = inAttribute ( ch ) ;
115+ state . stringStartCol = stream . column ( ) ;
114116 return state . tokenize ( stream , state ) ;
115117 } else {
116118 stream . eatWhile ( / [ ^ \s \u00a0 = < > \" \' ] / ) ;
@@ -119,7 +121,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
119121 }
120122
121123 function inAttribute ( quote ) {
122- return function ( stream , state ) {
124+ var closure = function ( stream , state ) {
123125 while ( ! stream . eol ( ) ) {
124126 if ( stream . next ( ) == quote ) {
125127 state . tokenize = inTag ;
@@ -128,6 +130,8 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
128130 }
129131 return "string" ;
130132 } ;
133+ closure . isInAttribute = true ;
134+ return closure ;
131135 }
132136
133137 function inBlock ( style , terminator ) {
@@ -299,10 +303,20 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
299303
300304 indent : function ( state , textAfter , fullLine ) {
301305 var context = state . context ;
306+ // Indent multi-line strings (e.g. css).
307+ if ( state . tokenize . isInAttribute ) {
308+ return state . stringStartCol + 1 ;
309+ }
302310 if ( ( state . tokenize != inTag && state . tokenize != inText ) ||
303311 context && context . noIndent )
304312 return fullLine ? fullLine . match ( / ^ ( \s * ) / ) [ 0 ] . length : 0 ;
305- if ( state . tagName ) return state . tagStart + indentUnit * multilineTagIndentFactor ;
313+ // Indent the starts of attribute names.
314+ if ( state . tagName ) {
315+ if ( multilineTagIndentPastTag )
316+ return state . tagStart + state . tagName . length + 2 ;
317+ else
318+ return state . tagStart + indentUnit * multilineTagIndentFactor ;
319+ }
306320 if ( alignCDATA && / < ! \[ C D A T A \[ / . test ( textAfter ) ) return 0 ;
307321 if ( context && / ^ < \/ / . test ( textAfter ) )
308322 context = context . prev ;
0 commit comments