Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / cm / htmlmixed.js
blob250ef8cd243fcc7155488ff79b54f3f18ce7e4a5
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
14 CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
15 var htmlMode = CodeMirror.getMode(config, {name: "xml",
16 htmlMode: true,
17 multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
18 multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
19 var cssMode = CodeMirror.getMode(config, "css");
21 var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
22 scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
23 mode: CodeMirror.getMode(config, "javascript")});
24 if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
25 var conf = scriptTypesConf[i];
26 scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
28 scriptTypes.push({matches: /./,
29 mode: CodeMirror.getMode(config, "text/plain")});
31 function html(stream, state) {
32 var tagName = state.htmlState.tagName;
33 if (tagName) tagName = tagName.toLowerCase();
34 var style = htmlMode.token(stream, state.htmlState);
35 if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
36 // Script block: mode to change to depends on type attribute
37 var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
38 scriptType = scriptType ? scriptType[1] : "";
39 if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
40 for (var i = 0; i < scriptTypes.length; ++i) {
41 var tp = scriptTypes[i];
42 if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
43 if (tp.mode) {
44 state.token = script;
45 state.localMode = tp.mode;
46 state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
48 break;
51 } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
52 state.token = css;
53 state.localMode = cssMode;
54 state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
56 return style;
58 function maybeBackup(stream, pat, style) {
59 var cur = stream.current();
60 var close = cur.search(pat), m;
61 if (close > -1) stream.backUp(cur.length - close);
62 else if (m = cur.match(/<\/?$/)) {
63 stream.backUp(cur.length);
64 if (!stream.match(pat, false)) stream.match(cur);
66 return style;
68 function script(stream, state) {
69 if (stream.match(/^<\/\s*script\s*>/i, false)) {
70 state.token = html;
71 state.localState = state.localMode = null;
72 return html(stream, state);
74 return maybeBackup(stream, /<\/\s*script\s*>/,
75 state.localMode.token(stream, state.localState));
77 function css(stream, state) {
78 if (stream.match(/^<\/\s*style\s*>/i, false)) {
79 state.token = html;
80 state.localState = state.localMode = null;
81 return html(stream, state);
83 return maybeBackup(stream, /<\/\s*style\s*>/,
84 cssMode.token(stream, state.localState));
87 return {
88 startState: function() {
89 var state = htmlMode.startState();
90 return {token: html, localMode: null, localState: null, htmlState: state};
93 copyState: function(state) {
94 if (state.localState)
95 var local = CodeMirror.copyState(state.localMode, state.localState);
96 return {token: state.token, localMode: state.localMode, localState: local,
97 htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
100 token: function(stream, state) {
101 return state.token(stream, state);
104 indent: function(state, textAfter) {
105 if (!state.localMode || /^\s*<\//.test(textAfter))
106 return htmlMode.indent(state.htmlState, textAfter);
107 else if (state.localMode.indent)
108 return state.localMode.indent(state.localState, textAfter);
109 else
110 return CodeMirror.Pass;
113 innerMode: function(state) {
114 return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
117 }, "xml", "javascript", "css");
119 CodeMirror.defineMIME("text/html", "htmlmixed");