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