Merge branch '2.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / js / 3rdParty / codemirror / addon / mode / multiplex.js
CommitLineData
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 11CodeMirror.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});