├── LICENSE ├── README.md └── jsx.js /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Kevin Kwok 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # codemirror-jsx 2 | CodeMirror Mode for React E4X/JSX 3 | -------------------------------------------------------------------------------- /jsx.js: -------------------------------------------------------------------------------- 1 | // based on https://github.com/rarous/brackets-jsx/blob/cf2653505b2db92c5d8f8aa0fe68dc4774beefe5/main.js 2 | 3 | var CodeMirror = require('codemirror') 4 | 5 | CodeMirror.defineMode("jsx", function(config, parserConfig) { 6 | var jsMode = CodeMirror.getMode(config, "javascript"); 7 | var xmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true}); 8 | 9 | function js(stream, state) { 10 | if ((state.jsState.lastType == "operator" 11 | || state.jsState.lastType == "keyword c" 12 | || state.jsState.lastType == "=>" 13 | || /^[\[{}\(,;:]$/.test(state.jsState.lastType)) 14 | && stream.match(/^<[a-zA-Z]+/i, false)) { 15 | state.token = xml; 16 | return xmlMode.token(stream, state.localState); 17 | state.localState = xmlMode.startState(jsMode.indent(state.jsState, "")); 18 | state.localMode = xmlMode; 19 | state.indented = stream.backUp(1); 20 | return xml(stream, state); 21 | } 22 | return jsMode.token(stream, state.jsState);; 23 | } 24 | 25 | function xml(stream, state) { 26 | var oldContext = state.localState.context 27 | var style = xmlMode.token(stream, state.localState); 28 | if(oldContext && !state.localState.context){ 29 | state.token = js; 30 | return jsMode.token(stream, state.jsState); 31 | } 32 | return style 33 | } 34 | 35 | return { 36 | startState: function() { 37 | var state = jsMode.startState(); 38 | var xmlState = xmlMode.startState(); 39 | return {token: js, localState: xmlState, jsState: state}; 40 | }, 41 | 42 | copyState: function(state) { 43 | return {token: state.token, 44 | localState: CodeMirror.copyState(xmlMode, state.localState), 45 | jsState: CodeMirror.copyState(jsMode, state.jsState)}; 46 | }, 47 | 48 | token: function(stream, state) { 49 | return state.token(stream, state); 50 | }, 51 | 52 | indent: function(state, textAfter) { 53 | if (state.token == js) 54 | return jsMode.indent(state.jsState, textAfter); 55 | else 56 | return xmlMode.indent(state.localState, textAfter); 57 | }, 58 | blockCommentStart: "/*", 59 | blockCommentEnd: "*/", 60 | lineComment: "//", 61 | fold: "brace", 62 | closeBrackets: "()[]{}''\"\"``", 63 | electricChars: "/{}:" 64 | }; 65 | }); 66 | --------------------------------------------------------------------------------