'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _draftJs = require('draft-js');

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _draftJsExportHtml = require('draft-js-export-html');

var _draftJsImportHtml = require('draft-js-import-html');

var _FieldControl = require('../FieldControl');

var _FieldControl2 = _interopRequireDefault(_FieldControl);

var _BlockTypesControls = require('./BlockTypesControls');

var _BlockTypesControls2 = _interopRequireDefault(_BlockTypesControls);

var _InlineStylesControls = require('./InlineStylesControls');

var _InlineStylesControls2 = _interopRequireDefault(_InlineStylesControls);

var _index = require('./LinkButton/index');

var _index2 = _interopRequireDefault(_index);

var _tools = require('../_helpers/tools');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var draftBlockRender = _draftJs.DefaultDraftBlockRenderMap.remove('header-one').remove('header-two').remove('header-three').remove('header-four').remove('header-five').remove('header-six').remove('atomic').remove('code-block').remove('blockquote').concat({
  'text-align-left': { element: 'div' },
  'text-align-right': { element: 'div' },
  'text-align-center': { element: 'div' },
  'text-align-justify': { element: 'div' }
});

function filterClassName(type) {
  switch (type) {
    case 'text-align-left':
    case 'text-align-right':
    case 'text-align-center':
    case 'text-align-justify':
      return type;
    default:
      return undefined;
  }
}
function myBlockStyleFn(contentBlock) {
  var type = contentBlock.getType();
  return filterClassName(type);
}
var optionsStateToHTML = {
  blockStyleFn: function blockStyleFn(block) {
    var className = myBlockStyleFn(block);
    return className ? {
      attributes: { class: className }
    } : {};
  }
};
var optionsStateFromHTML = {
  customBlockFn: function customBlockFn(element) {
    var className = element.className;

    var type = filterClassName(className);
    if (type) {
      return { type: type, element: 'div' };
    }
  }
};

var Link = function Link(props) {
  var _props$contentState$g = props.contentState.getEntity(props.entityKey).getData(),
      url = _props$contentState$g.url;

  return _react2.default.createElement(
    'a',
    { href: url },
    props.children
  );
};
Link.propTypes = {
  entityKey: _propTypes2.default.string,
  children: _propTypes2.default.node,
  contentState: _propTypes2.default.object.isRequired
};

Link.defaultProps = {
  entityKey: null,
  children: null
};

function findLinkEntities(contentBlock, callback) {
  contentBlock.findEntityRanges(function (character) {
    var entityKey = character.getEntity();
    return entityKey !== null && _draftJs.Entity.get(entityKey).getType() === 'LINK';
  }, callback);
}

var RichTextEditor = function (_Component) {
  _inherits(RichTextEditor, _Component);

  function RichTextEditor(props) {
    _classCallCheck(this, RichTextEditor);

    var _this = _possibleConstructorReturn(this, (RichTextEditor.__proto__ || Object.getPrototypeOf(RichTextEditor)).call(this, props));

    _this.onChange = function (editorState) {
      var _getInputProps = (0, _tools.getInputProps)(_this.props),
          onChange = _getInputProps.onChange;

      var html = editorState.getCurrentContent().hasText() ? (0, _draftJsExportHtml.stateToHTML)(editorState.getCurrentContent(), optionsStateToHTML) : '';
      _this.setState({ editorState: editorState });
      onChange(html);
    };

    _this.setEditorContent = function () {
      var decorator = new _draftJs.CompositeDecorator([{
        strategy: findLinkEntities,
        component: Link
      }]);
      var value = (0, _tools.getInputProps)(_this.props).value || '<p></p>';
      var initialContentState = (0, _draftJsImportHtml.stateFromHTML)(value, optionsStateFromHTML);
      // this uses the DOM, so it must be restricted to the CLIENT
      _this.setState({ editorState: _draftJs.EditorState.createWithContent(initialContentState, decorator) });
    };

    _this.handleKeyCommand = function (command) {
      var editorState = _this.state.editorState;

      var newState = _draftJs.RichUtils.handleKeyCommand(editorState, command);
      if (newState) {
        _this.onChange(newState);
        return true;
      }
      return false;
    };

    _this.toggleBlockType = function (blockType) {
      _this.onChange(_draftJs.RichUtils.toggleBlockType(_this.state.editorState, blockType));
    };

    _this.toggleInlineStyle = function (inlineStyle) {
      _this.onChange(_draftJs.RichUtils.toggleInlineStyle(_this.state.editorState, inlineStyle));
    };

    _this.focus = function () {
      _this.editor.focus();
    };

    _this.state = { editorState: _draftJs.EditorState.createEmpty() };
    return _this;
  }

  _createClass(RichTextEditor, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      this.setEditorContent();
    }
  }, {
    key: 'componentWillReceiveProps',
    value: function componentWillReceiveProps(nextProps) {
      var _getInputProps2 = (0, _tools.getInputProps)(this.props),
          value = _getInputProps2.value;

      var _getInputProps3 = (0, _tools.getInputProps)(nextProps),
          valueNextProps = _getInputProps3.value;

      if (value === '' && valueNextProps !== '') {
        var contentState = (0, _draftJsImportHtml.stateFromHTML)(valueNextProps, optionsStateFromHTML);
        // this uses the DOM, so it must be restricted to the CLIENT
        this.state = {
          editorState: _draftJs.EditorState.push(this.state.editorState, contentState, 'insert-fragment')
        };
      } else if (valueNextProps === '') {
        var _contentState = (0, _draftJsImportHtml.stateFromHTML)(valueNextProps, optionsStateFromHTML);
        // this uses the DOM, so it must be restricted to the CLIENT
        this.setState({
          editorState: _draftJs.EditorState.push(this.state.editorState, _contentState, 'insert-fragment')
        });
      }
    }
  }, {
    key: 'render',
    value: function render() {
      var _this2 = this;

      var _props = this.props,
          className = _props.className,
          editorClassName = _props.editorClassName,
          disabled = _props.disabled,
          props = _objectWithoutProperties(_props, ['className', 'editorClassName', 'disabled']);

      var _getInputProps4 = (0, _tools.getInputProps)(props),
          value = _getInputProps4.value;

      var editorState = this.state.editorState;

      return _react2.default.createElement(
        _FieldControl2.default,
        props,
        _react2.default.createElement(
          'div',
          {
            className: (0, _classnames2.default)('rich-text-editor', className, { 'rich-text-editor--disabled': disabled })
          },
          _react2.default.createElement(
            'div',
            { className: 'rich-text-editor--controls' },
            _react2.default.createElement(_InlineStylesControls2.default, {
              editorState: editorState,
              onToggle: this.toggleInlineStyle,
              controls: [{ label: 'B', style: 'BOLD', className: 'bold' }, { label: 'I', style: 'ITALIC', className: 'italic' }, { label: 'U', style: 'UNDERLINE', className: 'underline' }]
            }),
            _react2.default.createElement(_index2.default, { className: 'link', editorState: editorState, label: '', onChange: this.onChange }),
            _react2.default.createElement(_BlockTypesControls2.default, {
              editorState: editorState,
              onToggle: this.toggleBlockType,
              controls: [{ label: '', style: 'unordered-list-item', className: 'unordered-list' }, { label: '', style: 'ordered-list-item', className: 'ordered-list' }]
            }),
            _react2.default.createElement(_BlockTypesControls2.default, {
              editorState: editorState,
              onToggle: this.toggleBlockType,
              controls: [{ label: '', style: 'text-align-left', className: 'align-left' }, { label: '', style: 'text-align-center', className: 'align-center' }, { label: '', style: 'text-align-right', className: 'align-right' }, { label: '', style: 'text-align-justify', className: 'align-justify' }]
            })
          ),
          _react2.default.createElement(
            'div',
            { className: (0, _classnames2.default)(editorClassName, 'editor-wrapper') },
            disabled ? _react2.default.createElement('div', { dangerouslySetInnerHTML: { __html: value } }) : _react2.default.createElement(_draftJs.Editor, {
              ref: function ref(_ref) {
                _this2.editor = _ref;
              },
              editorState: editorState,
              onChange: this.onChange,
              handleKeyCommand: this.handleKeyCommand,
              blockRenderMap: draftBlockRender,
              blockStyleFn: myBlockStyleFn
            })
          )
        )
      );
    }
  }]);

  return RichTextEditor;
}(_react.Component);

RichTextEditor.propTypes = {
  value: _propTypes2.default.string,
  onChange: _propTypes2.default.func,
  className: _propTypes2.default.string,
  editorClassName: _propTypes2.default.string,
  disabled: _propTypes2.default.bool
};

RichTextEditor.defaultProps = {
  value: '',
  onChange: null,
  className: undefined,
  editorClassName: undefined,
  disabled: false
};

exports.default = RichTextEditor;
module.exports = exports['default'];