Created
August 27, 2015 12:15
-
-
Save josephj/2f50bc6ab0c15089f95c 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'; | |
/** | |
* <CodeEditor | |
* data={that.state.data} | |
* stack={that.state.stack} | |
* hidden={(that.state.viewMode !== 'code')} | |
* onChange={that.handleEditorChange}/> | |
*/ | |
// Main stylesheet | |
import '!style!css!sass!admin/widgets/_code-editor.scss'; | |
// Tools | |
import React from 'react'; | |
import _ from 'lodash'; | |
import cx from 'classnames'; | |
import joinClasses from 'react/lib/joinClasses'; | |
import LogMixin from 'js/common/log-mixin'; | |
// UI Kit Components | |
import ButtonGroup from 'stackla-uikit/js/button-group'; | |
import Button from 'stackla-uikit/js/button'; | |
import Icon from 'stackla-uikit/js/icon'; | |
import CodeMirror from 'stackla-uikit/jsx/codemirror'; | |
import less from 'exports?less!js/admin/less-1.4.1.min.js'; | |
// Constants | |
const CLASS_NAME = 'CodeEditor'; | |
module.exports = React.createClass({ | |
//=================== | |
// Properties | |
//=================== | |
displayName: CLASS_NAME, | |
mixins: [LogMixin], | |
propTypes: { | |
data: React.PropTypes.object, | |
hidden: React.PropTypes.bool, | |
mode: React.PropTypes.string, | |
stack: React.PropTypes.string, | |
onChange: React.PropTypes.func | |
}, | |
//=================== | |
// Core Methods | |
//=================== | |
toString () { | |
return CLASS_NAME; | |
}, | |
getDefaultProps () { | |
return { | |
data: {}, | |
hidden: false, | |
mode: 'inline', | |
stack: null, | |
onChange: function () {} | |
}; | |
}, | |
getInitialState () { | |
var that = this, | |
data = that.props.data; | |
return { | |
mode: that.props.mode, | |
reloadCount: 0, | |
sourceCss: data.source_css, | |
customCss: data.custom_css, | |
customJs: data.custom_js, | |
hasLightbox: true, | |
lightboxSourceCss: data.lightbox_source_css, | |
lightboxCustomCss: data.lightbox_custom_css, | |
lightboxCustomJs: data.lightbox_custom_js | |
}; | |
}, | |
render () { | |
var that = this, | |
props = that.props, | |
src = `/${props.stack}/admin/widgets/style_preview/${props.data.id}?r=${that.state.reloadCount}`, | |
mode = that.state.mode, | |
title = (mode === 'inline') ? 'Inline Tile ' : 'Expanded Tile ', | |
classNames = joinClasses(props.className, 'codeEditor', (!props.hidden) && 'is-active'), | |
hasLightbox = (props.data.style.type === 'fluid'), | |
isVisible = props.hidden, | |
switchNode; | |
that.log('render() is executed'); | |
if (hasLightbox) { | |
switchNode = ( | |
<div className="codeEditor-switcher"> | |
<a href="javascript:void(0)" | |
className={cx('codeEditor-switchLink', {'is-active': (mode === 'inline')})} | |
onClick={that.handleSwitch.bind(that, 'inline')}> | |
Inline Tile | |
</a>{' '} | |
|{' '} | |
<a href="javascript:void(0)" | |
className={cx('codeEditor-switchLink', {'is-active': (mode === 'expanded')})} | |
onClick={that.handleSwitch.bind(that, 'expanded')}> | |
Expanded Tile | |
</a> | |
</div> | |
); | |
} else { | |
title = 'Tile '; | |
switchNode = ( | |
<div className="codeEditor-switcher"> | |
<span>Inline Tile</span> | |
</div> | |
); | |
} | |
return ( | |
<div className={classNames}> | |
{switchNode} | |
<div className="codeEditor-panel"> | |
<div className={cx('codeEditor-editorGroup', (mode === 'inline') && 'is-active')}> | |
<div className="codeEditor-editorItem"> | |
<div className="codeEditor-editorTitle">{title + 'CSS'}</div> | |
<CodeMirror | |
ref="sourceCss" | |
mode="text/x-less" | |
className="codeEditor-editor" | |
value={that.state.sourceCss} | |
onChange={that.handleChange.bind(that, 'source_css')}/> | |
</div> | |
<div className="codeEditor-editorItem"> | |
<div className="codeEditor-editorTitle">{title + 'JS'}</div> | |
<CodeMirror | |
ref="customJs" | |
className="codeEditor-editor" | |
value={that.state.customJs} | |
onChange={that.handleChange.bind(that, 'custom_js')}/> | |
</div> | |
</div> | |
<div className={cx('codeEditor-editorGroup', (mode === 'expanded') && 'is-active')}> | |
<div className="codeEditor-editorItem"> | |
<div className="codeEditor-editorTitle">{title + 'CSS'}</div> | |
<CodeMirror | |
ref="lightboxSourceCss" | |
mode="text/x-less" | |
className="codeEditor-editor" | |
value={that.state.lightboxSourceCss} | |
onChange={that.handleChange.bind(that, 'lightbox_source_css')}/> | |
</div> | |
<div className="codeEditor-editorItem"> | |
<div className="codeEditor-editorTitle">{title + 'JS'}</div> | |
<CodeMirror | |
ref="lightboxCustomJs" | |
className="codeEditor-editor" | |
value={that.state.lightboxCustomJs} | |
onChange={that.handleChange.bind(that, 'lightbox_custom_js')}/> | |
</div> | |
</div> | |
</div> | |
<div className="codeEditor-previewer"> | |
<div className="codeEditor-editorTitle">{title + 'Preview'}</div> | |
<iframe className="codeEditor-frame" src={src} scrolling="no"></iframe> | |
</div> | |
{that.props.children} | |
</div> | |
); | |
}, | |
componentWillMount () { | |
var that = this, | |
refs = that.refs; | |
that.log('componentDidMount() is executed'); | |
that.lessParser = new(less.Parser); | |
}, | |
componentWillUnmount () { | |
var that = this, | |
refs = that.refs; | |
that.log('componentDidUnmount() is executed'); | |
that.lessParser = null; | |
}, | |
//================ | |
// Event Handlers | |
//================ | |
handleSwitch (mode) { | |
var that = this; | |
that.log('handleSwitch("' + mode + '") is executed'); | |
that.setState({'mode': mode}); | |
}, | |
handleChange (type, e) { | |
var that = this, | |
data = {}, | |
code = e.target.value; | |
that.log('handleChange(' + type + ') is executed'); | |
data[type] = code; | |
switch (type) { | |
case 'custom_js': | |
that.setState({customJs: code}) | |
break; | |
case 'lightbox_custom_js': | |
that.setState({lightboxCustomJs: code}) | |
break; | |
case 'source_css': | |
that.setState({sourceCss: code}) | |
var result = that.parse(code); | |
if (result !== false) { | |
data.lightbox_custom_css = result; | |
that.setState({lightboxCustomCss: result}); | |
} | |
break; | |
case 'lightbox_source_css': | |
that.setState({lightboxSourceCss: code}) | |
var result = that.parse(code); | |
if (result !== false) { | |
data.lightbox_custom_css = result; | |
that.setState({lightboxCustomCss: result}); | |
} | |
break; | |
} | |
that.props.onChange(data); | |
}, | |
parse (value, callback) { | |
var that = this; | |
that.log('parse() is executed'); | |
that.lessParser.parse(value, function (err, tree) { | |
// Lint Error | |
if (err) { | |
value = false; | |
that.parsed = false; | |
that.parseError = '"' + err.message + '" at line ' + err.line; | |
return; | |
} | |
// Parsing Error | |
try { | |
value = tree.toCSS(); | |
} catch (e) { | |
value = false; | |
that.parsed = false; | |
that.parseError = e.message; | |
return; | |
} | |
that.parsed = true; | |
that.parseError = ''; | |
}); | |
return value; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment