deku
Version:
Render interfaces using pure functions and virtual DOM
81 lines (63 loc) • 2.34 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createElement;
var _element = require('../element');
var _setAttribute = require('./setAttribute');
var _svg = require('./svg');
var _svg2 = _interopRequireDefault(_svg);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var cache = {};
/**
* Create a real DOM element from a virtual element, recursively looping down.
* When it finds custom elements it will render them, cache them, and keep going,
* so they are treated like any other native element.
*/
function createElement(vnode, path, dispatch, context) {
if ((0, _element.isText)(vnode)) {
var value = typeof vnode.nodeValue === 'string' || typeof vnode.nodeValue === 'number' ? vnode.nodeValue : '';
return document.createTextNode(value);
}
if ((0, _element.isEmpty)(vnode)) {
return document.createElement('noscript');
}
if ((0, _element.isThunk)(vnode)) {
var props = vnode.props;
var component = vnode.component;
var children = vnode.children;
var onCreate = component.onCreate;
var render = typeof component === 'function' ? component : component.render;
var model = {
children: children,
props: props,
path: path,
dispatch: dispatch,
context: context
};
var output = render(model);
var _DOMElement = createElement(output, (0, _element.createPath)(path, output.key || '0'), dispatch, context);
if (onCreate) onCreate(model);
vnode.state = {
vnode: output,
model: model
};
return _DOMElement;
}
var cached = cache[vnode.type];
if (typeof cached === 'undefined') {
cached = cache[vnode.type] = _svg2.default.isElement(vnode.type) ? document.createElementNS(_svg2.default.namespace, vnode.type) : document.createElement(vnode.type);
}
var DOMElement = cached.cloneNode(false);
for (var name in vnode.attributes) {
(0, _setAttribute.setAttribute)(DOMElement, name, vnode.attributes[name]);
}
vnode.children.forEach(function (node, index) {
if (node === null || node === undefined) {
return;
}
var child = createElement(node, (0, _element.createPath)(path, node.key || index), dispatch, context);
DOMElement.appendChild(child);
});
return DOMElement;
}