Skip to content

Instantly share code, notes, and snippets.

@josephj
Created August 27, 2015 12:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josephj/2f50bc6ab0c15089f95c to your computer and use it in GitHub Desktop.
Save josephj/2f50bc6ab0c15089f95c to your computer and use it in GitHub Desktop.
'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