| Index: third_party/WebKit/Source/devtools/front_end/cm_modes/jsx.js
|
| diff --git a/third_party/WebKit/Source/devtools/front_end/cm_modes/jsx.js b/third_party/WebKit/Source/devtools/front_end/cm_modes/jsx.js
|
| index c3d227a88206039d24bab7aac80490e2459fd2ba..aff01b8d355665439b84201950e7a6b0616d5dff 100644
|
| --- a/third_party/WebKit/Source/devtools/front_end/cm_modes/jsx.js
|
| +++ b/third_party/WebKit/Source/devtools/front_end/cm_modes/jsx.js
|
| @@ -11,75 +11,137 @@
|
| })(function(CodeMirror) {
|
| "use strict"
|
|
|
| + // Depth means the amount of open braces in JS context, in XML
|
| + // context 0 means not in tag, 1 means in tag, and 2 means in tag
|
| + // and js block comment.
|
| + function Context(state, mode, depth, prev) {
|
| + this.state = state; this.mode = mode; this.depth = depth; this.prev = prev
|
| + }
|
| +
|
| function copyContext(context) {
|
| - return {state: CodeMirror.copyState(context.mode, context.state),
|
| - mode: context.mode,
|
| - depth: context.depth,
|
| - prev: context.prev && copyContext(context.prev)}
|
| + return new Context(CodeMirror.copyState(context.mode, context.state),
|
| + context.mode,
|
| + context.depth,
|
| + context.prev && copyContext(context.prev))
|
| }
|
|
|
| - CodeMirror.defineMode("jsx", function(config) {
|
| - var xmlMode = CodeMirror.getMode(config, "xml")
|
| - var jsMode = CodeMirror.getMode(config, "javascript")
|
| + CodeMirror.defineMode("jsx", function(config, modeConfig) {
|
| + var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
|
| + var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
|
| +
|
| + function flatXMLIndent(state) {
|
| + var tagName = state.tagName
|
| + state.tagName = null
|
| + var result = xmlMode.indent(state, "")
|
| + state.tagName = tagName
|
| + return result
|
| + }
|
| +
|
| + function token(stream, state) {
|
| + if (state.context.mode == xmlMode)
|
| + return xmlToken(stream, state, state.context)
|
| + else
|
| + return jsToken(stream, state, state.context)
|
| + }
|
| +
|
| + function xmlToken(stream, state, cx) {
|
| + if (cx.depth == 2) { // Inside a JS /* */ comment
|
| + if (stream.match(/^.*?\*\//)) cx.depth = 1
|
| + else stream.skipToEnd()
|
| + return "comment"
|
| + }
|
| +
|
| + if (stream.peek() == "{") {
|
| + xmlMode.skipAttribute(cx.state)
|
| +
|
| + var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context
|
| + // If JS starts on same line as tag
|
| + if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) {
|
| + while (xmlContext.prev && !xmlContext.startOfLine)
|
| + xmlContext = xmlContext.prev
|
| + // If tag starts the line, use XML indentation level
|
| + if (xmlContext.startOfLine) indent -= config.indentUnit
|
| + // Else use JS indentation level
|
| + else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented
|
| + // Else if inside of tag
|
| + } else if (cx.depth == 1) {
|
| + indent += config.indentUnit
|
| + }
|
| +
|
| + state.context = new Context(CodeMirror.startState(jsMode, indent),
|
| + jsMode, 0, state.context)
|
| + return null
|
| + }
|
| +
|
| + if (cx.depth == 1) { // Inside of tag
|
| + if (stream.peek() == "<") { // Tag inside of tag
|
| + xmlMode.skipAttribute(cx.state)
|
| + state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)),
|
| + xmlMode, 0, state.context)
|
| + return null
|
| + } else if (stream.match("//")) {
|
| + stream.skipToEnd()
|
| + return "comment"
|
| + } else if (stream.match("/*")) {
|
| + cx.depth = 2
|
| + return token(stream, state)
|
| + }
|
| + }
|
| +
|
| + var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop
|
| + if (/\btag\b/.test(style)) {
|
| + if (/>$/.test(cur)) {
|
| + if (cx.state.context) cx.depth = 0
|
| + else state.context = state.context.prev
|
| + } else if (/^</.test(cur)) {
|
| + cx.depth = 1
|
| + }
|
| + } else if (!style && (stop = cur.indexOf("{")) > -1) {
|
| + stream.backUp(cur.length - stop)
|
| + }
|
| + return style
|
| + }
|
| +
|
| + function jsToken(stream, state, cx) {
|
| + if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
|
| + jsMode.skipExpression(cx.state)
|
| + state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
|
| + xmlMode, 0, state.context)
|
| + return null
|
| + }
|
| +
|
| + var style = jsMode.token(stream, cx.state)
|
| + if (!style && cx.depth != null) {
|
| + var cur = stream.current()
|
| + if (cur == "{") {
|
| + cx.depth++
|
| + } else if (cur == "}") {
|
| + if (--cx.depth == 0) state.context = state.context.prev
|
| + }
|
| + }
|
| + return style
|
| + }
|
|
|
| return {
|
| startState: function() {
|
| - return {context: {state: CodeMirror.startState(jsMode), mode: jsMode}}
|
| + return {context: new Context(CodeMirror.startState(jsMode), jsMode)}
|
| },
|
|
|
| copyState: function(state) {
|
| return {context: copyContext(state.context)}
|
| },
|
|
|
| - token: function(stream, state) {
|
| - var cx = state.context
|
| - if (cx.mode == xmlMode) {
|
| - if (stream.peek() == "{") {
|
| - xmlMode.skipAttribute(cx.state)
|
| - state.context = {state: CodeMirror.startState(jsMode, xmlMode.indent(cx.state, "")),
|
| - mode: jsMode,
|
| - depth: 1,
|
| - prev: state.context}
|
| - return jsMode.token(stream, state.context.state)
|
| - } else { // FIXME skip attribute
|
| - var style = xmlMode.token(stream, cx.state), cur, brace
|
| - if (/\btag\b/.test(style) && !cx.state.context && /^\/?>$/.test(stream.current()))
|
| - state.context = state.context.prev
|
| - else if (!style && (brace = (cur = stream.current()).indexOf("{")) > -1)
|
| - stream.backUp(cur.length - brace)
|
| - return style
|
| - }
|
| - } else { // jsMode
|
| - if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
|
| - jsMode.skipExpression(cx.state)
|
| - state.context = {state: CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
|
| - mode: xmlMode,
|
| - prev: state.context}
|
| - return xmlMode.token(stream, state.context.state)
|
| - } else {
|
| - var style = jsMode.token(stream, cx.state)
|
| - if (!style && cx.depth != null) {
|
| - var cur = stream.current()
|
| - if (cur == "{") {
|
| - cx.depth++
|
| - } else if (cur == "}") {
|
| - if (--cx.depth == 0) state.context = state.context.prev
|
| - }
|
| - }
|
| - return style
|
| - }
|
| - }
|
| - },
|
| + token: token,
|
|
|
| indent: function(state, textAfter, fullLine) {
|
| return state.context.mode.indent(state.context.state, textAfter, fullLine)
|
| },
|
|
|
| innerMode: function(state) {
|
| - return state.context[state.context.length - 1]
|
| + return state.context
|
| }
|
| }
|
| }, "xml", "javascript")
|
|
|
| CodeMirror.defineMIME("text/jsx", "jsx")
|
| -})
|
| +});
|
|
|