UNPKG

hyperglue

Version:

update html elements by mapping query selectors to attributes, text, and hypertext

116 lines (99 loc) 3.58 kB
var domify = require('domify'); module.exports = hyperglue; var outer = null; function hyperglue (src, updates) { if (!updates) updates = {}; var dom = typeof src === 'object' ? [ src ] : domify(src); if (!outer) outer = document.createElement('div'); forEach(objectKeys(updates), function (selector) { var value = updates[selector]; forEach(dom, function (d) { var parentNode = d.parentNode; if (selector === ':first') { bind(d, value); } else if (/:first$/.test(selector)) { var k = selector.replace(/:first$/, ''); if (parentNode) parentNode.removeChild(d); outer.appendChild(d); var elem = outer.querySelector(k); outer.removeChild(d); if (parentNode) parentNode.appendChild(d); if (elem) bind(elem, value); } else { if (parentNode) parentNode.removeChild(d); outer.appendChild(d); var nodes = d.parentNode.querySelectorAll(selector); outer.removeChild(d); if (parentNode) parentNode.appendChild(d); if (nodes.length === 0) return; for (var i = 0; i < nodes.length; i++) { bind(nodes[i], value); } } }); }); return dom.length === 1 ? dom[0] : dom; } function bind (node, value) { if (isElement(value)) { node.innerHTML = ''; node.appendChild(value); } else if (isArray(value)) { for (var i = 0; i < value.length; i++) { var e = hyperglue(node.cloneNode(true), value[i]); node.parentNode.insertBefore(e, node); } node.parentNode.removeChild(node); } else if (value && typeof value === 'object') { forEach(objectKeys(value), function (key) { if (key === '_text') { setText(node, value[key]); } else if (key === '_html' && isElement(value[key])) { node.innerHTML = ''; node.appendChild(value[key]); } else if (key === '_html') { node.innerHTML = value[key]; } else if (value[key] && typeof value[key] === 'object') { var vk = value[key]; if (vk.append) { node.setAttribute(key, node.getAttribute(key) + vk.append); } else if (vk.prepend) { node.setAttribute(key, vk.prepend + node.getAttribute(key)); } } else node.setAttribute(key, value[key]); }); } else setText(node, value); } function forEach(xs, f) { if (xs.forEach) return xs.forEach(f); for (var i = 0; i < xs.length; i++) f(xs[i], i) } var objectKeys = Object.keys || function (obj) { var res = []; for (var key in obj) res.push(key); return res; }; function isElement (e) { return e && typeof e === 'object' && e.childNodes && (typeof e.appendChild === 'function' || typeof e.appendChild === 'object') ; } var isArray = Array.isArray || function (xs) { return Object.prototype.toString.call(xs) === '[object Array]'; }; function setText (e, s) { e.innerHTML = ''; var txt = document.createTextNode(String(s)); e.appendChild(txt); }