overlay.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Utility function that allows modes to be combined. The mode given
  2. // as the base argument takes care of most of the normal mode
  3. // functionality, but a second (typically simple) mode is used, which
  4. // can override the style of text. Both modes get to parse all of the
  5. // text, but when both assign a non-null style to a piece of code, the
  6. // overlay wins, unless the combine argument was true, in which case
  7. // the styles are combined.
  8. (function(mod) {
  9. if (typeof exports == "object" && typeof module == "object") // CommonJS
  10. mod(require("../../lib/codemirror"));
  11. else if (typeof define == "function" && define.amd) // AMD
  12. define(["../../lib/codemirror"], mod);
  13. else // Plain browser env
  14. mod(CodeMirror);
  15. })(function(CodeMirror) {
  16. "use strict";
  17. CodeMirror.overlayMode = function(base, overlay, combine) {
  18. return {
  19. startState: function() {
  20. return {
  21. base: CodeMirror.startState(base),
  22. overlay: CodeMirror.startState(overlay),
  23. basePos: 0, baseCur: null,
  24. overlayPos: 0, overlayCur: null
  25. };
  26. },
  27. copyState: function(state) {
  28. return {
  29. base: CodeMirror.copyState(base, state.base),
  30. overlay: CodeMirror.copyState(overlay, state.overlay),
  31. basePos: state.basePos, baseCur: null,
  32. overlayPos: state.overlayPos, overlayCur: null
  33. };
  34. },
  35. token: function(stream, state) {
  36. if (stream.start == state.basePos) {
  37. state.baseCur = base.token(stream, state.base);
  38. state.basePos = stream.pos;
  39. }
  40. if (stream.start == state.overlayPos) {
  41. stream.pos = stream.start;
  42. state.overlayCur = overlay.token(stream, state.overlay);
  43. state.overlayPos = stream.pos;
  44. }
  45. stream.pos = Math.min(state.basePos, state.overlayPos);
  46. if (stream.eol()) state.basePos = state.overlayPos = 0;
  47. if (state.overlayCur == null) return state.baseCur;
  48. if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
  49. else return state.overlayCur;
  50. },
  51. indent: base.indent && function(state, textAfter) {
  52. return base.indent(state.base, textAfter);
  53. },
  54. electricChars: base.electricChars,
  55. innerMode: function(state) { return {state: state.base, mode: base}; },
  56. blankLine: function(state) {
  57. if (base.blankLine) base.blankLine(state.base);
  58. if (overlay.blankLine) overlay.blankLine(state.overlay);
  59. }
  60. };
  61. };
  62. });