2 if (typeof exports
== "object" && typeof module
== "object") // CommonJS
3 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
4 else if (typeof define
== "function" && define
.amd
) // AMD
5 define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod
);
6 else // Plain browser env
8 })(function(CodeMirror
) {
11 CodeMirror
.defineMode("htmlmixed", function(config
, parserConfig
) {
12 var htmlMode
= CodeMirror
.getMode(config
, {name
: "xml",
14 multilineTagIndentFactor
: parserConfig
.multilineTagIndentFactor
,
15 multilineTagIndentPastTag
: parserConfig
.multilineTagIndentPastTag
});
16 var cssMode
= CodeMirror
.getMode(config
, "css");
18 var scriptTypes
= [], scriptTypesConf
= parserConfig
&& parserConfig
.scriptTypes
;
19 scriptTypes
.push({matches
: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
20 mode
: CodeMirror
.getMode(config
, "javascript")});
21 if (scriptTypesConf
) for (var i
= 0; i
< scriptTypesConf
.length
; ++i
) {
22 var conf
= scriptTypesConf
[i
];
23 scriptTypes
.push({matches
: conf
.matches
, mode
: conf
.mode
&& CodeMirror
.getMode(config
, conf
.mode
)});
25 scriptTypes
.push({matches
: /./,
26 mode
: CodeMirror
.getMode(config
, "text/plain")});
28 function html(stream
, state
) {
29 var tagName
= state
.htmlState
.tagName
;
30 var style
= htmlMode
.token(stream
, state
.htmlState
);
31 if (tagName
== "script" && /\btag\b/.test(style
) && stream
.current() == ">") {
32 // Script block: mode to change to depends on type attribute
33 var scriptType
= stream
.string
.slice(Math
.max(0, stream
.pos
- 100), stream
.pos
).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
34 scriptType
= scriptType
? scriptType
[1] : "";
35 if (scriptType
&& /[\"\']/.test(scriptType
.charAt(0))) scriptType
= scriptType
.slice(1, scriptType
.length
- 1);
36 for (var i
= 0; i
< scriptTypes
.length
; ++i
) {
37 var tp
= scriptTypes
[i
];
38 if (typeof tp
.matches
== "string" ? scriptType
== tp
.matches
: tp
.matches
.test(scriptType
)) {
41 state
.localMode
= tp
.mode
;
42 state
.localState
= tp
.mode
.startState
&& tp
.mode
.startState(htmlMode
.indent(state
.htmlState
, ""));
47 } else if (tagName
== "style" && /\btag\b/.test(style
) && stream
.current() == ">") {
49 state
.localMode
= cssMode
;
50 state
.localState
= cssMode
.startState(htmlMode
.indent(state
.htmlState
, ""));
54 function maybeBackup(stream
, pat
, style
) {
55 var cur
= stream
.current();
56 var close
= cur
.search(pat
), m
;
57 if (close
> -1) stream
.backUp(cur
.length
- close
);
58 else if (m
= cur
.match(/<\/?$/)) {
59 stream
.backUp(cur
.length
);
60 if (!stream
.match(pat
, false)) stream
.match(cur
);
64 function script(stream
, state
) {
65 if (stream
.match(/^<\/\s*script\s*>/i, false)) {
67 state
.localState
= state
.localMode
= null;
68 return html(stream
, state
);
70 return maybeBackup(stream
, /<\/\s*script\s*>/,
71 state
.localMode
.token(stream
, state
.localState
));
73 function css(stream
, state
) {
74 if (stream
.match(/^<\/\s*style\s*>/i, false)) {
76 state
.localState
= state
.localMode
= null;
77 return html(stream
, state
);
79 return maybeBackup(stream
, /<\/\s*style\s*>/,
80 cssMode
.token(stream
, state
.localState
));
84 startState: function() {
85 var state
= htmlMode
.startState();
86 return {token
: html
, localMode
: null, localState
: null, htmlState
: state
};
89 copyState: function(state
) {
91 var local
= CodeMirror
.copyState(state
.localMode
, state
.localState
);
92 return {token
: state
.token
, localMode
: state
.localMode
, localState
: local
,
93 htmlState
: CodeMirror
.copyState(htmlMode
, state
.htmlState
)};
96 token: function(stream
, state
) {
97 return state
.token(stream
, state
);
100 indent: function(state
, textAfter
) {
101 if (!state
.localMode
|| /^\s*<\//.test(textAfter
))
102 return htmlMode
.indent(state
.htmlState
, textAfter
);
103 else if (state
.localMode
.indent
)
104 return state
.localMode
.indent(state
.localState
, textAfter
);
106 return CodeMirror
.Pass
;
109 innerMode: function(state
) {
110 return {state
: state
.localState
|| state
.htmlState
, mode
: state
.localMode
|| htmlMode
};
113 }, "xml", "javascript", "css");
115 CodeMirror
.defineMIME("text/html", "htmlmixed");