htmlmixed.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. function html(stream, state) {
  6. var style = htmlMode.token(stream, state.htmlState);
  7. if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
  8. if (/^script$/i.test(state.htmlState.context.tagName)) {
  9. state.token = javascript;
  10. state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
  11. state.mode = "javascript";
  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. state.mode = "css";
  17. }
  18. }
  19. return style;
  20. }
  21. function maybeBackup(stream, pat, style) {
  22. var cur = stream.current();
  23. var close = cur.search(pat);
  24. if (close > -1) stream.backUp(cur.length - close);
  25. return style;
  26. }
  27. function javascript(stream, state) {
  28. if (stream.match(/^<\/\s*script\s*>/i, false)) {
  29. state.token = html;
  30. state.curState = null;
  31. state.mode = "html";
  32. return html(stream, state);
  33. }
  34. return maybeBackup(stream, /<\/\s*script\s*>/,
  35. jsMode.token(stream, state.localState));
  36. }
  37. function css(stream, state) {
  38. if (stream.match(/^<\/\s*style\s*>/i, false)) {
  39. state.token = html;
  40. state.localState = null;
  41. state.mode = "html";
  42. return html(stream, state);
  43. }
  44. return maybeBackup(stream, /<\/\s*style\s*>/,
  45. cssMode.token(stream, state.localState));
  46. }
  47. return {
  48. startState: function() {
  49. var state = htmlMode.startState();
  50. return {token: html, localState: null, mode: "html", htmlState: state};
  51. },
  52. copyState: function(state) {
  53. if (state.localState)
  54. var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
  55. return {token: state.token, localState: local, mode: state.mode,
  56. htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
  57. },
  58. token: function(stream, state) {
  59. return state.token(stream, state);
  60. },
  61. indent: function(state, textAfter) {
  62. if (state.token == html || /^\s*<\//.test(textAfter))
  63. return htmlMode.indent(state.htmlState, textAfter);
  64. else if (state.token == javascript)
  65. return jsMode.indent(state.localState, textAfter);
  66. else
  67. return cssMode.indent(state.localState, textAfter);
  68. },
  69. electricChars: "/{}:"
  70. }
  71. });
  72. CodeMirror.defineMIME("text/html", "htmlmixed");