Cleaned up code, added support for lists, classes, attributes, and more. Added more test code, everything appears to be working. More cleanup and testing is needed.
This commit is contained in:
226
src/ignite-template.js
Normal file
226
src/ignite-template.js
Normal file
@ -0,0 +1,226 @@
|
||||
import { IgniteProperty, IgniteAttribute } from './ignite-html.js';
|
||||
|
||||
class IgniteTemplate {
|
||||
constructor(items) {
|
||||
this.siblings = [];
|
||||
this.children = [];
|
||||
this.attributes = {};
|
||||
this.classes = [];
|
||||
this.tagName = null;
|
||||
this.element = null;
|
||||
this.properties = {};
|
||||
|
||||
if (items) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i] instanceof IgniteAttribute) {
|
||||
this.attributes.push(items[i]);
|
||||
} else if (items[i] instanceof IgniteProperty) {
|
||||
this.children.push(new propertyObserver(items[i]));
|
||||
} else {
|
||||
this.children.push(items[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class(...items) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i] instanceof IgniteProperty) {
|
||||
items[i].onPropertyChange.push((oldValue, newValue) => this.onClassChanged(oldValue, newValue));
|
||||
this.classes.push(items[i].value);
|
||||
} else {
|
||||
this.classes.push(items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
attribute(name, value) {
|
||||
if (value instanceof IgniteProperty) {
|
||||
value.onPropertyChange.push((oldValue, newValue) => this.onAttributeChanged(oldValue, newValue, name));
|
||||
this.attributes[name] = value.value;
|
||||
} else {
|
||||
this.attributes[name] = value;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
property(name, value) {
|
||||
if (value instanceof IgniteProperty) {
|
||||
value.onPropertyChange.push((oldValue, newValue) => this.onPropertyChanged(oldValue, newValue, name));
|
||||
this.properties[name] = value.value;
|
||||
} else {
|
||||
this.properties[name] = value;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
child(...items) {
|
||||
this.children = this.children.concat(items);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
construct(parent) {
|
||||
//Construct this element if we haven't already
|
||||
if (!this.element) {
|
||||
this.element = window.document.createElement(this.tagName);
|
||||
parent.appendChild(this.element);
|
||||
}
|
||||
|
||||
//Set the classes on this element
|
||||
for (var i = 0; i < this.classes.length; i++) {
|
||||
if (this.classes[i] !== null && this.classes[i] !== undefined) {
|
||||
this.element.classList.add(this.classes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//Set the attributes on this element
|
||||
var keys = Object.keys(this.attributes);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (this.attributes[keys[i]] !== null && this.attributes[keys[i]] !== undefined) {
|
||||
this.element.setAttribute(keys[i], this.attributes[keys[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
//Set the properties on this element
|
||||
var keys = Object.keys(this.properties);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
this.element[keys[i]] = this.properties[keys[i]];
|
||||
}
|
||||
|
||||
//Construct the children under this element
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
if (this.children[i] instanceof String || typeof this.children[i] === 'string') {
|
||||
this.element.appendChild(document.createTextNode(this.children[i]));
|
||||
} else if (this.children[i] instanceof IgniteTemplate || this.children[i].prototype instanceof IgniteTemplate) {
|
||||
this.children[i].construct(this.element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClassChanged(oldValue, newValue) {
|
||||
console.log(`Class changed, oldValue: ${oldValue} newValue: ${newValue}`);
|
||||
|
||||
if (oldValue !== null && oldValue !== undefined && oldValue !== "" && oldValue !== " ") {
|
||||
this.element.classList.remove(oldValue);
|
||||
}
|
||||
|
||||
if (newValue !== null && newValue !== undefined && newValue !== "" && newValue !== " ") {
|
||||
this.element.classList.add(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
onAttributeChanged(oldValue, newValue, attributeName) {
|
||||
console.log(`Attribute changed, oldValue: ${oldValue} newValue: ${newValue} attribute: ${attributeName}`);
|
||||
|
||||
if (newValue == null || newValue == undefined) {
|
||||
this.element.removeAttribute(attributeName);
|
||||
} else {
|
||||
this.element.setAttribute(attributeName, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
onPropertyChanged(oldValue, newValue, propertyName) {
|
||||
console.log(`Property changed, oldValue: ${oldValue} newValue: ${newValue} property: ${propertyName}`);
|
||||
this.properties[propertyName] = newValue;
|
||||
this.element[propertyName] = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
class div extends IgniteTemplate {
|
||||
constructor(...items) {
|
||||
super(items);
|
||||
|
||||
this.tagName = "div";
|
||||
}
|
||||
}
|
||||
|
||||
class a extends IgniteTemplate {
|
||||
constructor(...items) {
|
||||
super(items);
|
||||
|
||||
this.tagName = "a";
|
||||
}
|
||||
}
|
||||
|
||||
class html extends IgniteTemplate {
|
||||
constructor(code) {
|
||||
super([]);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
construct(parent) {
|
||||
if (!parent) {
|
||||
parent = window.document.body;
|
||||
}
|
||||
|
||||
parent.insertAdjacentHTML('beforeend', this.code);
|
||||
}
|
||||
}
|
||||
|
||||
class list extends IgniteTemplate {
|
||||
constructor(list, forEach) {
|
||||
super([]);
|
||||
|
||||
if (list instanceof IgniteProperty) {
|
||||
list.onPropertyChange.push((oldValue, newValue) => {
|
||||
this.list = list.value;
|
||||
this.construct(null); //If the list changed, reconstruct this template
|
||||
});
|
||||
|
||||
this.list = list.value;
|
||||
} else {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
this.forEach = forEach;
|
||||
this.elements = [];
|
||||
}
|
||||
|
||||
construct(parent) {
|
||||
if (!this.element) {
|
||||
this.element = window.document.createTextNode(""); //Use a textnode as our placeholder
|
||||
parent.appendChild(this.element);
|
||||
}
|
||||
|
||||
//If we already have elements we created, destroy them.
|
||||
if (this.elements.length > 0) {
|
||||
for (var i = 0; i < this.elements.length; i++) {
|
||||
this.elements[i].remove();
|
||||
}
|
||||
this.elements = [];
|
||||
}
|
||||
|
||||
//Create a temporary container
|
||||
var container = window.document.createElement("div");
|
||||
|
||||
//Construct all the items in our list and use the container
|
||||
if (this.list) {
|
||||
for (var i = 0; i < this.list.length; i++) {
|
||||
this.forEach(this.list[i]).construct(container);
|
||||
}
|
||||
}
|
||||
|
||||
//If we have any child nodes in the container, save the element, and add it after our placeholder
|
||||
while (container.childNodes.length > 0) {
|
||||
this.elements.push(container.childNodes[0]);
|
||||
this.element.parentElement.insertBefore(container.childNodes[0], this.element);
|
||||
}
|
||||
|
||||
//Make sure we cleanup the container to be safe.
|
||||
container.remove();
|
||||
container = null;
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
IgniteTemplate,
|
||||
div,
|
||||
html,
|
||||
list,
|
||||
a
|
||||
};
|
Reference in New Issue
Block a user