Moved properties over to a object model and added a resetProperties function that will reset properties to their default values. Fixed a few bugs and cleaned up the code a little more.
This commit is contained in:
		| @@ -15,7 +15,7 @@ class IgniteElement extends HTMLElement { | ||||
|      * Returns the properties for this ignite element. | ||||
|      */ | ||||
|     get properties() { | ||||
|         return []; | ||||
|         return {}; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -25,8 +25,11 @@ class IgniteElement extends HTMLElement { | ||||
|     createProperties() { | ||||
|         var props = this.properties; | ||||
|  | ||||
|         for (var i = 0; i < props.length; i++) { | ||||
|             this[`_${props[i]}`] = new IgniteProperty(); | ||||
|         var keys = Object.keys(props); | ||||
|         for (var i = 0; i < keys.length; i++) { | ||||
|             var prop = new IgniteProperty(); | ||||
|             this[`_${keys[i]}`] = prop; | ||||
|             prop._value = props[keys[i]]; | ||||
|  | ||||
|             ((propName) => { | ||||
|                 Object.defineProperty(this, propName, { | ||||
| @@ -38,7 +41,22 @@ class IgniteElement extends HTMLElement { | ||||
|                         this[`_${propName}`].value = value; | ||||
|                     } | ||||
|                 }); | ||||
|             })(props[i]); | ||||
|  | ||||
|  | ||||
|             })(keys[i]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Resets the properties for this element back to their original default | ||||
|      * value. | ||||
|      */ | ||||
|     resetProperties() { | ||||
|         var props = this.properties; | ||||
|  | ||||
|         var keys = Object.keys(props); | ||||
|         for (var i = 0; i < keys.length; i++) { | ||||
|             this[keys[i]] = props[keys[i]]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -47,9 +65,13 @@ class IgniteElement extends HTMLElement { | ||||
|      * this function is called by the DOM upon this element being created somewhere. | ||||
|      */ | ||||
|     connectedCallback() { | ||||
|         //If we don't already have a template, make sure we create one, | ||||
|         //this can happen if this element was constructed in the DOM instead of within a template. | ||||
|         if (!this.template) { | ||||
|             this.template = new IgniteTemplate(); | ||||
|             this.template.element = this; | ||||
|             this.template.tagName = this.tagName; | ||||
|         } | ||||
|  | ||||
|         //Add any childNodes we have to the elements list within this | ||||
|         this.childNodes.forEach((item) => this.elements.push(item)); | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import { IgniteProperty } from './ignite-html.js'; | ||||
| import { IgniteElement } from './ignite-element.js'; | ||||
|  | ||||
| class IgniteTemplate { | ||||
|     constructor(items) { | ||||
| @@ -31,7 +32,7 @@ class IgniteTemplate { | ||||
|     class(...items) { | ||||
|         for (var i = 0; i < items.length; i++) { | ||||
|             if (items[i] instanceof IgniteProperty) { | ||||
|                 this.callbacks.push(items[i].attach(this.onClassChanged)); | ||||
|                 this.callbacks.push(items[i].attach((oldValue, newValue) => this.onClassChanged(oldValue, newValue))); | ||||
|                 this.classes.push(items[i].value); | ||||
|             } else { | ||||
|                 this.classes.push(items[i]); | ||||
| @@ -64,7 +65,7 @@ class IgniteTemplate { | ||||
|      */ | ||||
|     property(name, value) { | ||||
|         if (value instanceof IgniteProperty) { | ||||
|             this.callbacks.push(value.attach((oldValue, newValue) => this.onAttributeChanged(oldValue, newValue, name))); | ||||
|             this.callbacks.push(value.attach((oldValue, newValue) => this.onPropertyChanged(oldValue, newValue, name))); | ||||
|             this.properties[name] = value.value; | ||||
|         } else { | ||||
|             this.properties[name] = value; | ||||
| @@ -113,14 +114,19 @@ class IgniteTemplate { | ||||
|      * @param {HTMLElement} sibling  | ||||
|      */ | ||||
|     construct(parent, sibling) { | ||||
|         //Don't construct if we have no parent, no sibling and no element. | ||||
|         if (!parent && !sibling && !this.element) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         //Construct this element if we haven't already | ||||
|         if (!this.element) { | ||||
|             this.element = window.document.createElement(this.tagName); | ||||
|  | ||||
|             if (sibling) { | ||||
|                 parent.insertBefore(this.element, sibling); | ||||
|             } else { | ||||
|                 parent.appendChild(this.element); | ||||
|             //If this template is creating an ignite element, pass back our template so the element | ||||
|             //can use it without having to create another one. | ||||
|             if (this.element instanceof IgniteElement) { | ||||
|                 this.element.template = this; | ||||
|             } | ||||
|  | ||||
|             //If the element has a onDisconnected function, attach to it | ||||
| @@ -162,6 +168,15 @@ class IgniteTemplate { | ||||
|                 this.children[i].construct(this.element); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //If our element has not been added to the dom yet, then add it. | ||||
|         if (this.element.isConnected == false && this.element.parentElement == null) { | ||||
|             if (sibling) { | ||||
|                 parent.insertBefore(this.element, sibling); | ||||
|             } else { | ||||
|                 parent.appendChild(this.element); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -206,6 +221,7 @@ class IgniteTemplate { | ||||
|      */ | ||||
|     onClassChanged(oldValue, newValue) { | ||||
|         console.log(`Class changed, oldValue: ${oldValue} newValue: ${newValue}`); | ||||
|         if (this.element) { | ||||
|             if (oldValue !== null && oldValue !== undefined && oldValue !== "" && oldValue !== " ") { | ||||
|                 this.element.classList.remove(oldValue); | ||||
|             } | ||||
| @@ -215,6 +231,10 @@ class IgniteTemplate { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this.classes = this.classes.filter(cl => cl != oldValue && cl != newValue); | ||||
|         this.classes.push(newValue); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Called when a attribute on this template was changed and needs to be updated | ||||
|      * on the template's element. | ||||
| @@ -224,6 +244,7 @@ class IgniteTemplate { | ||||
|      */ | ||||
|     onAttributeChanged(oldValue, newValue, attributeName) { | ||||
|         console.log(`Attribute changed, oldValue: ${oldValue} newValue: ${newValue} attribute: ${attributeName}`); | ||||
|         if (this.element) { | ||||
|             if (newValue == null || newValue == undefined) { | ||||
|                 this.element.removeAttribute(attributeName); | ||||
|             } else { | ||||
| @@ -231,6 +252,9 @@ class IgniteTemplate { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this.attributes[attributeName] = newValue; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Called when a property on this template was changed and needs to be updated | ||||
|      * on the template's element. | ||||
| @@ -240,9 +264,12 @@ class IgniteTemplate { | ||||
|      */ | ||||
|     onPropertyChanged(oldValue, newValue, propertyName) { | ||||
|         console.log(`Property changed, oldValue: ${oldValue} newValue: ${newValue} property: ${propertyName}`); | ||||
|         this.properties[propertyName] = newValue; | ||||
|         if (this.element) { | ||||
|             this.element[propertyName] = newValue; | ||||
|         } | ||||
|  | ||||
|         this.properties[propertyName] = newValue; | ||||
|     } | ||||
| } | ||||
|  | ||||
| class div extends IgniteTemplate { | ||||
| @@ -266,14 +293,38 @@ class html extends IgniteTemplate { | ||||
|         super([]); | ||||
|         this.code = code; | ||||
|         this.tagName = "shadow html"; | ||||
|         this.elements = []; | ||||
|     } | ||||
|  | ||||
|     construct(parent) { | ||||
|         if (!parent) { | ||||
|             parent = window.document.body; | ||||
|     construct(parent, sibling) { | ||||
|         //Don't construct if we have no parent, no sibling and no element. | ||||
|         if (!parent && !sibling && !this.element) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         parent.insertAdjacentHTML('beforeend', this.code); | ||||
|         if (!this.element) { | ||||
|             this.element = window.document.createTextNode(""); | ||||
|  | ||||
|             if (sibling) { | ||||
|                 sibling.parentElement.insertBefore(this.element, sibling); | ||||
|             } else { | ||||
|                 parent.appendChild(this.element); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //If we haven't created any elements before then create some now. | ||||
|         if (this.elements.length == 0) { | ||||
|             //Create a template to hold the elements that will be created from the | ||||
|             //properties value and then add them to the DOM and store their pointer. | ||||
|             var template = window.document.createElement("template"); | ||||
|             template.innerHTML = this.code; | ||||
|             while (template.content.childNodes.length > 0) { | ||||
|                 var item = template.content.childNodes[0]; | ||||
|                 this.element.parentElement.insertBefore(item, this.element); | ||||
|                 this.elements.push(item); | ||||
|             } | ||||
|             template.remove(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -298,9 +349,19 @@ class list extends IgniteTemplate { | ||||
|     } | ||||
|  | ||||
|     construct(parent, sibling) { | ||||
|         //Don't construct if we have no parent, no sibling and no element. | ||||
|         if (!parent && !sibling && !this.element) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!this.element) { | ||||
|             this.element = window.document.createTextNode(""); //Use a textnode as our placeholder | ||||
|  | ||||
|             if (sibling) { | ||||
|                 sibling.parentElement.insertBefore(this.element, sibling); | ||||
|             } else { | ||||
|                 parent.appendChild(this.element); | ||||
|             } | ||||
|         } else { | ||||
|             parent = this.element.parentElement; | ||||
|         } | ||||
| @@ -345,11 +406,16 @@ class property extends IgniteTemplate { | ||||
|     } | ||||
|  | ||||
|     construct(parent, sibling) { | ||||
|         //Don't construct if we have no parent, no sibling and no element. | ||||
|         if (!parent && !sibling && !this.element) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!this.element) { | ||||
|             this.element = window.document.createTextNode(""); | ||||
|  | ||||
|             if (sibling) { | ||||
|                 parent.insertBefore(this.element, sibling); | ||||
|                 sibling.parentElement.insertBefore(this.element, sibling); | ||||
|             } else { | ||||
|                 parent.appendChild(this.element); | ||||
|             } | ||||
| @@ -383,11 +449,16 @@ class slot extends IgniteTemplate { | ||||
|     } | ||||
|  | ||||
|     construct(parent, sibling) { | ||||
|         //Don't construct if we have no parent, no sibling and no element. | ||||
|         if (!parent && !sibling && !this.element) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!this.element) { | ||||
|             this.element = window.document.createTextNode(""); | ||||
|  | ||||
|             if (sibling) { | ||||
|                 parent.insertBefore(this.element, sibling); | ||||
|                 sibling.parentElement.insertBefore(this.element, sibling); | ||||
|             } else { | ||||
|                 parent.appendChild(this.element); | ||||
|             } | ||||
|   | ||||
| @@ -5,19 +5,25 @@ import { Sheet } from './sheet.js'; | ||||
| class MainApp extends IgniteElement { | ||||
|     constructor() { | ||||
|         super(); | ||||
|  | ||||
|         this.name = "Default Name"; | ||||
|     } | ||||
|  | ||||
|     get properties() { | ||||
|         return [ | ||||
|             "name", | ||||
|         ]; | ||||
|         return { | ||||
|             name: "I'm a boss!", | ||||
|             items: ["main1", "main2"], | ||||
|             sheetClass: "test" | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     render() { | ||||
|         return this.template | ||||
|             .child(new Sheet().property("name", this.name)) | ||||
|             .child( | ||||
|                 new Sheet() | ||||
|                     .property("name", this.name) | ||||
|                     .property("items", this.items) | ||||
|                     .class(this.sheetClass) | ||||
|                     .child(new html(`<h3>Im a child for sheet!</h3>`)) | ||||
|             ) | ||||
|             .child( | ||||
|                 new div( | ||||
|                     new html(`<h1>This is a slot!`), | ||||
|   | ||||
							
								
								
									
										26
									
								
								src/sheet.js
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/sheet.js
									
									
									
									
									
								
							| @@ -1,23 +1,18 @@ | ||||
| import { IgniteElement } from './ignite-element.js'; | ||||
| import { IgniteTemplate, div, html, list, a } from './ignite-template.js'; | ||||
| import { IgniteTemplate, div, html, list, a, slot } from './ignite-template.js'; | ||||
|  | ||||
| class Sheet extends IgniteElement { | ||||
|     constructor() { | ||||
|         super(); | ||||
|  | ||||
|         this.show = false; | ||||
|         this.items = []; | ||||
|         this.href = "www.google.com"; | ||||
|         this.name = "default content"; | ||||
|     } | ||||
|  | ||||
|     get properties() { | ||||
|         return [ | ||||
|             "show", | ||||
|             "name", | ||||
|             "items", | ||||
|             "href" | ||||
|         ]; | ||||
|         return { | ||||
|             show: false, | ||||
|             items: ["1", "2"], | ||||
|             href: "www.google.com", | ||||
|             name: "default content" | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     render() { | ||||
| @@ -27,9 +22,12 @@ class Sheet extends IgniteElement { | ||||
|                 new div( | ||||
|                     new html("<h2>this is before</h2>"), | ||||
|                     new list(this.items, (item) => { | ||||
|                         return new a(this.name).attribute("href", this.href) | ||||
|                         return new a(new html(`<h3>${item}</h3>`)).attribute("href", this.href) | ||||
|                     }), | ||||
|                     new html("<h2>this is after</h2>") | ||||
|                     new html("<h2>this is after</h2>"), | ||||
|                     new html("<h3>---- begin sheet's slot ----<h3>"), | ||||
|                     new slot(this), | ||||
|                     new html("<h3>---- end of slot ----</h3>") | ||||
|                 ) | ||||
|             ); | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user