application/components/common/rich-editor/embed.js
import React from 'react';
import Codemirror from 'react-codemirror';
require('codemirror/mode/htmlmixed/htmlmixed');
import FlatButton from 'material-ui/FlatButton';
import TextField from 'material-ui/TextField';
import {Card, CardActions, CardHeader, CardMedia, CardTitle, CardText} from 'material-ui/Card';
import {AtomicBlockUtils, Entity} from 'draft-js';
import BaseView from './../../base-view';
/**
* Embed component handles random embed data. Mostly javascript stuff
* Includes CodeMirror editor for an extra bit of fancyness
*/
class Embed extends BaseView {
constructor(props) {
super(props);
this.displayName = 'Embed';
this.getValue = this.getValue.bind(this);
this.handleSave = this.handleSave.bind(this);
this.handleCancel = this.handleCancel.bind(this);
this.handleClick = this.handleClick.bind(this);
this.onChange = this.onChange.bind(this);
this.startEdit = this.startEdit.bind(this);
this.finishEdit = this.finishEdit.bind(this);
this.state = {
editMode: false,
code: '',
label: ''
}
}
/**
* If there is no code value, start in edit mode.
* @return {[type]} [description]
*/
componentWillMount() {
const val = this.getValue();
this.setState({code: val['content'], label: val['label']});
if (!this.getValue()) {
this.setState({'editMode': true});
this.startEdit();
}
}
onChange(code) {
this.setState({code: code});
}
onLabelChange(e) {
this.setState({label: e.target.value});
}
/**
* Return only the code string
* @return {String}
*/
getValue() {
if (!this.props.block) {
return '';
}
return this.props.contentState
.getEntity(this.props.block.getEntityAt(0))
.getData();
}
startEdit() {
if (!this.props.blockProps) {
return;
}
this.props.blockProps.onStartEdit(this.props.block.getKey());
}
finishEdit() {
if (!this.props.blockProps) {
return;
}
this.props.blockProps.onFinishEdit(this.props.block.getKey());
}
/**
* Handle start editmode on click
*/
handleClick() {
if (this.state.editMode) {
return;
}
this.setState({editMode: true}, () => { this.startEdit() });
}
handleCancel() {
this.setState({editMode: false}, () => { this.finishEdit() });
}
handleSave() {
const newContents = this.state.code
.replace(/“/g, '"')
.replace(/”/g, '"')
.replace(/‘/g, '\'')
.replace(/’/g, '\'');
const newLabel = this.state.label;
const key = this.props.block.getEntityAt(0);
this.props.contentState.mergeEntityData(key, {content: newContents, label: newLabel});
this.setState({editMode: false}, () => { this.finishEdit() });
}
render() {
let contents;
let className = 'RichEditor-embed RichEditor-pullQuote';
if (this.state.editMode) {
const cmOptions = {
lineNumbers: true,
mode: 'htmlmixed'
};
contents = (
<Card>
<CardHeader
title="Embed Code"
/>
<CardText>
<Codemirror ref="content" value={this.state.code} onChange={this.onChange} options={cmOptions} />
</CardText>
<CardActions>
<FlatButton onClick={this.handleSave} label='Done' />
<FlatButton onClick={this.handleCancel} label='Cancel' />
</CardActions>
</Card>
);
className = className + ' active';
} else {
contents = (
<Card>
<CardHeader
title="Embed Code"
/>
<CardText>
<div className="richEditor-embed-contentPreview">
{this.getValue()['content'] ? this.getValue()['content'] : 'Click to edit...'}
</div>
</CardText>
</Card>
);
}
return (
<div onClick={this.handleClick}>
{contents}
</div>
);
}}
const insertEmbed = (editorState) => {
const newContentState = editorState.getCurrentContent().createEntity(
'TOKEN',
'IMMUTABLE',
{customType: 'embed', content: '', label: ''}
);
const entityKey = newContentState.getLastCreatedEntityKey();
return AtomicBlockUtils.insertAtomicBlock(
editorState,
entityKey,
' '
);
}
export {Embed as default, insertEmbed};