1 | CodeMirror.defineMode("htmlmixed", function(config, parserConfig) { |
---|
2 | var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true}); |
---|
3 | var jsMode = CodeMirror.getMode(config, "javascript"); |
---|
4 | var cssMode = CodeMirror.getMode(config, "css"); |
---|
5 | |
---|
6 | function html(stream, state) { |
---|
7 | var style = htmlMode.token(stream, state.htmlState); |
---|
8 | if (style == "xml-tag" && stream.current() == ">" && state.htmlState.context) { |
---|
9 | if (/^script$/i.test(state.htmlState.context.tagName)) { |
---|
10 | state.token = javascript; |
---|
11 | state.localState = jsMode.startState(htmlMode.indent(state.htmlState, "")); |
---|
12 | } |
---|
13 | else if (/^style$/i.test(state.htmlState.context.tagName)) { |
---|
14 | state.token = css; |
---|
15 | state.localState = cssMode.startState(htmlMode.indent(state.htmlState, "")); |
---|
16 | } |
---|
17 | } |
---|
18 | return style; |
---|
19 | } |
---|
20 | function javascript(stream, state) { |
---|
21 | if (stream.match(/^<\/\s*script\s*>/i, false)) { |
---|
22 | state.token = html; |
---|
23 | state.curState = null; |
---|
24 | return html(stream, state); |
---|
25 | } |
---|
26 | return jsMode.token(stream, state.localState); |
---|
27 | } |
---|
28 | function css(stream, state) { |
---|
29 | if (stream.match(/^<\/\s*style\s*>/i, false)) { |
---|
30 | state.token = html; |
---|
31 | state.localState = null; |
---|
32 | return html(stream, state); |
---|
33 | } |
---|
34 | return cssMode.token(stream, state.localState); |
---|
35 | } |
---|
36 | |
---|
37 | return { |
---|
38 | startState: function() { |
---|
39 | var state = htmlMode.startState(); |
---|
40 | return {token: html, localState: null, htmlState: state}; |
---|
41 | }, |
---|
42 | |
---|
43 | copyState: function(state) { |
---|
44 | if (state.localState) |
---|
45 | var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState); |
---|
46 | return {token: state.token, localState: local, htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; |
---|
47 | }, |
---|
48 | |
---|
49 | token: function(stream, state) { |
---|
50 | return state.token(stream, state); |
---|
51 | }, |
---|
52 | |
---|
53 | indent: function(state, textAfter) { |
---|
54 | if (state.token == html || /^\s*<\//.test(textAfter)) |
---|
55 | return htmlMode.indent(state.htmlState, textAfter); |
---|
56 | else if (state.token == javascript) |
---|
57 | return jsMode.indent(state.localState, textAfter); |
---|
58 | else |
---|
59 | return cssMode.indent(state.localState, textAfter); |
---|
60 | }, |
---|
61 | |
---|
62 | electricChars: "/{}:" |
---|
63 | } |
---|
64 | }); |
---|
65 | |
---|
66 | CodeMirror.defineMIME("text/html", "htmlmixed"); |
---|