Commit | Line | Data |
---|---|---|
837afb80 TD |
1 | (function(mod) { |
2 | if (typeof exports == "object" && typeof module == "object") // CommonJS | |
3 | mod(require("../../lib/codemirror")); | |
4 | else if (typeof define == "function" && define.amd) // AMD | |
5 | define(["../../lib/codemirror"], mod); | |
6 | else // Plain browser env | |
7 | mod(CodeMirror); | |
8 | })(function(CodeMirror) { | |
9 | "use strict"; | |
10 | ||
77b7b761 | 11 | CodeMirror.multiplexingMode = function(outer /*, others */) { |
837afb80 | 12 | // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects |
77b7b761 TD |
13 | var others = Array.prototype.slice.call(arguments, 1); |
14 | var n_others = others.length; | |
15 | ||
16 | function indexOf(string, pattern, from) { | |
17 | if (typeof pattern == "string") return string.indexOf(pattern, from); | |
18 | var m = pattern.exec(from ? string.slice(from) : string); | |
19 | return m ? m.index + from : -1; | |
20 | } | |
21 | ||
22 | return { | |
23 | startState: function() { | |
24 | return { | |
25 | outer: CodeMirror.startState(outer), | |
26 | innerActive: null, | |
27 | inner: null | |
28 | }; | |
29 | }, | |
30 | ||
31 | copyState: function(state) { | |
32 | return { | |
33 | outer: CodeMirror.copyState(outer, state.outer), | |
34 | innerActive: state.innerActive, | |
35 | inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner) | |
36 | }; | |
37 | }, | |
38 | ||
39 | token: function(stream, state) { | |
40 | if (!state.innerActive) { | |
41 | var cutOff = Infinity, oldContent = stream.string; | |
42 | for (var i = 0; i < n_others; ++i) { | |
43 | var other = others[i]; | |
44 | var found = indexOf(oldContent, other.open, stream.pos); | |
45 | if (found == stream.pos) { | |
46 | stream.match(other.open); | |
47 | state.innerActive = other; | |
48 | state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); | |
49 | return other.delimStyle; | |
50 | } else if (found != -1 && found < cutOff) { | |
51 | cutOff = found; | |
52 | } | |
53 | } | |
54 | if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff); | |
55 | var outerToken = outer.token(stream, state.outer); | |
56 | if (cutOff != Infinity) stream.string = oldContent; | |
57 | return outerToken; | |
58 | } else { | |
59 | var curInner = state.innerActive, oldContent = stream.string; | |
837afb80 TD |
60 | if (!curInner.close && stream.sol()) { |
61 | state.innerActive = state.inner = null; | |
62 | return this.token(stream, state); | |
63 | } | |
64 | var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos) : -1; | |
77b7b761 TD |
65 | if (found == stream.pos) { |
66 | stream.match(curInner.close); | |
67 | state.innerActive = state.inner = null; | |
68 | return curInner.delimStyle; | |
69 | } | |
70 | if (found > -1) stream.string = oldContent.slice(0, found); | |
71 | var innerToken = curInner.mode.token(stream, state.inner); | |
72 | if (found > -1) stream.string = oldContent; | |
837afb80 TD |
73 | |
74 | if (curInner.innerStyle) { | |
75 | if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle; | |
76 | else innerToken = curInner.innerStyle; | |
77 | } | |
78 | ||
77b7b761 TD |
79 | return innerToken; |
80 | } | |
81 | }, | |
82 | ||
83 | indent: function(state, textAfter) { | |
84 | var mode = state.innerActive ? state.innerActive.mode : outer; | |
85 | if (!mode.indent) return CodeMirror.Pass; | |
86 | return mode.indent(state.innerActive ? state.inner : state.outer, textAfter); | |
87 | }, | |
88 | ||
89 | blankLine: function(state) { | |
90 | var mode = state.innerActive ? state.innerActive.mode : outer; | |
91 | if (mode.blankLine) { | |
92 | mode.blankLine(state.innerActive ? state.inner : state.outer); | |
93 | } | |
94 | if (!state.innerActive) { | |
95 | for (var i = 0; i < n_others; ++i) { | |
96 | var other = others[i]; | |
97 | if (other.open === "\n") { | |
98 | state.innerActive = other; | |
99 | state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0); | |
100 | } | |
101 | } | |
102 | } else if (state.innerActive.close === "\n") { | |
103 | state.innerActive = state.inner = null; | |
104 | } | |
105 | }, | |
106 | ||
107 | electricChars: outer.electricChars, | |
108 | ||
109 | innerMode: function(state) { | |
110 | return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer}; | |
111 | } | |
112 | }; | |
113 | }; | |
837afb80 TD |
114 | |
115 | }); |