decca
Version:
Render interfaces using pure functions and virtual DOM, kinda
56 lines (55 loc) • 1.78 kB
JavaScript
/**
* @module decca/dom
*/
;
var diff = require('virtual-dom/diff');
var patch = require('virtual-dom/patch');
var createElement = require('virtual-dom/create-element');
var build_1 = require('./build');
/**
* Creates a renderer function that will update the given `rootEl` DOM Node if
* called.
*
* @param {DOMNode} el The DOM element to mount to
* @param {function=} dispatch The dispatch function to the store
* @return {render} a renderer function; see [render](#render)
*/
function createRenderer(rootEl, dispatch) {
var tree, rootNode; // virtual-dom states
return render;
/*
* Renders an element `el` (output of `element()`) with the given `context`
*/
function render(el, context) {
var build = build_1["default"](context, dispatch);
update(build, el); // Update DOM
}
/*
* Internal: Updates the DOM tree with the given element `el`.
* Either builds the initial tree, or makes a patch on the existing tree.
*/
function update(build, el) {
if (!tree) {
// Build initial tree
tree = build(el);
rootNode = createElement(tree);
rootEl.innerHTML = '';
rootEl.appendChild(rootNode);
}
else {
// Build diff
var newTree = build(el);
var delta = diff(tree, newTree);
rootNode = patch(rootNode, delta);
tree = newTree;
}
}
}
exports.createRenderer = createRenderer;
/**
* A renderer function returned by [createRenderer()](#createrenderer).
*
* @callback render
* @param {Element} element Virtual element to render; given by [element()](#element)
* @param {*=} context The context to be passed onto the components as `context`
*/