From 3eadebec0c1614a23fea95125e666dd4e585432a Mon Sep 17 00:00:00 2001 From: MattMo Date: Tue, 7 Nov 2023 08:25:54 -0800 Subject: [PATCH] Fixed some major issues with list splice construction and other templates incorrectly constructing an element after a specified sibling. Improved documentation as well. --- ignite-template.js | 108 +++++++++++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 29 deletions(-) diff --git a/ignite-template.js b/ignite-template.js index 1b69fa2..1effe10 100644 --- a/ignite-template.js +++ b/ignite-template.js @@ -1415,8 +1415,8 @@ class IgniteTemplate { //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); + if (sibling && sibling.nextSibling) { + sibling.parentElement.insertBefore(this.element, sibling.nextSibling); } else { parent.appendChild(this.element); } @@ -2302,6 +2302,12 @@ class text extends IgniteTemplate { IgniteRendering.pop(); } + /** + * Constructs this template and adds it to the DOM if this template + * has not already been constructed. + * @param {HTMLElement} parent Parent element that will contain the constructed element. + * @param {HTMLElement} sibling Optional sibling element that can be used to add the element adjacantly. + */ construct(parent, sibling) { //Don't construct if we have no parent, no sibling and no element. if (!parent && !sibling && !this.element) { @@ -2311,8 +2317,8 @@ class text extends IgniteTemplate { if (!this.element) { this.element = window.document.createTextNode(""); - if (sibling) { - sibling.parentElement.insertBefore(this.element, sibling); + if (sibling && sibling.nextSibling) { + sibling.parentElement.insertBefore(this.element, sibling.nextSibling); } else { parent.appendChild(this.element); } @@ -2355,6 +2361,12 @@ class html extends IgniteTemplate { this.elements = []; } + /** + * Constructs this template and adds it to the DOM if this template + * has not already been constructed. + * @param {HTMLElement} parent Parent element that will contain the constructed element. + * @param {HTMLElement} sibling Optional sibling element that can be used to add the element adjacantly. + */ construct(parent, sibling) { //Don't construct if we have no parent, no sibling and no element. if (!parent && !sibling && !this.element) { @@ -2364,8 +2376,8 @@ class html extends IgniteTemplate { if (!this.element) { this.element = window.document.createTextNode(""); - if (sibling) { - sibling.parentElement.insertBefore(this.element, sibling); + if (sibling && sibling.nextSibling) { + sibling.parentElement.insertBefore(this.element, sibling.nextSibling); } else { parent.appendChild(this.element); } @@ -2453,6 +2465,12 @@ class list extends IgniteTemplate { this.tagName = "shadow list"; } + /** + * Constructs this template and adds it to the DOM if this template + * has not already been constructed. + * @param {HTMLElement} parent Parent element that will contain the constructed element. + * @param {HTMLElement} sibling Optional sibling element that can be used to add the element adjacantly. + */ construct(parent, sibling) { //Don't construct if we have no parent, no sibling and no element. if (!parent && !sibling && !this.element) { @@ -2462,8 +2480,8 @@ class list extends IgniteTemplate { if (!this.element) { this.element = window.document.createTextNode(""); //Use a textnode as our placeholder - if (sibling) { - sibling.parentElement.insertBefore(this.element, sibling); + if (sibling && sibling.nextSibling) { + sibling.parentElement.insertBefore(this.element, sibling.nextSibling); } else { parent.appendChild(this.element); } @@ -2503,7 +2521,11 @@ class list extends IgniteTemplate { var template = this.forEachCallback(this.list[i], i, this.list.length); if (template) { - template.construct(parent, this.element); + if (this.elements.length > 0) { + template.construct(parent, this.elements[this.elements.length - 1]); + } else { + template.construct(parent, this.element); + } //If we are reflecting, attach to the elements disconnect event. if (this.reflecting) { @@ -2544,7 +2566,11 @@ class list extends IgniteTemplate { items.forEach(item => { var template = this.forEachCallback(item, this.children.length); - template.construct(this.element.parentElement, this.element); + if (this.elements.length > 0) { + template.construct(this.element.parentElement, this.elements[this.elements.length - 1]); + } else { + template.construct(this.element.parentElement, this.element); + } //If we are reflecting, attach to the elements disconnect event. if (this.reflecting) { @@ -2569,11 +2595,7 @@ class list extends IgniteTemplate { items.forEach(item => { var template = this.forEachCallback(item, 0); - if (this.elements.length > 0) { - template.construct(this.element.parentElement, this.elements[0]); - } else { - template.construct(this.element.parentElement, this.element); - } + template.construct(this.element.parentElement, this.element); if (this.reflecting) { this.reflectCallbacks.unshift(template.element.attachOnDisconnect(disconnect => this.onItemRemove(item))); @@ -2646,11 +2668,12 @@ class list extends IgniteTemplate { items.forEach(item => { var template = this.forEachCallback(item, start); - //If we have elements already, construct this item after the element at the current start. Otherwise use the placeholder element. - if (this.elements.length > 0) { - template.construct(this.element.parentElement, this.elements[start]); - } else { + if (start == 0) { template.construct(this.element.parentElement, this.element); + } else if (start <= this.elements.length) { + template.construct(this.element.parentElement, this.elements[start - 1]); + } else { + template.construct(this.element.parentElement, this.elements[this.elements.length - 1]); } if (this.reflecting) { @@ -2730,6 +2753,12 @@ class converter extends IgniteTemplate { this.tagName = "converter"; } + /** + * Constructs this template and adds it to the DOM if this template + * has not already been constructed. + * @param {HTMLElement} parent Parent element that will contain the constructed element. + * @param {HTMLElement} sibling Optional sibling element that can be used to add the element adjacantly. + */ construct(parent, sibling) { //Don't construct if we have no parent, no sibling and no element. if (!parent && !sibling && !this.element) { @@ -2739,8 +2768,8 @@ class converter extends IgniteTemplate { if (!this.element) { this.element = window.document.createTextNode(""); //Use a textnode as our placeholder - if (sibling) { - sibling.parentElement.insertBefore(this.element, sibling); + if (sibling && sibling.nextSibling) { + sibling.parentElement.insertBefore(this.element, sibling.nextSibling); } else { parent.appendChild(this.element); } @@ -2846,8 +2875,8 @@ class slot extends IgniteTemplate { if (!this.element) { this.element = window.document.createTextNode(""); - if (sibling) { - sibling.parentElement.insertBefore(this.element, sibling); + if (sibling && sibling.nextSibling) { + sibling.parentElement.insertBefore(this.element, sibling.nextSibling); } else { parent.appendChild(this.element); } @@ -3039,6 +3068,13 @@ class pagination extends IgniteTemplate { } } + /** + * Constructs this template and adds it to the DOM if this template + * has not already been constructed. + * @param {HTMLElement} parent Parent element that will contain the constructed element. + * @param {HTMLElement} sibling Optional sibling element that can be used to add the element adjacantly. + * @ignore + */ construct(parent, sibling) { //Don't construct if we have no parent, no sibling and no element. if (!parent && !sibling && !this.element) { @@ -3048,8 +3084,8 @@ class pagination extends IgniteTemplate { if (!this.element) { this.element = window.document.createTextNode(""); //Use a textnode as our placeholder - if (sibling) { - sibling.parentElement.insertBefore(this.element, sibling); + if (sibling && sibling.nextSibling) { + sibling.parentElement.insertBefore(this.element, sibling.nextSibling); } else { parent.appendChild(this.element); } @@ -3379,6 +3415,13 @@ class pager extends IgniteTemplate { this.recalculate(); } + /** + * Constructs this template and adds it to the DOM if this template + * has not already been constructed. + * @param {HTMLElement} parent Parent element that will contain the constructed element. + * @param {HTMLElement} sibling Optional sibling element that can be used to add the element adjacantly. + * @ignore + */ construct(parent, sibling) { //Don't construct if we have no parent, no sibling and no element. if (!parent && !sibling && !this.element) { @@ -3388,8 +3431,8 @@ class pager extends IgniteTemplate { if (!this.element) { this.element = window.document.createTextNode(""); //Use a textnode as our placeholder - if (sibling) { - sibling.parentElement.insertBefore(this.element, sibling); + if (sibling && sibling.nextSibling) { + sibling.parentElement.insertBefore(this.element, sibling.nextSibling); } else { parent.appendChild(this.element); } @@ -3618,6 +3661,13 @@ class population extends IgniteTemplate { this.tagName = "shadow population"; } + /** + * Constructs this template and adds it to the DOM if this template + * has not already been constructed. + * @param {HTMLElement} parent Parent element that will contain the constructed element. + * @param {HTMLElement} sibling Optional sibling element that can be used to add the element adjacantly. + * @ignore + */ construct(parent, sibling) { //Don't construct if we have no parent, no sibling and no element. if (!parent && !sibling && !this.element) { @@ -3627,8 +3677,8 @@ class population extends IgniteTemplate { if (!this.element) { this.element = window.document.createTextNode(""); //Use a textnode as our placeholder - if (sibling) { - sibling.parentElement.insertBefore(this.element, sibling); + if (sibling && sibling.nextSibling) { + sibling.parentElement.insertBefore(this.element, sibling.nextSibling); } else { parent.appendChild(this.element); }