DOM tweaks, basic templating
This commit is contained in:
75
dom.js
75
dom.js
@@ -5,6 +5,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { jsonQuery } from './json.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper class to create (and manipulate) elements in the DOM.
|
* A helper class to create (and manipulate) elements in the DOM.
|
||||||
*
|
*
|
||||||
@@ -64,7 +66,7 @@ class DomHelper {
|
|||||||
tag.appendChild(children);
|
tag.appendChild(children);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (typeof children == 'string') {
|
if (typeof children == 'string' || typeof children == 'number') {
|
||||||
//console.debug(`-> appended string`);
|
//console.debug(`-> appended string`);
|
||||||
let n = document.createTextNode(children);
|
let n = document.createTextNode(children);
|
||||||
tag.appendChild(n);
|
tag.appendChild(n);
|
||||||
@@ -91,6 +93,77 @@ class DomHelper {
|
|||||||
});
|
});
|
||||||
return str;
|
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
|
// The DOM helper
|
||||||
|
|||||||
Reference in New Issue
Block a user