@oscarpalmer/abydon 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -14,58 +14,155 @@ function getString(value2) {
14
14
  function isNullableOrWhitespace(value2) {
15
15
  return value2 == null || /^\s*$/.test(getString(value2));
16
16
  }
17
+ // node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/js/string/index.mjs
18
+ function getString2(value3) {
19
+ if (typeof value3 === "string") {
20
+ return value3;
21
+ }
22
+ if (typeof value3 !== "object" || value3 == null) {
23
+ return String(value3);
24
+ }
25
+ const valueOff = value3.valueOf?.() ?? value3;
26
+ const asString = valueOff?.toString?.() ?? String(valueOff);
27
+ return asString.startsWith("[object ") ? JSON.stringify(value3) : asString;
28
+ }
29
+ // node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/js/is.mjs
30
+ function isPlainObject2(value3) {
31
+ if (typeof value3 !== "object" || value3 === null) {
32
+ return false;
33
+ }
34
+ const prototype = Object.getPrototypeOf(value3);
35
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value3) && !(Symbol.iterator in value3);
36
+ }
17
37
 
18
- // src/helpers/index.ts
19
- function isFragment(value2) {
20
- return typeof value2 === "object" && value2 != null && "$fragment" in value2 && value2.$fragment === true;
38
+ // node_modules/@oscarpalmer/toretto/dist/attribute.mjs
39
+ function isBadAttribute(attribute) {
40
+ return onPrefix.test(attribute.name) || sourcePrefix.test(attribute.name) && valuePrefix.test(attribute.value);
21
41
  }
22
- function isFragmentElement(value2) {
23
- return value2 instanceof HTMLElement || value2 instanceof SVGElement;
42
+ function isBooleanAttribute(name) {
43
+ return booleanAttributes.includes(name.toLowerCase());
24
44
  }
25
- function isFragmentNode(value2) {
26
- return value2 instanceof Comment || value2 instanceof Element || value2 instanceof Text;
45
+ function isEmptyNonBooleanAttribute(attribute) {
46
+ return !booleanAttributes.includes(attribute.name) && attribute.value.trim().length === 0;
47
+ }
48
+ function isInvalidBooleanAttribute(attribute) {
49
+ if (!booleanAttributes.includes(attribute.name)) {
50
+ return true;
51
+ }
52
+ const normalised = attribute.value.toLowerCase().trim();
53
+ return !(normalised.length === 0 || normalised === attribute.name || attribute.name === "hidden" && normalised === "until-found");
27
54
  }
55
+ function setAttribute(element, first, second) {
56
+ if (isPlainObject2(first) && typeof first?.name === "string") {
57
+ setAttributeValue(element, first.name, first.value);
58
+ } else if (typeof first === "string") {
59
+ setAttributeValue(element, first, second);
60
+ }
61
+ }
62
+ function setAttributeValue(element, name, value3) {
63
+ if (value3 == null) {
64
+ element.removeAttribute(name);
65
+ } else {
66
+ element.setAttribute(name, typeof value3 === "string" ? value3 : getString2(value3));
67
+ }
68
+ }
69
+ var booleanAttributes = Object.freeze([
70
+ "async",
71
+ "autofocus",
72
+ "autoplay",
73
+ "checked",
74
+ "controls",
75
+ "default",
76
+ "defer",
77
+ "disabled",
78
+ "formnovalidate",
79
+ "hidden",
80
+ "inert",
81
+ "ismap",
82
+ "itemscope",
83
+ "loop",
84
+ "multiple",
85
+ "muted",
86
+ "nomodule",
87
+ "novalidate",
88
+ "open",
89
+ "playsinline",
90
+ "readonly",
91
+ "required",
92
+ "reversed",
93
+ "selected"
94
+ ]);
95
+ var onPrefix = /^on/i;
96
+ var sourcePrefix = /^(href|src|xlink:href)$/i;
97
+ var valuePrefix = /(data:text\/html|javascript:)/i;
28
98
 
29
- // src/helpers/dom.ts
30
- function createNodes(value2) {
31
- if (isFragmentNode(value2)) {
32
- return [value2];
99
+ // node_modules/@oscarpalmer/toretto/dist/sanitise.mjs
100
+ function sanitise(value3, options) {
101
+ return sanitiseNodes(Array.isArray(value3) ? value3 : [value3], {
102
+ sanitiseBooleanAttributes: options?.sanitiseBooleanAttributes ?? true
103
+ });
104
+ }
105
+ function sanitiseAttributes(element, attributes, options) {
106
+ const { length } = attributes;
107
+ for (let index = 0;index < length; index += 1) {
108
+ const attribute2 = attributes[index];
109
+ if (isBadAttribute(attribute2) || isEmptyNonBooleanAttribute(attribute2)) {
110
+ element.removeAttribute(attribute2.name);
111
+ } else if (options.sanitiseBooleanAttributes && isInvalidBooleanAttribute(attribute2)) {
112
+ element.setAttribute(attribute2.name, "");
113
+ }
33
114
  }
34
- if (isFragment(value2)) {
35
- return value2.get();
115
+ }
116
+ function sanitiseNodes(nodes, options) {
117
+ const { length } = nodes;
118
+ for (let index = 0;index < length; index += 1) {
119
+ const node = nodes[index];
120
+ if (node instanceof Element) {
121
+ sanitiseAttributes(node, [...node.attributes], options);
122
+ }
123
+ sanitiseNodes([...node.childNodes], options);
36
124
  }
37
- return [new Text(getString(value2))];
125
+ return nodes;
38
126
  }
127
+
128
+ // node_modules/@oscarpalmer/toretto/dist/html.mjs
39
129
  function createTemplate(html) {
40
- const template2 = document.createElement("template");
41
- template2.innerHTML = html;
42
- const cloned = template2.content.cloneNode(true);
43
- const scripts = [
44
- ...cloned instanceof Element ? cloned.querySelectorAll("script") : []
45
- ];
130
+ const template3 = document.createElement("template");
131
+ template3.innerHTML = html;
132
+ templates[html] = template3;
133
+ return template3;
134
+ }
135
+ function getTemplate(value3) {
136
+ if (value3.trim().length === 0) {
137
+ return;
138
+ }
139
+ let template3;
140
+ if (/^[\w-]+$/.test(value3)) {
141
+ template3 = document.querySelector(`#${value3}`);
142
+ }
143
+ if (template3 instanceof HTMLTemplateElement) {
144
+ return template3;
145
+ }
146
+ return templates[value3] ?? createTemplate(value3);
147
+ }
148
+ function html(value3, sanitisation) {
149
+ const options = sanitisation == null || sanitisation === true ? {} : isPlainObject2(sanitisation) ? { ...sanitisation } : null;
150
+ const template3 = value3 instanceof HTMLTemplateElement ? value3 : typeof value3 === "string" ? getTemplate(value3) : null;
151
+ if (template3 == null) {
152
+ return [];
153
+ }
154
+ const cloned = template3.content.cloneNode(true);
155
+ const scripts = cloned.querySelectorAll("script");
46
156
  const { length } = scripts;
47
157
  for (let index = 0;index < length; index += 1) {
48
158
  scripts[index].remove();
49
159
  }
50
160
  cloned.normalize();
51
- return cloned;
52
- }
53
- function getNodes(node) {
54
- return /^documentfragment$/i.test(node.constructor.name) ? [...node.childNodes] : [node];
55
- }
56
- function replaceNodes(from, to) {
57
- const { length } = from;
58
- for (let index = 0;index < length; index += 1) {
59
- const node = from[index];
60
- if (index === 0) {
61
- node.replaceWith(...to);
62
- } else {
63
- node.remove();
64
- }
65
- }
161
+ return options != null ? sanitise([...cloned.childNodes], options) : [...cloned.childNodes];
66
162
  }
163
+ var templates = {};
67
164
 
68
- // node_modules/@oscarpalmer/atoms/dist/js/queue.mjs
165
+ // node_modules/@oscarpalmer/sentinel/node_modules/@oscarpalmer/atoms/dist/js/queue.mjs
69
166
  if (globalThis._atomic_queued == null) {
70
167
  const queued = new Set;
71
168
  Object.defineProperty(globalThis, "_atomic_queued", {
@@ -126,11 +223,11 @@ class Effect {
126
223
  }
127
224
 
128
225
  // node_modules/@oscarpalmer/sentinel/dist/helpers/is.mjs
129
- function isReactive(value2) {
130
- return isSentinel(value2, /^array|computed|signal|store$/i);
226
+ function isReactive(value3) {
227
+ return isSentinel(value3, /^array|computed|signal|store$/i);
131
228
  }
132
- function isSentinel(value2, expression) {
133
- return expression.test(value2?.$sentinel ?? "");
229
+ function isSentinel(value3, expression) {
230
+ return expression.test(value3?.$sentinel ?? "");
134
231
  }
135
232
 
136
233
  // node_modules/@oscarpalmer/sentinel/dist/helpers/value.mjs
@@ -145,10 +242,42 @@ var arrayOperations = new Set([
145
242
  "splice",
146
243
  "unshift"
147
244
  ]);
148
-
149
245
  // node_modules/@oscarpalmer/sentinel/dist/reactive/index.mjs
150
246
  var primitives = new Set(["boolean", "number", "string"]);
151
247
 
248
+ // src/helpers/index.ts
249
+ function isFragment(value11) {
250
+ return typeof value11 === "object" && value11 != null && "$fragment" in value11 && value11.$fragment === true;
251
+ }
252
+ function isProperElement(value11) {
253
+ return value11 instanceof HTMLElement || value11 instanceof SVGElement;
254
+ }
255
+ function isProperNode(value11) {
256
+ return value11 instanceof CharacterData || value11 instanceof Element;
257
+ }
258
+
259
+ // src/helpers/dom.ts
260
+ function createNodes(value11) {
261
+ if (isFragment(value11)) {
262
+ return value11.get();
263
+ }
264
+ if (isProperNode(value11)) {
265
+ return [value11];
266
+ }
267
+ return [new Text(getString(value11))];
268
+ }
269
+ function replaceNodes(from, to) {
270
+ const { length } = from;
271
+ for (let index = 0;index < length; index += 1) {
272
+ const node = from[index];
273
+ if (index === 0) {
274
+ node.replaceWith(...to);
275
+ } else {
276
+ node.remove();
277
+ }
278
+ }
279
+ }
280
+
152
281
  // src/node/event.ts
153
282
  function getOptions(options) {
154
283
  const parts = options.split(":");
@@ -158,145 +287,74 @@ function getOptions(options) {
158
287
  passive: !parts.includes("a") && !parts.includes("active")
159
288
  };
160
289
  }
161
- function mapEvent(element, name, value9) {
290
+ function mapEvent(element, name, value11) {
162
291
  element.removeAttribute(name);
163
292
  const [, type, options] = /^@(\w+)(?::([a-z:]+))?$/.exec(name) ?? [];
164
- if (typeof value9 === "function" && type != null) {
165
- element.addEventListener(type, value9, getOptions(options ?? ""));
293
+ if (typeof value11 === "function" && type != null) {
294
+ element.addEventListener(type, value11, getOptions(options ?? ""));
166
295
  }
167
296
  }
168
297
 
169
- // node_modules/@oscarpalmer/atoms/dist/js/element/closest.mjs
170
- function calculateDistance(origin, target) {
171
- if (origin === target || origin.parentElement === target) {
172
- return 0;
173
- }
174
- const comparison = origin.compareDocumentPosition(target);
175
- const children = [...origin.parentElement?.children ?? []];
176
- switch (true) {
177
- case children.includes(target):
178
- return Math.abs(children.indexOf(origin) - children.indexOf(target));
179
- case !!(comparison & 2 || comparison & 8):
180
- return traverse(origin, target);
181
- case !!(comparison & 4 || comparison & 16):
182
- return traverse(target, origin);
183
- default:
184
- return -1;
185
- }
186
- }
187
- function closest(origin, selector, context) {
188
- if (origin.matches(selector)) {
189
- return [origin];
190
- }
191
- const elements = [...(context ?? document).querySelectorAll(selector)];
192
- const { length } = elements;
193
- if (length === 0) {
194
- return [];
195
- }
196
- const distances = [];
197
- let minimum = null;
198
- for (let index = 0;index < length; index += 1) {
199
- const element = elements[index];
200
- const distance = calculateDistance(origin, element);
201
- if (distance < 0) {
202
- continue;
203
- }
204
- if (minimum == null || distance < minimum) {
205
- minimum = distance;
206
- }
207
- distances.push({
208
- distance,
209
- element
210
- });
211
- }
212
- return minimum == null ? [] : distances.filter((found) => found.distance === minimum).map((found) => found.element);
213
- }
214
- function traverse(from, to) {
215
- const children = [...to.children];
216
- if (children.includes(from)) {
217
- return children.indexOf(from) + 1;
218
- }
219
- let current = from;
220
- let distance = 0;
221
- let parent = from.parentElement;
222
- while (parent != null) {
223
- if (parent === to) {
224
- return distance + 1;
225
- }
226
- const children2 = [...parent.children ?? []];
227
- if (children2.includes(to)) {
228
- return distance + Math.abs(children2.indexOf(current) - children2.indexOf(to));
229
- }
230
- const index = children2.findIndex((child) => child.contains(to));
231
- if (index > -1) {
232
- return distance + Math.abs(index - children2.indexOf(current)) + traverse(to, children2[index]);
233
- }
234
- current = parent;
235
- distance += 1;
236
- parent = parent.parentElement;
237
- }
238
- return -1e6;
239
- }
240
298
  // src/node/attribute/value.ts
241
- function setAttribute(element2, name, value9) {
242
- element2.removeAttribute(name);
299
+ function setAttribute2(element, name, value11) {
300
+ element.removeAttribute(name);
243
301
  switch (true) {
244
302
  case classPattern.test(name):
245
- setClasses(element2, name, value9);
303
+ setClasses(element, name, value11);
246
304
  return;
247
305
  case stylePattern.test(name):
248
- setStyle(element2, name, value9);
306
+ setStyle(element, name, value11);
249
307
  return;
250
308
  default:
251
- setValue3(element2, name, value9);
309
+ setValue5(element, name, value11);
252
310
  break;
253
311
  }
254
312
  }
255
- function setClasses(element2, name, value9) {
256
- function update(value10) {
257
- if (/^(|true)$/.test(getString(value10))) {
258
- element2.classList.add(...classes);
313
+ function setClasses(element, name, value11) {
314
+ function update(value12) {
315
+ if (/^(|true)$/.test(getString(value12))) {
316
+ element.classList.add(...classes);
259
317
  } else {
260
- element2.classList.remove(...classes);
318
+ element.classList.remove(...classes);
261
319
  }
262
320
  }
263
321
  const classes = name.slice(6).split(".");
264
- if (isReactive(value9)) {
322
+ if (isReactive(value11)) {
265
323
  effect(() => {
266
- update(value9.get());
324
+ update(value11.get());
267
325
  });
268
326
  } else {
269
- update(value9);
327
+ update(value11);
270
328
  }
271
329
  }
272
- function setStyle(element2, name, value9) {
273
- function update(value10) {
274
- if (value10 == null || value10 === false || value10 === true && unit == null) {
275
- element2.style.removeProperty(property);
330
+ function setStyle(element, name, value11) {
331
+ function update(value12) {
332
+ if (value12 == null || value12 === false || value12 === true && unit == null) {
333
+ element.style.removeProperty(property);
276
334
  } else {
277
- element2.style.setProperty(property, value10 === true ? unit : getString(value10));
335
+ element.style.setProperty(property, value12 === true ? unit : getString(value12));
278
336
  }
279
337
  }
280
338
  const [, property, unit] = /^\w+\.([a-z-]+)(?:\.(\w+))?$/i.exec(name) ?? [];
281
339
  if (property == null) {
282
340
  return;
283
341
  }
284
- if (isReactive(value9)) {
342
+ if (isReactive(value11)) {
285
343
  effect(() => {
286
- update(value9.get());
344
+ update(value11.get());
287
345
  });
288
346
  } else {
289
- update(value9);
347
+ update(value11);
290
348
  }
291
349
  }
292
- function setValue3(element2, name, value9) {
293
- const callback = booleanAttributes.has(name) && name in element2 ? name === "selected" ? updateSelected(element2) : updateProperty : updateAttribute;
294
- if (isReactive(value9)) {
350
+ function setValue5(element, name, value11) {
351
+ const callback = isBooleanAttribute(name) && name in element ? name === "selected" ? updateSelected : updateProperty : setAttribute;
352
+ if (isReactive(value11)) {
295
353
  effect(() => {
296
- callback(element2, name, value9.get());
354
+ callback(element, name, value11.get());
297
355
  });
298
356
  } else {
299
- callback(element2, name, value9);
357
+ callback(element, name, value11);
300
358
  }
301
359
  }
302
360
  function triggerSelectChange(select) {
@@ -304,184 +362,193 @@ function triggerSelectChange(select) {
304
362
  select.dispatchEvent(new Event("change", { bubbles: true }));
305
363
  }
306
364
  }
307
- function updateAttribute(element2, name, value9) {
308
- if (value9 == null) {
309
- element2.removeAttribute(name);
310
- } else {
311
- element2.setAttribute(name, getString(value9));
312
- }
313
- }
314
- function updateProperty(element2, name, value9) {
315
- element2[name] = /^(|true)$/.test(getString(value9));
365
+ function updateProperty(element, name, value11) {
366
+ element[name] = /^(|true)$/.test(getString(value11));
316
367
  }
317
- function updateSelected(element2) {
318
- const select = closest(element2, "select")[0];
368
+ function updateSelected(element, name, value11) {
369
+ const select = element.closest("select");
319
370
  const options = [...select?.options ?? []];
320
- return (element3, name, value9) => {
321
- if (select != null && options.includes(element3)) {
322
- triggerSelectChange(select);
323
- }
324
- updateProperty(element3, name, value9);
325
- };
371
+ if (select != null && options.includes(element)) {
372
+ triggerSelectChange(select);
373
+ }
374
+ updateProperty(element, name, value11);
326
375
  }
327
- var booleanAttributes = new Set([
328
- "checked",
329
- "disabled",
330
- "hidden",
331
- "inert",
332
- "multiple",
333
- "open",
334
- "readOnly",
335
- "required",
336
- "selected"
337
- ]);
338
376
  var classPattern = /^class\./;
339
377
  var stylePattern = /^style\./;
340
378
 
341
379
  // src/node/attribute/index.ts
342
- function getValue3(data2, original) {
380
+ function getValue5(data, original) {
343
381
  const matches = commentExpression.exec(original ?? "");
344
- return matches == null ? original : data2.values[+matches[1]];
382
+ return matches == null ? original : data.values[+matches[1]];
345
383
  }
346
- function isBadAttribute(name, value10) {
347
- return /^on/i.test(name) || /^(href|src|xlink:href)$/i.test(name) && /(data:text\/html|javascript:)/i.test(value10);
348
- }
349
- function mapAttributes(data2, element2) {
350
- const attributes = [...element2.attributes];
384
+ function mapAttributes(data, element) {
385
+ const attributes = [...element.attributes];
351
386
  const { length } = attributes;
352
387
  for (let index = 0;index < length; index += 1) {
353
- const { name, value: value10 } = attributes[index];
354
- if (isBadAttribute(name, value10)) {
355
- element2.removeAttribute(name);
356
- continue;
357
- }
358
- const actual = getValue3(data2, value10);
388
+ const { name, value: value12 } = attributes[index];
389
+ const actual = getValue5(data, value12);
359
390
  if (name.startsWith("@")) {
360
- mapEvent(element2, name, actual);
391
+ mapEvent(element, name, actual);
361
392
  } else if (name.includes(".") || isReactive(actual)) {
362
- mapValue(element2, name, actual);
393
+ mapValue(element, name, actual);
363
394
  }
364
395
  }
365
396
  }
366
- function mapValue(element2, name, value10) {
397
+ function mapValue(element, name, value12) {
367
398
  switch (true) {
368
- case typeof value10 === "function":
369
- mapValue(element2, name, value10());
399
+ case typeof value12 === "function":
400
+ mapValue(element, name, value12());
370
401
  return;
371
402
  default:
372
- setAttribute(element2, name, value10);
403
+ setAttribute2(element, name, value12);
373
404
  break;
374
405
  }
375
406
  }
376
407
  var commentExpression = /^<!--abydon\.(\d+)-->$/;
377
408
 
378
409
  // src/node/value.ts
379
- function setReactiveNode(comment, reactive3) {
410
+ function setNodes(nodes, comment, text, value12) {
411
+ const next = createNodes(value12);
412
+ if (nodes == null) {
413
+ if (comment.parentNode != null) {
414
+ replaceNodes([comment], next);
415
+ } else if (text.parentNode != null) {
416
+ replaceNodes([text], next);
417
+ }
418
+ } else {
419
+ replaceNodes(nodes, next);
420
+ }
421
+ return next;
422
+ }
423
+ function setReactiveNode(data, comment, reactive3) {
424
+ const item = data.items.find((item2) => item2.nodes.includes(comment));
380
425
  const text = new Text;
381
426
  let nodes;
382
427
  effect(() => {
383
- const value10 = reactive3.get();
384
- if (isFragment(value10) || isFragmentNode(value10)) {
385
- const next = createNodes(value10);
386
- if (nodes == null) {
387
- if (comment.parentNode != null) {
388
- replaceNodes([comment], next);
389
- } else if (text.parentNode != null) {
390
- replaceNodes([text], next);
391
- }
392
- } else {
393
- replaceNodes(nodes, next);
394
- }
395
- nodes = next;
396
- return;
428
+ const value12 = reactive3.get();
429
+ const valueIsFragment = isFragment(value12);
430
+ if (valueIsFragment || isProperNode(value12)) {
431
+ nodes = setNodes(nodes, comment, text, value12);
432
+ } else {
433
+ nodes = setText(nodes, comment, text, value12) ? [text] : undefined;
397
434
  }
398
- const isNullable = isNullableOrWhitespace(value10);
399
- text.textContent = getString(value10);
400
- if (nodes != null) {
401
- replaceNodes(nodes, [isNullable ? comment : text]);
402
- } else if (isNullable && comment.parentNode == null) {
403
- text.replaceWith(comment);
404
- } else if (!isNullable && text.parentNode == null) {
405
- comment.replaceWith(text);
435
+ if (item != null) {
436
+ item.fragment = valueIsFragment ? value12 : undefined;
437
+ item.nodes = [...nodes ?? [comment]];
406
438
  }
407
- nodes = undefined;
408
439
  });
409
440
  }
441
+ function setText(nodes, comment, text, value12) {
442
+ const isNullable = isNullableOrWhitespace(value12);
443
+ text.textContent = isNullable ? "" : getString(value12);
444
+ if (nodes != null) {
445
+ replaceNodes(nodes, [isNullable ? comment : text]);
446
+ return !isNullable;
447
+ }
448
+ if (isNullable && comment.parentNode == null) {
449
+ text.replaceWith(comment);
450
+ return false;
451
+ }
452
+ if (!isNullable && text.parentNode == null) {
453
+ comment.replaceWith(text);
454
+ return true;
455
+ }
456
+ return false;
457
+ }
410
458
 
411
459
  // src/node/index.ts
412
- function mapNode(data2, comment) {
460
+ function mapNode(data, comment) {
413
461
  const matches = commentExpression2.exec(comment.textContent ?? "");
414
- const value11 = matches == null ? null : data2.values[+matches[1]];
415
- if (value11 != null) {
416
- mapValue2(comment, value11);
462
+ const value13 = matches == null ? null : data.values[+matches[1]];
463
+ if (value13 != null) {
464
+ mapValue2(data, comment, value13);
417
465
  }
418
466
  }
419
- function mapNodes(data2, nodes) {
467
+ function mapNodes(data, nodes) {
420
468
  const { length } = nodes;
421
469
  for (let index = 0;index < length; index += 1) {
422
470
  const node = nodes[index];
423
471
  if (node instanceof Comment) {
424
- mapNode(data2, node);
472
+ mapNode(data, node);
425
473
  continue;
426
474
  }
427
- if (isFragmentElement(node)) {
428
- mapAttributes(data2, node);
475
+ if (isProperElement(node)) {
476
+ mapAttributes(data, node);
429
477
  }
430
478
  if (node.hasChildNodes()) {
431
- mapNodes(data2, [...node.childNodes]);
479
+ mapNodes(data, [...node.childNodes]);
432
480
  }
433
481
  }
434
482
  }
435
- function mapValue2(comment, value11) {
483
+ function mapValue2(data, comment, value13) {
436
484
  switch (true) {
437
- case typeof value11 === "function":
438
- mapValue2(comment, value11());
485
+ case typeof value13 === "function":
486
+ mapValue2(data, comment, value13());
439
487
  return;
440
- case isReactive(value11):
441
- setReactiveNode(comment, value11);
488
+ case isReactive(value13):
489
+ setReactiveNode(data, comment, value13);
442
490
  break;
443
491
  default:
444
- comment.replaceWith(...createNodes(value11));
492
+ replaceComment(data, comment, value13);
445
493
  break;
446
494
  }
447
495
  }
496
+ function replaceComment(data, comment, value13) {
497
+ const item = data.items.find((item2) => item2.nodes.includes(comment));
498
+ const nodes = createNodes(value13);
499
+ if (item != null) {
500
+ item.fragment = isFragment(value13) ? value13 : undefined;
501
+ item.nodes = nodes;
502
+ }
503
+ comment.replaceWith(...nodes);
504
+ }
448
505
  var commentExpression2 = /^abydon\.(\d+)$/;
449
506
 
450
507
  // src/fragment.ts
451
508
  class Fragment {
509
+ $fragment = true;
452
510
  data;
453
511
  constructor(strings, expressions) {
454
512
  this.data = {
455
513
  expressions,
456
514
  strings,
457
- nodes: [],
515
+ items: [],
458
516
  values: []
459
517
  };
460
518
  }
461
- appendTo(element2) {
462
- element2.append(...this.get());
519
+ appendTo(element) {
520
+ element.append(...this.get());
463
521
  }
464
522
  get() {
465
- if (this.data.nodes.length === 0) {
466
- const parsed = parse2(this.data);
467
- const templated = createTemplate(parsed);
468
- this.data.nodes.splice(0, this.data.nodes.length, ...getNodes(templated));
469
- mapNodes(this.data, this.data.nodes);
523
+ if (this.data.items.length === 0) {
524
+ const parsed = parse(this.data);
525
+ const templated = html(parsed, {
526
+ sanitiseBooleanAttributes: false
527
+ });
528
+ this.data.items.splice(0, this.data.items.length, ...templated.map((node2) => ({
529
+ nodes: [node2]
530
+ })));
531
+ mapNodes(this.data, this.data.items.flatMap((item) => item.fragment?.get() ?? item.nodes));
470
532
  }
471
- return [...this.data.nodes];
533
+ return [
534
+ ...this.data.items.flatMap((item) => item.fragment?.get() ?? item.nodes)
535
+ ];
472
536
  }
473
537
  remove() {
474
- const { length } = this.data.nodes;
538
+ const { length } = this.data.items;
475
539
  for (let index = 0;index < length; index += 1) {
476
- const node2 = this.data.nodes[index];
477
- node2.parentNode?.removeChild(node2);
540
+ const item = this.data.items[index];
541
+ item.fragment?.remove();
542
+ for (const node2 of item.nodes) {
543
+ node2.remove();
544
+ }
478
545
  }
479
- this.data.nodes.splice(0, length);
546
+ this.data.items.splice(0, length);
480
547
  }
481
548
  }
482
549
 
483
550
  // src/html.ts
484
- function handleExpression(data2, prefix, expression) {
551
+ function handleExpression(data, prefix, expression) {
485
552
  if (isNullableOrWhitespace(expression)) {
486
553
  return prefix;
487
554
  }
@@ -489,27 +556,27 @@ function handleExpression(data2, prefix, expression) {
489
556
  const { length } = expression;
490
557
  let expressions = "";
491
558
  for (let index = 0;index < length; index += 1) {
492
- expressions += handleExpression(data2, "", expression[index]);
559
+ expressions += handleExpression(data, "", expression[index]);
493
560
  }
494
561
  return `${prefix}${expressions}`;
495
562
  }
496
563
  if (typeof expression === "function" || typeof expression === "object") {
497
- const index = data2.values.push(expression) - 1;
564
+ const index = data.values.push(expression) - 1;
498
565
  return `${prefix}<!--abydon.${index}-->`;
499
566
  }
500
567
  return `${prefix}${expression}`;
501
568
  }
502
- function html2(strings, ...values) {
569
+ function html4(strings, ...values) {
503
570
  return new Fragment(strings, values);
504
571
  }
505
- function parse2(data2) {
506
- const { length } = data2.strings;
507
- let template2 = "";
572
+ function parse(data) {
573
+ const { length } = data.strings;
574
+ let template4 = "";
508
575
  for (let index = 0;index < length; index += 1) {
509
- template2 += handleExpression(data2, data2.strings[index], data2.expressions[index]);
576
+ template4 += handleExpression(data, data.strings[index], data.expressions[index]);
510
577
  }
511
- return template2;
578
+ return template4;
512
579
  }
513
580
  export {
514
- html2 as html
581
+ html4 as html
515
582
  };