diff --git a/example/components/card.html b/example/components/card.html
index b5f053a..7d78acd 100644
--- a/example/components/card.html
+++ b/example/components/card.html
@@ -3,17 +3,31 @@
No header
No data
+
+ No action
+
+
diff --git a/example/components/root.html b/example/components/root.html
index 57436f1..d8bd718 100644
--- a/example/components/root.html
+++ b/example/components/root.html
@@ -4,7 +4,7 @@
Just add script tag and it works
-
+
Easy to understand
No complex parts at all - just plain HTML
diff --git a/src/create-component.ts b/src/create-component.ts
index c1969d4..916ca50 100644
--- a/src/create-component.ts
+++ b/src/create-component.ts
@@ -1,9 +1,5 @@
import {appendCssLink, applyGlobalStyles, getEncapsulatedCss} from './css-helpers.js';
-import {
- cloneNode,
- returnIfDefined,
- throwIfNotDefined,
-} from './helpers.js';
+import {cloneNode, returnIfDefined, throwIfNotDefined} from './helpers.js';
import {CleanupFn, executeScript} from "./execute-script.js";
interface AttributeChanged {
@@ -46,7 +42,10 @@ export function createComponent(definedElement: Document, relativeTo: string): [
readonly #attrElements: HTMLElement[] = [];
readonly #attrDefaults = new WeakMap();
- readonly #optionalElements: Element[] = [];
+
+ readonly #optionalElements: HTMLElement[] = [];
+ readonly #optionalMarkers = new WeakMap();
+
readonly #cleanupFns = new Set();
constructor() {
@@ -74,11 +73,23 @@ export function createComponent(definedElement: Document, relativeTo: string): [
#initOptionality(): void {
for (const element of this.#optionalElements) {
if (!this.#isElementVisible(element)) {
- element.setAttribute('hidden', '');
+ this.#hideOptional(element);
}
}
}
+ #hideOptional(element: HTMLElement): void {
+ if (this.#optionalMarkers.has(element)) {
+ // Already hidden
+ return;
+ }
+ const text = ` data-if="${element.getAttribute('data-if')}" `;
+ const marker = document.createComment(text)
+ element.before(marker);
+ this.#optionalMarkers.set(element, marker);
+ element.remove();
+ }
+
#isElementVisible(element: Element): boolean {
const name = element.getAttribute('data-if');
throwIfNotDefined(name);
@@ -158,10 +169,17 @@ export function createComponent(definedElement: Document, relativeTo: string): [
#applyOptionality(name: string): void {
const optionalForElements = this.#optionalElements.filter((element) => element.getAttribute('data-if') === name);
for (const element of optionalForElements) {
- if (!this.#isElementVisible(element)) {
- element.setAttribute('hidden', '');
+ if (this.#isElementVisible(element)) {
+ const marker = this.#optionalMarkers.get(element);
+ if (!marker) {
+ // Already visible
+ continue;
+ }
+ marker.after(element);
+ marker.remove();
+ this.#optionalMarkers.delete(element);
} else {
- element.removeAttribute('hidden');
+ this.#hideOptional(element);
}
}
}
@@ -182,8 +200,8 @@ export function createComponent(definedElement: Document, relativeTo: string): [
}
#setAttrs(): void {
- for (const attrElement of this.#attrElements) {
- this.#attrDefaults.set(attrElement, Array.from(attrElement.childNodes));
+ for (const element of this.#attrElements) {
+ this.#attrDefaults.set(element, Array.from(element.childNodes));
}
for (const name of this.getAttributeNames()) {
this.#applyAttr(name, returnIfDefined(this.getAttribute(name)));
@@ -209,11 +227,11 @@ export function createComponent(definedElement: Document, relativeTo: string): [
return [selector, Component];
}
-function getUsedAttributes(template: HTMLTemplateElement, dataAttributeNames: string[]): string[] {
- return dataAttributeNames
- .map((dataAttributeName) => {
- return Array.from(template.content.querySelectorAll(`[${dataAttributeName}]`))
- .map((element) => returnIfDefined(element.getAttribute(dataAttributeName)))
+function getUsedAttributes(template: HTMLTemplateElement, attributeNames: string[]): string[] {
+ return attributeNames
+ .map((attributeName) => {
+ return Array.from(template.content.querySelectorAll(`[${attributeName}]`))
+ .map((element) => returnIfDefined(element.getAttribute(attributeName)))
})
.flat()
.filter((v, i, arr) => arr.indexOf(v) === i);