'use strict';

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

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _server = require('react-dom/server');

var _server2 = _interopRequireDefault(_server);

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

/**
 * A implementation of Ext.Template that supports React elements (JSX).
 * 
 * Usage:
 * 
 *  const tpl = new Template(data => (
 *      <div>
 *          <div>{data.firstName} {data.lastName}</div>    
 *          <div>{data.title}</div>
 *      </div>
 *  ))
 * 
 *  const html = tpl.apply({ firstName: 'Joe', lastName: 'Smith', title: 'CEO' });
 */
var Template = Ext.define(null, {
    extend: 'Ext.Template',

    /**
     * @param {Function} fn A function that takes data values as an object and returns a React.Element to be rendered.
     */
    constructor: function constructor(fn) {
        this.fn = fn;
    },


    // overrides Ext.Template
    apply: function apply(values) {
        return _server2.default.renderToStaticMarkup(this.fn(values));
    },


    // overrides Ext.Template
    doInsert: function doInsert(where, el, values, returnElement) {
        var target = this.getCachedTarget();
        this.doRender(values, target);
        return Ext.dom.Helper.doInsert(el, target.firstChild, returnElement, where);
    },


    // overrides Ext.Template
    overwrite: function overwrite(el, values, returnElement) {
        var dom = this.doRender(values, Ext.getDom(el));
        return returnElement ? new Ext.Element(dom) : dom;
    },


    /**
     * @private
     * @return {HTMLElement}
     */
    getCachedTarget: function getCachedTarget() {
        if (!this.cachedTarget) this.cachedTarget = document.createElement('div');
        return this.cachedTarget;
    },


    /**
     * Renders the result of this.fn to the specified target
     * @private
     * @param {Object} values Values to pass to this.fn
     * @param {HTMLElement} target The element into which the result should be rendered.
     * @return {HTMLElement} The newly rendered element
     */
    doRender: function doRender(values, target) {
        var reactElement = this.fn(values);
        _reactDom2.default.render(reactElement, target);
        return target.firstChild;
    }
});

exports.default = Template;

// Hook Ext.XTemplate.get so that we can just pass a function that returns JSX in place of a XTemplate.
//# sourceMappingURL=Template.js.map