All files / src/ui TextEditor.js

90.48% Statements 19/21
100% Branches 0/0
80% Functions 8/10
89.47% Lines 17/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 651x 1x 1x 1x 1x       1x   2x                           1x         1x   1x 3x     1x       1x       1x                           1x 1x         1x  
import React, {Component} from 'react';
import PropTypes from 'prop-types/prop-types';
import {connect} from 'react-redux';
import {UnControlled as CodeMirror} from 'react-codemirror2';
import SHARED from '../shared';
 
// CodeMirror APIs that we need to disallow
// NOTE(Emmanuel): we should probably block 'on' and 'off'...
const unsupportedAPIs = ['startOperation', 'endOperation', 'operation'];
 
class TextEditor extends Component {
  static propTypes = {
    cmOptions: PropTypes.object,
    parser: PropTypes.object.isRequired,
    initialCode: PropTypes.string.isRequired,
    onBeforeChange: PropTypes.func,
    onMount:PropTypes.func.isRequired,
    setAnnouncer: PropTypes.func.isRequired,
    api: PropTypes.object,
    passedAST: PropTypes.object,
  }
 
  handleEditorDidMount = ed => {
    // pass the text-mode CM editor, API, and current AST
    this.props.onMount(ed, this.buildAPI(ed), this.props.passedAST);
  }
 
  // override default CM methods, or add our own
  buildAPI() {
    const api = {};
    // show which APIs are unsupported
    unsupportedAPIs.forEach(f =>
      api[f] = () => {
        throw `The CM API '${f}' is not supported in CodeMirrorBlocks`;
      });
    return api;
  }
 
  componentDidMount() {
    SHARED.parser = this.props.parser;
  }
 
  render() {
    return (
      // we add a wrapper div to maintain a consistent DOM with BlockEditor
      // see DragAndDropEditor.js for why the DND context needs a wrapper
      <div> 
        <CodeMirror
          value={this.props.initialCode}
          onBeforeChange={this.props.onBeforeChange}
          options={this.props.cmOptions}
          editorDidMount={this.handleEditorDidMount} />
      </div>
    );
  }
}
 
const mapStateToProps = _state => ({});
const mapDispatchToProps = dispatch => ({
  dispatch,
  setAnnouncer: announcer => dispatch({type: 'SET_ANNOUNCER', announcer}),
});
 
export default connect(mapStateToProps, mapDispatchToProps)(TextEditor);