123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- // CodeMirror, copyright (c) by Marijn Haverbeke and others
- // Distributed under an MIT license: https://codemirror.net/LICENSE
- ;(function (mod) {
- if (typeof exports == 'object' && typeof module == 'object')
- // CommonJS
- mod(require('../../lib/codemirror'))
- else if (typeof define == 'function' && define.amd)
- // AMD
- define(['../../lib/codemirror'], mod)
- // Plain browser env
- else mod(CodeMirror)
- })(function (CodeMirror) {
- 'use strict'
- CodeMirror.multiplexingMode = function (outer /*, others */) {
- // Others should be {open, close, mode [, delimStyle] [, innerStyle] [, parseDelimiters]} objects
- var others = Array.prototype.slice.call(arguments, 1)
- function indexOf(string, pattern, from, returnEnd) {
- if (typeof pattern == 'string') {
- var found = string.indexOf(pattern, from)
- return returnEnd && found > -1 ? found + pattern.length : found
- }
- var m = pattern.exec(from ? string.slice(from) : string)
- return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1
- }
- return {
- startState: function () {
- return {
- outer: CodeMirror.startState(outer),
- innerActive: null,
- inner: null,
- startingInner: false,
- }
- },
- copyState: function (state) {
- return {
- outer: CodeMirror.copyState(outer, state.outer),
- innerActive: state.innerActive,
- inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner),
- startingInner: state.startingInner,
- }
- },
- token: function (stream, state) {
- if (!state.innerActive) {
- var cutOff = Infinity,
- oldContent = stream.string
- for (var i = 0; i < others.length; ++i) {
- var other = others[i]
- var found = indexOf(oldContent, other.open, stream.pos)
- if (found == stream.pos) {
- if (!other.parseDelimiters) stream.match(other.open)
- state.startingInner = !!other.parseDelimiters
- state.innerActive = other
- // Get the outer indent, making sure to handle CodeMirror.Pass
- var outerIndent = 0
- if (outer.indent) {
- var possibleOuterIndent = outer.indent(state.outer, '', '')
- if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent
- }
- state.inner = CodeMirror.startState(other.mode, outerIndent)
- return other.delimStyle && other.delimStyle + ' ' + other.delimStyle + '-open'
- } else if (found != -1 && found < cutOff) {
- cutOff = found
- }
- }
- if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff)
- var outerToken = outer.token(stream, state.outer)
- if (cutOff != Infinity) stream.string = oldContent
- return outerToken
- } else {
- var curInner = state.innerActive,
- oldContent = stream.string
- if (!curInner.close && stream.sol()) {
- state.innerActive = state.inner = null
- return this.token(stream, state)
- }
- var found = curInner.close && !state.startingInner ? indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1
- if (found == stream.pos && !curInner.parseDelimiters) {
- stream.match(curInner.close)
- state.innerActive = state.inner = null
- return curInner.delimStyle && curInner.delimStyle + ' ' + curInner.delimStyle + '-close'
- }
- if (found > -1) stream.string = oldContent.slice(0, found)
- var innerToken = curInner.mode.token(stream, state.inner)
- if (found > -1) stream.string = oldContent
- else if (stream.pos > stream.start) state.startingInner = false
- if (found == stream.pos && curInner.parseDelimiters) state.innerActive = state.inner = null
- if (curInner.innerStyle) {
- if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle
- else innerToken = curInner.innerStyle
- }
- return innerToken
- }
- },
- indent: function (state, textAfter, line) {
- var mode = state.innerActive ? state.innerActive.mode : outer
- if (!mode.indent) return CodeMirror.Pass
- return mode.indent(state.innerActive ? state.inner : state.outer, textAfter, line)
- },
- blankLine: function (state) {
- var mode = state.innerActive ? state.innerActive.mode : outer
- if (mode.blankLine) {
- mode.blankLine(state.innerActive ? state.inner : state.outer)
- }
- if (!state.innerActive) {
- for (var i = 0; i < others.length; ++i) {
- var other = others[i]
- if (other.open === '\n') {
- state.innerActive = other
- state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, '', '') : 0)
- }
- }
- } else if (state.innerActive.close === '\n') {
- state.innerActive = state.inner = null
- }
- },
- electricChars: outer.electricChars,
- innerMode: function (state) {
- return state.inner ? { state: state.inner, mode: state.innerActive.mode } : { state: state.outer, mode: outer }
- },
- }
- }
- })
|