thunderous 2.0.1 → 2.0.3
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 +156 -145
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +156 -145
- 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) ?? template.content;
|
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,166 @@ 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
|
-
|
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("");
|
346
|
+
}
|
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
|
+
let init = false;
|
381
|
+
createEffect(() => {
|
382
|
+
const result = signal();
|
383
|
+
const nextNode = createNewNode(result, element);
|
384
|
+
if (nextNode instanceof Text) {
|
385
|
+
throw new TypeError(
|
386
|
+
"Signal mismatch: expected DocumentFragment or Array<DocumentFragment>, but got Text"
|
387
|
+
);
|
388
|
+
}
|
389
|
+
let lastSibling = element.lastChild;
|
390
|
+
for (const child2 of element.children) {
|
391
|
+
const key = child2.getAttribute("key");
|
392
|
+
if (key === null) continue;
|
393
|
+
const matchingNode = nextNode.querySelector(`[key="${key}"]`);
|
394
|
+
if (init && matchingNode === null) {
|
395
|
+
child2.remove();
|
396
|
+
}
|
397
|
+
}
|
398
|
+
for (const child2 of nextNode.children) {
|
399
|
+
const key = child2.getAttribute("key");
|
400
|
+
const matchingNode = element.querySelector(`[key="${key}"]`);
|
401
|
+
if (matchingNode === null) continue;
|
402
|
+
matchingNode.__customCallbackFns = child2.__customCallbackFns;
|
403
|
+
for (const attr of child2.attributes) {
|
404
|
+
matchingNode.setAttribute(attr.name, attr.value);
|
405
|
+
}
|
406
|
+
matchingNode.replaceChildren(...child2.childNodes);
|
407
|
+
lastSibling = matchingNode.nextSibling;
|
408
|
+
child2.replaceWith(matchingNode);
|
409
|
+
}
|
410
|
+
element.insertBefore(nextNode, lastSibling);
|
411
|
+
if (!init) init = true;
|
412
|
+
});
|
413
|
+
}
|
414
|
+
});
|
346
415
|
}
|
347
|
-
if (
|
348
|
-
const
|
349
|
-
const
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
416
|
+
if (child instanceof Element && child.hasAttribute(FRAGMENT_ATTRIBUTE)) {
|
417
|
+
const uniqueKey = child.getAttribute(FRAGMENT_ATTRIBUTE);
|
418
|
+
const childFragment = renderState.fragmentMap.get(uniqueKey);
|
419
|
+
if (childFragment !== void 0) {
|
420
|
+
child.replaceWith(childFragment);
|
421
|
+
}
|
422
|
+
} else if (child instanceof Element) {
|
423
|
+
for (const attr of child.attributes) {
|
424
|
+
if (SIGNAL_BINDING_REGEX.test(attr.value)) {
|
425
|
+
const textList = attr.value.split(SIGNAL_BINDING_REGEX);
|
426
|
+
createEffect(() => {
|
427
|
+
let newText = "";
|
428
|
+
let hasNull = false;
|
429
|
+
for (const text of textList) {
|
430
|
+
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
431
|
+
const signal = uniqueKey !== text ? renderState.signalMap.get(uniqueKey) : void 0;
|
432
|
+
const value = signal !== void 0 ? signal() : text;
|
433
|
+
if (value === null) hasNull = true;
|
434
|
+
newText += String(value);
|
435
|
+
}
|
436
|
+
if (hasNull && newText === "null") {
|
437
|
+
child.removeAttribute(attr.name);
|
438
|
+
} else {
|
439
|
+
child.setAttribute(attr.name, newText);
|
440
|
+
}
|
441
|
+
});
|
442
|
+
} else if (LEGACY_CALLBACK_BINDING_REGEX.test(attr.value)) {
|
443
|
+
const getRootNode = child.getRootNode.bind(child);
|
444
|
+
child.getRootNode = () => {
|
445
|
+
const rootNode = getRootNode();
|
446
|
+
return rootNode instanceof ShadowRoot ? rootNode : fragment;
|
447
|
+
};
|
448
|
+
} else if (CALLBACK_BINDING_REGEX.test(attr.value)) {
|
449
|
+
const textList = attr.value.split(CALLBACK_BINDING_REGEX);
|
450
|
+
createEffect(() => {
|
451
|
+
child.__customCallbackFns = child.__customCallbackFns ?? /* @__PURE__ */ new Map();
|
452
|
+
let uniqueKey = "";
|
453
|
+
for (const text of textList) {
|
454
|
+
const _uniqueKey = text.replace(/\{\{callback:(.+)\}\}/, "$1");
|
455
|
+
if (_uniqueKey !== text) uniqueKey = _uniqueKey;
|
456
|
+
const callback = uniqueKey !== text ? renderState.callbackMap.get(uniqueKey) : void 0;
|
457
|
+
if (callback !== void 0) {
|
458
|
+
child.__customCallbackFns.set(uniqueKey, callback);
|
459
|
+
}
|
460
|
+
}
|
461
|
+
if (uniqueKey !== "") {
|
462
|
+
child.setAttribute(attr.name, `this.__customCallbackFns.get('${uniqueKey}')(event)`);
|
463
|
+
}
|
464
|
+
});
|
465
|
+
}
|
354
466
|
}
|
355
|
-
|
356
|
-
}
|
357
|
-
if (typeof value === "function") {
|
358
|
-
const uniqueKey = crypto.randomUUID();
|
359
|
-
callbackMap.set(uniqueKey, value);
|
360
|
-
return isServer ? String(value()) : `{{callback:${uniqueKey}}}`;
|
361
|
-
}
|
362
|
-
if (typeof value === "object" && value !== null) {
|
363
|
-
logValueError(value);
|
364
|
-
return "";
|
467
|
+
evaluateBindings(child, fragment);
|
365
468
|
}
|
366
|
-
|
367
|
-
|
368
|
-
|
469
|
+
}
|
470
|
+
};
|
471
|
+
var html = (strings, ...values) => {
|
472
|
+
const innerHTML = strings.reduce((innerHTML2, str, i) => {
|
369
473
|
let value = values[i] ?? "";
|
370
474
|
if (Array.isArray(value)) {
|
371
475
|
value = value.map((item) => processValue(item)).join("");
|
372
476
|
} else {
|
373
477
|
value = processValue(value);
|
374
478
|
}
|
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);
|
479
|
+
innerHTML2 += str + String(value === null ? "" : value);
|
480
|
+
return innerHTML2;
|
481
|
+
}, "");
|
482
|
+
if (isServer) return innerHTML;
|
483
|
+
const template = document.createElement("template");
|
484
|
+
template.innerHTML = innerHTML;
|
485
|
+
const fragment = renderState.currentShadowRoot === null ? template.content : renderState.currentShadowRoot.importNode?.(template.content, true) ?? template.content;
|
486
|
+
evaluateBindings(fragment, fragment);
|
475
487
|
return fragment;
|
476
488
|
};
|
477
489
|
var adoptedStylesSupported = typeof window !== "undefined" && window.ShadowRoot?.prototype.hasOwnProperty("adoptedStyleSheets") && window.CSSStyleSheet?.prototype.hasOwnProperty("replace");
|
@@ -721,8 +733,7 @@ You must set an initial value before calling a property signal's getter.
|
|
721
733
|
for (const fn of this.#clientOnlyCallbackFns) {
|
722
734
|
fn();
|
723
735
|
}
|
724
|
-
|
725
|
-
root.append(fragment);
|
736
|
+
root.replaceChildren(fragment);
|
726
737
|
}
|
727
738
|
static get formAssociated() {
|
728
739
|
return formAssociated;
|
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) ?? template.content;
|
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,166 @@ 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
|
-
|
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("");
|
311
|
+
}
|
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
|
+
let init = false;
|
346
|
+
createEffect(() => {
|
347
|
+
const result = signal();
|
348
|
+
const nextNode = createNewNode(result, element);
|
349
|
+
if (nextNode instanceof Text) {
|
350
|
+
throw new TypeError(
|
351
|
+
"Signal mismatch: expected DocumentFragment or Array<DocumentFragment>, but got Text"
|
352
|
+
);
|
353
|
+
}
|
354
|
+
let lastSibling = element.lastChild;
|
355
|
+
for (const child2 of element.children) {
|
356
|
+
const key = child2.getAttribute("key");
|
357
|
+
if (key === null) continue;
|
358
|
+
const matchingNode = nextNode.querySelector(`[key="${key}"]`);
|
359
|
+
if (init && matchingNode === null) {
|
360
|
+
child2.remove();
|
361
|
+
}
|
362
|
+
}
|
363
|
+
for (const child2 of nextNode.children) {
|
364
|
+
const key = child2.getAttribute("key");
|
365
|
+
const matchingNode = element.querySelector(`[key="${key}"]`);
|
366
|
+
if (matchingNode === null) continue;
|
367
|
+
matchingNode.__customCallbackFns = child2.__customCallbackFns;
|
368
|
+
for (const attr of child2.attributes) {
|
369
|
+
matchingNode.setAttribute(attr.name, attr.value);
|
370
|
+
}
|
371
|
+
matchingNode.replaceChildren(...child2.childNodes);
|
372
|
+
lastSibling = matchingNode.nextSibling;
|
373
|
+
child2.replaceWith(matchingNode);
|
374
|
+
}
|
375
|
+
element.insertBefore(nextNode, lastSibling);
|
376
|
+
if (!init) init = true;
|
377
|
+
});
|
378
|
+
}
|
379
|
+
});
|
311
380
|
}
|
312
|
-
if (
|
313
|
-
const
|
314
|
-
const
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
381
|
+
if (child instanceof Element && child.hasAttribute(FRAGMENT_ATTRIBUTE)) {
|
382
|
+
const uniqueKey = child.getAttribute(FRAGMENT_ATTRIBUTE);
|
383
|
+
const childFragment = renderState.fragmentMap.get(uniqueKey);
|
384
|
+
if (childFragment !== void 0) {
|
385
|
+
child.replaceWith(childFragment);
|
386
|
+
}
|
387
|
+
} else if (child instanceof Element) {
|
388
|
+
for (const attr of child.attributes) {
|
389
|
+
if (SIGNAL_BINDING_REGEX.test(attr.value)) {
|
390
|
+
const textList = attr.value.split(SIGNAL_BINDING_REGEX);
|
391
|
+
createEffect(() => {
|
392
|
+
let newText = "";
|
393
|
+
let hasNull = false;
|
394
|
+
for (const text of textList) {
|
395
|
+
const uniqueKey = text.replace(/\{\{signal:(.+)\}\}/, "$1");
|
396
|
+
const signal = uniqueKey !== text ? renderState.signalMap.get(uniqueKey) : void 0;
|
397
|
+
const value = signal !== void 0 ? signal() : text;
|
398
|
+
if (value === null) hasNull = true;
|
399
|
+
newText += String(value);
|
400
|
+
}
|
401
|
+
if (hasNull && newText === "null") {
|
402
|
+
child.removeAttribute(attr.name);
|
403
|
+
} else {
|
404
|
+
child.setAttribute(attr.name, newText);
|
405
|
+
}
|
406
|
+
});
|
407
|
+
} else if (LEGACY_CALLBACK_BINDING_REGEX.test(attr.value)) {
|
408
|
+
const getRootNode = child.getRootNode.bind(child);
|
409
|
+
child.getRootNode = () => {
|
410
|
+
const rootNode = getRootNode();
|
411
|
+
return rootNode instanceof ShadowRoot ? rootNode : fragment;
|
412
|
+
};
|
413
|
+
} else if (CALLBACK_BINDING_REGEX.test(attr.value)) {
|
414
|
+
const textList = attr.value.split(CALLBACK_BINDING_REGEX);
|
415
|
+
createEffect(() => {
|
416
|
+
child.__customCallbackFns = child.__customCallbackFns ?? /* @__PURE__ */ new Map();
|
417
|
+
let uniqueKey = "";
|
418
|
+
for (const text of textList) {
|
419
|
+
const _uniqueKey = text.replace(/\{\{callback:(.+)\}\}/, "$1");
|
420
|
+
if (_uniqueKey !== text) uniqueKey = _uniqueKey;
|
421
|
+
const callback = uniqueKey !== text ? renderState.callbackMap.get(uniqueKey) : void 0;
|
422
|
+
if (callback !== void 0) {
|
423
|
+
child.__customCallbackFns.set(uniqueKey, callback);
|
424
|
+
}
|
425
|
+
}
|
426
|
+
if (uniqueKey !== "") {
|
427
|
+
child.setAttribute(attr.name, `this.__customCallbackFns.get('${uniqueKey}')(event)`);
|
428
|
+
}
|
429
|
+
});
|
430
|
+
}
|
319
431
|
}
|
320
|
-
|
321
|
-
}
|
322
|
-
if (typeof value === "function") {
|
323
|
-
const uniqueKey = crypto.randomUUID();
|
324
|
-
callbackMap.set(uniqueKey, value);
|
325
|
-
return isServer ? String(value()) : `{{callback:${uniqueKey}}}`;
|
326
|
-
}
|
327
|
-
if (typeof value === "object" && value !== null) {
|
328
|
-
logValueError(value);
|
329
|
-
return "";
|
432
|
+
evaluateBindings(child, fragment);
|
330
433
|
}
|
331
|
-
|
332
|
-
|
333
|
-
|
434
|
+
}
|
435
|
+
};
|
436
|
+
var html = (strings, ...values) => {
|
437
|
+
const innerHTML = strings.reduce((innerHTML2, str, i) => {
|
334
438
|
let value = values[i] ?? "";
|
335
439
|
if (Array.isArray(value)) {
|
336
440
|
value = value.map((item) => processValue(item)).join("");
|
337
441
|
} else {
|
338
442
|
value = processValue(value);
|
339
443
|
}
|
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);
|
444
|
+
innerHTML2 += str + String(value === null ? "" : value);
|
445
|
+
return innerHTML2;
|
446
|
+
}, "");
|
447
|
+
if (isServer) return innerHTML;
|
448
|
+
const template = document.createElement("template");
|
449
|
+
template.innerHTML = innerHTML;
|
450
|
+
const fragment = renderState.currentShadowRoot === null ? template.content : renderState.currentShadowRoot.importNode?.(template.content, true) ?? template.content;
|
451
|
+
evaluateBindings(fragment, fragment);
|
440
452
|
return fragment;
|
441
453
|
};
|
442
454
|
var adoptedStylesSupported = typeof window !== "undefined" && window.ShadowRoot?.prototype.hasOwnProperty("adoptedStyleSheets") && window.CSSStyleSheet?.prototype.hasOwnProperty("replace");
|
@@ -686,8 +698,7 @@ You must set an initial value before calling a property signal's getter.
|
|
686
698
|
for (const fn of this.#clientOnlyCallbackFns) {
|
687
699
|
fn();
|
688
700
|
}
|
689
|
-
|
690
|
-
root.append(fragment);
|
701
|
+
root.replaceChildren(fragment);
|
691
702
|
}
|
692
703
|
static get formAssociated() {
|
693
704
|
return formAssociated;
|