diff --git a/dom.js b/dom.js index ebbcf22..b810826 100644 --- a/dom.js +++ b/dom.js @@ -5,6 +5,8 @@ * */ +import { jsonQuery } from './json.js'; + /** * A helper class to create (and manipulate) elements in the DOM. * @@ -64,7 +66,7 @@ class DomHelper { tag.appendChild(children); return; } - if (typeof children == 'string') { + if (typeof children == 'string' || typeof children == 'number') { //console.debug(`-> appended string`); let n = document.createTextNode(children); tag.appendChild(n); @@ -91,6 +93,77 @@ class DomHelper { }); return str; } + + /** + * Discover parent node matching query + * + * + */ + parent(el, match) { + let m = el; // pointer + while (m.querySelector(match) === null) { + if (!m.parentNode) return false; + m = m.parentNode; + } + return m.querySelector(match); + } + + /** + * Apply data to a cloned template element and return it + * + * @param {string|Element} el + * @param {*} data + */ + template(el, data) { + if (!("content" in document.createElement('template'))) { + console.error("Templates not supported on this browser."); + return; + } + const tpl = (el instanceof Element) ? el : document.querySelector(el); + const clone = tpl.content.cloneNode(true); + + clone.querySelectorAll('[if]').forEach(el => { + let path = el.getAttribute('if'); + let negate = false; + if (path[0] === '!') { + negate = true; + path = path.substring(1); + } + let value = false; + if (path[0] === '.') { + value = jsonQuery(data, path, null); + } else { + value = !!eval('(' + path + ')'); + } + if (negate) value = !value; + if (!value) { + el.classList.add('d-none'); + } else { + el.classList.remove('d-none'); + } + }); + + clone.querySelectorAll('[template]').forEach(el => { + const path = el.getAttribute('template'); + let value = jsonQuery(data, path, null); + if (value !== null) { + if ('value' in el) { + el.value = value; + } else { + el.innerText = value; + } + } + }); + + clone.querySelectorAll('[templated]').forEach(el => { + let value = eval(el.innerText); + if (value !== null) { + el.innerText = value; + } + }); + + return clone; + } }; // The DOM helper