Last active
August 27, 2015 12:36
-
-
Save josephj/70c2df5f889a32c545a1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/** | |
* <CodeMirror | |
* mode="text/css" | |
* value={that.state.customCss} | |
* onChange={that.handleEditorChange}/> | |
*/ | |
// CodeMirror modules | |
import 'codemirror/lib/codemirror.css'; | |
import 'codemirror/mode/javascript/javascript.js'; | |
import 'codemirror/mode/css/css.js'; | |
import 'codemirror/theme/ambiance.css'; | |
import 'codemirror/addon/edit/matchbrackets.js'; | |
import 'codemirror/addon/lint/lint.css'; | |
import 'codemirror/addon/hint/javascript-hint.js'; | |
import 'codemirror/addon/hint/css-hint.js'; | |
import 'codemirror/addon/lint/lint.js'; | |
import 'codemirror/addon/lint/javascript-lint.js'; | |
import 'codemirror/addon/lint/json-lint.js'; | |
import 'codemirror/addon/lint/css-lint.js'; | |
import 'codemirror/addon/scroll/simplescrollbars.css'; | |
import 'codemirror/addon/scroll/simplescrollbars.js'; | |
// Tools | |
import React from 'react'; | |
import _ from 'lodash'; | |
import LogMixin from 'js/common/log-mixin'; | |
import joinClasses from 'react/lib/joinClasses'; | |
import CodeMirror from 'codemirror'; | |
const IS_MOBILE = typeof navigator === 'undefined' || ( | |
navigator.userAgent.match(/Android/i) | |
|| navigator.userAgent.match(/webOS/i) | |
|| navigator.userAgent.match(/iPhone/i) | |
|| navigator.userAgent.match(/iPad/i) | |
|| navigator.userAgent.match(/iPod/i) | |
|| navigator.userAgent.match(/BlackBerry/i) | |
|| navigator.userAgent.match(/Windows Phone/i) | |
); | |
module.exports = React.createClass({ | |
//=================== | |
// Properties | |
//=================== | |
displayName: 'CodeMirror', | |
mixins: [LogMixin], | |
propTypes: { | |
indentUnit: React.PropTypes.number, | |
indentWithTabs: React.PropTypes.bool, | |
lineNumbers: React.PropTypes.bool, | |
lint: React.PropTypes.bool, | |
matchBrackets: React.PropTypes.bool, | |
mode: React.PropTypes.string, | |
onChange: React.PropTypes.func, | |
smartIndent: React.PropTypes.bool, | |
tabSize: React.PropTypes.number, | |
theme: React.PropTypes.string, | |
value: React.PropTypes.string, | |
}, | |
//=================== | |
// Core Methods | |
//=================== | |
toString () { | |
return 'CodeMirror' | |
}, | |
getDefaultProps () { | |
return { | |
gutters: ['CodeMirror-lint-markers'], | |
indentUnit: 4, | |
indentWithTabs: true, | |
lineNumbers: true, | |
lint: true, | |
matchBrackets: true, | |
mode: 'javascript', | |
scrollbarStyle: 'simple', | |
smartIndent: true, | |
tabSize: 4, | |
theme: 'ambiance' | |
} | |
}, | |
render () { | |
let that = this, | |
props = that.props, | |
className = {}, | |
style = {}; | |
that.log('render() is executed'); | |
_.assign(style, props.style); | |
delete props.style | |
className.wrapper = joinClasses(props.className); | |
return ( | |
<div | |
ref="editor" | |
style={style} | |
className={className.wrapper}> | |
</div> | |
); | |
}, | |
//=================== | |
// Lifecycle Methods | |
//=================== | |
componentDidMount () { | |
let that = this, | |
isTextarea = that.props.forceTextArea || IS_MOBILE; | |
that.log('componentDidMount() is executed'); | |
if (!isTextarea) { | |
that.editor = CodeMirror(that.refs.editor.getDOMNode(), that.props); | |
that.editor.on('change', that.handleChange); | |
} | |
}, | |
componentDidUpdate () { | |
let that = this, | |
nextValue, | |
prevValue; | |
that.log('componentDidUpdate() is executed'); | |
if (!that.editor) { | |
return; | |
} | |
prevValue = that.editor.getValue(); | |
nextValue = that.props.value; | |
if (prevValue === nextValue) { | |
return; | |
} | |
that.editor.setValue(that.props.value); | |
}, | |
//================ | |
// Event Handlers | |
//================ | |
handleChange (e) { | |
let that = this, | |
prevValue, | |
nextValue; | |
that.log('handleChange() is executed'); | |
// Stop if it's normal textarea | |
if (!that.editor) { | |
return; | |
} | |
prevValue = that.props.value; | |
nextValue = that.editor.getValue(); | |
// Stop if previous value is same with current value | |
if (prevValue === nextValue) { | |
return; | |
} | |
that.props.onChange && that.props.onChange({target: {value: nextValue}}); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment