jails-js 5.9.0 → 6.0.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 ADDED
@@ -0,0 +1,1121 @@
1
+ const textarea = document.createElement("textarea");
2
+ const g = {
3
+ scope: {}
4
+ };
5
+ const decodeHTML = (text) => {
6
+ textarea.innerHTML = text;
7
+ return textarea.value;
8
+ };
9
+ const uuid = () => {
10
+ return Math.random().toString(36).substring(2, 9);
11
+ };
12
+ const dup = (o) => {
13
+ return JSON.parse(JSON.stringify(o));
14
+ };
15
+ const safe = (execute, val) => {
16
+ try {
17
+ return execute();
18
+ } catch (err) {
19
+ return val || "";
20
+ }
21
+ };
22
+ var Idiomorph = /* @__PURE__ */ function() {
23
+ let EMPTY_SET = /* @__PURE__ */ new Set();
24
+ let defaults = {
25
+ morphStyle: "outerHTML",
26
+ callbacks: {
27
+ beforeNodeAdded: noOp,
28
+ afterNodeAdded: noOp,
29
+ beforeNodeMorphed: noOp,
30
+ afterNodeMorphed: noOp,
31
+ beforeNodeRemoved: noOp,
32
+ afterNodeRemoved: noOp,
33
+ beforeAttributeUpdated: noOp,
34
+ beforeNodePantried: noOp
35
+ },
36
+ head: {
37
+ style: "merge",
38
+ shouldPreserve: function(elt) {
39
+ return elt.getAttribute("im-preserve") === "true";
40
+ },
41
+ shouldReAppend: function(elt) {
42
+ return elt.getAttribute("im-re-append") === "true";
43
+ },
44
+ shouldRemove: noOp,
45
+ afterHeadMorphed: noOp
46
+ }
47
+ };
48
+ function morph(oldNode, newContent, config2 = {}) {
49
+ if (oldNode instanceof Document) {
50
+ oldNode = oldNode.documentElement;
51
+ }
52
+ if (typeof newContent === "string") {
53
+ newContent = parseContent(newContent);
54
+ }
55
+ let normalizedContent = normalizeContent(newContent);
56
+ let ctx = createMorphContext(oldNode, normalizedContent, config2);
57
+ return morphNormalizedContent(oldNode, normalizedContent, ctx);
58
+ }
59
+ function morphNormalizedContent(oldNode, normalizedNewContent, ctx) {
60
+ var _a, _b;
61
+ if (ctx.head.block) {
62
+ let oldHead = oldNode.querySelector("head");
63
+ let newHead = normalizedNewContent.querySelector("head");
64
+ if (oldHead && newHead) {
65
+ let promises = handleHeadElement(newHead, oldHead, ctx);
66
+ Promise.all(promises).then(function() {
67
+ morphNormalizedContent(
68
+ oldNode,
69
+ normalizedNewContent,
70
+ Object.assign(ctx, {
71
+ head: {
72
+ block: false,
73
+ ignore: true
74
+ }
75
+ })
76
+ );
77
+ });
78
+ return;
79
+ }
80
+ }
81
+ if (ctx.morphStyle === "innerHTML") {
82
+ morphChildren(normalizedNewContent, oldNode, ctx);
83
+ if (ctx.config.twoPass) {
84
+ restoreFromPantry(oldNode, ctx);
85
+ }
86
+ return Array.from(oldNode.children);
87
+ } else if (ctx.morphStyle === "outerHTML" || ctx.morphStyle == null) {
88
+ let bestMatch = findBestNodeMatch(normalizedNewContent, oldNode, ctx);
89
+ let previousSibling = (_a = bestMatch == null ? void 0 : bestMatch.previousSibling) != null ? _a : null;
90
+ let nextSibling = (_b = bestMatch == null ? void 0 : bestMatch.nextSibling) != null ? _b : null;
91
+ let morphedNode = morphOldNodeTo(oldNode, bestMatch, ctx);
92
+ if (bestMatch) {
93
+ if (morphedNode) {
94
+ const elements = insertSiblings(
95
+ previousSibling,
96
+ morphedNode,
97
+ nextSibling
98
+ );
99
+ if (ctx.config.twoPass) {
100
+ restoreFromPantry(morphedNode.parentNode, ctx);
101
+ }
102
+ return elements;
103
+ }
104
+ } else {
105
+ return [];
106
+ }
107
+ } else {
108
+ throw "Do not understand how to morph style " + ctx.morphStyle;
109
+ }
110
+ }
111
+ function ignoreValueOfActiveElement(possibleActiveElement, ctx) {
112
+ return !!ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;
113
+ }
114
+ function morphOldNodeTo(oldNode, newContent, ctx) {
115
+ var _a, _b;
116
+ if (ctx.ignoreActive && oldNode === document.activeElement) ;
117
+ else if (newContent == null) {
118
+ if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;
119
+ (_a = oldNode.parentNode) == null ? void 0 : _a.removeChild(oldNode);
120
+ ctx.callbacks.afterNodeRemoved(oldNode);
121
+ return null;
122
+ } else if (!isSoftMatch(oldNode, newContent)) {
123
+ if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;
124
+ if (ctx.callbacks.beforeNodeAdded(newContent) === false) return oldNode;
125
+ (_b = oldNode.parentNode) == null ? void 0 : _b.replaceChild(newContent, oldNode);
126
+ ctx.callbacks.afterNodeAdded(newContent);
127
+ ctx.callbacks.afterNodeRemoved(oldNode);
128
+ return newContent;
129
+ } else {
130
+ if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false)
131
+ return oldNode;
132
+ if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) ;
133
+ else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== "morph") {
134
+ handleHeadElement(
135
+ /** @type {HTMLHeadElement} */
136
+ newContent,
137
+ oldNode,
138
+ ctx
139
+ );
140
+ } else {
141
+ syncNodeFrom(newContent, oldNode, ctx);
142
+ if (!ignoreValueOfActiveElement(oldNode, ctx)) {
143
+ morphChildren(newContent, oldNode, ctx);
144
+ }
145
+ }
146
+ ctx.callbacks.afterNodeMorphed(oldNode, newContent);
147
+ return oldNode;
148
+ }
149
+ return null;
150
+ }
151
+ function morphChildren(newParent, oldParent, ctx) {
152
+ if (newParent instanceof HTMLTemplateElement && oldParent instanceof HTMLTemplateElement) {
153
+ newParent = newParent.content;
154
+ oldParent = oldParent.content;
155
+ }
156
+ let nextNewChild = newParent.firstChild;
157
+ let insertionPoint = oldParent.firstChild;
158
+ let newChild;
159
+ while (nextNewChild) {
160
+ newChild = nextNewChild;
161
+ nextNewChild = newChild.nextSibling;
162
+ if (insertionPoint == null) {
163
+ if (ctx.config.twoPass && ctx.persistentIds.has(
164
+ /** @type {Element} */
165
+ newChild.id
166
+ )) {
167
+ oldParent.appendChild(newChild);
168
+ } else {
169
+ if (ctx.callbacks.beforeNodeAdded(newChild) === false) continue;
170
+ oldParent.appendChild(newChild);
171
+ ctx.callbacks.afterNodeAdded(newChild);
172
+ }
173
+ removeIdsFromConsideration(ctx, newChild);
174
+ continue;
175
+ }
176
+ if (isIdSetMatch(newChild, insertionPoint, ctx)) {
177
+ morphOldNodeTo(insertionPoint, newChild, ctx);
178
+ insertionPoint = insertionPoint.nextSibling;
179
+ removeIdsFromConsideration(ctx, newChild);
180
+ continue;
181
+ }
182
+ let idSetMatch = findIdSetMatch(
183
+ newParent,
184
+ oldParent,
185
+ newChild,
186
+ insertionPoint,
187
+ ctx
188
+ );
189
+ if (idSetMatch) {
190
+ insertionPoint = removeNodesBetween(insertionPoint, idSetMatch, ctx);
191
+ morphOldNodeTo(idSetMatch, newChild, ctx);
192
+ removeIdsFromConsideration(ctx, newChild);
193
+ continue;
194
+ }
195
+ let softMatch = findSoftMatch(
196
+ newParent,
197
+ oldParent,
198
+ newChild,
199
+ insertionPoint,
200
+ ctx
201
+ );
202
+ if (softMatch) {
203
+ insertionPoint = removeNodesBetween(insertionPoint, softMatch, ctx);
204
+ morphOldNodeTo(softMatch, newChild, ctx);
205
+ removeIdsFromConsideration(ctx, newChild);
206
+ continue;
207
+ }
208
+ if (ctx.config.twoPass && ctx.persistentIds.has(
209
+ /** @type {Element} */
210
+ newChild.id
211
+ )) {
212
+ oldParent.insertBefore(newChild, insertionPoint);
213
+ } else {
214
+ if (ctx.callbacks.beforeNodeAdded(newChild) === false) continue;
215
+ oldParent.insertBefore(newChild, insertionPoint);
216
+ ctx.callbacks.afterNodeAdded(newChild);
217
+ }
218
+ removeIdsFromConsideration(ctx, newChild);
219
+ }
220
+ while (insertionPoint !== null) {
221
+ let tempNode = insertionPoint;
222
+ insertionPoint = insertionPoint.nextSibling;
223
+ removeNode(tempNode, ctx);
224
+ }
225
+ }
226
+ function ignoreAttribute(attr, to, updateType, ctx) {
227
+ if (attr === "value" && ctx.ignoreActiveValue && to === document.activeElement) {
228
+ return true;
229
+ }
230
+ return ctx.callbacks.beforeAttributeUpdated(attr, to, updateType) === false;
231
+ }
232
+ function syncNodeFrom(from, to, ctx) {
233
+ let type = from.nodeType;
234
+ if (type === 1) {
235
+ const fromEl = (
236
+ /** @type {Element} */
237
+ from
238
+ );
239
+ const toEl = (
240
+ /** @type {Element} */
241
+ to
242
+ );
243
+ const fromAttributes = fromEl.attributes;
244
+ const toAttributes = toEl.attributes;
245
+ for (const fromAttribute of fromAttributes) {
246
+ if (ignoreAttribute(fromAttribute.name, toEl, "update", ctx)) {
247
+ continue;
248
+ }
249
+ if (toEl.getAttribute(fromAttribute.name) !== fromAttribute.value) {
250
+ toEl.setAttribute(fromAttribute.name, fromAttribute.value);
251
+ }
252
+ }
253
+ for (let i = toAttributes.length - 1; 0 <= i; i--) {
254
+ const toAttribute = toAttributes[i];
255
+ if (!toAttribute) continue;
256
+ if (!fromEl.hasAttribute(toAttribute.name)) {
257
+ if (ignoreAttribute(toAttribute.name, toEl, "remove", ctx)) {
258
+ continue;
259
+ }
260
+ toEl.removeAttribute(toAttribute.name);
261
+ }
262
+ }
263
+ }
264
+ if (type === 8 || type === 3) {
265
+ if (to.nodeValue !== from.nodeValue) {
266
+ to.nodeValue = from.nodeValue;
267
+ }
268
+ }
269
+ if (!ignoreValueOfActiveElement(to, ctx)) {
270
+ syncInputValue(from, to, ctx);
271
+ }
272
+ }
273
+ function syncBooleanAttribute(from, to, attributeName, ctx) {
274
+ if (!(from instanceof Element && to instanceof Element)) return;
275
+ const fromLiveValue = from[attributeName], toLiveValue = to[attributeName];
276
+ if (fromLiveValue !== toLiveValue) {
277
+ let ignoreUpdate = ignoreAttribute(attributeName, to, "update", ctx);
278
+ if (!ignoreUpdate) {
279
+ to[attributeName] = from[attributeName];
280
+ }
281
+ if (fromLiveValue) {
282
+ if (!ignoreUpdate) {
283
+ to.setAttribute(attributeName, fromLiveValue);
284
+ }
285
+ } else {
286
+ if (!ignoreAttribute(attributeName, to, "remove", ctx)) {
287
+ to.removeAttribute(attributeName);
288
+ }
289
+ }
290
+ }
291
+ }
292
+ function syncInputValue(from, to, ctx) {
293
+ if (from instanceof HTMLInputElement && to instanceof HTMLInputElement && from.type !== "file") {
294
+ let fromValue = from.value;
295
+ let toValue = to.value;
296
+ syncBooleanAttribute(from, to, "checked", ctx);
297
+ syncBooleanAttribute(from, to, "disabled", ctx);
298
+ if (!from.hasAttribute("value")) {
299
+ if (!ignoreAttribute("value", to, "remove", ctx)) {
300
+ to.value = "";
301
+ to.removeAttribute("value");
302
+ }
303
+ } else if (fromValue !== toValue) {
304
+ if (!ignoreAttribute("value", to, "update", ctx)) {
305
+ to.setAttribute("value", fromValue);
306
+ to.value = fromValue;
307
+ }
308
+ }
309
+ } else if (from instanceof HTMLOptionElement && to instanceof HTMLOptionElement) {
310
+ syncBooleanAttribute(from, to, "selected", ctx);
311
+ } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) {
312
+ let fromValue = from.value;
313
+ let toValue = to.value;
314
+ if (ignoreAttribute("value", to, "update", ctx)) {
315
+ return;
316
+ }
317
+ if (fromValue !== toValue) {
318
+ to.value = fromValue;
319
+ }
320
+ if (to.firstChild && to.firstChild.nodeValue !== fromValue) {
321
+ to.firstChild.nodeValue = fromValue;
322
+ }
323
+ }
324
+ }
325
+ function handleHeadElement(newHeadTag, currentHead, ctx) {
326
+ let added = [];
327
+ let removed = [];
328
+ let preserved = [];
329
+ let nodesToAppend = [];
330
+ let headMergeStyle = ctx.head.style;
331
+ let srcToNewHeadNodes = /* @__PURE__ */ new Map();
332
+ for (const newHeadChild of newHeadTag.children) {
333
+ srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);
334
+ }
335
+ for (const currentHeadElt of currentHead.children) {
336
+ let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);
337
+ let isReAppended = ctx.head.shouldReAppend(currentHeadElt);
338
+ let isPreserved = ctx.head.shouldPreserve(currentHeadElt);
339
+ if (inNewContent || isPreserved) {
340
+ if (isReAppended) {
341
+ removed.push(currentHeadElt);
342
+ } else {
343
+ srcToNewHeadNodes.delete(currentHeadElt.outerHTML);
344
+ preserved.push(currentHeadElt);
345
+ }
346
+ } else {
347
+ if (headMergeStyle === "append") {
348
+ if (isReAppended) {
349
+ removed.push(currentHeadElt);
350
+ nodesToAppend.push(currentHeadElt);
351
+ }
352
+ } else {
353
+ if (ctx.head.shouldRemove(currentHeadElt) !== false) {
354
+ removed.push(currentHeadElt);
355
+ }
356
+ }
357
+ }
358
+ }
359
+ nodesToAppend.push(...srcToNewHeadNodes.values());
360
+ let promises = [];
361
+ for (const newNode of nodesToAppend) {
362
+ let newElt = (
363
+ /** @type {ChildNode} */
364
+ document.createRange().createContextualFragment(newNode.outerHTML).firstChild
365
+ );
366
+ if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {
367
+ if ("href" in newElt && newElt.href || "src" in newElt && newElt.src) {
368
+ let resolve;
369
+ let promise = new Promise(function(_resolve) {
370
+ resolve = _resolve;
371
+ });
372
+ newElt.addEventListener("load", function() {
373
+ resolve();
374
+ });
375
+ promises.push(promise);
376
+ }
377
+ currentHead.appendChild(newElt);
378
+ ctx.callbacks.afterNodeAdded(newElt);
379
+ added.push(newElt);
380
+ }
381
+ }
382
+ for (const removedElement of removed) {
383
+ if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {
384
+ currentHead.removeChild(removedElement);
385
+ ctx.callbacks.afterNodeRemoved(removedElement);
386
+ }
387
+ }
388
+ ctx.head.afterHeadMorphed(currentHead, {
389
+ added,
390
+ kept: preserved,
391
+ removed
392
+ });
393
+ return promises;
394
+ }
395
+ function noOp() {
396
+ }
397
+ function mergeDefaults(config2) {
398
+ let finalConfig = Object.assign({}, defaults);
399
+ Object.assign(finalConfig, config2);
400
+ finalConfig.callbacks = Object.assign(
401
+ {},
402
+ defaults.callbacks,
403
+ config2.callbacks
404
+ );
405
+ finalConfig.head = Object.assign({}, defaults.head, config2.head);
406
+ return finalConfig;
407
+ }
408
+ function createMorphContext(oldNode, newContent, config2) {
409
+ const mergedConfig = mergeDefaults(config2);
410
+ return {
411
+ target: oldNode,
412
+ newContent,
413
+ config: mergedConfig,
414
+ morphStyle: mergedConfig.morphStyle,
415
+ ignoreActive: mergedConfig.ignoreActive,
416
+ ignoreActiveValue: mergedConfig.ignoreActiveValue,
417
+ idMap: createIdMap(oldNode, newContent),
418
+ deadIds: /* @__PURE__ */ new Set(),
419
+ persistentIds: mergedConfig.twoPass ? createPersistentIds(oldNode, newContent) : /* @__PURE__ */ new Set(),
420
+ pantry: mergedConfig.twoPass ? createPantry() : document.createElement("div"),
421
+ callbacks: mergedConfig.callbacks,
422
+ head: mergedConfig.head
423
+ };
424
+ }
425
+ function createPantry() {
426
+ const pantry = document.createElement("div");
427
+ pantry.hidden = true;
428
+ document.body.insertAdjacentElement("afterend", pantry);
429
+ return pantry;
430
+ }
431
+ function isIdSetMatch(node1, node2, ctx) {
432
+ if (node1 == null || node2 == null) {
433
+ return false;
434
+ }
435
+ if (node1 instanceof Element && node2 instanceof Element && node1.tagName === node2.tagName) {
436
+ if (node1.id !== "" && node1.id === node2.id) {
437
+ return true;
438
+ } else {
439
+ return getIdIntersectionCount(ctx, node1, node2) > 0;
440
+ }
441
+ }
442
+ return false;
443
+ }
444
+ function isSoftMatch(oldNode, newNode) {
445
+ if (oldNode == null || newNode == null) {
446
+ return false;
447
+ }
448
+ if (
449
+ /** @type {Element} */
450
+ oldNode.id && /** @type {Element} */
451
+ oldNode.id !== /** @type {Element} */
452
+ newNode.id
453
+ ) {
454
+ return false;
455
+ }
456
+ return oldNode.nodeType === newNode.nodeType && /** @type {Element} */
457
+ oldNode.tagName === /** @type {Element} */
458
+ newNode.tagName;
459
+ }
460
+ function removeNodesBetween(startInclusive, endExclusive, ctx) {
461
+ let cursor = startInclusive;
462
+ while (cursor !== endExclusive) {
463
+ let tempNode = (
464
+ /** @type {Node} */
465
+ cursor
466
+ );
467
+ cursor = tempNode.nextSibling;
468
+ removeNode(tempNode, ctx);
469
+ }
470
+ removeIdsFromConsideration(ctx, endExclusive);
471
+ return endExclusive.nextSibling;
472
+ }
473
+ function findIdSetMatch(newContent, oldParent, newChild, insertionPoint, ctx) {
474
+ let newChildPotentialIdCount = getIdIntersectionCount(
475
+ ctx,
476
+ newChild,
477
+ oldParent
478
+ );
479
+ let potentialMatch = null;
480
+ if (newChildPotentialIdCount > 0) {
481
+ potentialMatch = insertionPoint;
482
+ let otherMatchCount = 0;
483
+ while (potentialMatch != null) {
484
+ if (isIdSetMatch(newChild, potentialMatch, ctx)) {
485
+ return potentialMatch;
486
+ }
487
+ otherMatchCount += getIdIntersectionCount(
488
+ ctx,
489
+ potentialMatch,
490
+ newContent
491
+ );
492
+ if (otherMatchCount > newChildPotentialIdCount) {
493
+ return null;
494
+ }
495
+ potentialMatch = potentialMatch.nextSibling;
496
+ }
497
+ }
498
+ return potentialMatch;
499
+ }
500
+ function findSoftMatch(newContent, oldParent, newChild, insertionPoint, ctx) {
501
+ let potentialSoftMatch = insertionPoint;
502
+ let nextSibling = newChild.nextSibling;
503
+ let siblingSoftMatchCount = 0;
504
+ while (potentialSoftMatch != null) {
505
+ if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) {
506
+ return null;
507
+ }
508
+ if (isSoftMatch(potentialSoftMatch, newChild)) {
509
+ return potentialSoftMatch;
510
+ }
511
+ if (isSoftMatch(potentialSoftMatch, nextSibling)) {
512
+ siblingSoftMatchCount++;
513
+ nextSibling = /** @type {Node} */
514
+ nextSibling.nextSibling;
515
+ if (siblingSoftMatchCount >= 2) {
516
+ return null;
517
+ }
518
+ }
519
+ potentialSoftMatch = potentialSoftMatch.nextSibling;
520
+ }
521
+ return potentialSoftMatch;
522
+ }
523
+ const generatedByIdiomorph = /* @__PURE__ */ new WeakSet();
524
+ function parseContent(newContent) {
525
+ let parser = new DOMParser();
526
+ let contentWithSvgsRemoved = newContent.replace(
527
+ /<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,
528
+ ""
529
+ );
530
+ if (contentWithSvgsRemoved.match(/<\/html>/) || contentWithSvgsRemoved.match(/<\/head>/) || contentWithSvgsRemoved.match(/<\/body>/)) {
531
+ let content = parser.parseFromString(newContent, "text/html");
532
+ if (contentWithSvgsRemoved.match(/<\/html>/)) {
533
+ generatedByIdiomorph.add(content);
534
+ return content;
535
+ } else {
536
+ let htmlElement = content.firstChild;
537
+ if (htmlElement) {
538
+ generatedByIdiomorph.add(htmlElement);
539
+ return htmlElement;
540
+ } else {
541
+ return null;
542
+ }
543
+ }
544
+ } else {
545
+ let responseDoc = parser.parseFromString(
546
+ "<body><template>" + newContent + "</template></body>",
547
+ "text/html"
548
+ );
549
+ let content = (
550
+ /** @type {HTMLTemplateElement} */
551
+ responseDoc.body.querySelector("template").content
552
+ );
553
+ generatedByIdiomorph.add(content);
554
+ return content;
555
+ }
556
+ }
557
+ function normalizeContent(newContent) {
558
+ if (newContent == null) {
559
+ const dummyParent = document.createElement("div");
560
+ return dummyParent;
561
+ } else if (generatedByIdiomorph.has(
562
+ /** @type {Element} */
563
+ newContent
564
+ )) {
565
+ return (
566
+ /** @type {Element} */
567
+ newContent
568
+ );
569
+ } else if (newContent instanceof Node) {
570
+ const dummyParent = document.createElement("div");
571
+ dummyParent.append(newContent);
572
+ return dummyParent;
573
+ } else {
574
+ const dummyParent = document.createElement("div");
575
+ for (const elt of [...newContent]) {
576
+ dummyParent.append(elt);
577
+ }
578
+ return dummyParent;
579
+ }
580
+ }
581
+ function insertSiblings(previousSibling, morphedNode, nextSibling) {
582
+ var _a, _b;
583
+ let stack = [];
584
+ let added = [];
585
+ while (previousSibling != null) {
586
+ stack.push(previousSibling);
587
+ previousSibling = previousSibling.previousSibling;
588
+ }
589
+ let node = stack.pop();
590
+ while (node !== void 0) {
591
+ added.push(node);
592
+ (_a = morphedNode.parentElement) == null ? void 0 : _a.insertBefore(node, morphedNode);
593
+ node = stack.pop();
594
+ }
595
+ added.push(morphedNode);
596
+ while (nextSibling != null) {
597
+ stack.push(nextSibling);
598
+ added.push(nextSibling);
599
+ nextSibling = nextSibling.nextSibling;
600
+ }
601
+ while (stack.length > 0) {
602
+ const node2 = (
603
+ /** @type {Node} */
604
+ stack.pop()
605
+ );
606
+ (_b = morphedNode.parentElement) == null ? void 0 : _b.insertBefore(node2, morphedNode.nextSibling);
607
+ }
608
+ return added;
609
+ }
610
+ function findBestNodeMatch(newContent, oldNode, ctx) {
611
+ let currentElement;
612
+ currentElement = newContent.firstChild;
613
+ let bestElement = currentElement;
614
+ let score = 0;
615
+ while (currentElement) {
616
+ let newScore = scoreElement(currentElement, oldNode, ctx);
617
+ if (newScore > score) {
618
+ bestElement = currentElement;
619
+ score = newScore;
620
+ }
621
+ currentElement = currentElement.nextSibling;
622
+ }
623
+ return bestElement;
624
+ }
625
+ function scoreElement(node1, node2, ctx) {
626
+ if (isSoftMatch(node2, node1)) {
627
+ return 0.5 + getIdIntersectionCount(
628
+ ctx,
629
+ /** @type {Node} */
630
+ node1,
631
+ node2
632
+ );
633
+ }
634
+ return 0;
635
+ }
636
+ function removeNode(tempNode, ctx) {
637
+ var _a;
638
+ removeIdsFromConsideration(ctx, tempNode);
639
+ if (ctx.config.twoPass && hasPersistentIdNodes(ctx, tempNode) && tempNode instanceof Element) {
640
+ moveToPantry(tempNode, ctx);
641
+ } else {
642
+ if (ctx.callbacks.beforeNodeRemoved(tempNode) === false) return;
643
+ (_a = tempNode.parentNode) == null ? void 0 : _a.removeChild(tempNode);
644
+ ctx.callbacks.afterNodeRemoved(tempNode);
645
+ }
646
+ }
647
+ function moveToPantry(node, ctx) {
648
+ var _a;
649
+ if (ctx.callbacks.beforeNodePantried(node) === false) return;
650
+ Array.from(node.childNodes).forEach((child) => {
651
+ moveToPantry(child, ctx);
652
+ });
653
+ if (ctx.persistentIds.has(
654
+ /** @type {Element} */
655
+ node.id
656
+ )) {
657
+ if (ctx.pantry.moveBefore) {
658
+ ctx.pantry.moveBefore(node, null);
659
+ } else {
660
+ ctx.pantry.insertBefore(node, null);
661
+ }
662
+ } else {
663
+ if (ctx.callbacks.beforeNodeRemoved(node) === false) return;
664
+ (_a = node.parentNode) == null ? void 0 : _a.removeChild(node);
665
+ ctx.callbacks.afterNodeRemoved(node);
666
+ }
667
+ }
668
+ function restoreFromPantry(root, ctx) {
669
+ if (root instanceof Element) {
670
+ Array.from(ctx.pantry.children).reverse().forEach((element) => {
671
+ var _a;
672
+ const matchElement = root.querySelector(`#${element.id}`);
673
+ if (matchElement) {
674
+ if ((_a = matchElement.parentElement) == null ? void 0 : _a.moveBefore) {
675
+ matchElement.parentElement.moveBefore(element, matchElement);
676
+ while (matchElement.hasChildNodes()) {
677
+ element.moveBefore(matchElement.firstChild, null);
678
+ }
679
+ } else {
680
+ matchElement.before(element);
681
+ while (matchElement.firstChild) {
682
+ element.insertBefore(matchElement.firstChild, null);
683
+ }
684
+ }
685
+ if (ctx.callbacks.beforeNodeMorphed(element, matchElement) !== false) {
686
+ syncNodeFrom(matchElement, element, ctx);
687
+ ctx.callbacks.afterNodeMorphed(element, matchElement);
688
+ }
689
+ matchElement.remove();
690
+ }
691
+ });
692
+ ctx.pantry.remove();
693
+ }
694
+ }
695
+ function isIdInConsideration(ctx, id) {
696
+ return !ctx.deadIds.has(id);
697
+ }
698
+ function idIsWithinNode(ctx, id, targetNode) {
699
+ let idSet = ctx.idMap.get(targetNode) || EMPTY_SET;
700
+ return idSet.has(id);
701
+ }
702
+ function removeIdsFromConsideration(ctx, node) {
703
+ let idSet = ctx.idMap.get(node) || EMPTY_SET;
704
+ for (const id of idSet) {
705
+ ctx.deadIds.add(id);
706
+ }
707
+ }
708
+ function hasPersistentIdNodes(ctx, node) {
709
+ for (const id of ctx.idMap.get(node) || EMPTY_SET) {
710
+ if (ctx.persistentIds.has(id)) {
711
+ return true;
712
+ }
713
+ }
714
+ return false;
715
+ }
716
+ function getIdIntersectionCount(ctx, node1, node2) {
717
+ let sourceSet = ctx.idMap.get(node1) || EMPTY_SET;
718
+ let matchCount = 0;
719
+ for (const id of sourceSet) {
720
+ if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) {
721
+ ++matchCount;
722
+ }
723
+ }
724
+ return matchCount;
725
+ }
726
+ function nodesWithIds(content) {
727
+ let nodes = Array.from(content.querySelectorAll("[id]"));
728
+ if (content.id) {
729
+ nodes.push(content);
730
+ }
731
+ return nodes;
732
+ }
733
+ function populateIdMapForNode(node, idMap) {
734
+ let nodeParent = node.parentElement;
735
+ for (const elt of nodesWithIds(node)) {
736
+ let current = elt;
737
+ while (current !== nodeParent && current != null) {
738
+ let idSet = idMap.get(current);
739
+ if (idSet == null) {
740
+ idSet = /* @__PURE__ */ new Set();
741
+ idMap.set(current, idSet);
742
+ }
743
+ idSet.add(elt.id);
744
+ current = current.parentElement;
745
+ }
746
+ }
747
+ }
748
+ function createIdMap(oldContent, newContent) {
749
+ let idMap = /* @__PURE__ */ new Map();
750
+ populateIdMapForNode(oldContent, idMap);
751
+ populateIdMapForNode(newContent, idMap);
752
+ return idMap;
753
+ }
754
+ function createPersistentIds(oldContent, newContent) {
755
+ const toIdTagName = (node) => node.tagName + "#" + node.id;
756
+ const oldIdSet = new Set(nodesWithIds(oldContent).map(toIdTagName));
757
+ let matchIdSet = /* @__PURE__ */ new Set();
758
+ for (const newNode of nodesWithIds(newContent)) {
759
+ if (oldIdSet.has(toIdTagName(newNode))) {
760
+ matchIdSet.add(newNode.id);
761
+ }
762
+ }
763
+ return matchIdSet;
764
+ }
765
+ return {
766
+ morph,
767
+ defaults
768
+ };
769
+ }();
770
+ const topics = {};
771
+ const _async = {};
772
+ const publish = (name, params) => {
773
+ _async[name] = Object.assign({}, _async[name], params);
774
+ if (topics[name])
775
+ topics[name].forEach((topic) => topic(params));
776
+ };
777
+ const subscribe = (name, method) => {
778
+ topics[name] = topics[name] || [];
779
+ topics[name].push(method);
780
+ if (name in _async) {
781
+ method(_async[name]);
782
+ }
783
+ return () => {
784
+ topics[name] = topics[name].filter((fn) => fn != method);
785
+ };
786
+ };
787
+ const Component = ({ name, module, dependencies, node, templates: templates2, signal, register: register2 }) => {
788
+ var _a;
789
+ let tick;
790
+ let preserve = [];
791
+ const _model = module.model || {};
792
+ const initialState = new Function(`return ${node.getAttribute("html-model") || "{}"}`)();
793
+ const tplid = node.getAttribute("tplid");
794
+ const scopeid = node.getAttribute("html-scopeid");
795
+ const tpl = templates2[tplid];
796
+ const scope = g.scope[scopeid];
797
+ const model = dup(((_a = module == null ? void 0 : module.model) == null ? void 0 : _a.apply) ? _model({ elm: node, initialState }) : _model);
798
+ const state = Object.assign({}, scope, model, initialState);
799
+ const view = module.view ? module.view : (data) => data;
800
+ const base = {
801
+ name,
802
+ model,
803
+ elm: node,
804
+ template: tpl.template,
805
+ dependencies,
806
+ publish,
807
+ subscribe,
808
+ main(fn) {
809
+ node.addEventListener(":mount", fn);
810
+ },
811
+ /**
812
+ * @State
813
+ */
814
+ state: {
815
+ protected(list) {
816
+ if (list) {
817
+ preserve = list;
818
+ } else {
819
+ return preserve;
820
+ }
821
+ },
822
+ save(data) {
823
+ if (data.constructor === Function) {
824
+ data(state);
825
+ } else {
826
+ Object.assign(state, data);
827
+ }
828
+ },
829
+ set(data) {
830
+ if (!document.body.contains(node)) {
831
+ return;
832
+ }
833
+ if (data.constructor === Function) {
834
+ data(state);
835
+ } else {
836
+ Object.assign(state, data);
837
+ }
838
+ const newstate = Object.assign({}, state, scope);
839
+ render(newstate);
840
+ return Promise.resolve(newstate);
841
+ },
842
+ get() {
843
+ return Object.assign({}, state);
844
+ }
845
+ },
846
+ /**
847
+ * @Events
848
+ */
849
+ on(ev, selectorOrCallback, callback) {
850
+ if (callback) {
851
+ callback.handler = (e) => {
852
+ const detail = e.detail || {};
853
+ let parent = e.target;
854
+ while (parent) {
855
+ if (parent.matches(selectorOrCallback)) {
856
+ e.delegateTarget = parent;
857
+ callback.apply(node, [e].concat(detail.args));
858
+ }
859
+ if (parent === node) break;
860
+ parent = parent.parentNode;
861
+ }
862
+ };
863
+ node.addEventListener(ev, callback.handler, {
864
+ signal,
865
+ capture: ev == "focus" || ev == "blur" || ev == "mouseenter" || ev == "mouseleave"
866
+ });
867
+ } else {
868
+ selectorOrCallback.handler = (e) => {
869
+ e.delegateTarget = node;
870
+ selectorOrCallback.apply(node, [e].concat(e.detail.args));
871
+ };
872
+ node.addEventListener(ev, selectorOrCallback.handler, { signal });
873
+ }
874
+ },
875
+ off(ev, callback) {
876
+ if (callback.handler) {
877
+ node.removeEventListener(ev, callback.handler);
878
+ }
879
+ },
880
+ trigger(ev, selectorOrCallback, data) {
881
+ if (selectorOrCallback.constructor === String) {
882
+ Array.from(node.querySelectorAll(selectorOrCallback)).forEach((children) => {
883
+ children.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }));
884
+ });
885
+ } else {
886
+ node.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }));
887
+ }
888
+ },
889
+ emit(ev, data) {
890
+ node.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }));
891
+ },
892
+ unmount(fn) {
893
+ node.addEventListener(":unmount", fn);
894
+ },
895
+ innerHTML(target, html_) {
896
+ const element = html_ ? target : node;
897
+ const clone = element.cloneNode();
898
+ const html = html_ ? html_ : target;
899
+ clone.innerHTML = html;
900
+ Idiomorph.morph(element, clone);
901
+ }
902
+ };
903
+ const render = (data) => {
904
+ clearTimeout(tick);
905
+ tick = setTimeout(() => {
906
+ const html = tpl.render.call(view(data), node, safe, g);
907
+ Idiomorph.morph(node, html, IdiomorphOptions(node, register2));
908
+ Promise.resolve().then(() => {
909
+ node.querySelectorAll("[tplid]").forEach((element) => {
910
+ const child = register2.get(element);
911
+ if (!child) return;
912
+ child.state.protected().forEach((key) => delete data[key]);
913
+ child.state.set(data);
914
+ });
915
+ Promise.resolve().then(() => g.scope = {});
916
+ });
917
+ });
918
+ };
919
+ render(state);
920
+ register2.set(node, base);
921
+ return module.default(base);
922
+ };
923
+ const IdiomorphOptions = (parent, register2) => ({
924
+ callbacks: {
925
+ beforeNodeMorphed(node) {
926
+ if (node.nodeType === 1) {
927
+ if ("html-static" in node.attributes) {
928
+ return false;
929
+ }
930
+ if (register2.get(node) && node !== parent) {
931
+ return false;
932
+ }
933
+ }
934
+ }
935
+ }
936
+ });
937
+ const register$1 = /* @__PURE__ */ new WeakMap();
938
+ const Element$1 = ({ component, templates: templates2, start: start2 }) => {
939
+ const { name, module, dependencies } = component;
940
+ return class extends HTMLElement {
941
+ constructor() {
942
+ super();
943
+ }
944
+ connectedCallback() {
945
+ this.abortController = new AbortController();
946
+ if (!this.getAttribute("tplid")) {
947
+ start2(this.parentNode);
948
+ }
949
+ const rtrn = Component({
950
+ node: this,
951
+ name,
952
+ module,
953
+ dependencies,
954
+ templates: templates2,
955
+ signal: this.abortController.signal,
956
+ register: register$1
957
+ });
958
+ if (rtrn && rtrn.constructor === Promise) {
959
+ rtrn.then(() => {
960
+ this.dispatchEvent(new CustomEvent(":mount"));
961
+ });
962
+ } else {
963
+ this.dispatchEvent(new CustomEvent(":mount"));
964
+ }
965
+ }
966
+ disconnectedCallback() {
967
+ this.dispatchEvent(new CustomEvent(":unmount"));
968
+ this.abortController.abort();
969
+ }
970
+ };
971
+ };
972
+ const templates = {};
973
+ const config = {
974
+ tags: ["{{", "}}"]
975
+ };
976
+ const templateConfig$1 = (newconfig) => {
977
+ Object.assign(config, newconfig);
978
+ };
979
+ const template = (target, { components: components2 }) => {
980
+ tagElements(target, [...Object.keys(components2), "[html-if]", "template"]);
981
+ const clone = target.cloneNode(true);
982
+ transformTemplate(clone);
983
+ removeTemplateTagsRecursively(clone);
984
+ setTemplates(clone, components2);
985
+ return templates;
986
+ };
987
+ const compile = (html) => {
988
+ const parsedHtml = JSON.stringify(html);
989
+ return new Function("$element", "safe", "$g", `
990
+ var $data = this;
991
+ with( $data ){
992
+ var output=${parsedHtml.replace(/%%_=(.+?)_%%/g, function(_, variable) {
993
+ return '"+safe(function(){return ' + decodeHTML(variable) + ';})+"';
994
+ }).replace(/%%_(.+?)_%%/g, function(_, variable) {
995
+ return '";' + decodeHTML(variable) + '\noutput+="';
996
+ })};return output;
997
+ }
998
+ `);
999
+ };
1000
+ const tagElements = (target, keys) => {
1001
+ target.querySelectorAll(keys.toString()).forEach((node) => {
1002
+ if (node.localName === "template") {
1003
+ return tagElements(node.content, keys);
1004
+ }
1005
+ node.setAttribute("tplid", uuid());
1006
+ if (node.getAttribute("html-if") && !node.id) {
1007
+ node.id = uuid();
1008
+ }
1009
+ });
1010
+ };
1011
+ const transformAttributes = (html) => {
1012
+ const regexTags = new RegExp(`\\${config.tags[0]}(.+?)\\${config.tags[1]}`, "g");
1013
+ return html.replace(/jails___scope-id/g, "%%_=$scopeid_%%").replace(regexTags, "%%_=$1_%%").replace(/html-(allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|formnovalidate|inert|ismap|itemscope|loop|multiple|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|selected)=\"(.*?)\"/g, `%%_if(safe(function(){ return $2 })){_%%$1%%_}_%%`).replace(/html-(.*?)=\"(.*?)\"/g, (all, key, value) => {
1014
+ if (key === "key" || key === "model" || key === "scopeid") {
1015
+ return all;
1016
+ }
1017
+ if (value) {
1018
+ value = value.replace(/^{|}$/g, "");
1019
+ return `${key}="%%_=safe(function(){ return ${value} })_%%"`;
1020
+ } else {
1021
+ return all;
1022
+ }
1023
+ });
1024
+ };
1025
+ const transformTemplate = (clone) => {
1026
+ clone.querySelectorAll("template, [html-for], [html-if], [html-inner], [html-class]").forEach((element) => {
1027
+ const htmlFor = element.getAttribute("html-for");
1028
+ const htmlIf = element.getAttribute("html-if");
1029
+ const htmlInner = element.getAttribute("html-inner");
1030
+ const htmlClass = element.getAttribute("html-class");
1031
+ if (htmlFor) {
1032
+ element.removeAttribute("html-for");
1033
+ const split = htmlFor.match(/(.*)\sin\s(.*)/) || "";
1034
+ const varname = split[1];
1035
+ const object = split[2];
1036
+ const objectname = object.split(/\./).shift();
1037
+ const open = document.createTextNode(`%%_ ;(function(){ var $index = 0; for(var $key in safe(function(){ return ${object} }) ){ var $scopeid = Math.random().toString(36).substring(2, 9); var ${varname} = ${object}[$key]; $g.scope[$scopeid] = Object.assign({}, { ${objectname}: ${objectname} }, { ${varname} :${varname}, $index: $index, $key: $key }); _%%`);
1038
+ const close = document.createTextNode(`%%_ $index++; } })() _%%`);
1039
+ wrap(open, element, close);
1040
+ }
1041
+ if (htmlIf) {
1042
+ element.removeAttribute("html-if");
1043
+ const open = document.createTextNode(`%%_ if ( safe(function(){ return ${htmlIf} }) ){ _%%`);
1044
+ const close = document.createTextNode(`%%_ } _%%`);
1045
+ wrap(open, element, close);
1046
+ }
1047
+ if (htmlInner) {
1048
+ element.removeAttribute("html-inner");
1049
+ element.innerHTML = `%%_=${htmlInner}_%%`;
1050
+ }
1051
+ if (htmlClass) {
1052
+ element.removeAttribute("html-class");
1053
+ element.className = (element.className + ` %%_=${htmlClass}_%%`).trim();
1054
+ }
1055
+ if (element.localName === "template") {
1056
+ transformTemplate(element.content);
1057
+ }
1058
+ });
1059
+ };
1060
+ const setTemplates = (clone, components2) => {
1061
+ Array.from(clone.querySelectorAll("[tplid]")).reverse().forEach((node) => {
1062
+ const tplid = node.getAttribute("tplid");
1063
+ const name = node.localName;
1064
+ node.setAttribute("html-scopeid", "jails___scope-id");
1065
+ if (name in components2 && components2[name].module.template) {
1066
+ const children = node.innerHTML;
1067
+ const html2 = components2[name].module.template({ elm: node, children });
1068
+ node.innerHTML = html2;
1069
+ }
1070
+ const html = transformAttributes(node.outerHTML);
1071
+ templates[tplid] = {
1072
+ template: html,
1073
+ render: compile(html)
1074
+ };
1075
+ });
1076
+ };
1077
+ const removeTemplateTagsRecursively = (node) => {
1078
+ const templates2 = node.querySelectorAll("template");
1079
+ templates2.forEach((template2) => {
1080
+ if (template2.getAttribute("html-if") || template2.getAttribute("html-inner")) {
1081
+ return;
1082
+ }
1083
+ removeTemplateTagsRecursively(template2.content);
1084
+ const parent = template2.parentNode;
1085
+ if (parent) {
1086
+ const content = template2.content;
1087
+ while (content.firstChild) {
1088
+ parent.insertBefore(content.firstChild, template2);
1089
+ }
1090
+ parent.removeChild(template2);
1091
+ }
1092
+ });
1093
+ };
1094
+ const wrap = (open, node, close) => {
1095
+ var _a, _b;
1096
+ (_a = node.parentNode) == null ? void 0 : _a.insertBefore(open, node);
1097
+ (_b = node.parentNode) == null ? void 0 : _b.insertBefore(close, node.nextSibling);
1098
+ };
1099
+ const components = {};
1100
+ const templateConfig = (options) => {
1101
+ templateConfig$1(options);
1102
+ };
1103
+ const register = (name, module, dependencies) => {
1104
+ components[name] = { name, module, dependencies };
1105
+ };
1106
+ const start = (target = document.body) => {
1107
+ const templates2 = template(target, { components });
1108
+ Object.values(components).forEach(({ name, module, dependencies }) => {
1109
+ if (!customElements.get(name)) {
1110
+ customElements.define(name, Element$1({ component: { name, module, dependencies }, templates: templates2, start }));
1111
+ }
1112
+ });
1113
+ };
1114
+ export {
1115
+ publish,
1116
+ register,
1117
+ start,
1118
+ subscribe,
1119
+ templateConfig
1120
+ };
1121
+ //# sourceMappingURL=index.js.map