thunderous 2.0.0 → 2.0.2
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/README.md +2 -2
- package/dist/index.cjs +150 -146
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +150 -146
- package/package.json +1 -1
package/README.md
CHANGED
@@ -35,9 +35,9 @@ const myStyleSheet = css`
|
|
35
35
|
}
|
36
36
|
`;
|
37
37
|
|
38
|
-
const MyElement = customElement(({
|
38
|
+
const MyElement = customElement(({ refs, adoptStyleSheet }) => {
|
39
39
|
const [count, setCount] = createSignal(0);
|
40
|
-
const increment =
|
40
|
+
const increment = () => setCount(count() + 1);
|
41
41
|
adoptStyleSheet(myStyleSheet);
|
42
42
|
return html`
|
43
43
|
<button onclick="${increment}">Increment</button>
|
package/dist/index.cjs
CHANGED
@@ -271,19 +271,15 @@ var clientOnlyCallback = (fn) => {
|
|
271
271
|
};
|
272
272
|
|
273
273
|
// src/render.ts
|
274
|
+
var CALLBACK_BINDING_REGEX = /(\{\{callback:.+\}\})/;
|
275
|
+
var LEGACY_CALLBACK_BINDING_REGEX = /(this.getRootNode\(\).host.__customCallbackFns.get\('.+'\)\(event\))/;
|
276
|
+
var SIGNAL_BINDING_REGEX = /(\{\{signal:.+\}\})/;
|
277
|
+
var FRAGMENT_ATTRIBUTE = "___thunderous-fragment";
|
274
278
|
var renderState = {
|
275
|
-
currentShadowRoot: null
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
element.childNodes[0].remove();
|
280
|
-
}
|
281
|
-
};
|
282
|
-
var parseFragment = (htmlStr) => {
|
283
|
-
const template = document.createElement("template");
|
284
|
-
template.innerHTML = htmlStr;
|
285
|
-
const fragment = renderState.currentShadowRoot === null ? template.content : renderState.currentShadowRoot.importNode(template.content, true);
|
286
|
-
return fragment;
|
279
|
+
currentShadowRoot: null,
|
280
|
+
signalMap: /* @__PURE__ */ new Map(),
|
281
|
+
callbackMap: /* @__PURE__ */ new Map(),
|
282
|
+
fragmentMap: /* @__PURE__ */ new Map()
|
287
283
|
};
|
288
284
|
var logValueError = (value) => {
|
289
285
|
console.error(
|
@@ -296,7 +292,7 @@ var arrayToDocumentFragment = (array, parent) => {
|
|
296
292
|
let count = 0;
|
297
293
|
const keys = /* @__PURE__ */ new Set();
|
298
294
|
for (const item of array) {
|
299
|
-
const node =
|
295
|
+
const node = createNewNode(item, parent);
|
300
296
|
if (node instanceof DocumentFragment) {
|
301
297
|
const child = node.firstElementChild;
|
302
298
|
if (node.children.length > 1) {
|
@@ -328,150 +324,151 @@ var arrayToDocumentFragment = (array, parent) => {
|
|
328
324
|
}
|
329
325
|
return documentFragment;
|
330
326
|
};
|
331
|
-
var
|
327
|
+
var createNewNode = (value, parent) => {
|
332
328
|
if (typeof value === "string") return new Text(value);
|
333
329
|
if (Array.isArray(value)) return arrayToDocumentFragment(value, parent);
|
334
330
|
if (value instanceof DocumentFragment) return value;
|
335
331
|
return new Text("");
|
336
332
|
};
|
337
|
-
var
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
signalMap.set(uniqueKey, getter);
|
351
|
-
let result = getter();
|
352
|
-
if (Array.isArray(result)) {
|
353
|
-
result = result.map((item) => processValue(item)).join("");
|
354
|
-
}
|
355
|
-
return isServer ? String(result) : `{{signal:${uniqueKey}}}`;
|
333
|
+
var processValue = (value) => {
|
334
|
+
if (!isServer && value instanceof DocumentFragment) {
|
335
|
+
const uniqueKey = crypto.randomUUID();
|
336
|
+
renderState.fragmentMap.set(uniqueKey, value);
|
337
|
+
return `<div ${FRAGMENT_ATTRIBUTE}="${uniqueKey}"></div>`;
|
338
|
+
}
|
339
|
+
if (typeof value === "function" && "getter" in value && value.getter === true) {
|
340
|
+
const getter = value;
|
341
|
+
const uniqueKey = crypto.randomUUID();
|
342
|
+
renderState.signalMap.set(uniqueKey, getter);
|
343
|
+
let result = getter();
|
344
|
+
if (Array.isArray(result)) {
|
345
|
+
result = result.map((item) => processValue(item)).join("");
|
356
346
|
}
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
347
|
+
return isServer ? String(result) : `{{signal:${uniqueKey}}}`;
|
348
|
+
}
|
349
|
+
if (typeof value === "function") {
|
350
|
+
const uniqueKey = crypto.randomUUID();
|
351
|
+
renderState.callbackMap.set(uniqueKey, value);
|
352
|
+
return isServer ? String(value()) : `{{callback:${uniqueKey}}}`;
|
353
|
+
}
|
354
|
+
if (typeof value === "object" && value !== null) {
|
355
|
+
logValueError(value);
|
356
|
+
return "";
|
357
|
+
}
|
358
|
+
return String(value);
|
359
|
+
};
|
360
|
+
var evaluateBindings = (element, fragment) => {
|
361
|
+
for (const child of element.childNodes) {
|
362
|
+
if (child instanceof Text && SIGNAL_BINDING_REGEX.test(child.data)) {
|
363
|
+
const textList = child.data.split(SIGNAL_BINDING_REGEX);
|
364
|
+
const sibling = child.nextSibling;
|
365
|
+
textList.forEach((text, i) => {
|
366
|
+
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
367
|
+
const signal = uniqueKey !== text ? renderState.signalMap.get(uniqueKey) : void 0;
|
368
|
+
const newValue = signal !== void 0 ? signal() : text;
|
369
|
+
const newNode = createNewNode(newValue, element);
|
370
|
+
if (i === 0) {
|
371
|
+
child.replaceWith(newNode);
|
372
|
+
} else {
|
373
|
+
element.insertBefore(newNode, sibling);
|
374
|
+
}
|
375
|
+
if (signal !== void 0 && newNode instanceof Text) {
|
376
|
+
createEffect(() => {
|
377
|
+
newNode.data = signal();
|
378
|
+
});
|
379
|
+
} else if (signal !== void 0 && newNode instanceof DocumentFragment) {
|
380
|
+
createEffect(() => {
|
381
|
+
const result = signal();
|
382
|
+
const nextNode = createNewNode(result, element);
|
383
|
+
if (nextNode instanceof Text) {
|
384
|
+
throw new TypeError(
|
385
|
+
"Signal mismatch: expected DocumentFragment or Array<DocumentFragment>, but got Text"
|
386
|
+
);
|
387
|
+
}
|
388
|
+
let lastSibling = element.lastChild;
|
389
|
+
for (const child2 of nextNode.children) {
|
390
|
+
const key = child2.getAttribute("key");
|
391
|
+
const matchingNode = element.querySelector(`[key="${key}"]`);
|
392
|
+
if (matchingNode === null) continue;
|
393
|
+
lastSibling = matchingNode.nextSibling;
|
394
|
+
child2.replaceWith(matchingNode);
|
395
|
+
}
|
396
|
+
element.insertBefore(nextNode, lastSibling);
|
397
|
+
});
|
398
|
+
}
|
399
|
+
});
|
361
400
|
}
|
362
|
-
if (
|
363
|
-
|
364
|
-
|
401
|
+
if (child instanceof Element && child.hasAttribute(FRAGMENT_ATTRIBUTE)) {
|
402
|
+
const uniqueKey = child.getAttribute(FRAGMENT_ATTRIBUTE);
|
403
|
+
const childFragment = renderState.fragmentMap.get(uniqueKey);
|
404
|
+
if (childFragment !== void 0) {
|
405
|
+
child.replaceWith(childFragment);
|
406
|
+
}
|
407
|
+
} else if (child instanceof Element) {
|
408
|
+
for (const attr of child.attributes) {
|
409
|
+
if (SIGNAL_BINDING_REGEX.test(attr.value)) {
|
410
|
+
const textList = attr.value.split(SIGNAL_BINDING_REGEX);
|
411
|
+
createEffect(() => {
|
412
|
+
let newText = "";
|
413
|
+
let hasNull = false;
|
414
|
+
for (const text of textList) {
|
415
|
+
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
416
|
+
const signal = uniqueKey !== text ? renderState.signalMap.get(uniqueKey) : void 0;
|
417
|
+
const value = signal !== void 0 ? signal() : text;
|
418
|
+
if (value === null) hasNull = true;
|
419
|
+
newText += String(value);
|
420
|
+
}
|
421
|
+
if (hasNull && newText === "null") {
|
422
|
+
child.removeAttribute(attr.name);
|
423
|
+
} else {
|
424
|
+
child.setAttribute(attr.name, newText);
|
425
|
+
}
|
426
|
+
});
|
427
|
+
} else if (LEGACY_CALLBACK_BINDING_REGEX.test(attr.value)) {
|
428
|
+
const getRootNode = child.getRootNode.bind(child);
|
429
|
+
child.getRootNode = () => {
|
430
|
+
const rootNode = getRootNode();
|
431
|
+
return rootNode instanceof ShadowRoot ? rootNode : fragment;
|
432
|
+
};
|
433
|
+
} else if (CALLBACK_BINDING_REGEX.test(attr.value)) {
|
434
|
+
const textList = attr.value.split(CALLBACK_BINDING_REGEX);
|
435
|
+
createEffect(() => {
|
436
|
+
child.__customCallbackFns = child.__customCallbackFns ?? /* @__PURE__ */ new Map();
|
437
|
+
let uniqueKey = "";
|
438
|
+
for (const text of textList) {
|
439
|
+
const _uniqueKey = text.replace(/\{\{callback:(.+)\}\}/, "$1");
|
440
|
+
if (_uniqueKey !== text) uniqueKey = _uniqueKey;
|
441
|
+
const callback = uniqueKey !== text ? renderState.callbackMap.get(uniqueKey) : void 0;
|
442
|
+
if (callback !== void 0) {
|
443
|
+
child.__customCallbackFns.set(uniqueKey, callback);
|
444
|
+
}
|
445
|
+
}
|
446
|
+
if (uniqueKey !== "") {
|
447
|
+
child.setAttribute(attr.name, `this.__customCallbackFns.get('${uniqueKey}')(event)`);
|
448
|
+
}
|
449
|
+
});
|
450
|
+
}
|
451
|
+
}
|
452
|
+
evaluateBindings(child, fragment);
|
365
453
|
}
|
366
|
-
|
367
|
-
|
368
|
-
|
454
|
+
}
|
455
|
+
};
|
456
|
+
var html = (strings, ...values) => {
|
457
|
+
const innerHTML = strings.reduce((innerHTML2, str, i) => {
|
369
458
|
let value = values[i] ?? "";
|
370
459
|
if (Array.isArray(value)) {
|
371
460
|
value = value.map((item) => processValue(item)).join("");
|
372
461
|
} else {
|
373
462
|
value = processValue(value);
|
374
463
|
}
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
const
|
382
|
-
|
383
|
-
const signalBindingRegex = /(\{\{signal:.+\}\})/;
|
384
|
-
const parseChildren = (element) => {
|
385
|
-
for (const child of element.childNodes) {
|
386
|
-
if (child instanceof Text && signalBindingRegex.test(child.data)) {
|
387
|
-
const textList = child.data.split(signalBindingRegex);
|
388
|
-
const sibling = child.nextSibling;
|
389
|
-
textList.forEach((text, i) => {
|
390
|
-
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
391
|
-
const signal = uniqueKey !== text ? signalMap.get(uniqueKey) : void 0;
|
392
|
-
const newValue = signal !== void 0 ? signal() : text;
|
393
|
-
const newNode = getNewNode(newValue, element);
|
394
|
-
if (i === 0) {
|
395
|
-
child.replaceWith(newNode);
|
396
|
-
} else {
|
397
|
-
element.insertBefore(newNode, sibling);
|
398
|
-
}
|
399
|
-
if (signal !== void 0 && newNode instanceof Text) {
|
400
|
-
createEffect(() => {
|
401
|
-
newNode.data = signal();
|
402
|
-
});
|
403
|
-
} else if (signal !== void 0 && newNode instanceof DocumentFragment) {
|
404
|
-
createEffect(() => {
|
405
|
-
const result = signal();
|
406
|
-
const nextNode = getNewNode(result, element);
|
407
|
-
if (nextNode instanceof Text) {
|
408
|
-
throw new TypeError(
|
409
|
-
"Signal mismatch: expected DocumentFragment or Array<DocumentFragment>, but got Text"
|
410
|
-
);
|
411
|
-
}
|
412
|
-
let lastSibling = element.lastChild;
|
413
|
-
for (const child2 of nextNode.children) {
|
414
|
-
const key = child2.getAttribute("key");
|
415
|
-
const matchingNode = element.querySelector(`[key="${key}"]`);
|
416
|
-
if (matchingNode === null) continue;
|
417
|
-
lastSibling = matchingNode.nextSibling;
|
418
|
-
child2.replaceWith(matchingNode);
|
419
|
-
}
|
420
|
-
element.insertBefore(nextNode, lastSibling);
|
421
|
-
});
|
422
|
-
}
|
423
|
-
});
|
424
|
-
}
|
425
|
-
if (child instanceof Element) {
|
426
|
-
for (const attr of child.attributes) {
|
427
|
-
if (signalBindingRegex.test(attr.value)) {
|
428
|
-
const textList = attr.value.split(signalBindingRegex);
|
429
|
-
createEffect(() => {
|
430
|
-
let newText = "";
|
431
|
-
let hasNull = false;
|
432
|
-
for (const text of textList) {
|
433
|
-
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
434
|
-
const signal = uniqueKey !== text ? signalMap.get(uniqueKey) : void 0;
|
435
|
-
const value = signal !== void 0 ? signal() : text;
|
436
|
-
if (value === null) hasNull = true;
|
437
|
-
newText += String(value);
|
438
|
-
}
|
439
|
-
if (hasNull && newText === "null") {
|
440
|
-
child.removeAttribute(attr.name);
|
441
|
-
} else {
|
442
|
-
child.setAttribute(attr.name, newText);
|
443
|
-
}
|
444
|
-
});
|
445
|
-
} else if (legacyCallbackBindingRegex.test(attr.value)) {
|
446
|
-
const getRootNode = child.getRootNode.bind(child);
|
447
|
-
child.getRootNode = () => {
|
448
|
-
const rootNode = getRootNode();
|
449
|
-
return rootNode instanceof ShadowRoot ? rootNode : fragment;
|
450
|
-
};
|
451
|
-
} else if (callbackBindingRegex.test(attr.value)) {
|
452
|
-
const textList = attr.value.split(callbackBindingRegex);
|
453
|
-
createEffect(() => {
|
454
|
-
child.__customCallbackFns = child.__customCallbackFns ?? /* @__PURE__ */ new Map();
|
455
|
-
let uniqueKey = "";
|
456
|
-
for (const text of textList) {
|
457
|
-
const _uniqueKey = text.replace(/\{\{callback:(.+)\}\}/, "$1");
|
458
|
-
if (_uniqueKey !== text) uniqueKey = _uniqueKey;
|
459
|
-
const callback = uniqueKey !== text ? callbackMap.get(uniqueKey) : void 0;
|
460
|
-
if (callback !== void 0) {
|
461
|
-
child.__customCallbackFns.set(uniqueKey, callback);
|
462
|
-
}
|
463
|
-
}
|
464
|
-
if (uniqueKey !== "") {
|
465
|
-
child.setAttribute(attr.name, `this.__customCallbackFns.get('${uniqueKey}')(event)`);
|
466
|
-
}
|
467
|
-
});
|
468
|
-
}
|
469
|
-
}
|
470
|
-
parseChildren(child);
|
471
|
-
}
|
472
|
-
}
|
473
|
-
};
|
474
|
-
parseChildren(fragment);
|
464
|
+
innerHTML2 += str + String(value === null ? "" : value);
|
465
|
+
return innerHTML2;
|
466
|
+
}, "");
|
467
|
+
if (isServer) return innerHTML;
|
468
|
+
const template = document.createElement("template");
|
469
|
+
template.innerHTML = innerHTML;
|
470
|
+
const fragment = renderState.currentShadowRoot === null ? template.content : renderState.currentShadowRoot.importNode?.(template.content, true) ?? template.content;
|
471
|
+
evaluateBindings(fragment, fragment);
|
475
472
|
return fragment;
|
476
473
|
};
|
477
474
|
var adoptedStylesSupported = typeof window !== "undefined" && window.ShadowRoot?.prototype.hasOwnProperty("adoptedStyleSheets") && window.CSSStyleSheet?.prototype.hasOwnProperty("replace");
|
@@ -721,8 +718,7 @@ You must set an initial value before calling a property signal's getter.
|
|
721
718
|
for (const fn of this.#clientOnlyCallbackFns) {
|
722
719
|
fn();
|
723
720
|
}
|
724
|
-
|
725
|
-
root.append(fragment);
|
721
|
+
root.replaceChildren(fragment);
|
726
722
|
}
|
727
723
|
static get formAssociated() {
|
728
724
|
return formAssociated;
|
@@ -853,7 +849,15 @@ var createRegistry = (args) => {
|
|
853
849
|
const customElementTags = /* @__PURE__ */ new Set();
|
854
850
|
const nativeRegistry = (() => {
|
855
851
|
if (isServer) return;
|
856
|
-
if (scoped)
|
852
|
+
if (scoped) {
|
853
|
+
try {
|
854
|
+
return new CustomElementRegistry();
|
855
|
+
} catch {
|
856
|
+
console.error(
|
857
|
+
"The scoped custom elements polyfill was not found. Falling back to global registry.\n\nCheck `RegistryResult.scoped` at https://thunderous.dev/docs/registries for more information."
|
858
|
+
);
|
859
|
+
}
|
860
|
+
}
|
857
861
|
return customElements;
|
858
862
|
})();
|
859
863
|
return {
|
package/dist/index.d.cts
CHANGED
@@ -170,6 +170,9 @@ declare const derived: <T>(fn: () => T) => SignalGetter<T>;
|
|
170
170
|
*/
|
171
171
|
declare const createEffect: (fn: () => void) => void;
|
172
172
|
|
173
|
+
/**
|
174
|
+
* A tagged template function for creating DocumentFragment instances.
|
175
|
+
*/
|
173
176
|
declare const html: (strings: TemplateStringsArray, ...values: unknown[]) => DocumentFragment;
|
174
177
|
declare const css: (strings: TemplateStringsArray, ...values: unknown[]) => Styles;
|
175
178
|
|
package/dist/index.d.ts
CHANGED
@@ -170,6 +170,9 @@ declare const derived: <T>(fn: () => T) => SignalGetter<T>;
|
|
170
170
|
*/
|
171
171
|
declare const createEffect: (fn: () => void) => void;
|
172
172
|
|
173
|
+
/**
|
174
|
+
* A tagged template function for creating DocumentFragment instances.
|
175
|
+
*/
|
173
176
|
declare const html: (strings: TemplateStringsArray, ...values: unknown[]) => DocumentFragment;
|
174
177
|
declare const css: (strings: TemplateStringsArray, ...values: unknown[]) => Styles;
|
175
178
|
|
package/dist/index.js
CHANGED
@@ -236,19 +236,15 @@ var clientOnlyCallback = (fn) => {
|
|
236
236
|
};
|
237
237
|
|
238
238
|
// src/render.ts
|
239
|
+
var CALLBACK_BINDING_REGEX = /(\{\{callback:.+\}\})/;
|
240
|
+
var LEGACY_CALLBACK_BINDING_REGEX = /(this.getRootNode\(\).host.__customCallbackFns.get\('.+'\)\(event\))/;
|
241
|
+
var SIGNAL_BINDING_REGEX = /(\{\{signal:.+\}\})/;
|
242
|
+
var FRAGMENT_ATTRIBUTE = "___thunderous-fragment";
|
239
243
|
var renderState = {
|
240
|
-
currentShadowRoot: null
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
element.childNodes[0].remove();
|
245
|
-
}
|
246
|
-
};
|
247
|
-
var parseFragment = (htmlStr) => {
|
248
|
-
const template = document.createElement("template");
|
249
|
-
template.innerHTML = htmlStr;
|
250
|
-
const fragment = renderState.currentShadowRoot === null ? template.content : renderState.currentShadowRoot.importNode(template.content, true);
|
251
|
-
return fragment;
|
244
|
+
currentShadowRoot: null,
|
245
|
+
signalMap: /* @__PURE__ */ new Map(),
|
246
|
+
callbackMap: /* @__PURE__ */ new Map(),
|
247
|
+
fragmentMap: /* @__PURE__ */ new Map()
|
252
248
|
};
|
253
249
|
var logValueError = (value) => {
|
254
250
|
console.error(
|
@@ -261,7 +257,7 @@ var arrayToDocumentFragment = (array, parent) => {
|
|
261
257
|
let count = 0;
|
262
258
|
const keys = /* @__PURE__ */ new Set();
|
263
259
|
for (const item of array) {
|
264
|
-
const node =
|
260
|
+
const node = createNewNode(item, parent);
|
265
261
|
if (node instanceof DocumentFragment) {
|
266
262
|
const child = node.firstElementChild;
|
267
263
|
if (node.children.length > 1) {
|
@@ -293,150 +289,151 @@ var arrayToDocumentFragment = (array, parent) => {
|
|
293
289
|
}
|
294
290
|
return documentFragment;
|
295
291
|
};
|
296
|
-
var
|
292
|
+
var createNewNode = (value, parent) => {
|
297
293
|
if (typeof value === "string") return new Text(value);
|
298
294
|
if (Array.isArray(value)) return arrayToDocumentFragment(value, parent);
|
299
295
|
if (value instanceof DocumentFragment) return value;
|
300
296
|
return new Text("");
|
301
297
|
};
|
302
|
-
var
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
signalMap.set(uniqueKey, getter);
|
316
|
-
let result = getter();
|
317
|
-
if (Array.isArray(result)) {
|
318
|
-
result = result.map((item) => processValue(item)).join("");
|
319
|
-
}
|
320
|
-
return isServer ? String(result) : `{{signal:${uniqueKey}}}`;
|
298
|
+
var processValue = (value) => {
|
299
|
+
if (!isServer && value instanceof DocumentFragment) {
|
300
|
+
const uniqueKey = crypto.randomUUID();
|
301
|
+
renderState.fragmentMap.set(uniqueKey, value);
|
302
|
+
return `<div ${FRAGMENT_ATTRIBUTE}="${uniqueKey}"></div>`;
|
303
|
+
}
|
304
|
+
if (typeof value === "function" && "getter" in value && value.getter === true) {
|
305
|
+
const getter = value;
|
306
|
+
const uniqueKey = crypto.randomUUID();
|
307
|
+
renderState.signalMap.set(uniqueKey, getter);
|
308
|
+
let result = getter();
|
309
|
+
if (Array.isArray(result)) {
|
310
|
+
result = result.map((item) => processValue(item)).join("");
|
321
311
|
}
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
312
|
+
return isServer ? String(result) : `{{signal:${uniqueKey}}}`;
|
313
|
+
}
|
314
|
+
if (typeof value === "function") {
|
315
|
+
const uniqueKey = crypto.randomUUID();
|
316
|
+
renderState.callbackMap.set(uniqueKey, value);
|
317
|
+
return isServer ? String(value()) : `{{callback:${uniqueKey}}}`;
|
318
|
+
}
|
319
|
+
if (typeof value === "object" && value !== null) {
|
320
|
+
logValueError(value);
|
321
|
+
return "";
|
322
|
+
}
|
323
|
+
return String(value);
|
324
|
+
};
|
325
|
+
var evaluateBindings = (element, fragment) => {
|
326
|
+
for (const child of element.childNodes) {
|
327
|
+
if (child instanceof Text && SIGNAL_BINDING_REGEX.test(child.data)) {
|
328
|
+
const textList = child.data.split(SIGNAL_BINDING_REGEX);
|
329
|
+
const sibling = child.nextSibling;
|
330
|
+
textList.forEach((text, i) => {
|
331
|
+
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
332
|
+
const signal = uniqueKey !== text ? renderState.signalMap.get(uniqueKey) : void 0;
|
333
|
+
const newValue = signal !== void 0 ? signal() : text;
|
334
|
+
const newNode = createNewNode(newValue, element);
|
335
|
+
if (i === 0) {
|
336
|
+
child.replaceWith(newNode);
|
337
|
+
} else {
|
338
|
+
element.insertBefore(newNode, sibling);
|
339
|
+
}
|
340
|
+
if (signal !== void 0 && newNode instanceof Text) {
|
341
|
+
createEffect(() => {
|
342
|
+
newNode.data = signal();
|
343
|
+
});
|
344
|
+
} else if (signal !== void 0 && newNode instanceof DocumentFragment) {
|
345
|
+
createEffect(() => {
|
346
|
+
const result = signal();
|
347
|
+
const nextNode = createNewNode(result, element);
|
348
|
+
if (nextNode instanceof Text) {
|
349
|
+
throw new TypeError(
|
350
|
+
"Signal mismatch: expected DocumentFragment or Array<DocumentFragment>, but got Text"
|
351
|
+
);
|
352
|
+
}
|
353
|
+
let lastSibling = element.lastChild;
|
354
|
+
for (const child2 of nextNode.children) {
|
355
|
+
const key = child2.getAttribute("key");
|
356
|
+
const matchingNode = element.querySelector(`[key="${key}"]`);
|
357
|
+
if (matchingNode === null) continue;
|
358
|
+
lastSibling = matchingNode.nextSibling;
|
359
|
+
child2.replaceWith(matchingNode);
|
360
|
+
}
|
361
|
+
element.insertBefore(nextNode, lastSibling);
|
362
|
+
});
|
363
|
+
}
|
364
|
+
});
|
326
365
|
}
|
327
|
-
if (
|
328
|
-
|
329
|
-
|
366
|
+
if (child instanceof Element && child.hasAttribute(FRAGMENT_ATTRIBUTE)) {
|
367
|
+
const uniqueKey = child.getAttribute(FRAGMENT_ATTRIBUTE);
|
368
|
+
const childFragment = renderState.fragmentMap.get(uniqueKey);
|
369
|
+
if (childFragment !== void 0) {
|
370
|
+
child.replaceWith(childFragment);
|
371
|
+
}
|
372
|
+
} else if (child instanceof Element) {
|
373
|
+
for (const attr of child.attributes) {
|
374
|
+
if (SIGNAL_BINDING_REGEX.test(attr.value)) {
|
375
|
+
const textList = attr.value.split(SIGNAL_BINDING_REGEX);
|
376
|
+
createEffect(() => {
|
377
|
+
let newText = "";
|
378
|
+
let hasNull = false;
|
379
|
+
for (const text of textList) {
|
380
|
+
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
381
|
+
const signal = uniqueKey !== text ? renderState.signalMap.get(uniqueKey) : void 0;
|
382
|
+
const value = signal !== void 0 ? signal() : text;
|
383
|
+
if (value === null) hasNull = true;
|
384
|
+
newText += String(value);
|
385
|
+
}
|
386
|
+
if (hasNull && newText === "null") {
|
387
|
+
child.removeAttribute(attr.name);
|
388
|
+
} else {
|
389
|
+
child.setAttribute(attr.name, newText);
|
390
|
+
}
|
391
|
+
});
|
392
|
+
} else if (LEGACY_CALLBACK_BINDING_REGEX.test(attr.value)) {
|
393
|
+
const getRootNode = child.getRootNode.bind(child);
|
394
|
+
child.getRootNode = () => {
|
395
|
+
const rootNode = getRootNode();
|
396
|
+
return rootNode instanceof ShadowRoot ? rootNode : fragment;
|
397
|
+
};
|
398
|
+
} else if (CALLBACK_BINDING_REGEX.test(attr.value)) {
|
399
|
+
const textList = attr.value.split(CALLBACK_BINDING_REGEX);
|
400
|
+
createEffect(() => {
|
401
|
+
child.__customCallbackFns = child.__customCallbackFns ?? /* @__PURE__ */ new Map();
|
402
|
+
let uniqueKey = "";
|
403
|
+
for (const text of textList) {
|
404
|
+
const _uniqueKey = text.replace(/\{\{callback:(.+)\}\}/, "$1");
|
405
|
+
if (_uniqueKey !== text) uniqueKey = _uniqueKey;
|
406
|
+
const callback = uniqueKey !== text ? renderState.callbackMap.get(uniqueKey) : void 0;
|
407
|
+
if (callback !== void 0) {
|
408
|
+
child.__customCallbackFns.set(uniqueKey, callback);
|
409
|
+
}
|
410
|
+
}
|
411
|
+
if (uniqueKey !== "") {
|
412
|
+
child.setAttribute(attr.name, `this.__customCallbackFns.get('${uniqueKey}')(event)`);
|
413
|
+
}
|
414
|
+
});
|
415
|
+
}
|
416
|
+
}
|
417
|
+
evaluateBindings(child, fragment);
|
330
418
|
}
|
331
|
-
|
332
|
-
|
333
|
-
|
419
|
+
}
|
420
|
+
};
|
421
|
+
var html = (strings, ...values) => {
|
422
|
+
const innerHTML = strings.reduce((innerHTML2, str, i) => {
|
334
423
|
let value = values[i] ?? "";
|
335
424
|
if (Array.isArray(value)) {
|
336
425
|
value = value.map((item) => processValue(item)).join("");
|
337
426
|
} else {
|
338
427
|
value = processValue(value);
|
339
428
|
}
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
const
|
347
|
-
|
348
|
-
const signalBindingRegex = /(\{\{signal:.+\}\})/;
|
349
|
-
const parseChildren = (element) => {
|
350
|
-
for (const child of element.childNodes) {
|
351
|
-
if (child instanceof Text && signalBindingRegex.test(child.data)) {
|
352
|
-
const textList = child.data.split(signalBindingRegex);
|
353
|
-
const sibling = child.nextSibling;
|
354
|
-
textList.forEach((text, i) => {
|
355
|
-
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
356
|
-
const signal = uniqueKey !== text ? signalMap.get(uniqueKey) : void 0;
|
357
|
-
const newValue = signal !== void 0 ? signal() : text;
|
358
|
-
const newNode = getNewNode(newValue, element);
|
359
|
-
if (i === 0) {
|
360
|
-
child.replaceWith(newNode);
|
361
|
-
} else {
|
362
|
-
element.insertBefore(newNode, sibling);
|
363
|
-
}
|
364
|
-
if (signal !== void 0 && newNode instanceof Text) {
|
365
|
-
createEffect(() => {
|
366
|
-
newNode.data = signal();
|
367
|
-
});
|
368
|
-
} else if (signal !== void 0 && newNode instanceof DocumentFragment) {
|
369
|
-
createEffect(() => {
|
370
|
-
const result = signal();
|
371
|
-
const nextNode = getNewNode(result, element);
|
372
|
-
if (nextNode instanceof Text) {
|
373
|
-
throw new TypeError(
|
374
|
-
"Signal mismatch: expected DocumentFragment or Array<DocumentFragment>, but got Text"
|
375
|
-
);
|
376
|
-
}
|
377
|
-
let lastSibling = element.lastChild;
|
378
|
-
for (const child2 of nextNode.children) {
|
379
|
-
const key = child2.getAttribute("key");
|
380
|
-
const matchingNode = element.querySelector(`[key="${key}"]`);
|
381
|
-
if (matchingNode === null) continue;
|
382
|
-
lastSibling = matchingNode.nextSibling;
|
383
|
-
child2.replaceWith(matchingNode);
|
384
|
-
}
|
385
|
-
element.insertBefore(nextNode, lastSibling);
|
386
|
-
});
|
387
|
-
}
|
388
|
-
});
|
389
|
-
}
|
390
|
-
if (child instanceof Element) {
|
391
|
-
for (const attr of child.attributes) {
|
392
|
-
if (signalBindingRegex.test(attr.value)) {
|
393
|
-
const textList = attr.value.split(signalBindingRegex);
|
394
|
-
createEffect(() => {
|
395
|
-
let newText = "";
|
396
|
-
let hasNull = false;
|
397
|
-
for (const text of textList) {
|
398
|
-
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
399
|
-
const signal = uniqueKey !== text ? signalMap.get(uniqueKey) : void 0;
|
400
|
-
const value = signal !== void 0 ? signal() : text;
|
401
|
-
if (value === null) hasNull = true;
|
402
|
-
newText += String(value);
|
403
|
-
}
|
404
|
-
if (hasNull && newText === "null") {
|
405
|
-
child.removeAttribute(attr.name);
|
406
|
-
} else {
|
407
|
-
child.setAttribute(attr.name, newText);
|
408
|
-
}
|
409
|
-
});
|
410
|
-
} else if (legacyCallbackBindingRegex.test(attr.value)) {
|
411
|
-
const getRootNode = child.getRootNode.bind(child);
|
412
|
-
child.getRootNode = () => {
|
413
|
-
const rootNode = getRootNode();
|
414
|
-
return rootNode instanceof ShadowRoot ? rootNode : fragment;
|
415
|
-
};
|
416
|
-
} else if (callbackBindingRegex.test(attr.value)) {
|
417
|
-
const textList = attr.value.split(callbackBindingRegex);
|
418
|
-
createEffect(() => {
|
419
|
-
child.__customCallbackFns = child.__customCallbackFns ?? /* @__PURE__ */ new Map();
|
420
|
-
let uniqueKey = "";
|
421
|
-
for (const text of textList) {
|
422
|
-
const _uniqueKey = text.replace(/\{\{callback:(.+)\}\}/, "$1");
|
423
|
-
if (_uniqueKey !== text) uniqueKey = _uniqueKey;
|
424
|
-
const callback = uniqueKey !== text ? callbackMap.get(uniqueKey) : void 0;
|
425
|
-
if (callback !== void 0) {
|
426
|
-
child.__customCallbackFns.set(uniqueKey, callback);
|
427
|
-
}
|
428
|
-
}
|
429
|
-
if (uniqueKey !== "") {
|
430
|
-
child.setAttribute(attr.name, `this.__customCallbackFns.get('${uniqueKey}')(event)`);
|
431
|
-
}
|
432
|
-
});
|
433
|
-
}
|
434
|
-
}
|
435
|
-
parseChildren(child);
|
436
|
-
}
|
437
|
-
}
|
438
|
-
};
|
439
|
-
parseChildren(fragment);
|
429
|
+
innerHTML2 += str + String(value === null ? "" : value);
|
430
|
+
return innerHTML2;
|
431
|
+
}, "");
|
432
|
+
if (isServer) return innerHTML;
|
433
|
+
const template = document.createElement("template");
|
434
|
+
template.innerHTML = innerHTML;
|
435
|
+
const fragment = renderState.currentShadowRoot === null ? template.content : renderState.currentShadowRoot.importNode?.(template.content, true) ?? template.content;
|
436
|
+
evaluateBindings(fragment, fragment);
|
440
437
|
return fragment;
|
441
438
|
};
|
442
439
|
var adoptedStylesSupported = typeof window !== "undefined" && window.ShadowRoot?.prototype.hasOwnProperty("adoptedStyleSheets") && window.CSSStyleSheet?.prototype.hasOwnProperty("replace");
|
@@ -686,8 +683,7 @@ You must set an initial value before calling a property signal's getter.
|
|
686
683
|
for (const fn of this.#clientOnlyCallbackFns) {
|
687
684
|
fn();
|
688
685
|
}
|
689
|
-
|
690
|
-
root.append(fragment);
|
686
|
+
root.replaceChildren(fragment);
|
691
687
|
}
|
692
688
|
static get formAssociated() {
|
693
689
|
return formAssociated;
|
@@ -818,7 +814,15 @@ var createRegistry = (args) => {
|
|
818
814
|
const customElementTags = /* @__PURE__ */ new Set();
|
819
815
|
const nativeRegistry = (() => {
|
820
816
|
if (isServer) return;
|
821
|
-
if (scoped)
|
817
|
+
if (scoped) {
|
818
|
+
try {
|
819
|
+
return new CustomElementRegistry();
|
820
|
+
} catch {
|
821
|
+
console.error(
|
822
|
+
"The scoped custom elements polyfill was not found. Falling back to global registry.\n\nCheck `RegistryResult.scoped` at https://thunderous.dev/docs/registries for more information."
|
823
|
+
);
|
824
|
+
}
|
825
|
+
}
|
822
826
|
return customElements;
|
823
827
|
})();
|
824
828
|
return {
|