|
31 | 31 | } |
32 | 32 |
|
33 | 33 | function tokenUntil(stream, state, untilRegExp) { |
| 34 | + if (stream.sol()) { |
| 35 | + for (var indent = 0; indent < state.indent; indent++) { |
| 36 | + if (!stream.eat(/\s/)) break; |
| 37 | + } |
| 38 | + if (indent) return null; |
| 39 | + } |
34 | 40 | var oldString = stream.string; |
35 | 41 | var match = untilRegExp.exec(oldString.substr(stream.pos)); |
36 | 42 | if (match) { |
|
39 | 45 | stream.string = oldString.substr(0, stream.pos + match.index); |
40 | 46 | } |
41 | 47 | var result = stream.hideFirstChars(state.indent, function() { |
42 | | - return state.localMode.token(stream, state.localState); |
| 48 | + var localState = last(state.localStates); |
| 49 | + return localState.mode.token(stream, localState.state); |
43 | 50 | }); |
44 | 51 | stream.string = oldString; |
45 | 52 | return result; |
|
83 | 90 | variables: null, |
84 | 91 | scopes: null, |
85 | 92 | indent: 0, |
86 | | - localMode: modes.html, |
87 | | - localState: CodeMirror.startState(modes.html) |
| 93 | + localStates: [{ |
| 94 | + mode: modes.html, |
| 95 | + state: CodeMirror.startState(modes.html) |
| 96 | + }] |
88 | 97 | }; |
89 | 98 | }, |
90 | 99 |
|
|
98 | 107 | variables: state.variables, |
99 | 108 | scopes: state.scopes, |
100 | 109 | indent: state.indent, // Indentation of the following line. |
101 | | - localMode: state.localMode, |
102 | | - localState: CodeMirror.copyState(state.localMode, state.localState) |
| 110 | + localStates: state.localStates.map(function(localState) { |
| 111 | + return { |
| 112 | + mode: localState.mode, |
| 113 | + state: CodeMirror.copyState(localState.mode, localState.state) |
| 114 | + }; |
| 115 | + }) |
103 | 116 | }; |
104 | 117 | }, |
105 | 118 |
|
|
187 | 200 | var kind = match[1]; |
188 | 201 | state.kind.push(kind); |
189 | 202 | state.kindTag.push(state.tag); |
190 | | - state.localMode = modes[kind] || modes.html; |
191 | | - state.localState = CodeMirror.startState(state.localMode); |
| 203 | + var mode = modes[kind] || modes.html; |
| 204 | + var localState = last(state.localStates); |
| 205 | + state.indent += localState.mode.indent(localState.state, ""); |
| 206 | + state.localStates.push({ |
| 207 | + mode: mode, |
| 208 | + state: CodeMirror.startState(mode) |
| 209 | + }); |
192 | 210 | } |
193 | 211 | return "attribute"; |
194 | 212 | } else if (stream.match(/^"/)) { |
|
233 | 251 | return "keyword"; |
234 | 252 | } else if (match = stream.match(/^\{([\/@\\]?[\w?]*)/)) { |
235 | 253 | if (match[1] != "/switch") |
236 | | - state.indent += (/^(\/|(else|elseif|ifempty|case|default)$)/.test(match[1]) && state.tag != "switch" ? 1 : 2) * config.indentUnit; |
| 254 | + state.indent += (/^(\/|(else|elseif|ifempty|case|fallbackmsg|default)$)/.test(match[1]) && state.tag != "switch" ? 1 : 2) * config.indentUnit; |
237 | 255 | state.tag = match[1]; |
238 | 256 | if (state.tag == "/" + last(state.kindTag)) { |
239 | 257 | // We found the tag that opened the current kind="". |
240 | 258 | state.kind.pop(); |
241 | 259 | state.kindTag.pop(); |
242 | | - state.localMode = modes[last(state.kind)] || modes.html; |
243 | | - state.localState = CodeMirror.startState(state.localMode); |
| 260 | + state.localStates.pop(); |
| 261 | + var localState = last(state.localStates); |
| 262 | + state.indent -= localState.mode.indent(localState.state, ""); |
244 | 263 | } |
245 | 264 | state.soyState.push("tag"); |
246 | 265 | if (state.tag == "template" || state.tag == "deltemplate") { |
|
277 | 296 | if (state.tag != "switch" && /^\{(case|default)\b/.test(textAfter)) indent -= config.indentUnit; |
278 | 297 | if (/^\{\/switch\b/.test(textAfter)) indent -= config.indentUnit; |
279 | 298 | } |
280 | | - if (indent && state.localMode.indent) |
281 | | - indent += state.localMode.indent(state.localState, textAfter); |
| 299 | + var localState = last(state.localStates); |
| 300 | + if (indent && localState.mode.indent) { |
| 301 | + indent += localState.mode.indent(localState.state, textAfter); |
| 302 | + } |
282 | 303 | return indent; |
283 | 304 | }, |
284 | 305 |
|
285 | 306 | innerMode: function(state) { |
286 | 307 | if (state.soyState.length && last(state.soyState) != "literal") return null; |
287 | | - else return {state: state.localState, mode: state.localMode}; |
| 308 | + else return last(state.localStates); |
288 | 309 | }, |
289 | 310 |
|
290 | 311 | electricInput: /^\s*\{(\/|\/template|\/deltemplate|\/switch|fallbackmsg|elseif|else|case|default|ifempty|\/literal\})$/, |
|
0 commit comments