Skip to content

Commit

Permalink
[jsx mode] Only recognize comments inside of tags
Browse files Browse the repository at this point in the history
Issue #3745
  • Loading branch information
marijnh committed Dec 30, 2015
1 parent d103ebf commit bec6669
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 17 deletions.
35 changes: 22 additions & 13 deletions mode/jsx/jsx.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
})(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
}
Expand All @@ -23,7 +26,7 @@
}

CodeMirror.defineMode("jsx", function(config) {
var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true})
var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
var jsMode = CodeMirror.getMode(config, "javascript")

return {
Expand All @@ -38,38 +41,44 @@
token: function(stream, state) {
var cx = state.context
if (cx.mode == xmlMode) {
if (cx.depth) { // Inside a JS /* */ comment
if (stream.match(/^.*?\*\//)) cx.depth = 0
if (cx.depth == 2) { // Inside a JS /* */ comment
if (stream.match(/^.*?\*\//)) cx.depth = 1
else stream.skipToEnd()
return "comment"
} else if (stream.peek() == "{") {
xmlMode.skipAttribute(cx.state)
var tagName = cx.state.tagName
cx.state.tagName = null
state.context = new Context(CodeMirror.startState(jsMode, xmlMode.indent(cx.state, "")),
jsMode, 1, state.context)
jsMode, 0, state.context)
cx.state.tagName = tagName
return jsMode.token(stream, state.context.state)
} else if (stream.match("//")) {
return this.token(stream, state)
} else if (cx.depth == 1 && stream.match("//")) {
stream.skipToEnd()
return "comment"
} else if (stream.match("/*")) {
cx.depth = 1
} else if (cx.depth == 1 && stream.match("/*")) {
cx.depth = 2
return this.token(stream, state)
} else { // FIXME skip attribute
var style = xmlMode.token(stream, cx.state), cur, stop
if (/\btag\b/.test(style) && !cx.state.context && /^\/?>$/.test(stream.current()))
state.context = state.context.prev
else if (!style && (stop = (cur = stream.current()).search(/\{|\/[*\/]/)) > -1)
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
}
} else { // jsMode
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 xmlMode.token(stream, state.context.state)
return this.token(stream, state)
} else {
var style = jsMode.token(stream, cx.state)
if (!style && cx.depth != null) {
Expand Down
17 changes: 13 additions & 4 deletions mode/jsx/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,22 @@
"[variable x] [operator =] [string-2 `quasi${][bracket&tag <][tag foo][bracket&tag />][string-2 }quoted`]")

MT("line_comment",
"([bracket&tag <][tag foo][bracket&tag >] [comment // hello]",
"([bracket&tag <][tag foo] [comment // hello]",
" [bracket&tag ></][tag foo][bracket&tag >][operator ++])")

MT("line_comment_not_in_tag",
"([bracket&tag <][tag foo][bracket&tag >] // hello",
" [bracket&tag </][tag foo][bracket&tag >][operator ++])")

MT("block_comment",
"([bracket&tag <][tag foo][bracket&tag >] [comment /* hello]",
"[comment line 2]",
"[comment line 3 */] [bracket&tag </][tag foo][bracket&tag >][operator ++])")
"([bracket&tag <][tag foo] [comment /* hello]",
"[comment line 2]",
"[comment line 3 */] [bracket&tag ></][tag foo][bracket&tag >][operator ++])")

MT("block_comment_not_in_tag",
"([bracket&tag <][tag foo][bracket&tag >]/* hello",
" line 2",
" line 3 */ [bracket&tag </][tag foo][bracket&tag >][operator ++])")

MT("missing_attr",
"([bracket&tag <][tag foo] [attribute selected][bracket&tag />][operator ++])")
Expand Down

0 comments on commit bec6669

Please sign in to comment.