LaravelTest
148 строк · 5.1 Кб
1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: https://codemirror.net/LICENSE
3
4(function(mod) {5if (typeof exports == "object" && typeof module == "object") // CommonJS6mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"))7else if (typeof define == "function" && define.amd) // AMD8define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod)9else // Plain browser env10mod(CodeMirror)11})(function(CodeMirror) {12"use strict"13
14// Depth means the amount of open braces in JS context, in XML15// context 0 means not in tag, 1 means in tag, and 2 means in tag16// and js block comment.17function Context(state, mode, depth, prev) {18this.state = state; this.mode = mode; this.depth = depth; this.prev = prev19}20
21function copyContext(context) {22return new Context(CodeMirror.copyState(context.mode, context.state),23context.mode,24context.depth,25context.prev && copyContext(context.prev))26}27
28CodeMirror.defineMode("jsx", function(config, modeConfig) {29var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false, allowMissingTagName: true})30var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")31
32function flatXMLIndent(state) {33var tagName = state.tagName34state.tagName = null35var result = xmlMode.indent(state, "", "")36state.tagName = tagName37return result38}39
40function token(stream, state) {41if (state.context.mode == xmlMode)42return xmlToken(stream, state, state.context)43else44return jsToken(stream, state, state.context)45}46
47function xmlToken(stream, state, cx) {48if (cx.depth == 2) { // Inside a JS /* */ comment49if (stream.match(/^.*?\*\//)) cx.depth = 150else stream.skipToEnd()51return "comment"52}53
54if (stream.peek() == "{") {55xmlMode.skipAttribute(cx.state)56
57var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context58// If JS starts on same line as tag59if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) {60while (xmlContext.prev && !xmlContext.startOfLine)61xmlContext = xmlContext.prev62// If tag starts the line, use XML indentation level63if (xmlContext.startOfLine) indent -= config.indentUnit64// Else use JS indentation level65else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented66// Else if inside of tag67} else if (cx.depth == 1) {68indent += config.indentUnit69}70
71state.context = new Context(CodeMirror.startState(jsMode, indent),72jsMode, 0, state.context)73return null74}75
76if (cx.depth == 1) { // Inside of tag77if (stream.peek() == "<") { // Tag inside of tag78xmlMode.skipAttribute(cx.state)79state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)),80xmlMode, 0, state.context)81return null82} else if (stream.match("//")) {83stream.skipToEnd()84return "comment"85} else if (stream.match("/*")) {86cx.depth = 287return token(stream, state)88}89}90
91var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop92if (/\btag\b/.test(style)) {93if (/>$/.test(cur)) {94if (cx.state.context) cx.depth = 095else state.context = state.context.prev96} else if (/^</.test(cur)) {97cx.depth = 198}99} else if (!style && (stop = cur.indexOf("{")) > -1) {100stream.backUp(cur.length - stop)101}102return style103}104
105function jsToken(stream, state, cx) {106if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {107state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "", "")),108xmlMode, 0, state.context)109jsMode.skipExpression(cx.state)110return null111}112
113var style = jsMode.token(stream, cx.state)114if (!style && cx.depth != null) {115var cur = stream.current()116if (cur == "{") {117cx.depth++118} else if (cur == "}") {119if (--cx.depth == 0) state.context = state.context.prev120}121}122return style123}124
125return {126startState: function() {127return {context: new Context(CodeMirror.startState(jsMode), jsMode)}128},129
130copyState: function(state) {131return {context: copyContext(state.context)}132},133
134token: token,135
136indent: function(state, textAfter, fullLine) {137return state.context.mode.indent(state.context.state, textAfter, fullLine)138},139
140innerMode: function(state) {141return state.context142}143}144}, "xml", "javascript")145
146CodeMirror.defineMIME("text/jsx", "jsx")147CodeMirror.defineMIME("text/typescript-jsx", {name: "jsx", base: {name: "javascript", typescript: true}})148});149