diff --git a/src/components/layers/JSONEditor.jsx b/src/components/layers/JSONEditor.jsx index 2f01b824..466c8652 100644 --- a/src/components/layers/JSONEditor.jsx +++ b/src/components/layers/JSONEditor.jsx @@ -1,9 +1,9 @@ import React from 'react' import PropTypes from 'prop-types' -import {Controlled as CodeMirror} from 'react-codemirror2' import InputBlock from '../inputs/InputBlock' import StringInput from '../inputs/StringInput' +import CodeMirror from 'codemirror'; import 'codemirror/mode/javascript/javascript' import 'codemirror/addon/lint/lint' @@ -25,36 +25,82 @@ class JSONEditor extends React.Component { constructor(props) { super(props) this.state = { - code: JSON.stringify(props.layer, null, 2) - } + isEditing: false, + prevValue: this.getValue(), + }; + } + + getValue () { + return JSON.stringify(this.props.layer, null, 2); + } + + componentDidMount () { + this._doc = CodeMirror(this._el, { + value: this.getValue(), + mode: { + name: "javascript", + json: true + }, + tabSize: 2, + theme: 'maputnik', + viewportMargin: Infinity, + lineNumbers: true, + lint: true, + gutters: ["CodeMirror-lint-markers"], + scrollbarStyle: "null", + }); + + this._doc.on('change', this.onChange); + this._doc.on('focus', this.onFocus); + this._doc.on('blur', this.onBlur); + } + + onFocus = () => { + this.setState({ + isEditing: true + }); + } + + onBlur = () => { + this.setState({ + isEditing: false + }); + } + + componentWillUnMount () { + this._doc.off('change', this.onChange); + this._doc.off('focus', this.onFocus); + this._doc.off('blur', this.onBlur); } componentDidUpdate(prevProps) { - if (prevProps.layer !== this.props.layer) { - this.setState({ - code: JSON.stringify(this.props.layer, null, 2) - }) + if (!this.state.isEditing && prevProps.layer !== this.props.layer) { + this._cancelNextChange = true; + this._doc.setValue( + this.getValue(), + ) } } - onCodeUpdate(newCode) { - try { - const parsedLayer = JSON.parse(newCode) - this.props.onChange(parsedLayer) - } catch(err) { - console.warn(err) - } finally { - this.setState({ - code: newCode - }) + onChange = (e) => { + if (this._cancelNextChange) { + this._cancelNextChange = false; + return; + } + const newCode = this._doc.getValue(); + + if (this.state.prevValue !== newCode) { + try { + const parsedLayer = JSON.parse(newCode) + this.props.onChange(parsedLayer) + } catch(err) { + console.warn(err) + } } - } - resetValue() { - console.log('reset') this.setState({ - code: JSON.stringify(this.props.layer, null, 2) - }) + prevValue: newCode, + }); } render() { @@ -69,12 +115,7 @@ class JSONEditor extends React.Component { scrollbarStyle: "null", } - return this.onCodeUpdate(value)} - onFocusChange={focused => focused ? true : this.resetValue()} - options={codeMirrorOptions} - /> + return
this._el = el} /> } }