mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-13 15:12:43 +00:00
Merge branch 'styleEditor' into noHtml
This commit is contained in:
@@ -33,7 +33,7 @@ const ContinousSave = React.createClass({
|
|||||||
window.onbeforeunload = function(){};
|
window.onbeforeunload = function(){};
|
||||||
},
|
},
|
||||||
actionHandler : function(actionType){
|
actionHandler : function(actionType){
|
||||||
if(actionType == 'UPDATE_BREW_TEXT' || actionType == 'UPDATE_META'){
|
if(actionType == 'UPDATE_BREW_CODE' || actionType == 'UPDATE_META' || actionType == 'UPDATE_BREW_STYLE'){
|
||||||
Actions.pendingSave();
|
Actions.pendingSave();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -51,6 +51,9 @@ const ContinousSave = React.createClass({
|
|||||||
Oops!
|
Oops!
|
||||||
<div className='errorContainer'>
|
<div className='errorContainer'>
|
||||||
Looks like there was a problem saving. <br />
|
Looks like there was a problem saving. <br />
|
||||||
|
Back up your brew in a text file, just in case.
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
Report the issue <a target='_blank' href={'https://github.com/stolksdorf/naturalcrit/issues/new?body='+ encodeURIComponent(errMsg)}>
|
Report the issue <a target='_blank' href={'https://github.com/stolksdorf/naturalcrit/issues/new?body='+ encodeURIComponent(errMsg)}>
|
||||||
here
|
here
|
||||||
</a>.
|
</a>.
|
||||||
|
|||||||
@@ -120,7 +120,7 @@
|
|||||||
top : 29px;
|
top : 29px;
|
||||||
left : -20px;
|
left : -20px;
|
||||||
z-index : 1000;
|
z-index : 1000;
|
||||||
width : 120px;
|
width : 170px;
|
||||||
padding : 8px;
|
padding : 8px;
|
||||||
background-color : #333;
|
background-color : #333;
|
||||||
a{
|
a{
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"codemirror",
|
"codemirror",
|
||||||
"codemirror/mode/gfm/gfm.js",
|
"codemirror/mode/gfm/gfm.js",
|
||||||
"codemirror/mode/javascript/javascript.js",
|
"codemirror/mode/javascript/javascript.js",
|
||||||
|
"codemirror/mode/css/css.js",
|
||||||
"moment",
|
"moment",
|
||||||
"superagent",
|
"superagent",
|
||||||
"marked",
|
"marked",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const BrewSchema = mongoose.Schema({
|
|||||||
editId : {type : String, default: shortid.generate, index: { unique: true }},
|
editId : {type : String, default: shortid.generate, index: { unique: true }},
|
||||||
|
|
||||||
text : {type : String, default : ""},
|
text : {type : String, default : ""},
|
||||||
|
style : {type : String, default : ""},
|
||||||
|
|
||||||
title : {type : String, default : ""},
|
title : {type : String, default : ""},
|
||||||
description : {type : String, default : ""},
|
description : {type : String, default : ""},
|
||||||
@@ -23,7 +24,7 @@ const BrewSchema = mongoose.Schema({
|
|||||||
updatedAt : { type: Date, default: Date.now},
|
updatedAt : { type: Date, default: Date.now},
|
||||||
lastViewed : { type: Date, default: Date.now},
|
lastViewed : { type: Date, default: Date.now},
|
||||||
views : {type:Number, default:0},
|
views : {type:Number, default:0},
|
||||||
version : {type: Number, default:1}
|
version : {type: Number, default:2}
|
||||||
}, {
|
}, {
|
||||||
versionKey: false,
|
versionKey: false,
|
||||||
toJSON : {
|
toJSON : {
|
||||||
|
|||||||
@@ -54,10 +54,13 @@ const Actions = {
|
|||||||
setBrew : (brew) => {
|
setBrew : (brew) => {
|
||||||
dispatch('SET_BREW', brew);
|
dispatch('SET_BREW', brew);
|
||||||
},
|
},
|
||||||
updateBrewText : (brewText) => {
|
updateBrewCode : (brewCode) => {
|
||||||
dispatch('UPDATE_BREW_TEXT', brewText)
|
dispatch('UPDATE_BREW_CODE', brewCode)
|
||||||
},
|
},
|
||||||
updateMetaData : (meta) => {
|
updateBrewStyle : (style) => {
|
||||||
|
dispatch('UPDATE_BREW_STYLE', style)
|
||||||
|
},
|
||||||
|
updateMetadata : (meta) => {
|
||||||
dispatch('UPDATE_META', meta);
|
dispatch('UPDATE_META', meta);
|
||||||
},
|
},
|
||||||
pendingSave : () => {
|
pendingSave : () => {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ let State = {
|
|||||||
|
|
||||||
brew : {
|
brew : {
|
||||||
text : '',
|
text : '',
|
||||||
|
style : '',
|
||||||
shareId : undefined,
|
shareId : undefined,
|
||||||
editId : undefined,
|
editId : undefined,
|
||||||
createdAt : undefined,
|
createdAt : undefined,
|
||||||
@@ -29,9 +30,13 @@ const Store = flux.createStore({
|
|||||||
SET_BREW : (brew) => {
|
SET_BREW : (brew) => {
|
||||||
State.brew = brew;
|
State.brew = brew;
|
||||||
},
|
},
|
||||||
UPDATE_BREW_TEXT : (brewText) => {
|
UPDATE_BREW_CODE : (brewCode) => {
|
||||||
State.brew.text = brewText;
|
State.brew.text = brewCode;
|
||||||
State.errors = Markdown.validate(brewText);
|
State.errors = Markdown.validate(brewCode);
|
||||||
|
},
|
||||||
|
UPDATE_BREW_STYLE : (style) => {
|
||||||
|
//TODO: add in an error checker?
|
||||||
|
State.brew.style = style;
|
||||||
},
|
},
|
||||||
UPDATE_META : (meta) => {
|
UPDATE_META : (meta) => {
|
||||||
State.brew = _.merge({}, State.brew, meta);
|
State.brew = _.merge({}, State.brew, meta);
|
||||||
@@ -50,11 +55,14 @@ Store.init = (state)=>{
|
|||||||
Store.getBrew = ()=>{
|
Store.getBrew = ()=>{
|
||||||
return State.brew;
|
return State.brew;
|
||||||
};
|
};
|
||||||
Store.getBrewText = ()=>{
|
Store.getBrewCode = ()=>{
|
||||||
return State.brew.text;
|
return State.brew.text;
|
||||||
};
|
};
|
||||||
|
Store.getBrewStyle = ()=>{
|
||||||
|
return State.brew.style;
|
||||||
|
};
|
||||||
Store.getMetaData = ()=>{
|
Store.getMetaData = ()=>{
|
||||||
return _.omit(State.brew, ['text']);
|
return _.omit(State.brew, ['text', 'style']);
|
||||||
};
|
};
|
||||||
Store.getErrors = ()=>{
|
Store.getErrors = ()=>{
|
||||||
return State.errors;
|
return State.errors;
|
||||||
|
|||||||
@@ -6,35 +6,36 @@ const CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx');
|
|||||||
const SnippetBar = require('./snippetbar/snippetbar.jsx');
|
const SnippetBar = require('./snippetbar/snippetbar.jsx');
|
||||||
const MetadataEditor = require('./metadataEditor/metadataEditor.jsx');
|
const MetadataEditor = require('./metadataEditor/metadataEditor.jsx');
|
||||||
|
|
||||||
|
const Menubar = require('./menubar/menubar.jsx');
|
||||||
|
|
||||||
const splice = function(str, index, inject){
|
const splice = function(str, index, inject){
|
||||||
return str.slice(0, index) + inject + str.slice(index);
|
return str.slice(0, index) + inject + str.slice(index);
|
||||||
};
|
};
|
||||||
|
|
||||||
const SNIPPETBAR_HEIGHT = 25;
|
const MENUBAR_HEIGHT = 25;
|
||||||
|
|
||||||
const BrewEditor = React.createClass({
|
const BrewEditor = React.createClass({
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
value : '',
|
brew : {
|
||||||
onChange : ()=>{},
|
text : '',
|
||||||
|
style : '',
|
||||||
|
},
|
||||||
|
|
||||||
metadata : {},
|
onCodeChange : ()=>{},
|
||||||
onMetadataChange : ()=>{},
|
onStyleChange : ()=>{},
|
||||||
|
onMetaChange : ()=>{},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
showMetadataEditor: false
|
view : 'code', //'code', 'style', 'meta'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
cursorPosition : {
|
|
||||||
line : 0,
|
|
||||||
ch : 0
|
|
||||||
},
|
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
this.updateEditorSize();
|
this.updateEditorSize();
|
||||||
this.highlightPageLines();
|
//this.highlightPageLines();
|
||||||
window.addEventListener("resize", this.updateEditorSize);
|
window.addEventListener("resize", this.updateEditorSize);
|
||||||
},
|
},
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
@@ -42,17 +43,15 @@ const BrewEditor = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateEditorSize : function() {
|
updateEditorSize : function() {
|
||||||
|
if(this.refs.codeEditor){
|
||||||
let paneHeight = this.refs.main.parentNode.clientHeight;
|
let paneHeight = this.refs.main.parentNode.clientHeight;
|
||||||
paneHeight -= SNIPPETBAR_HEIGHT + 1;
|
paneHeight -= MENUBAR_HEIGHT + 1;
|
||||||
this.refs.codeEditor.codeMirror.setSize(null, paneHeight);
|
this.refs.codeEditor.codeMirror.setSize(null, paneHeight);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTextChange : function(text){
|
|
||||||
this.props.onChange(text);
|
|
||||||
},
|
|
||||||
handleCursorActivty : function(curpos){
|
|
||||||
this.cursorPosition = curpos;
|
|
||||||
},
|
|
||||||
handleInject : function(injectText){
|
handleInject : function(injectText){
|
||||||
const lines = this.props.value.split('\n');
|
const lines = this.props.value.split('\n');
|
||||||
lines[this.cursorPosition.line] = splice(lines[this.cursorPosition.line], this.cursorPosition.ch, injectText);
|
lines[this.cursorPosition.line] = splice(lines[this.cursorPosition.line], this.cursorPosition.ch, injectText);
|
||||||
@@ -60,23 +59,32 @@ const BrewEditor = React.createClass({
|
|||||||
this.handleTextChange(lines.join('\n'));
|
this.handleTextChange(lines.join('\n'));
|
||||||
this.refs.codeEditor.setCursorPosition(this.cursorPosition.line, this.cursorPosition.ch + injectText.length);
|
this.refs.codeEditor.setCursorPosition(this.cursorPosition.line, this.cursorPosition.ch + injectText.length);
|
||||||
},
|
},
|
||||||
handgleToggle : function(){
|
|
||||||
|
|
||||||
|
|
||||||
|
handleViewChange : function(newView){
|
||||||
this.setState({
|
this.setState({
|
||||||
showMetadataEditor : !this.state.showMetadataEditor
|
view : newView
|
||||||
})
|
}, this.updateEditorSize);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
brewJump : function(){
|
brewJump : function(){
|
||||||
const currentPage = this.getCurrentPage();
|
const currentPage = this.getCurrentPage();
|
||||||
window.location.hash = 'p' + currentPage;
|
window.location.hash = 'p' + currentPage;
|
||||||
},
|
},
|
||||||
|
|
||||||
//Called when there are changes to the editor's dimensions
|
//Called when there are changes to the editor's dimensions
|
||||||
|
/*
|
||||||
update : function(){
|
update : function(){
|
||||||
this.refs.codeEditor.updateSize();
|
if(this.refs.codeEditor) this.refs.codeEditor.updateSize();
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
//TODO: convert this into a generic function for columns and blocks
|
//TODO: convert this into a generic function for columns and blocks
|
||||||
|
//MOve this to a util.sj file
|
||||||
highlightPageLines : function(){
|
highlightPageLines : function(){
|
||||||
if(!this.refs.codeEditor) return;
|
if(!this.refs.codeEditor) return;
|
||||||
const codeMirror = this.refs.codeEditor.codeMirror;
|
const codeMirror = this.refs.codeEditor.codeMirror;
|
||||||
@@ -91,6 +99,7 @@ const BrewEditor = React.createClass({
|
|||||||
return lineNumbers
|
return lineNumbers
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
renderMetadataEditor : function(){
|
renderMetadataEditor : function(){
|
||||||
if(!this.state.showMetadataEditor) return;
|
if(!this.state.showMetadataEditor) return;
|
||||||
return <MetadataEditor
|
return <MetadataEditor
|
||||||
@@ -98,25 +107,49 @@ const BrewEditor = React.createClass({
|
|||||||
onChange={this.props.onMetadataChange}
|
onChange={this.props.onMetadataChange}
|
||||||
/>
|
/>
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
renderEditor : function(){
|
||||||
|
if(this.state.view == 'meta'){
|
||||||
|
return <MetadataEditor
|
||||||
|
metadata={this.props.brew}
|
||||||
|
onChange={this.props.onMetaChange} />
|
||||||
|
}
|
||||||
|
if(this.state.view == 'style'){
|
||||||
|
return <CodeEditor key='style'
|
||||||
|
ref='codeEditor'
|
||||||
|
language='css'
|
||||||
|
value={this.props.brew.style}
|
||||||
|
onChange={this.props.onStyleChange} />
|
||||||
|
}
|
||||||
|
if(this.state.view == 'code'){
|
||||||
|
return <CodeEditor key='code'
|
||||||
|
ref='codeEditor'
|
||||||
|
language='gfm'
|
||||||
|
value={this.props.brew.text}
|
||||||
|
onChange={this.props.onCodeChange} />
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
|
|
||||||
this.highlightPageLines();
|
|
||||||
|
|
||||||
return <div className='brewEditor' ref='main'>
|
return <div className='brewEditor' ref='main'>
|
||||||
|
{/*
|
||||||
<SnippetBar
|
<SnippetBar
|
||||||
brew={this.props.value}
|
brew={this.props.value}
|
||||||
onInject={this.handleInject}
|
onInject={this.handleInject}
|
||||||
onToggle={this.handgleToggle}
|
onToggle={this.handgleToggle}
|
||||||
showmeta={this.state.showMetadataEditor} />
|
showmeta={this.state.showMetadataEditor} />
|
||||||
{this.renderMetadataEditor()}
|
*/}
|
||||||
<CodeEditor
|
<Menubar
|
||||||
ref='codeEditor'
|
view={this.state.view}
|
||||||
wrap={true}
|
onViewChange={this.handleViewChange}
|
||||||
language='gfm'
|
|
||||||
value={this.props.value}
|
/>
|
||||||
onChange={this.handleTextChange}
|
|
||||||
onCursorActivity={this.handleCursorActivty} />
|
{this.renderEditor()}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ const BrewEditor = require('./brewEditor.jsx')
|
|||||||
|
|
||||||
module.exports = Store.createSmartComponent(BrewEditor, ()=>{
|
module.exports = Store.createSmartComponent(BrewEditor, ()=>{
|
||||||
return {
|
return {
|
||||||
value : Store.getBrewText(),
|
brew : Store.getBrew(),
|
||||||
onChange : Actions.updateBrewText,
|
|
||||||
metadata : Store.getMetaData(),
|
onCodeChange : Actions.updateBrewCode,
|
||||||
onMetadataChange : Actions.updateMetaData,
|
onStyleChange : Actions.updateBrewStyle,
|
||||||
|
onMetaChange : Actions.updateMetadata,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
35
shared/homebrewery/brewEditor/menubar/menubar.jsx
Normal file
35
shared/homebrewery/brewEditor/menubar/menubar.jsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
const React = require('react');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const cx = require('classnames');
|
||||||
|
|
||||||
|
const Menubar = React.createClass({
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
view : '',
|
||||||
|
onViewChange : ()=>{},
|
||||||
|
onSnippetInject : ()=>{},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render: function(){
|
||||||
|
return <div className='menubar'>
|
||||||
|
|
||||||
|
<div className='editors'>
|
||||||
|
<div className={cx('code', {selected : this.props.view == 'code'})}
|
||||||
|
onClick={this.props.onViewChange.bind(null, 'code')}>
|
||||||
|
<i className='fa fa-beer' />
|
||||||
|
</div>
|
||||||
|
<div className={cx('style', {selected : this.props.view == 'style'})}
|
||||||
|
onClick={this.props.onViewChange.bind(null, 'style')}>
|
||||||
|
<i className='fa fa-paint-brush' />
|
||||||
|
</div>
|
||||||
|
<div className={cx('meta', {selected : this.props.view == 'meta'})}
|
||||||
|
onClick={this.props.onViewChange.bind(null, 'meta')}>
|
||||||
|
<i className='fa fa-bars' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = Menubar;
|
||||||
35
shared/homebrewery/brewEditor/menubar/menubar.less
Normal file
35
shared/homebrewery/brewEditor/menubar/menubar.less
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
.menubar{
|
||||||
|
@menuHeight : 25px;
|
||||||
|
position : relative;
|
||||||
|
height : @menuHeight;
|
||||||
|
background-color : #ddd;
|
||||||
|
.editors{
|
||||||
|
position : absolute;
|
||||||
|
display : flex;
|
||||||
|
top : 0px;
|
||||||
|
right : 0px;
|
||||||
|
height : @menuHeight;
|
||||||
|
width : 90px;
|
||||||
|
justify-content : space-between;
|
||||||
|
&>div{
|
||||||
|
height : @menuHeight;
|
||||||
|
width : @menuHeight;
|
||||||
|
cursor : pointer;
|
||||||
|
line-height : @menuHeight;
|
||||||
|
text-align : center;
|
||||||
|
&:hover,&.selected{
|
||||||
|
background-color : #999;
|
||||||
|
}
|
||||||
|
&.code{
|
||||||
|
.tooltipLeft('Brew Editor');
|
||||||
|
}
|
||||||
|
&.style{
|
||||||
|
.tooltipLeft('Style Editor');
|
||||||
|
}
|
||||||
|
&.meta{
|
||||||
|
.tooltipLeft('Metadata');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
.metadataEditor{
|
.metadataEditor{
|
||||||
position : absolute;
|
position : absolute;
|
||||||
z-index : 10000;
|
|
||||||
box-sizing : border-box;
|
box-sizing : border-box;
|
||||||
width : 100%;
|
width : 100%;
|
||||||
padding : 25px;
|
padding : 25px;
|
||||||
background-color : #999;
|
// background-color : #999;
|
||||||
|
background-color: white;
|
||||||
.field{
|
.field{
|
||||||
display : flex;
|
display : flex;
|
||||||
width : 100%;
|
width : 100%;
|
||||||
|
|||||||
@@ -15,12 +15,13 @@ const PPR_THRESHOLD = 50;
|
|||||||
const BrewRenderer = React.createClass({
|
const BrewRenderer = React.createClass({
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
brewText : '',
|
value : '',
|
||||||
|
style : '',
|
||||||
errors : []
|
errors : []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
const pages = this.props.brewText.split('\\page');
|
const pages = this.props.value.split('\\page');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
viewablePageNumber: 0,
|
viewablePageNumber: 0,
|
||||||
@@ -45,7 +46,7 @@ const BrewRenderer = React.createClass({
|
|||||||
componentWillReceiveProps: function(nextProps) {
|
componentWillReceiveProps: function(nextProps) {
|
||||||
if(this.refs.pages && this.refs.pages.firstChild) this.pageHeight = this.refs.pages.firstChild.clientHeight;
|
if(this.refs.pages && this.refs.pages.firstChild) this.pageHeight = this.refs.pages.firstChild.clientHeight;
|
||||||
|
|
||||||
const pages = nextProps.brewText.split('\\page');
|
const pages = nextProps.value.split('\\page');
|
||||||
this.setState({
|
this.setState({
|
||||||
pages : pages,
|
pages : pages,
|
||||||
usePPR : pages.length >= PPR_THRESHOLD
|
usePPR : pages.length >= PPR_THRESHOLD
|
||||||
@@ -124,6 +125,10 @@ const BrewRenderer = React.createClass({
|
|||||||
return this.lastRender;
|
return this.lastRender;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderStyle : function(){
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
return <div className='brewRenderer'
|
return <div className='brewRenderer'
|
||||||
onScroll={this.handleScroll}
|
onScroll={this.handleScroll}
|
||||||
@@ -133,6 +138,8 @@ const BrewRenderer = React.createClass({
|
|||||||
<ErrorBar errors={this.props.errors} />
|
<ErrorBar errors={this.props.errors} />
|
||||||
<RenderWarnings />
|
<RenderWarnings />
|
||||||
|
|
||||||
|
|
||||||
|
<style>{this.props.style}</style>
|
||||||
<div className='pages' ref='pages'>
|
<div className='pages' ref='pages'>
|
||||||
{this.renderPages()}
|
{this.renderPages()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ const BrewRenderer = require('./brewRenderer.jsx');
|
|||||||
|
|
||||||
module.exports = Store.createSmartComponent(BrewRenderer, () => {
|
module.exports = Store.createSmartComponent(BrewRenderer, () => {
|
||||||
return {
|
return {
|
||||||
brewText : Store.getBrewText(),
|
value : Store.getBrewCode(),
|
||||||
|
style : Store.getBrewStyle(),
|
||||||
errors : Store.getErrors()
|
errors : Store.getErrors()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1,70 +1,70 @@
|
|||||||
var React = require('react');
|
const React = require('react');
|
||||||
var _ = require('lodash');
|
const _ = require('lodash');
|
||||||
var cx = require('classnames');
|
const cx = require('classnames');
|
||||||
|
|
||||||
|
let CodeMirror;
|
||||||
var CodeMirror;
|
|
||||||
if(typeof navigator !== 'undefined'){
|
if(typeof navigator !== 'undefined'){
|
||||||
var CodeMirror = require('codemirror');
|
CodeMirror = require('codemirror');
|
||||||
|
|
||||||
//Language Modes
|
//Language Modes
|
||||||
require('codemirror/mode/gfm/gfm.js'); //Github flavoured markdown
|
require('codemirror/mode/gfm/gfm.js'); //Github flavoured markdown
|
||||||
require('codemirror/mode/javascript/javascript.js');
|
require('codemirror/mode/javascript/javascript.js');
|
||||||
|
require('codemirror/mode/css/css.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var CodeEditor = React.createClass({
|
const CodeEditor = React.createClass({
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
language : '',
|
|
||||||
value : '',
|
value : '',
|
||||||
wrap : false,
|
|
||||||
onChange : function(){},
|
language : '',
|
||||||
onCursorActivity : function(){},
|
wrap : true,
|
||||||
|
onChange : ()=>{},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
componentWillReceiveProps: function(nextProps){
|
||||||
|
if(this.props.language !== nextProps.language){
|
||||||
|
this.buildEditor();
|
||||||
|
}
|
||||||
|
if(this.codeMirror && nextProps.value !== undefined && this.codeMirror.getValue() != nextProps.value) {
|
||||||
|
this.codeMirror.setValue(nextProps.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shouldComponentUpdate: function(nextProps, nextState) {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
this.buildEditor();
|
||||||
|
},
|
||||||
|
buildEditor : function(){
|
||||||
this.codeMirror = CodeMirror(this.refs.editor,{
|
this.codeMirror = CodeMirror(this.refs.editor,{
|
||||||
value : this.props.value,
|
value : this.props.value,
|
||||||
lineNumbers : true,
|
lineNumbers : true,
|
||||||
lineWrapping : this.props.wrap,
|
lineWrapping : this.props.wrap,
|
||||||
mode : this.props.language,
|
mode : this.props.language,
|
||||||
|
indentWithTabs : true,
|
||||||
|
tabSize : 2
|
||||||
|
});
|
||||||
|
this.codeMirror.on('change', ()=>{
|
||||||
|
this.props.onChange(this.codeMirror.getValue());
|
||||||
});
|
});
|
||||||
|
|
||||||
this.codeMirror.on('change', this.handleChange);
|
|
||||||
this.codeMirror.on('cursorActivity', this.handleCursorActivity);
|
|
||||||
this.updateSize();
|
this.updateSize();
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillReceiveProps: function(nextProps){
|
//Externally Used
|
||||||
if(this.codeMirror && nextProps.value !== undefined && this.codeMirror.getValue() != nextProps.value) {
|
|
||||||
this.codeMirror.setValue(nextProps.value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
shouldComponentUpdate: function(nextProps, nextState) {
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
setCursorPosition : function(line, char){
|
setCursorPosition : function(line, char){
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
this.codeMirror.focus();
|
this.codeMirror.focus();
|
||||||
this.codeMirror.doc.setCursor(line, char);
|
this.codeMirror.doc.setCursor(line, char);
|
||||||
}, 10);
|
}, 10);
|
||||||
},
|
},
|
||||||
|
getCursorPosition : function(){
|
||||||
|
return this.codeMirror.getCursor();
|
||||||
|
},
|
||||||
updateSize : function(){
|
updateSize : function(){
|
||||||
this.codeMirror.refresh();
|
this.codeMirror.refresh();
|
||||||
},
|
},
|
||||||
|
|
||||||
handleChange : function(editor){
|
|
||||||
this.props.onChange(editor.getValue());
|
|
||||||
},
|
|
||||||
handleCursorActivity : function(){
|
|
||||||
this.props.onCursorActivity(this.codeMirror.doc.getCursor());
|
|
||||||
},
|
|
||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
return <div className='codeEditor' ref='editor' />
|
return <div className='codeEditor' ref='editor' />
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user