'use strict';

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

var _react = require('react');

var React = _interopRequireWildcard(_react);

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

var _immutable = require('immutable');

var _Toolbar = require('../Toolbar');

var _ConfigStore = require('./ConfigStore');

var _ConfigStore2 = _interopRequireDefault(_ConfigStore);

var _getHTML = require('./export/getHTML');

var _getHTML2 = _interopRequireDefault(_getHTML);

var _exportText = require('./export/exportText');

var _exportText2 = _interopRequireDefault(_exportText);

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

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } }

function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }

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) : _defaults(subClass, superClass); }

var __assign = undefined && undefined.__assign || Object.assign || function (t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) {
            if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
        }
    }
    return t;
};
var hasCommandModifier = _draftJs.KeyBindingUtil.hasCommandModifier;

function noop() {}
;
var defaultPluginConfig = {};
var toolbar = (0, _Toolbar.createToolbar)();
var configStore = new _ConfigStore2["default"]();

var EditorCore = function (_React$Component) {
    _inherits(EditorCore, _React$Component);

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

        var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));

        _this.plugins = (0, _immutable.List)((0, _immutable.List)(props.plugins).flatten(true));
        var editorState = void 0;
        if (props.value !== undefined) {
            if (props.value instanceof _draftJs.EditorState) {
                editorState = props.value || _draftJs.EditorState.createEmpty();
            } else {
                editorState = _draftJs.EditorState.createEmpty();
            }
        } else {
            editorState = _draftJs.EditorState.createEmpty();
        }
        editorState = _this.generatorDefaultValue(editorState);
        _this.state = {
            plugins: _this.reloadPlugins(),
            editorState: editorState,
            customStyleMap: {},
            customBlockStyleMap: {},
            compositeDecorator: null
        };
        if (props.value !== undefined) {
            _this.controlledMode = true;
            console.warn('this component is in controllred mode');
        }
        return _this;
    }

    EditorCore.ToEditorState = function ToEditorState(text) {
        var createEmptyContentState = _draftJs.ContentState.createFromText((0, _exportText.decodeContent)(text) || '');
        var editorState = _draftJs.EditorState.createWithContent(createEmptyContentState);
        return _draftJs.EditorState.forceSelection(editorState, createEmptyContentState.getSelectionAfter());
    };

    EditorCore.prototype.Reset = function Reset() {
        var defaultValue = this.props.defaultValue;

        this.setEditorState(_draftJs.EditorState.push(this.state.editorState, defaultValue ? defaultValue.getCurrentContent() : _draftJs.ContentState.createFromText(''), 'remove-range'));
    };

    EditorCore.prototype.SetText = function SetText(text) {
        var createTextContentState = _draftJs.ContentState.createFromText(text || '');
        var editorState = _draftJs.EditorState.push(this.state.editorState, createTextContentState, 'change-block-data');
        this.setEditorState(_draftJs.EditorState.moveFocusToEnd(editorState), true);
    };

    EditorCore.prototype.reloadPlugins = function reloadPlugins() {
        var _this2 = this;

        return this.plugins && this.plugins.size ? this.plugins.map(function (plugin) {
            if (plugin.callbacks) {
                return plugin;
            }
            if (plugin.hasOwnProperty('constructor')) {
                var pluginConfig = Object.assign(_this2.props.pluginConfig, plugin.config || {}, defaultPluginConfig);
                return plugin.constructor(pluginConfig);
            }
            console.warn('>> 插件: [', plugin.name, '] 无效。插件或许已经过期。');
            return false;
        }).filter(function (plugin) {
            return plugin;
        }).toArray() : [];
    };

    EditorCore.prototype.componentWillMount = function componentWillMount() {
        var plugins = this.initPlugins().concat([toolbar]);
        var customStyleMap = {};
        var customBlockStyleMap = {};
        var customBlockRenderMap = (0, _immutable.Map)(_draftJs.DefaultDraftBlockRenderMap);
        var compositeDecorator = new _draftJs.CompositeDecorator(plugins.filter(function (plugin) {
            return plugin.decorators !== undefined;
        }).map(function (plugin) {
            return plugin.decorators;
        }).reduce(function (prev, curr) {
            return prev.concat(curr);
        }, []));
        var toolbarPlugins = (0, _immutable.List)(plugins.filter(function (plugin) {
            return !!plugin.component && plugin.name !== 'toolbar';
        }));
        plugins.forEach(function (plugin) {
            var styleMap = plugin.styleMap,
                blockStyleMap = plugin.blockStyleMap,
                blockRenderMap = plugin.blockRenderMap;

            if (styleMap) {
                for (var key in styleMap) {
                    if (styleMap.hasOwnProperty(key)) {
                        customStyleMap[key] = styleMap[key];
                    }
                }
            }
            if (blockStyleMap) {
                for (var _key in blockStyleMap) {
                    if (blockStyleMap.hasOwnProperty(_key)) {
                        customBlockStyleMap[_key] = blockStyleMap[_key];
                        customBlockRenderMap = customBlockRenderMap.set(_key, {
                            element: null
                        });
                    }
                }
            }
            if (blockRenderMap) {
                for (var _key2 in blockRenderMap) {
                    if (blockRenderMap.hasOwnProperty(_key2)) {
                        customBlockRenderMap = customBlockRenderMap.set(_key2, blockRenderMap[_key2]);
                    }
                }
            }
        });
        configStore.set('customStyleMap', customStyleMap);
        configStore.set('customBlockStyleMap', customBlockStyleMap);
        configStore.set('blockRenderMap', customBlockRenderMap);
        configStore.set('customStyleFn', this.customStyleFn.bind(this));
        this.setState({
            toolbarPlugins: toolbarPlugins,
            compositeDecorator: compositeDecorator
        });
        this.setEditorState(_draftJs.EditorState.set(this.state.editorState, { decorator: compositeDecorator }));
    };

    EditorCore.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
        if (this.controlledMode) {
            var decorators = nextProps.value.getDecorator();
            var editorState = decorators ? nextProps.value : _draftJs.EditorState.set(nextProps.value, { decorator: this.state.compositeDecorator });
            this.setState({
                editorState: editorState
            });
        }
    };

    EditorCore.prototype.generatorDefaultValue = function generatorDefaultValue(editorState) {
        var defaultValue = this.props.defaultValue;

        if (defaultValue) {
            return defaultValue;
        }
        return editorState;
    };

    EditorCore.prototype.getStyleMap = function getStyleMap() {
        return configStore.get('customStyleMap');
    };

    EditorCore.prototype.setStyleMap = function setStyleMap(customStyleMap) {
        configStore.set('customStyleMap', customStyleMap);
        this.render();
    };

    EditorCore.prototype.initPlugins = function initPlugins() {
        var _this3 = this;

        var enableCallbacks = ['getEditorState', 'setEditorState', 'getStyleMap', 'setStyleMap'];
        return this.getPlugins().map(function (plugin) {
            enableCallbacks.forEach(function (callbackName) {
                if (plugin.callbacks.hasOwnProperty(callbackName)) {
                    plugin.callbacks[callbackName] = _this3[callbackName].bind(_this3);
                }
            });
            return plugin;
        });
    };

    EditorCore.prototype.focus = function focus(ev) {
        var _this4 = this;

        var editorState = this.state.editorState;

        if (editorState.getSelection().getHasFocus()) {
            this.refs.editor.focus(ev);
        } else {
            this.setState({
                editorState: _draftJs.EditorState.moveFocusToEnd(editorState)
            }, function () {
                _this4.refs.editor.focus(ev);
                if (_this4.props.onFocus) {
                    _this4.props.onFocus(ev);
                }
            });
        }
    };

    EditorCore.prototype.getPlugins = function getPlugins() {
        return this.state.plugins.slice();
    };

    EditorCore.prototype.getEventHandler = function getEventHandler() {
        var _this5 = this;

        var enabledEvents = ['onUpArrow', 'onDownArrow', 'handleReturn', 'onFocus', 'onBlur', 'handlePastedText'];
        var eventHandler = {};
        enabledEvents.forEach(function (event) {
            eventHandler[event] = _this5.generatorEventHandler(event);
        });
        return eventHandler;
    };

    EditorCore.prototype.getEditorState = function getEditorState() {
        return this.state.editorState;
    };

    EditorCore.prototype.setEditorState = function setEditorState(editorState) {
        var _this6 = this;

        var focusEditor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

        var newEditorState = editorState;
        this.getPlugins().forEach(function (plugin) {
            if (plugin.onChange) {
                var updatedEditorState = plugin.onChange(newEditorState);
                if (updatedEditorState) {
                    newEditorState = updatedEditorState;
                }
            }
        });
        if (this.props.onChange) {
            this.props.onChange(newEditorState);
        }
        if (!this.controlledMode) {
            this.setState({ editorState: newEditorState }, focusEditor ? function () {
                return setTimeout(function () {
                    return _this6.refs.editor.focus();
                }, 100);
            } : noop);
        }
    };

    EditorCore.prototype.handleKeyBinding = function handleKeyBinding(ev) {
        if (this.props.onKeyDown) {
            ev.ctrlKey = hasCommandModifier(ev);
            var keyDownResult = this.props.onKeyDown(ev);
            if (keyDownResult) {
                return keyDownResult;
            }
            return (0, _draftJs.getDefaultKeyBinding)(ev);
        }
        return (0, _draftJs.getDefaultKeyBinding)(ev);
    };

    EditorCore.prototype.handleKeyCommand = function handleKeyCommand(command) {
        if (this.props.multiLines) {
            return this.eventHandle('handleKeyBinding', command);
        }
        return command === 'split-block' ? 'handled' : 'not-handled';
    };

    EditorCore.prototype.getBlockStyle = function getBlockStyle(contentBlock) {
        var customBlockStyleMap = configStore.get('customBlockStyleMap');
        var type = contentBlock.getType();
        if (customBlockStyleMap.hasOwnProperty(type)) {
            return customBlockStyleMap[type];
        }
    };

    EditorCore.prototype.blockRendererFn = function blockRendererFn(contentBlock) {
        var blockRenderResult = null;
        this.getPlugins().forEach(function (plugin) {
            if (plugin.blockRendererFn) {
                var result = plugin.blockRendererFn(contentBlock);
                if (result) {
                    blockRenderResult = result;
                }
            }
        });
        return blockRenderResult;
    };

    EditorCore.prototype.eventHandle = function eventHandle(eventName) {
        var _props;

        var plugins = this.getPlugins();

        for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key3 = 1; _key3 < _len; _key3++) {
            args[_key3 - 1] = arguments[_key3];
        }

        for (var i = 0; i < plugins.length; i++) {
            var plugin = plugins[i];
            if (plugin.callbacks[eventName] && typeof plugin.callbacks[eventName] === 'function') {
                var _plugin$callbacks;

                var result = (_plugin$callbacks = plugin.callbacks)[eventName].apply(_plugin$callbacks, args);
                if (result === true) {
                    return 'handled';
                }
            }
        }
        return this.props.hasOwnProperty(eventName) && (_props = this.props)[eventName].apply(_props, args) === true ? 'handled' : 'not-handled';
    };

    EditorCore.prototype.generatorEventHandler = function generatorEventHandler(eventName) {
        var _this7 = this;

        return function () {
            for (var _len2 = arguments.length, args = Array(_len2), _key4 = 0; _key4 < _len2; _key4++) {
                args[_key4] = arguments[_key4];
            }

            return _this7.eventHandle.apply(_this7, [eventName].concat(args));
        };
    };

    EditorCore.prototype.customStyleFn = function customStyleFn(styleSet) {
        if (styleSet.size === 0) {
            return {};
        }
        var plugins = this.getPlugins();
        var resultStyle = {};
        for (var i = 0; i < plugins.length; i++) {
            if (plugins[i].customStyleFn) {
                var styled = plugins[i].customStyleFn(styleSet);
                if (styled) {
                    Object.assign(resultStyle, styled);
                }
            }
        }
        return resultStyle;
    };

    EditorCore.prototype.render = function render() {
        var _props2 = this.props,
            prefixCls = _props2.prefixCls,
            toolbars = _props2.toolbars,
            style = _props2.style;
        var _state = this.state,
            editorState = _state.editorState,
            toolbarPlugins = _state.toolbarPlugins;

        var customStyleMap = configStore.get('customStyleMap');
        var blockRenderMap = configStore.get('blockRenderMap');
        var eventHandler = this.getEventHandler();
        var Toolbar = toolbar.component;
        return React.createElement("div", { style: style, className: prefixCls + '-editor', onClick: this.focus.bind(this) }, React.createElement(Toolbar, { editorState: editorState, prefixCls: prefixCls, className: prefixCls + '-toolbar', plugins: toolbarPlugins, toolbars: toolbars }), React.createElement("div", { className: prefixCls + '-editor-wrapper', style: style, onClick: function onClick(ev) {
                return ev.preventDefault();
            } }, React.createElement(_draftJs.Editor, __assign({}, this.props, eventHandler, { ref: "editor", customStyleMap: customStyleMap, customStyleFn: this.customStyleFn.bind(this), editorState: editorState, handleKeyCommand: this.handleKeyCommand.bind(this), keyBindingFn: this.handleKeyBinding.bind(this), onChange: this.setEditorState.bind(this), blockStyleFn: this.getBlockStyle.bind(this), blockRenderMap: blockRenderMap, blockRendererFn: this.blockRendererFn.bind(this) })), this.props.children));
    };

    return EditorCore;
}(React.Component);

EditorCore.GetText = _exportText2["default"];
EditorCore.GetHTML = (0, _getHTML2["default"])(configStore);
EditorCore.defaultProps = {
    multiLines: true,
    plugins: [],
    prefixCls: 'rc-editor-core',
    pluginConfig: {},
    toolbars: [],
    spilitLine: 'enter'
};
exports["default"] = EditorCore;
module.exports = exports['default'];