solarite 0.5.0 → 0.5.1
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/Solarite-debug.js +156 -2
- package/dist/Solarite.js +156 -2
- package/dist/Solarite.min.js +2 -2
- package/package.json +1 -1
- package/src/PathToEvent.js +8 -0
- package/src/Shell.js +6 -1
- package/src/Solarite.d.ts +8 -1
- package/src/Solarite.js +138 -0
- package/src/Template.js +3 -0
package/dist/Solarite-debug.js
CHANGED
|
@@ -1140,6 +1140,14 @@ class PathToEvent extends PathToAttribValue {
|
|
|
1140
1140
|
assert(Array.isArray(exprs));
|
|
1141
1141
|
//#ENDIF
|
|
1142
1142
|
|
|
1143
|
+
// Tested by Solariate.events.classicWithExpr
|
|
1144
|
+
// We have expressions within a string attribute value that's not a Solarite event. E.g.
|
|
1145
|
+
// <div onclick="alert(${1});"
|
|
1146
|
+
if (this.attrValue?.length > 1) {
|
|
1147
|
+
super.apply(exprs);
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1143
1151
|
// Don't bind events to component placeholders.
|
|
1144
1152
|
// PathToComponent will do the binding later when it instantiates the component.
|
|
1145
1153
|
if (this.isComponentAttrib && this.nodeMarker.tagName.endsWith('-SOLARITE-PLACEHOLDER'))
|
|
@@ -2310,7 +2318,12 @@ class Shell {
|
|
|
2310
2318
|
}
|
|
2311
2319
|
|
|
2312
2320
|
placeholdersUsed += parts.length - 1;
|
|
2313
|
-
|
|
2321
|
+
try {
|
|
2322
|
+
node.setAttribute(attr.name, parts.join(''));
|
|
2323
|
+
}
|
|
2324
|
+
catch (e) {
|
|
2325
|
+
throw new Error(`Error setting attribute "${attr.name}" on node <${node.tagName}>: ${e.message}`);
|
|
2326
|
+
}
|
|
2314
2327
|
}
|
|
2315
2328
|
}
|
|
2316
2329
|
}
|
|
@@ -3018,6 +3031,9 @@ class Template {
|
|
|
3018
3031
|
/** @type {Array} Used for toJSON() and getObjectHash(). Stores values used to quickly create a string hash of this template. */
|
|
3019
3032
|
hashedFields;
|
|
3020
3033
|
|
|
3034
|
+
closeKey;
|
|
3035
|
+
exactKey;
|
|
3036
|
+
|
|
3021
3037
|
isText;
|
|
3022
3038
|
|
|
3023
3039
|
/**
|
|
@@ -3730,7 +3746,145 @@ class Solarite extends HTMLElementAutoDefine {
|
|
|
3730
3746
|
}
|
|
3731
3747
|
return result;
|
|
3732
3748
|
}
|
|
3749
|
+
|
|
3750
|
+
|
|
3751
|
+
// TODO: Do we want to use this to get the tag name from the render() function, instead of having the user define it?
|
|
3752
|
+
/**
|
|
3753
|
+
* Get the tag name for a class, as defined by the tag used in render().
|
|
3754
|
+
*
|
|
3755
|
+
* This will parse the JavaScript code of the render() function to find the tag name.
|
|
3756
|
+
* It will itarage every character, keeping track of quotes and comments so it can
|
|
3757
|
+
* skip them until it finds the tag name passed to h(this)`<tagname>` inside the render() function.
|
|
3758
|
+
*
|
|
3759
|
+
* */
|
|
3760
|
+
/*
|
|
3761
|
+
static getTagName(Class) {
|
|
3762
|
+
let code = Class.prototype.render.toString();
|
|
3763
|
+
let i = 0;
|
|
3764
|
+
while (i < code.length) {
|
|
3765
|
+
let char = code[i];
|
|
3766
|
+
let next = code[i + 1];
|
|
3767
|
+
|
|
3768
|
+
// Skip single line comments
|
|
3769
|
+
if (char === '/' && next === '/') {
|
|
3770
|
+
i = code.indexOf('\n', i);
|
|
3771
|
+
if (i === -1) break;
|
|
3772
|
+
continue;
|
|
3773
|
+
}
|
|
3774
|
+
// Skip multi-line comments
|
|
3775
|
+
if (char === '/' && next === '*') {
|
|
3776
|
+
i = code.indexOf('*'+'/', i + 2);
|
|
3777
|
+
if (i === -1) break;
|
|
3778
|
+
i += 2;
|
|
3779
|
+
continue;
|
|
3780
|
+
}
|
|
3781
|
+
// Skip strings and template literals
|
|
3782
|
+
if (char === "'" || char === '"' || char === '`') {
|
|
3783
|
+
let quote = char;
|
|
3784
|
+
i++;
|
|
3785
|
+
while (i < code.length) {
|
|
3786
|
+
if (code[i] === '\\') i += 2;
|
|
3787
|
+
else if (code[i] === quote) { i++; break; }
|
|
3788
|
+
else i++;
|
|
3789
|
+
}
|
|
3790
|
+
continue;
|
|
3791
|
+
}
|
|
3792
|
+
// Skip regex literals (simple heuristic)
|
|
3793
|
+
if (char === '/') {
|
|
3794
|
+
let prev = code.slice(Math.max(0, i - 10), i).trim();
|
|
3795
|
+
// If / is preceded by something that indicates an operator or start of expression
|
|
3796
|
+
if (/[=(,;:[!&|?]$|return$|yield$|case$/.test(prev)) {
|
|
3797
|
+
i++;
|
|
3798
|
+
while (i < code.length) {
|
|
3799
|
+
if (code[i] === '\\') i += 2;
|
|
3800
|
+
else if (code[i] === '[') { // Skip character classes
|
|
3801
|
+
i++;
|
|
3802
|
+
while (i < code.length && code[i] !== ']') {
|
|
3803
|
+
if (code[i] === '\\') i += 2;
|
|
3804
|
+
else i++;
|
|
3805
|
+
}
|
|
3806
|
+
i++;
|
|
3807
|
+
}
|
|
3808
|
+
else if (code[i] === '/') { i++; break; }
|
|
3809
|
+
else i++;
|
|
3810
|
+
}
|
|
3811
|
+
continue;
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
// Check for h(this)`
|
|
3815
|
+
if (char === 'h' && code.slice(i, i + 8) === 'h(this)`') {
|
|
3816
|
+
i += 8;
|
|
3817
|
+
// We are now inside the template literal.
|
|
3818
|
+
// Skip whitespace and HTML comments
|
|
3819
|
+
while (i < code.length) {
|
|
3820
|
+
// Skip JS template literal end (shouldn't happen before tag, but for safety)
|
|
3821
|
+
if (code[i] === '`') return null;
|
|
3822
|
+
|
|
3823
|
+
// Skip whitespace
|
|
3824
|
+
if (/\s/.test(code[i])) { i++; continue; }
|
|
3825
|
+
|
|
3826
|
+
// Skip HTML comments <!-- ... -->
|
|
3827
|
+
if (code.slice(i, i + 4) === '<!--') {
|
|
3828
|
+
i = code.indexOf('-->', i + 4);
|
|
3829
|
+
if (i === -1) return null;
|
|
3830
|
+
i += 3;
|
|
3831
|
+
continue;
|
|
3832
|
+
}
|
|
3833
|
+
|
|
3834
|
+
// Find the first tag
|
|
3835
|
+
if (code[i] === '<') {
|
|
3836
|
+
let start = ++i;
|
|
3837
|
+
while (i < code.length && /[a-zA-Z0-9-]/.test(code[i])) i++;
|
|
3838
|
+
return code.slice(start, i);
|
|
3839
|
+
}
|
|
3840
|
+
|
|
3841
|
+
// If we encounter anything else (like text before a tag),
|
|
3842
|
+
// we can keep looking or return null depending on how strict we want to be.
|
|
3843
|
+
// For now, let's just skip non-tag characters.
|
|
3844
|
+
i++;
|
|
3845
|
+
}
|
|
3846
|
+
}
|
|
3847
|
+
i++;
|
|
3848
|
+
}
|
|
3849
|
+
return null;
|
|
3850
|
+
}
|
|
3851
|
+
*/
|
|
3852
|
+
}
|
|
3853
|
+
|
|
3854
|
+
|
|
3855
|
+
/**
|
|
3856
|
+
* Assign fields from `src` to `dest` if they exist in `dest` and their names are not in the `ignore` list.
|
|
3857
|
+
* When a value in `src` is a string and the existing value in `dest` is a boolean, number, or Date,
|
|
3858
|
+
* it will be converted to that type.
|
|
3859
|
+
* This is often used in class constructors that accept an object of arguments.
|
|
3860
|
+
* @param {object} dest
|
|
3861
|
+
* @param {?object} src
|
|
3862
|
+
* @param {string[]} [ignore=[]] */
|
|
3863
|
+
function assignFields(dest, src, ignore=[]) {
|
|
3864
|
+
for (let name in src || {}) {
|
|
3865
|
+
if (name in dest && !ignore.includes(name)) {
|
|
3866
|
+
const descriptor = Object.getOwnPropertyDescriptor(dest, name)
|
|
3867
|
+
|| Object.getOwnPropertyDescriptor(Object.getPrototypeOf(dest), name); // Also find (parent?) setters. Is this necssary?
|
|
3868
|
+
if (!descriptor || descriptor.writable || descriptor.set) {
|
|
3869
|
+
let srcVal = src[name];
|
|
3870
|
+
let destVal = dest[name];
|
|
3871
|
+
if (typeof src[name] === 'string') {
|
|
3872
|
+
if (typeof destVal === 'boolean') // empty string (when an attribute is present with no value) is true
|
|
3873
|
+
dest[name] = ![false, 'false', 0, '0'].includes(srcVal);
|
|
3874
|
+
else if (typeof destVal === 'number')
|
|
3875
|
+
dest[name] = Number(srcVal);
|
|
3876
|
+
else if (destVal instanceof Date) {
|
|
3877
|
+
dest[name] = new Date(srcVal); // TODO: read it as UTC 0 by default.
|
|
3878
|
+
}
|
|
3879
|
+
else
|
|
3880
|
+
dest[name] = srcVal;
|
|
3881
|
+
}
|
|
3882
|
+
else
|
|
3883
|
+
dest[name] = srcVal;
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
}
|
|
3733
3887
|
}
|
|
3734
3888
|
|
|
3735
3889
|
export default h;
|
|
3736
|
-
export { ArgType, Globals$1 as Globals, HtmlParser, NodeGroup, Shell, Solarite, Util as SolariteUtil, Template, delve, getArg, h, h as r, setArgs, t, toEl };
|
|
3890
|
+
export { ArgType, Globals$1 as Globals, HtmlParser, NodeGroup, Shell, Solarite, Util as SolariteUtil, Template, assignFields, delve, getArg, h, h as r, setArgs, t, toEl };
|
package/dist/Solarite.js
CHANGED
|
@@ -1030,6 +1030,14 @@ class PathToEvent extends PathToAttribValue {
|
|
|
1030
1030
|
apply(exprs) {
|
|
1031
1031
|
|
|
1032
1032
|
|
|
1033
|
+
// Tested by Solariate.events.classicWithExpr
|
|
1034
|
+
// We have expressions within a string attribute value that's not a Solarite event. E.g.
|
|
1035
|
+
// <div onclick="alert(${1});"
|
|
1036
|
+
if (this.attrValue?.length > 1) {
|
|
1037
|
+
super.apply(exprs);
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1033
1041
|
// Don't bind events to component placeholders.
|
|
1034
1042
|
// PathToComponent will do the binding later when it instantiates the component.
|
|
1035
1043
|
if (this.isComponentAttrib && this.nodeMarker.tagName.endsWith('-SOLARITE-PLACEHOLDER'))
|
|
@@ -2144,7 +2152,12 @@ class Shell {
|
|
|
2144
2152
|
}
|
|
2145
2153
|
|
|
2146
2154
|
placeholdersUsed += parts.length - 1;
|
|
2147
|
-
|
|
2155
|
+
try {
|
|
2156
|
+
node.setAttribute(attr.name, parts.join(''));
|
|
2157
|
+
}
|
|
2158
|
+
catch (e) {
|
|
2159
|
+
throw new Error(`Error setting attribute "${attr.name}" on node <${node.tagName}>: ${e.message}`);
|
|
2160
|
+
}
|
|
2148
2161
|
}
|
|
2149
2162
|
}
|
|
2150
2163
|
}
|
|
@@ -2773,6 +2786,9 @@ class Template {
|
|
|
2773
2786
|
/** @type {Array} Used for toJSON() and getObjectHash(). Stores values used to quickly create a string hash of this template. */
|
|
2774
2787
|
hashedFields;
|
|
2775
2788
|
|
|
2789
|
+
closeKey;
|
|
2790
|
+
exactKey;
|
|
2791
|
+
|
|
2776
2792
|
isText;
|
|
2777
2793
|
|
|
2778
2794
|
/**
|
|
@@ -3476,7 +3492,145 @@ class Solarite extends HTMLElementAutoDefine {
|
|
|
3476
3492
|
}
|
|
3477
3493
|
return result;
|
|
3478
3494
|
}
|
|
3495
|
+
|
|
3496
|
+
|
|
3497
|
+
// TODO: Do we want to use this to get the tag name from the render() function, instead of having the user define it?
|
|
3498
|
+
/**
|
|
3499
|
+
* Get the tag name for a class, as defined by the tag used in render().
|
|
3500
|
+
*
|
|
3501
|
+
* This will parse the JavaScript code of the render() function to find the tag name.
|
|
3502
|
+
* It will itarage every character, keeping track of quotes and comments so it can
|
|
3503
|
+
* skip them until it finds the tag name passed to h(this)`<tagname>` inside the render() function.
|
|
3504
|
+
*
|
|
3505
|
+
* */
|
|
3506
|
+
/*
|
|
3507
|
+
static getTagName(Class) {
|
|
3508
|
+
let code = Class.prototype.render.toString();
|
|
3509
|
+
let i = 0;
|
|
3510
|
+
while (i < code.length) {
|
|
3511
|
+
let char = code[i];
|
|
3512
|
+
let next = code[i + 1];
|
|
3513
|
+
|
|
3514
|
+
// Skip single line comments
|
|
3515
|
+
if (char === '/' && next === '/') {
|
|
3516
|
+
i = code.indexOf('\n', i);
|
|
3517
|
+
if (i === -1) break;
|
|
3518
|
+
continue;
|
|
3519
|
+
}
|
|
3520
|
+
// Skip multi-line comments
|
|
3521
|
+
if (char === '/' && next === '*') {
|
|
3522
|
+
i = code.indexOf('*'+'/', i + 2);
|
|
3523
|
+
if (i === -1) break;
|
|
3524
|
+
i += 2;
|
|
3525
|
+
continue;
|
|
3526
|
+
}
|
|
3527
|
+
// Skip strings and template literals
|
|
3528
|
+
if (char === "'" || char === '"' || char === '`') {
|
|
3529
|
+
let quote = char;
|
|
3530
|
+
i++;
|
|
3531
|
+
while (i < code.length) {
|
|
3532
|
+
if (code[i] === '\\') i += 2;
|
|
3533
|
+
else if (code[i] === quote) { i++; break; }
|
|
3534
|
+
else i++;
|
|
3535
|
+
}
|
|
3536
|
+
continue;
|
|
3537
|
+
}
|
|
3538
|
+
// Skip regex literals (simple heuristic)
|
|
3539
|
+
if (char === '/') {
|
|
3540
|
+
let prev = code.slice(Math.max(0, i - 10), i).trim();
|
|
3541
|
+
// If / is preceded by something that indicates an operator or start of expression
|
|
3542
|
+
if (/[=(,;:[!&|?]$|return$|yield$|case$/.test(prev)) {
|
|
3543
|
+
i++;
|
|
3544
|
+
while (i < code.length) {
|
|
3545
|
+
if (code[i] === '\\') i += 2;
|
|
3546
|
+
else if (code[i] === '[') { // Skip character classes
|
|
3547
|
+
i++;
|
|
3548
|
+
while (i < code.length && code[i] !== ']') {
|
|
3549
|
+
if (code[i] === '\\') i += 2;
|
|
3550
|
+
else i++;
|
|
3551
|
+
}
|
|
3552
|
+
i++;
|
|
3553
|
+
}
|
|
3554
|
+
else if (code[i] === '/') { i++; break; }
|
|
3555
|
+
else i++;
|
|
3556
|
+
}
|
|
3557
|
+
continue;
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
// Check for h(this)`
|
|
3561
|
+
if (char === 'h' && code.slice(i, i + 8) === 'h(this)`') {
|
|
3562
|
+
i += 8;
|
|
3563
|
+
// We are now inside the template literal.
|
|
3564
|
+
// Skip whitespace and HTML comments
|
|
3565
|
+
while (i < code.length) {
|
|
3566
|
+
// Skip JS template literal end (shouldn't happen before tag, but for safety)
|
|
3567
|
+
if (code[i] === '`') return null;
|
|
3568
|
+
|
|
3569
|
+
// Skip whitespace
|
|
3570
|
+
if (/\s/.test(code[i])) { i++; continue; }
|
|
3571
|
+
|
|
3572
|
+
// Skip HTML comments <!-- ... -->
|
|
3573
|
+
if (code.slice(i, i + 4) === '<!--') {
|
|
3574
|
+
i = code.indexOf('-->', i + 4);
|
|
3575
|
+
if (i === -1) return null;
|
|
3576
|
+
i += 3;
|
|
3577
|
+
continue;
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
// Find the first tag
|
|
3581
|
+
if (code[i] === '<') {
|
|
3582
|
+
let start = ++i;
|
|
3583
|
+
while (i < code.length && /[a-zA-Z0-9-]/.test(code[i])) i++;
|
|
3584
|
+
return code.slice(start, i);
|
|
3585
|
+
}
|
|
3586
|
+
|
|
3587
|
+
// If we encounter anything else (like text before a tag),
|
|
3588
|
+
// we can keep looking or return null depending on how strict we want to be.
|
|
3589
|
+
// For now, let's just skip non-tag characters.
|
|
3590
|
+
i++;
|
|
3591
|
+
}
|
|
3592
|
+
}
|
|
3593
|
+
i++;
|
|
3594
|
+
}
|
|
3595
|
+
return null;
|
|
3596
|
+
}
|
|
3597
|
+
*/
|
|
3598
|
+
}
|
|
3599
|
+
|
|
3600
|
+
|
|
3601
|
+
/**
|
|
3602
|
+
* Assign fields from `src` to `dest` if they exist in `dest` and their names are not in the `ignore` list.
|
|
3603
|
+
* When a value in `src` is a string and the existing value in `dest` is a boolean, number, or Date,
|
|
3604
|
+
* it will be converted to that type.
|
|
3605
|
+
* This is often used in class constructors that accept an object of arguments.
|
|
3606
|
+
* @param {object} dest
|
|
3607
|
+
* @param {?object} src
|
|
3608
|
+
* @param {string[]} [ignore=[]] */
|
|
3609
|
+
function assignFields(dest, src, ignore=[]) {
|
|
3610
|
+
for (let name in src || {}) {
|
|
3611
|
+
if (name in dest && !ignore.includes(name)) {
|
|
3612
|
+
const descriptor = Object.getOwnPropertyDescriptor(dest, name)
|
|
3613
|
+
|| Object.getOwnPropertyDescriptor(Object.getPrototypeOf(dest), name); // Also find (parent?) setters. Is this necssary?
|
|
3614
|
+
if (!descriptor || descriptor.writable || descriptor.set) {
|
|
3615
|
+
let srcVal = src[name];
|
|
3616
|
+
let destVal = dest[name];
|
|
3617
|
+
if (typeof src[name] === 'string') {
|
|
3618
|
+
if (typeof destVal === 'boolean') // empty string (when an attribute is present with no value) is true
|
|
3619
|
+
dest[name] = ![false, 'false', 0, '0'].includes(srcVal);
|
|
3620
|
+
else if (typeof destVal === 'number')
|
|
3621
|
+
dest[name] = Number(srcVal);
|
|
3622
|
+
else if (destVal instanceof Date) {
|
|
3623
|
+
dest[name] = new Date(srcVal); // TODO: read it as UTC 0 by default.
|
|
3624
|
+
}
|
|
3625
|
+
else
|
|
3626
|
+
dest[name] = srcVal;
|
|
3627
|
+
}
|
|
3628
|
+
else
|
|
3629
|
+
dest[name] = srcVal;
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
}
|
|
3479
3633
|
}
|
|
3480
3634
|
|
|
3481
3635
|
export default h;
|
|
3482
|
-
export { ArgType, Globals$1 as Globals, HtmlParser, NodeGroup, Shell, Solarite, Util as SolariteUtil, Template, delve, getArg, h, h as r, setArgs, t, toEl };
|
|
3636
|
+
export { ArgType, Globals$1 as Globals, HtmlParser, NodeGroup, Shell, Solarite, Util as SolariteUtil, Template, assignFields, delve, getArg, h, h as r, setArgs, t, toEl };
|
package/dist/Solarite.min.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Version 0.5.
|
|
1
|
+
// Version 0.5.1
|
|
2
2
|
// License: MIT
|
|
3
3
|
// http://vorticode.github.io/solarite
|
|
4
|
-
function assert(t){}let lastObjectId=1,objectIds=new WeakMap;function getObjectId(t){let e=objectIds.get(t);return void 0===e&&(e="~@"+lastObjectId++,objectIds.set(t,e)),e}let isHashing=!0;function toJSON(){return isHashing?getObjectId(this):this}function getObjectHash(t){Node.prototype.toJSON!==toJSON&&(Node.prototype.toJSON=toJSON,(()=>{}).toJSON!==toJSON&&(Function.prototype.toJSON=toJSON)),isHashing=!0;try{return JSON.stringify(t)}catch(e){return getObjectHashCircular(t)}finally{isHashing=!1}}function getObjectHashCircular(t){const e=new Set;return JSON.stringify(t,((t,l)=>{if("object"==typeof l&&null!==l){if(e.has(l))return getObjectId(l);e.add(l)}return l}))}var Globals;function reset(){Globals={connected:new WeakSet,t:null,l:null,div:document.createElement("div"),i:document,o:{},h:{},u:new WeakMap,p:new WeakMap,m:new WeakMap,$:new WeakSet,v:new WeakMap,reset}}reset();var Globals$1=Globals;function delve(t,e,l=d){let s=l!==d,i=e.length;if(!t&&!s&&i)return;let r=0;for(let o of e){if(void 0===t[o]){if(!s)return;i-1>r&&(t[o]=(e[r+1]+"").match(/^\d+$/)?[]:{})}s&&r===i-1&&(t[o]=l),t=t[o],r++}return t}let d={},Util={T(t,e){let l=t.length;if(l!==e.length)return!1;for(let s=0;l>s;s++)if(t[s]!==e[s])return!1;return!0},P(t,e=null){let l={};for(let s of t.attributes)s.name!==e&&(l[Util.G(s.name)]=s.value);return l},A(t,e){let l=e.getAttribute("data-id")||e.getAttribute("id");if(l){if(t[l]&&!t[l]?.nodeType)throw Error(`${t.constructor.name}.${l} already has a value. Can't set it as a reference to <${e.tagName.toLowerCase()} id="${l}">`);delve(t,l.split(/\./g),e)}},N(t,e){let l,s,i=e.tagName.toLowerCase();if(t.hasAttribute("global")||t.hasAttribute("data-global")){l=i,s="";let r=Globals$1.i||e.ownerDocument||document;r.head.querySelector(`style[data-style="${l}"]`)?t.remove():(r.head.append(t),t.setAttribute("data-style",l))}else{let t=e.getAttribute("data-style");t||(e.constructor.S||(e.constructor.S=1),t=e.constructor.S++,e.setAttribute("data-style",t)),s=`[data-style="${t}"]`}for(let e of t.childNodes)if(3===e.nodeType){let t=e.textContent,l=t.replace(/:host(?=[^a-z0-9_])/gi,`${i}${s}`);t!==l&&(e.textContent=l)}},O:t=>(t=(t=(t=t.replace(/([a-z0-9])([A-Z])/g,"$1-$2")).replace(/([A-Z])([A-Z][a-z])/g,"$1-$2")).replace(/([a-zA-Z])([0-9])/g,"$1-$2")).toLowerCase(),G:t=>t.replace(/-([a-z])/g,(t=>t[1].toUpperCase())),H(t,e){customElements[getName](t)||((e=e||Util.O(t.name)).includes("-")||(e+="-element"),customElements[define](e,t))},C:t=>"checkbox"===t.type||"radio"===t.type?t.checked:"file"===t.type?[...t.files]:"number"===t.type||"range"===t.type?t.valueAsNumber:"date"===t.type||"time"===t.type||"datetime-local"===t.type?t.valueAsDate:"select-multiple"===t.type?[...t.selectedOptions].map((t=>t.value)):t.hasAttribute("contenteditable")?t.innerHTML:t.value,j:t=>t.startsWith("on")&&t in Globals$1.div,U(t,e){let l=t.tagName+"."+e,s=Globals$1.h[l];if(void 0===s){let i=Object.getPrototypeOf(t);for(;i;){const t=i.constructor.name;if(t.startsWith("HTML")&&t.endsWith("Element"))break;i=Object.getPrototypeOf(i)}Globals$1.h[l]=s=!!i&&!!Object.getOwnPropertyDescriptor(i,e)?.set}return s},M:t=>Array.isArray(t)&&t.length>=2&&("object"==typeof t[0]||void 0===t[0])&&!t.slice(1).find((t=>"string"!=typeof t&&"number"!=typeof t)),L:t=>void 0===t||!1===t||null===t,I:t=>"function"==typeof t?Util.I(t()):t instanceof Date?t.toISOString().replace(/T/," "):Array.isArray(t)||"object"==typeof t?"":t,R(t,e,l){let s=t.get(e);s?s.push(l):(s=[l],t.set(e,s))},k(t){Globals$1.i.createDocumentFragment().append(...t)},F(t){const e=t=>t.nodeType!==Node.ELEMENT_NODE&&(t.nodeType!==Node.TEXT_NODE||""===t.textContent.trim()),l=[...t];for(;l.length>0&&e(l[0]);)l.shift();for(;l.length>0&&e(l[l.length-1]);)l.pop();return l}},define="define",getName="getName";class Path{J;V;D;W=[];Z;_;B;K;constructor(t,e){this.J=t,this.V=e}apply(t,e=!0){}q(){return 1}X(t,e){let l=t,s=this.B,i=s.length-e;for(let t=i-1;t>0;t--)l=l.childNodes[s[t]];return i?l.childNodes[s[0]]:t}clone(t,e=0){let l,s,i=t,r=this.B,o=r.length-e;for(let t=o-1;t>0;t--)i=i.childNodes[r[t]];let n=i.childNodes;l=o?n[r[0]]:t,this.J&&(s=n[this._]);let a=new this.constructor(s,l,this.attrName,this.Y);return a.tt=this.tt,a.et=this.et,a}lt(){return[this.V]}static get(t){let e=[];for(;;){let l=t.parentNode;if(!l)break;e.push([].indexOf.call(t.parentNode.childNodes,t)),t=l}return e}static resolve(t,e){for(let l=e.length-1;l>=0;l--)t=t.childNodes[e[l]];return t}}class HtmlParser{constructor(){this.st={context:HtmlParser.Text,quote:null,buffer:"",it:null},this.state={...this.st}}reset(){return this.state={...this.st},this.state.context}parse(t,e=null){if(null===t)return this.reset();for(let l=0;t.length>l;l++){const s=t[l];switch(this.state.context){case HtmlParser.Text:"<"===s&&t[l+1].match(/[/a-z!]/i)&&(e?.(t,l,this.state.context,HtmlParser.rt),this.state.context=HtmlParser.rt,this.state.buffer="");break;case HtmlParser.rt:if(">"===s)e?.(t,l+1,this.state.context,HtmlParser.Text),this.state.context=HtmlParser.Text,this.state.quote=null,this.state.buffer="";else{if(" "===s&&!this.state.buffer)continue;" "===s||"/"===s||"?"===s?this.state.buffer="":'"'===s||"'"===s||"="===s?(e?.(t,l,this.state.context,HtmlParser.ot),this.state.context=HtmlParser.ot,this.state.quote="="===s?null:s,this.state.buffer=""):this.state.buffer+=s}break;case HtmlParser.ot:this.state.quote||this.state.buffer.length||'"'!==s&&"'"!==s?s===this.state.quote||!this.state.quote&&this.state.buffer.length?(e?.(t,l,this.state.context,HtmlParser.rt),this.state.context=HtmlParser.rt,this.state.quote=null,this.state.buffer=""):this.state.quote||">"!==s?" "!==s&&(this.state.buffer+=s):(e?.(t,l+1,this.state.context,HtmlParser.Text),this.state.context=HtmlParser.Text,this.state.quote=null,this.state.buffer=""):this.state.quote=s}}return e?.(t,t.length,this.state.context,null),this.state.context}}HtmlParser.ot="Attribute",HtmlParser.Text="Text",HtmlParser.rt="Tag";class PathToAttribValue extends Path{attrName;Y;et;constructor(t,e,l=null,s=null){super(null,e),this.attrName=l,this.Y=s}apply(t){let e=this.V,l=t[0],s=this.Y;if(!s&&Util.M(l)){if(this.tt&&e.tagName.endsWith("-SOLARITE-PLACEHOLDER"))return;let[t,s]=[l[0],l.slice(1)];if(!t)throw Error(`Solarite cannot bind to <${e.tagName.toLowerCase()} ${this.attrName}=\${[${l.map((t=>t?`'${t}'`:t+"")).join(", ")}]}>.`);let i=delve(t,s);if("value"===this.attrName&&"select-multiple"===e.type&&Array.isArray(i)){let t=i.map((t=>t+""));for(let l of e.options)l.selected=t.includes(l.value)}else{const t=Util.L(i)?"":i;"value"===this.attrName&&e.hasAttribute("contenteditable")?t!==e.innerHTML&&(e.innerHTML=t):t!==e[this.attrName]&&(e[this.attrName]=t)}let r=()=>{let l="value"===this.attrName?Util.C(e):e[this.attrName];delve(t,s,l)};this.nt(e,this.D.getRootNode(),this.attrName,"input",r,[],!0)}else{let i=this.et;if(!s){if(Globals$1.t=this,"function"==typeof l){if(this.tt)return;this.K=l,l=l()}else l=Util.I(l);Globals$1.t=null}if(s||void 0!==l&&!1!==l&&null!==l)if(s||!0!==l){let r=s?this.ht(t):l;(i?e[this.attrName]:e.getAttribute(this.attrName))!==r&&(i?e[this.attrName]=r:"value"===this.attrName&&e.hasAttribute("contenteditable")&&(e.innerHTML=r),e.setAttribute(this.attrName,r))}else i&&(e[this.attrName]=!0),e.setAttribute(this.attrName,"");else i&&(e[this.attrName]=!1),e.removeAttribute(this.attrName)}}q(){return this.Y?this.Y.length-1:1}ht(t){if(!this.Y)return t[0];let e=[],l=this.Y;for(let s=0;l.length>s;s++)if(e.push(l[s]),l.length-1>s){Globals$1.t=this;let l=Util.I(t[s]);Globals$1.t=null,Util.L(l)||e.push(l)}return e.join("")}nt(t,e,l,s,i,r,o=!1){let n=Globals$1.u.get(t);n||(n={[l]:[,,,]},Globals$1.u.set(t,n));let a=n[l];if(a||(n[l]=a=[,,,]),"function"!=typeof i)throw Error(`Solarite cannot bind to <${t.tagName.toLowerCase()} ${this.attrName}=\${${i}}> because it's not a function.`);if(a[0]!==i){let[l,r,n]=a;l&&t.removeEventListener(s,r,o);let h=i,f=l=>h.call(e,...a[2],l,t);a[0]=h,a[1]=f,t.addEventListener(s,f,o)}n[l][2]=r}}class PathToEvent extends PathToAttribValue{constructor(t,e,l=null,s=null){super(null,e,l,s)}apply(t){if(this.tt&&this.V.tagName.endsWith("-SOLARITE-PLACEHOLDER"))return;let e,l=t[0],s=this.D.ft.root,i=this.V,r=this.attrName.slice(2),o=[];if(Array.isArray(l)&&"function"==typeof l[0])e=l[0],o=l.slice(1);else{if("function"!=typeof l)throw Error(`Invalid event binding: <${i.tagName.toLowerCase()} ${this.attrName}=\${${JSON.stringify(l)}}>`);e=l}this.nt(i,s,r,r,e,o)}}class PathToAttribs extends Path{ut;constructor(t,e){super(null,null),this.V=e,this.ut=new Set}apply(t,e){let l=t[0],s=this.V;Array.isArray(l)&&(l=l.flat().join(" "));let i=this.ut;if(this.ut=new Set,l)if("function"==typeof l&&(Globals$1.t=this,this.K=l,l=l(),Globals$1.t=null),"object"==typeof l)for(let t in l){let e=l[t];void 0!==e&&!1!==e&&null!==e&&(s.setAttribute(t,e),this.ut.add(t))}else{let t=(l+"").split(/([\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|\S+))/g).map((t=>t.trim())).filter((t=>t.length));for(let e of t){let[t,l]=e.split(/\s*=\s*/);l=(l||"").replace(/^(['"])(.*)\1$/,"$2"),s.setAttribute(t,l),this.ut.add(t)}}for(let t of i)this.ut.has(t)||s.removeAttribute(t)}q(){return 1}}const udomdiff=(t,e,l,s)=>{const i=l.length;let r=e.length,o=i,n=0,a=0,h=null;for(;r>n||o>a;)if(r===n){const e=i>o?a?l[a-1].nextSibling:l[o-a]:s;for(;o>a;){let s=l[a++];t.insertBefore(s,e)}}else if(o===a)for(;r>n;){let l=e[n];h&&h.has(l)||t.removeChild(l),n++}else if(e[n]===l[a])n++,a++;else if(e[r-1]===l[o-1])r--,o--;else if(e[n]===l[o-1]&&l[a]===e[r-1]){const s=e[--r].nextSibling;let i=l[a++],h=e[n++];t.insertBefore(i,h.nextSibling);let f=l[--o];t.insertBefore(f,s),e[r]=l[o]}else{if(!h){h=new Map;let t=a;for(;o>t;)h.set(l[t],t++)}if(h.has(e[n])){const s=h.get(e[n]);if(s>a&&o>s){let i=n,f=1;for(;++i<r&&o>i&&h.get(e[i])===s+f;)f++;if(f>s-a){const i=e[n];for(;s>a;){let e=l[a++];t.insertBefore(e,i)}}else{let s=e[n++],i=l[a++];t.replaceChild(i,s)}}else n++}else{let l=e[n++];t.removeChild(l)}}return l};class MultiValueMap{data={};add(t,e){let l=this.data,s=l[t];s||(s=new Set,l[t]=s),s.add(e)}ct(){for(let t in this.data)return!0;return!1}getAll(t){return this.data[t]||[]}delete(t,e=void 0){let l,s=this.data,i=s[t];if(i)return void 0===e?([l]=i,i.delete(l)):(i.delete(e),l=e),0===i.size&&delete s[t],l}dt(t){let e,l=this.data,s=l[t];if(s)return[e]=s,s.delete(e),0===s.size&&delete l[t],e}bt(t,e){let l,s=this.data,i=s[t];if(i)return i.delete(e),l=e,0===i.size&&delete s[t],l}yt(t){let e=this.data,l=[];for(let s in e)e[s].has(t)&&l.push(s);return l}}class PathToNodes extends Path{gt;$t=[];Et=new MultiValueMap;vt=new MultiValueMap;constructor(t,e){super(t,e)}apply(t,e=!0){let l=this,s=t[0];e&&l.Tt();let i=[],r=l.W,o=[];l.W=[],l.Pt(s,i,o);let n=!1;if(o.length){for(let[t,e]of o){let s=l.Gt(i[t],!1),r=s.lt();1===r.length?i[t]=r[0]:(i[t]=r,n=!0),l.W[e]=s}n&&(i=i.flat())}let a=l.lt();if(!Util.T(a,i)){l.Z=i,this.D.wt&&this.D.wt.At(),a.length&&!i.length&&l.Nt()||udomdiff(l.V.parentNode,a,i,l.V);for(let t of r)t.St.parentNode||Util.k(t.lt())}}Pt(t,e,l){if(t instanceof Template){let s=this.Gt(t,!0);if(s){let l=s.lt();return e.push(...l),s.Ot(t.exprs,!1,!1),this.W.push(s),s}l.push([e.length,this.W.length]),e.push(t),this.W.push(null)}else t instanceof NodeList?e.push(...t):t?.nodeType?11===t?.nodeType?e.push(...t.childNodes):e.push(t):this.Ht(t,(t=>{this.Pt(t,e,l)}))}Ct(t){let e=Math.min(t.xt,t.items.length),l=t.xt-e;for(let l=0;e>l;l++){let e=this.W[t.index+l],s=(this.gt||this.K)(t.items[l]);this.Ht(s,(s=>{let i=this.Gt(s,!0);if(i&&i===e);else{i||(i=this.Gt(s,!1)),this.W[t.index+l]=i;let r=e.St;for(let t of i.lt())r.parentNode.insertBefore(t,r);i!==e&&Util.k(e.lt())}}))}if(l>0){for(let s=0;l>s;s++)Util.k(this.W[t.index+e+s].lt());this.W.splice(t.index+e,l)}else{let l=t.items.slice(e),s=this.W[t.index+e]?.St||this.V;for(let t=0;l.length>t;t++){let e=this.gt(l[t]),i=this.Gt(e,!0);i||(i=this.Gt(e,!1)),this.W.push(i);for(let t of i.lt())s.parentNode.insertBefore(t,s)}}this.Z=null}At(){let t=this,e=this.V.parentNode;for(;t&&t.V.parentNode===e;)t.Z=null,t=t.D?.wt}Nt(){let t=this.J.parentNode;return this.J===t.firstChild&&this.V===t.lastChild&&(t.innerHTML="",t.append(this.J,this.V),!0)}Ht(t,e){if(Array.isArray(t))for(let l of t)this.Ht(l,e);else if("function"==typeof t)Globals$1.t=this,this.K=t,t=t(),Globals$1.t=null,this.Ht(t,e);else if(t instanceof Template||t?.nodeType)e(t);else{void 0===t||!1===t||null===t?t="":"string"!=typeof t&&(t+="");let l=new Template([t],[]);l.jt=!0,this.Ht(l,e)}}Gt(t,e=!0){let l,s=this.Et;if(e){if(l=s.dt(t.Ut()),l||(s=this.vt,l=s.dt(t.Ut())),!l)return null;s.bt(t.Mt(),l)}else t.exprs.length&&(l=s.dt(t.Mt()),l||(s=this.vt,l=s.dt(t.Mt())),l&&(s.bt(l.Lt,l),l.Ot(t.exprs),l.Lt=t.Ut()));return l||(l=new NodeGroup(t,this),l.Ot(t.exprs),l.Lt=t.Ut()),this.$t.push(l),l}Tt(){let t=this.Et.data,e=this.vt.data;for(let l in t){let s=e[l];if(s)for(let e of t[l])s.add(e);else e[l]=t[l]}this.Et=new MultiValueMap;let l=this.Et;for(let t of this.$t)l.add(t.Lt,t),l.add(t.It,t);this.$t=[]}lt(){let t;if(t=this.Z,t)return t;t=[];let e=this.J.nextSibling,l=this.V;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.Z=t,t}}class PathToComponent extends Path{Rt;constructor(t,e){super(null,e)}apply(t,e=!0,l=!0){let s=this.V,i=Util.P(s,"_is");for(let e,l=0;e=this.Rt[l];l++)i[Util.G(e.attrName)]=e.ht(t[l]);let r=s.getAttribute("_is");if(s.tagName.endsWith("-SOLARITE-PLACEHOLDER")||r){let e=(r||s.tagName.slice(0,-21)).toLowerCase(),o=customElements.get(e);if(!o)throw Error(`Must call customElements.define('${e}', Class) before using it.`);Globals$1.l=[...s.childNodes];let n=new o(i);r&&n.setAttribute("is",r);for(let t of s.attributes)"_is"!==t.name&&n.setAttribute(t.name,t.value);for(let t in i){let e=i[t],l=typeof e;"boolean"===l?!1!==e&&null!=e&&n.setAttribute(t,""):"string"!==l&&"number"!==l&&"bigint"!==l||n.setAttribute(t,e)}let a=n.getAttribute("data-id")||n.getAttribute("id");a&&delve(this.D.getRootNode(),a.split(/\./g),n);let h=this.D;this.V=n;for(let t of h.kt)t.V===s&&(t.V=n),t.J===s&&(t.J=n);h.St===s&&(h.St=n),h.Ft===s&&(h.Ft=n),"function"!=typeof n.render||Globals$1.$.has(n)||n.render(i,l);for(let e,l=0;e=this.Rt[l];l++)e.D=this.D,e.V=n,e.apply(t[l]);s.replaceWith(n)}else"function"==typeof s.render&&s.render(i,l);Globals$1.l=null}clone(t,e=0){let l=this.X(t,e),s=new PathToComponent(null,l);return s.Rt=this.Rt.map((l=>l.clone(t,e))),s}q(){return 0}}class Shell{fragment;kt=[];Jt=[];scripts=[];Vt=[];constructor(t=null){if(!t)return;if(1===t.length&&!t[0].match(/[<&]/))return void(this.fragment=Globals$1.i.createTextNode(t[0]));let e,l=Shell.Dt(t),s=Globals$1.i.createElement("template");l?s.innerHTML=l:s.content.append(Globals$1.i.createTextNode("")),this.fragment=s.content;let i=[],r=0;const o=Globals$1.i.createTreeWalker(this.fragment,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_TEXT);for(;e=o.nextNode();)if(i.map((t=>t.remove())),i=[],1===e.nodeType){const t=e.hasAttribute("is"),l=t||e.tagName.includes("-"),s=[];for(let t of[...e.attributes]){let i=t.name.match(/^[\ue000-\uf8ff]$/);if(i){let t=new PathToAttribs(null,e);this.kt.push(t),l&&s.push(t),r++,e.removeAttribute(i[0])}else{let i=t.value.split(/[\ue000-\uf8ff]/g);if(i.length>1){let o=2!==i.length||i[0].length||i[1].length?i:null,n=Util.j(t.name)?new PathToEvent(null,e,t.name,o):new PathToAttribValue(null,e,t.name,o);n.et=Util.U(e,t.name),this.kt.push(n),l&&(n.tt=!0,s.push(n)),r+=i.length-1,e.setAttribute(t.name,i.join(""))}}}if(l){let l=new PathToComponent(null,e);l.Rt=s,this.kt.splice(this.kt.length-s.length,0,l),t&&(e.setAttribute("_is",e.getAttribute("is")),e.removeAttribute("is"))}}else if(8===e.nodeType&&"!✨!"===e.nodeValue){if(e?.parentNode?.closest&&e?.parentNode?.closest("[contenteditable]"))throw Error('Contenteditable can\'t have expressions inside them. Use <div contenteditable value="${...}"> instead.');let t,l=e.previousSibling;l||(l=Globals$1.i.createComment("Path:"+this.kt.length),e.parentNode.insertBefore(l,e)),!e.nextSibling||8===e.nextSibling.nodeType&&"!✨!"===e.nextSibling.textContent?(t=e,t.textContent="PathEnd:"+this.kt.length):(t=e.nextSibling,i.push(e));let s=new PathToNodes(l,t);this.kt.push(s),r++}else{if(3===e.nodeType&&"TEXTAREA"===e.parentNode?.tagName&&e.textContent.includes("\x3c!--!✨!--\x3e"))throw Error('Textarea can\'t have expressions inside them. Use <textarea value="${...}"> instead.');if(8===e.nodeType){let t=e.textContent.split(/[\ue000-\uf8ff]/g);for(let l=0;t.length-1>l;l++){let t=new Path(e.previousSibling,e);this.kt.push(t),r++}}else if(3===e.nodeType&&["SCRIPT","STYLE"].includes(e.parentNode?.nodeName)){let t=e.textContent.split(commentPlaceholder);if(t.length>1){let l=[];for(let s=0;t.length>s;s++){let i=Globals$1.i.createTextNode(t[s]);e.parentNode.insertBefore(i,e),s>0&&l.push(i)}for(let t,e=0;t=l[e];e++){let e=new PathToNodes(t.previousSibling,t);this.kt.push(e),r++}i.push(e)}}}if(i.map((t=>t.remove())),r!==t.length-1)throw Error("Could not parse expressions in template. Check for duplicate attributes or malformed html: "+t.join("${...}"));for(let t of this.kt)t.J&&(t._=[].indexOf.call(t.J.parentNode.childNodes,t.J)),t.B=Path.get(t.V);this.zt()}static Dt(t){let e=[],l=new HtmlParser;for(let s=0;t.length>s;s++){let i=0,r=l.parse(t[s],((t,l,s)=>{if(i!==l){let r=t.slice(i,l);s===HtmlParser.rt&&(r=r.replace(/^<\/?[a-z][a-z0-9]*-[a-z0-9-]+/i,(t=>t+"-SOLARITE-PLACEHOLDER"))),e.push(r)}i=l}));t.length-1>s&&e.push(r===HtmlParser.Text?commentPlaceholder:String.fromCharCode(attribPlaceholder+s))}return e.join("")}zt(){this.scripts=[].map.call(this.fragment.querySelectorAll("scripts"),(t=>Path.get(t))),this.Vt=[].map.call(this.fragment.querySelectorAll("style"),(t=>Path.get(t)));let t=this.fragment.querySelectorAll("[id],[data-id]");for(let e of t){let t=e.getAttribute("data-id")||e.getAttribute("id");if(Globals$1.div.hasOwnProperty(t))throw Error(`<${e.tagName.toLowerCase()} id="${t}"> can't override existing HTMLElement id property.`)}this.Jt=[].map.call(t,(t=>Path.get(t)))}static get(t){let e=Globals$1.v.get(t);return e||(e=new Shell(t),Globals$1.v.set(t,e)),e}}const commentPlaceholder="\x3c!--!✨!--\x3e",attribPlaceholder=57344;class NodeGroup{ft;wt;St;Ft;kt=[];Lt;It;Z;Vt;Wt;root;constructor(t,e=null,l=null,s=null){if(this.ft=e?.D?.ft||this,this.wt=e,this.Wt=t,this.It=t.Mt(),t.jt)this.St=this.Ft=Globals$1.i.createTextNode(t.html[0]);else{const e=Shell.get(t.html),i=e.fragment.cloneNode(!0);if(11===i.nodeType?(this.St=i.firstChild,this.Ft=i.lastChild):this.St=this.Ft=i,this instanceof RootNodeGroup){let t=0;if(this.options=s,i instanceof Text){if(!l)throw Error("Cannot create a standalone text node");this.root=l,i.nodeValue.length&&this.root.append(i)}else{if(l){let e;if(this.root=l,(Globals$1.l||l.childNodes.length)&&(e=Globals$1.i.createDocumentFragment(),e.append(...Globals$1.l||l.childNodes)),isReplaceEl(i,this.root.tagName)){this.root.append(...i.children[0].childNodes);for(let t of i.children[0].attributes)this.root.hasAttribute(t.name)||this.root.setAttribute(t.name,t.value);t=1}else 1===i.childNodes.length&&3===i.childNodes[0].nodeType&&""===i.childNodes[0].textContent||this.root.append(...i.childNodes);if(e){for(let t of l.querySelectorAll("slot[name]")){let l=t.getAttribute("name");if(l){let s=e.querySelectorAll(`[slot='${l}']`);t.append(...s)}}let t=l.querySelector("slot:not([name])");t?t.append(e):l.append(e)}}else{let e=getSingleEl(i);this.root=e||i,e&&(t=1)}this.Zt(this.root,e.kt,t),this._t(this.root,e,t)}this.St=this.Ft=this.root,Globals$1.p.set(this.root,this)}else e&&(e.kt.length&&this.Zt(i,e.kt),this._t(i,e))}}Ot(t,e=!0,l=!0){let s=this.kt,i=t.length,r=Array(s.length);for(let o,n=s.length-1;o=s[n];n--){if(0===n&&o instanceof PathToComponent&&o.V===this.getRootNode())continue;let s=o.q();if(r[n]=t.slice(i-s,i),i-=s,o instanceof PathToComponent){let t=r.slice(n+1,n+1+o.Rt.length);o.apply(t,!0,e)}else l&&o.apply(r[n])}l&&(this.Bt(),this.Z=null)}Kt(t){}lt(){let t=this.Z;if(t)return t;t=[];let e=this.St,l=this.Ft?.nextSibling;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.Z=t,t}getRootNode(){return this.ft.root}qt(){return this.ft}Zt(t,e,l=0){let s=e.length;this.kt.length=s;for(let i=0;s>i;i++){let s=e[i].clone(t,l);s.D=this,this.kt[i]=s}}Bt(){if(this.Vt)for(let[t,e]of this.Vt)e!==t.textContent&&Util.N(t,this.qt().root)}_t(root,shell,pathOffset=0){let rootEl=this.ft.root;if(rootEl){let options=this.ft.options;if(!1!==options?.Jt)for(let t of shell.Jt){pathOffset&&(t=t.slice(0,-pathOffset));let e=Path.resolve(root,t);Util.A(rootEl,e)}if(!1!==options?.Vt){shell.Vt.length&&(this.Vt=new Map);for(let t of shell.Vt){pathOffset&&(t=t.slice(0,-pathOffset));let e=Path.resolve(root,t);1===rootEl.nodeType&&(Util.N(e,rootEl),this.Vt.set(e,e.textContent))}}if(!1!==options?.scripts)for(let path of shell.scripts){pathOffset&&(path=path.slice(0,-pathOffset));let script=Path.resolve(root,path);eval(script.textContent)}}}}function getSingleEl(t){let e=[];for(let l of t.childNodes)if(1===l.nodeType||3===l.nodeType&&l.textContent.trim().length){if(e.length)return null;e.push(l)}return e[0]}function isReplaceEl(t,e){return 1===t.children.length&&e.includes("-")&&t.children[0].tagName.replace("-SOLARITE-PLACEHOLDER","")===e}class RootNodeGroup extends NodeGroup{Xt}class Template{exprs=[];html=[];Yt;jt;constructor(t=[""],e=[]){this.html=t,this.exprs=e}toJSON(){return void 0===this.Yt&&(this.Yt=[getObjectId(this.html),this.exprs]),this.Yt}render(t=null,e={}){let l=t&&Globals$1.p.get(t);if(l||(l=new RootNodeGroup(this,null,t,e),t||(t=l.getRootNode()),Globals$1.p.set(t,l)),1!==this.html?.length||this.html[0]){let t=l.Lt,e=this.Ut();l.Ot(this.exprs,t!==e),l.Lt=e}else t.innerHTML="";return l.Xt=new Map,t}Ut(){return void 0===this.Lt&&(this.Lt=this.exprs.length?getObjectHash(this):this.html[0]),this.Lt}Mt(){return void 0===this.It&&(this.It=this.exprs.length?this.toJSON()[0]:this.html[0]),this.It}static Qt(t,e,l){const s=selfClosingTags.has(t.toLowerCase());let i=[],r=[],o="<"+t;if(e&&"object"==typeof e)for(let t in e){let l=e[t];"id"!==t&&"data-id"!==t?(o+=` ${t}=`,i.push(o),r.push(l),o=""):o+=` ${t}="${l}"`}if(!s){i.push(i.length>0?'"'===o?'">':">":o+">");for(let t of l)addChild(t,i,r)}return s?i.push(i.length>0?">":o+">"):i[i.length-1]+=`</${t}>`,new Template(i,r)}}const selfClosingTags=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),addChild=(t,e,l)=>{if(Array.isArray(t))for(let s of t)addChild(s,e,l);else{let s=!1;if(t instanceof Template)if(t.exprs.length>0)s=!0;else{const e=(t.html[0]||"").match(/^<([a-zA-Z][\w:-]*)/),l=e?e[1].toLowerCase():"";s=selfClosingTags.has(l)}if(s){e[e.length-1]+=t.html[0];for(let s=0;t.exprs.length>s;s++)l.push(t.exprs[s]),e.push(t.html[s+1]??"")}else l.push(t),e.push("")}};function toEl(t){if("string"==typeof t){let e=t;(e.match(/^\s^<\S+/)||e.match(/\S+>\s+$/))&&(e=e.trim());let l=Globals$1.i.createElement("template");l.innerHTML=e;let s=Util.F(l.content.childNodes);return 1===s.length?s[0]:l.content}if(t instanceof Template)return t.render();if(t&&"object"==typeof t){let e=t;if("Object"!==e.constructor.name)throw Error(`Solarate Web Component class ${e.constructor?.name} must extend HTMLElement.`);if(!Globals$1.m.has(e)){Globals$1.m.set(e,null),e[renderF]();let t=Globals$1.m.get(e);Globals$1.m.delete(e);for(let l in e)t[l]="function"==typeof e[l]?e[l].bind(t):e[l];return t}}throw Error("toEl() does not support argument of type: "+(t?typeof t:t))}let renderF="render";function h(t=void 0,...e){if(Array.isArray(arguments[0]))return new Template(arguments[0],e);if("string"==typeof arguments[0]||arguments[0]instanceof String){let t=arguments[0];if(!e.length||"object"!=typeof e[0]&&null!==e[0]){let e=t;return e.match(/^\s^</)&&(e=e.trim()),new Template([e],[])}{let l=t+"",s=e[0]||{},i=e.slice(1);return Template.Qt(l,s,i)}}if(arguments[0]instanceof HTMLElement||arguments[0]instanceof DocumentFragment){if(!(arguments[1]instanceof Template)){let t=arguments[0],e=arguments[1];t.shadowRoot&&(t.innerHTML="");let l=(l,...s)=>(Globals$1.$.add(t),new Template(l,s).render(t,e));return l}arguments[1].render(arguments[0],arguments[2])}else{if(!arguments.length)return(t,...e)=>toEl(h(t,...e));if("object"!=typeof arguments[0]||!Globals$1.m.has(arguments[0])){if(Util.L(arguments[0]))return new Template;throw Error("h() does not support argument of type: "+(arguments[0]?typeof arguments[0]:arguments[0]))}{let t=arguments[0];if("Object"!==t.constructor.name)throw Error(`Solarate Web Component class ${t.constructor?.name} must extend HTMLElement.`);if(!(arguments[1]instanceof Template))return((...e)=>{let l=h(...e).render();Globals$1.m.set(t,l)}).bind(t);{let e=arguments[1].render();Globals$1.m.set(t,e)}}}}function getArg(el,attributeName,defaultValue=void 0,type=ArgType.String){let val=defaultValue,attrVal=el.getAttribute(attributeName)||el.getAttribute(Util.O(attributeName));if(null!==attrVal&&(val=attrVal),Array.isArray(type))return type.includes(val)?val:void 0;if("function"==typeof type)return type.constructor?new type(val):type(val);if(type===ArgType.te){let t="string"==typeof val?val.toLowerCase():val;return!["false","0",!1,0,null,void 0,NaN].includes(t)&&(!(!["true",!0].includes(t)&&0===parseFloat(t))||void 0)}switch(type){case ArgType.ee:return parseInt(val);case ArgType.le:return parseFloat(val);case ArgType.String:return[void 0,null,!1].includes(val)?"":val+"";case ArgType.se:case ArgType.ie:if("string"!=typeof val||!val.length)return val;try{return type===ArgType.se?JSON.parse(val):eval(`(${val})`)}catch(t){return val}default:return val}}function setArgs(t,e,l){for(let s in e)this[s]=getArg(t,s,e[s],l[s]||ArgType.String)}var ArgType={te:"Bool",ee:"Int",le:"Float",String:"String",JSON:"Json",se:"Json",ie:"Eval"};function t(t){return new Template([t],[])}let HTMLElementAutoDefine=new Proxy(HTMLElement,{construct:(t,e,l)=>(Util.H(l),Reflect.construct(t,e,l))});class Solarite extends HTMLElementAutoDefine{constructor(t=null){if(super(),t){if("object"!=typeof t)throw Error("First argument to custom element constructor must be an object.");if(t&&!Object.keys(t).length){let e=Solarite.getAttribs(this);for(let l in e)t[l]=e[l]}}}render(){throw Error("render() is not defined for "+this.constructor.name)}renderFirstTime(){if(!Globals$1.$.has(this)){let t=Solarite.getAttribs(this);this.render(t)}}connectedCallback(){this.renderFirstTime()}static define(t=null){Util.H(this,t)}static getAttribs(t){let e=Util.P(t);for(let t in e){let l=e[t];l.startsWith("${")&&l.endsWith("}")&&(e[t]=JSON.parse(l.slice(2,-1)))}return e}}export default h;export{ArgType,Globals$1 as Globals,HtmlParser,NodeGroup,Shell,Solarite,Util as SolariteUtil,Template,delve,getArg,h,h as r,setArgs,t,toEl};
|
|
4
|
+
function assert(t){}let lastObjectId=1,objectIds=new WeakMap;function getObjectId(t){let e=objectIds.get(t);return void 0===e&&(e="~@"+lastObjectId++,objectIds.set(t,e)),e}let isHashing=!0;function toJSON(){return isHashing?getObjectId(this):this}function getObjectHash(t){Node.prototype.toJSON!==toJSON&&(Node.prototype.toJSON=toJSON,(()=>{}).toJSON!==toJSON&&(Function.prototype.toJSON=toJSON)),isHashing=!0;try{return JSON.stringify(t)}catch(e){return getObjectHashCircular(t)}finally{isHashing=!1}}function getObjectHashCircular(t){const e=new Set;return JSON.stringify(t,((t,l)=>{if("object"==typeof l&&null!==l){if(e.has(l))return getObjectId(l);e.add(l)}return l}))}var Globals;function reset(){Globals={connected:new WeakSet,t:null,l:null,div:document.createElement("div"),i:document,o:{},h:{},u:new WeakMap,p:new WeakMap,m:new WeakMap,$:new WeakSet,v:new WeakMap,reset}}reset();var Globals$1=Globals;function delve(t,e,l=d){let s=l!==d,i=e.length;if(!t&&!s&&i)return;let r=0;for(let o of e){if(void 0===t[o]){if(!s)return;i-1>r&&(t[o]=(e[r+1]+"").match(/^\d+$/)?[]:{})}s&&r===i-1&&(t[o]=l),t=t[o],r++}return t}let d={},Util={T(t,e){let l=t.length;if(l!==e.length)return!1;for(let s=0;l>s;s++)if(t[s]!==e[s])return!1;return!0},P(t,e=null){let l={};for(let s of t.attributes)s.name!==e&&(l[Util.G(s.name)]=s.value);return l},A(t,e){let l=e.getAttribute("data-id")||e.getAttribute("id");if(l){if(t[l]&&!t[l]?.nodeType)throw Error(`${t.constructor.name}.${l} already has a value. Can't set it as a reference to <${e.tagName.toLowerCase()} id="${l}">`);delve(t,l.split(/\./g),e)}},N(t,e){let l,s,i=e.tagName.toLowerCase();if(t.hasAttribute("global")||t.hasAttribute("data-global")){l=i,s="";let r=Globals$1.i||e.ownerDocument||document;r.head.querySelector(`style[data-style="${l}"]`)?t.remove():(r.head.append(t),t.setAttribute("data-style",l))}else{let t=e.getAttribute("data-style");t||(e.constructor.S||(e.constructor.S=1),t=e.constructor.S++,e.setAttribute("data-style",t)),s=`[data-style="${t}"]`}for(let e of t.childNodes)if(3===e.nodeType){let t=e.textContent,l=t.replace(/:host(?=[^a-z0-9_])/gi,`${i}${s}`);t!==l&&(e.textContent=l)}},O:t=>(t=(t=(t=t.replace(/([a-z0-9])([A-Z])/g,"$1-$2")).replace(/([A-Z])([A-Z][a-z])/g,"$1-$2")).replace(/([a-zA-Z])([0-9])/g,"$1-$2")).toLowerCase(),G:t=>t.replace(/-([a-z])/g,(t=>t[1].toUpperCase())),H(t,e){customElements[getName](t)||((e=e||Util.O(t.name)).includes("-")||(e+="-element"),customElements[define](e,t))},C:t=>"checkbox"===t.type||"radio"===t.type?t.checked:"file"===t.type?[...t.files]:"number"===t.type||"range"===t.type?t.valueAsNumber:"date"===t.type||"time"===t.type||"datetime-local"===t.type?t.valueAsDate:"select-multiple"===t.type?[...t.selectedOptions].map((t=>t.value)):t.hasAttribute("contenteditable")?t.innerHTML:t.value,j:t=>t.startsWith("on")&&t in Globals$1.div,U(t,e){let l=t.tagName+"."+e,s=Globals$1.h[l];if(void 0===s){let i=Object.getPrototypeOf(t);for(;i;){const t=i.constructor.name;if(t.startsWith("HTML")&&t.endsWith("Element"))break;i=Object.getPrototypeOf(i)}Globals$1.h[l]=s=!!i&&!!Object.getOwnPropertyDescriptor(i,e)?.set}return s},M:t=>Array.isArray(t)&&t.length>=2&&("object"==typeof t[0]||void 0===t[0])&&!t.slice(1).find((t=>"string"!=typeof t&&"number"!=typeof t)),L:t=>void 0===t||!1===t||null===t,I:t=>"function"==typeof t?Util.I(t()):t instanceof Date?t.toISOString().replace(/T/," "):Array.isArray(t)||"object"==typeof t?"":t,R(t,e,l){let s=t.get(e);s?s.push(l):(s=[l],t.set(e,s))},k(t){Globals$1.i.createDocumentFragment().append(...t)},F(t){const e=t=>t.nodeType!==Node.ELEMENT_NODE&&(t.nodeType!==Node.TEXT_NODE||""===t.textContent.trim()),l=[...t];for(;l.length>0&&e(l[0]);)l.shift();for(;l.length>0&&e(l[l.length-1]);)l.pop();return l}},define="define",getName="getName";class Path{J;V;D;W=[];K;Z;_;B;constructor(t,e){this.J=t,this.V=e}apply(t,e=!0){}q(){return 1}X(t,e){let l=t,s=this._,i=s.length-e;for(let t=i-1;t>0;t--)l=l.childNodes[s[t]];return i?l.childNodes[s[0]]:t}clone(t,e=0){let l,s,i=t,r=this._,o=r.length-e;for(let t=o-1;t>0;t--)i=i.childNodes[r[t]];let n=i.childNodes;l=o?n[r[0]]:t,this.J&&(s=n[this.Z]);let a=new this.constructor(s,l,this.attrName,this.Y);return a.tt=this.tt,a.et=this.et,a}lt(){return[this.V]}static get(t){let e=[];for(;;){let l=t.parentNode;if(!l)break;e.push([].indexOf.call(t.parentNode.childNodes,t)),t=l}return e}static resolve(t,e){for(let l=e.length-1;l>=0;l--)t=t.childNodes[e[l]];return t}}class HtmlParser{constructor(){this.st={context:HtmlParser.Text,quote:null,buffer:"",it:null},this.state={...this.st}}reset(){return this.state={...this.st},this.state.context}parse(t,e=null){if(null===t)return this.reset();for(let l=0;t.length>l;l++){const s=t[l];switch(this.state.context){case HtmlParser.Text:"<"===s&&t[l+1].match(/[/a-z!]/i)&&(e?.(t,l,this.state.context,HtmlParser.rt),this.state.context=HtmlParser.rt,this.state.buffer="");break;case HtmlParser.rt:if(">"===s)e?.(t,l+1,this.state.context,HtmlParser.Text),this.state.context=HtmlParser.Text,this.state.quote=null,this.state.buffer="";else{if(" "===s&&!this.state.buffer)continue;" "===s||"/"===s||"?"===s?this.state.buffer="":'"'===s||"'"===s||"="===s?(e?.(t,l,this.state.context,HtmlParser.ot),this.state.context=HtmlParser.ot,this.state.quote="="===s?null:s,this.state.buffer=""):this.state.buffer+=s}break;case HtmlParser.ot:this.state.quote||this.state.buffer.length||'"'!==s&&"'"!==s?s===this.state.quote||!this.state.quote&&this.state.buffer.length?(e?.(t,l,this.state.context,HtmlParser.rt),this.state.context=HtmlParser.rt,this.state.quote=null,this.state.buffer=""):this.state.quote||">"!==s?" "!==s&&(this.state.buffer+=s):(e?.(t,l+1,this.state.context,HtmlParser.Text),this.state.context=HtmlParser.Text,this.state.quote=null,this.state.buffer=""):this.state.quote=s}}return e?.(t,t.length,this.state.context,null),this.state.context}}HtmlParser.ot="Attribute",HtmlParser.Text="Text",HtmlParser.rt="Tag";class PathToAttribValue extends Path{attrName;Y;et;constructor(t,e,l=null,s=null){super(null,e),this.attrName=l,this.Y=s}apply(t){let e=this.V,l=t[0],s=this.Y;if(!s&&Util.M(l)){if(this.tt&&e.tagName.endsWith("-SOLARITE-PLACEHOLDER"))return;let[t,s]=[l[0],l.slice(1)];if(!t)throw Error(`Solarite cannot bind to <${e.tagName.toLowerCase()} ${this.attrName}=\${[${l.map((t=>t?`'${t}'`:t+"")).join(", ")}]}>.`);let i=delve(t,s);if("value"===this.attrName&&"select-multiple"===e.type&&Array.isArray(i)){let t=i.map((t=>t+""));for(let l of e.options)l.selected=t.includes(l.value)}else{const t=Util.L(i)?"":i;"value"===this.attrName&&e.hasAttribute("contenteditable")?t!==e.innerHTML&&(e.innerHTML=t):t!==e[this.attrName]&&(e[this.attrName]=t)}let r=()=>{let l="value"===this.attrName?Util.C(e):e[this.attrName];delve(t,s,l)};this.nt(e,this.D.getRootNode(),this.attrName,"input",r,[],!0)}else{let i=this.et;if(!s){if(Globals$1.t=this,"function"==typeof l){if(this.tt)return;this.B=l,l=l()}else l=Util.I(l);Globals$1.t=null}if(s||void 0!==l&&!1!==l&&null!==l)if(s||!0!==l){let r=s?this.ht(t):l;(i?e[this.attrName]:e.getAttribute(this.attrName))!==r&&(i?e[this.attrName]=r:"value"===this.attrName&&e.hasAttribute("contenteditable")&&(e.innerHTML=r),e.setAttribute(this.attrName,r))}else i&&(e[this.attrName]=!0),e.setAttribute(this.attrName,"");else i&&(e[this.attrName]=!1),e.removeAttribute(this.attrName)}}q(){return this.Y?this.Y.length-1:1}ht(t){if(!this.Y)return t[0];let e=[],l=this.Y;for(let s=0;l.length>s;s++)if(e.push(l[s]),l.length-1>s){Globals$1.t=this;let l=Util.I(t[s]);Globals$1.t=null,Util.L(l)||e.push(l)}return e.join("")}nt(t,e,l,s,i,r,o=!1){let n=Globals$1.u.get(t);n||(n={[l]:[,,,]},Globals$1.u.set(t,n));let a=n[l];if(a||(n[l]=a=[,,,]),"function"!=typeof i)throw Error(`Solarite cannot bind to <${t.tagName.toLowerCase()} ${this.attrName}=\${${i}}> because it's not a function.`);if(a[0]!==i){let[l,r,n]=a;l&&t.removeEventListener(s,r,o);let h=i,f=l=>h.call(e,...a[2],l,t);a[0]=h,a[1]=f,t.addEventListener(s,f,o)}n[l][2]=r}}class PathToEvent extends PathToAttribValue{constructor(t,e,l=null,s=null){super(null,e,l,s)}apply(t){if(this.Y?.length>1)return void super.apply(t);if(this.tt&&this.V.tagName.endsWith("-SOLARITE-PLACEHOLDER"))return;let e,l=t[0],s=this.D.ft.root,i=this.V,r=this.attrName.slice(2),o=[];if(Array.isArray(l)&&"function"==typeof l[0])e=l[0],o=l.slice(1);else{if("function"!=typeof l)throw Error(`Invalid event binding: <${i.tagName.toLowerCase()} ${this.attrName}=\${${JSON.stringify(l)}}>`);e=l}this.nt(i,s,r,r,e,o)}}class PathToAttribs extends Path{ut;constructor(t,e){super(null,null),this.V=e,this.ut=new Set}apply(t,e){let l=t[0],s=this.V;Array.isArray(l)&&(l=l.flat().join(" "));let i=this.ut;if(this.ut=new Set,l)if("function"==typeof l&&(Globals$1.t=this,this.B=l,l=l(),Globals$1.t=null),"object"==typeof l)for(let t in l){let e=l[t];void 0!==e&&!1!==e&&null!==e&&(s.setAttribute(t,e),this.ut.add(t))}else{let t=(l+"").split(/([\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|\S+))/g).map((t=>t.trim())).filter((t=>t.length));for(let e of t){let[t,l]=e.split(/\s*=\s*/);l=(l||"").replace(/^(['"])(.*)\1$/,"$2"),s.setAttribute(t,l),this.ut.add(t)}}for(let t of i)this.ut.has(t)||s.removeAttribute(t)}q(){return 1}}const udomdiff=(t,e,l,s)=>{const i=l.length;let r=e.length,o=i,n=0,a=0,h=null;for(;r>n||o>a;)if(r===n){const e=i>o?a?l[a-1].nextSibling:l[o-a]:s;for(;o>a;){let s=l[a++];t.insertBefore(s,e)}}else if(o===a)for(;r>n;){let l=e[n];h&&h.has(l)||t.removeChild(l),n++}else if(e[n]===l[a])n++,a++;else if(e[r-1]===l[o-1])r--,o--;else if(e[n]===l[o-1]&&l[a]===e[r-1]){const s=e[--r].nextSibling;let i=l[a++],h=e[n++];t.insertBefore(i,h.nextSibling);let f=l[--o];t.insertBefore(f,s),e[r]=l[o]}else{if(!h){h=new Map;let t=a;for(;o>t;)h.set(l[t],t++)}if(h.has(e[n])){const s=h.get(e[n]);if(s>a&&o>s){let i=n,f=1;for(;++i<r&&o>i&&h.get(e[i])===s+f;)f++;if(f>s-a){const i=e[n];for(;s>a;){let e=l[a++];t.insertBefore(e,i)}}else{let s=e[n++],i=l[a++];t.replaceChild(i,s)}}else n++}else{let l=e[n++];t.removeChild(l)}}return l};class MultiValueMap{data={};add(t,e){let l=this.data,s=l[t];s||(s=new Set,l[t]=s),s.add(e)}ct(){for(let t in this.data)return!0;return!1}getAll(t){return this.data[t]||[]}delete(t,e=void 0){let l,s=this.data,i=s[t];if(i)return void 0===e?([l]=i,i.delete(l)):(i.delete(e),l=e),0===i.size&&delete s[t],l}dt(t){let e,l=this.data,s=l[t];if(s)return[e]=s,s.delete(e),0===s.size&&delete l[t],e}bt(t,e){let l,s=this.data,i=s[t];if(i)return i.delete(e),l=e,0===i.size&&delete s[t],l}yt(t){let e=this.data,l=[];for(let s in e)e[s].has(t)&&l.push(s);return l}}class PathToNodes extends Path{gt;$t=[];Et=new MultiValueMap;vt=new MultiValueMap;constructor(t,e){super(t,e)}apply(t,e=!0){let l=this,s=t[0];e&&l.Tt();let i=[],r=l.W,o=[];l.W=[],l.Pt(s,i,o);let n=!1;if(o.length){for(let[t,e]of o){let s=l.wt(i[t],!1),r=s.lt();1===r.length?i[t]=r[0]:(i[t]=r,n=!0),l.W[e]=s}n&&(i=i.flat())}let a=l.lt();if(!Util.T(a,i)){l.K=i,this.D.Gt&&this.D.Gt.At(),a.length&&!i.length&&l.Nt()||udomdiff(l.V.parentNode,a,i,l.V);for(let t of r)t.St.parentNode||Util.k(t.lt())}}Pt(t,e,l){if(t instanceof Template){let s=this.wt(t,!0);if(s){let l=s.lt();return e.push(...l),s.Ot(t.exprs,!1,!1),this.W.push(s),s}l.push([e.length,this.W.length]),e.push(t),this.W.push(null)}else t instanceof NodeList?e.push(...t):t?.nodeType?11===t?.nodeType?e.push(...t.childNodes):e.push(t):this.Ht(t,(t=>{this.Pt(t,e,l)}))}xt(t){let e=Math.min(t.Ct,t.items.length),l=t.Ct-e;for(let l=0;e>l;l++){let e=this.W[t.index+l],s=(this.gt||this.B)(t.items[l]);this.Ht(s,(s=>{let i=this.wt(s,!0);if(i&&i===e);else{i||(i=this.wt(s,!1)),this.W[t.index+l]=i;let r=e.St;for(let t of i.lt())r.parentNode.insertBefore(t,r);i!==e&&Util.k(e.lt())}}))}if(l>0){for(let s=0;l>s;s++)Util.k(this.W[t.index+e+s].lt());this.W.splice(t.index+e,l)}else{let l=t.items.slice(e),s=this.W[t.index+e]?.St||this.V;for(let t=0;l.length>t;t++){let e=this.gt(l[t]),i=this.wt(e,!0);i||(i=this.wt(e,!1)),this.W.push(i);for(let t of i.lt())s.parentNode.insertBefore(t,s)}}this.K=null}At(){let t=this,e=this.V.parentNode;for(;t&&t.V.parentNode===e;)t.K=null,t=t.D?.Gt}Nt(){let t=this.J.parentNode;return this.J===t.firstChild&&this.V===t.lastChild&&(t.innerHTML="",t.append(this.J,this.V),!0)}Ht(t,e){if(Array.isArray(t))for(let l of t)this.Ht(l,e);else if("function"==typeof t)Globals$1.t=this,this.B=t,t=t(),Globals$1.t=null,this.Ht(t,e);else if(t instanceof Template||t?.nodeType)e(t);else{void 0===t||!1===t||null===t?t="":"string"!=typeof t&&(t+="");let l=new Template([t],[]);l.jt=!0,this.Ht(l,e)}}wt(t,e=!0){let l,s=this.Et;if(e){if(l=s.dt(t.Ut()),l||(s=this.vt,l=s.dt(t.Ut())),!l)return null;s.bt(t.Mt(),l)}else t.exprs.length&&(l=s.dt(t.Mt()),l||(s=this.vt,l=s.dt(t.Mt())),l&&(s.bt(l.Lt,l),l.Ot(t.exprs),l.Lt=t.Ut()));return l||(l=new NodeGroup(t,this),l.Ot(t.exprs),l.Lt=t.Ut()),this.$t.push(l),l}Tt(){let t=this.Et.data,e=this.vt.data;for(let l in t){let s=e[l];if(s)for(let e of t[l])s.add(e);else e[l]=t[l]}this.Et=new MultiValueMap;let l=this.Et;for(let t of this.$t)l.add(t.Lt,t),l.add(t.It,t);this.$t=[]}lt(){let t;if(t=this.K,t)return t;t=[];let e=this.J.nextSibling,l=this.V;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.K=t,t}}class PathToComponent extends Path{Rt;constructor(t,e){super(null,e)}apply(t,e=!0,l=!0){let s=this.V,i=Util.P(s,"_is");for(let e,l=0;e=this.Rt[l];l++)i[Util.G(e.attrName)]=e.ht(t[l]);let r=s.getAttribute("_is");if(s.tagName.endsWith("-SOLARITE-PLACEHOLDER")||r){let e=(r||s.tagName.slice(0,-21)).toLowerCase(),o=customElements.get(e);if(!o)throw Error(`Must call customElements.define('${e}', Class) before using it.`);Globals$1.l=[...s.childNodes];let n=new o(i);r&&n.setAttribute("is",r);for(let t of s.attributes)"_is"!==t.name&&n.setAttribute(t.name,t.value);for(let t in i){let e=i[t],l=typeof e;"boolean"===l?!1!==e&&null!=e&&n.setAttribute(t,""):"string"!==l&&"number"!==l&&"bigint"!==l||n.setAttribute(t,e)}let a=n.getAttribute("data-id")||n.getAttribute("id");a&&delve(this.D.getRootNode(),a.split(/\./g),n);let h=this.D;this.V=n;for(let t of h.kt)t.V===s&&(t.V=n),t.J===s&&(t.J=n);h.St===s&&(h.St=n),h.Ft===s&&(h.Ft=n),"function"!=typeof n.render||Globals$1.$.has(n)||n.render(i,l);for(let e,l=0;e=this.Rt[l];l++)e.D=this.D,e.V=n,e.apply(t[l]);s.replaceWith(n)}else"function"==typeof s.render&&s.render(i,l);Globals$1.l=null}clone(t,e=0){let l=this.X(t,e),s=new PathToComponent(null,l);return s.Rt=this.Rt.map((l=>l.clone(t,e))),s}q(){return 0}}class Shell{fragment;kt=[];Jt=[];scripts=[];Vt=[];constructor(t=null){if(!t)return;if(1===t.length&&!t[0].match(/[<&]/))return void(this.fragment=Globals$1.i.createTextNode(t[0]));let e,l=Shell.Dt(t),s=Globals$1.i.createElement("template");l?s.innerHTML=l:s.content.append(Globals$1.i.createTextNode("")),this.fragment=s.content;let i=[],r=0;const o=Globals$1.i.createTreeWalker(this.fragment,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_TEXT);for(;e=o.nextNode();)if(i.map((t=>t.remove())),i=[],1===e.nodeType){const t=e.hasAttribute("is"),l=t||e.tagName.includes("-"),s=[];for(let t of[...e.attributes]){let i=t.name.match(/^[\ue000-\uf8ff]$/);if(i){let t=new PathToAttribs(null,e);this.kt.push(t),l&&s.push(t),r++,e.removeAttribute(i[0])}else{let i=t.value.split(/[\ue000-\uf8ff]/g);if(i.length>1){let o=2!==i.length||i[0].length||i[1].length?i:null,n=Util.j(t.name)?new PathToEvent(null,e,t.name,o):new PathToAttribValue(null,e,t.name,o);n.et=Util.U(e,t.name),this.kt.push(n),l&&(n.tt=!0,s.push(n)),r+=i.length-1;try{e.setAttribute(t.name,i.join(""))}catch(l){throw Error(`Error setting attribute "${t.name}" on node <${e.tagName}>: ${l.message}`)}}}}if(l){let l=new PathToComponent(null,e);l.Rt=s,this.kt.splice(this.kt.length-s.length,0,l),t&&(e.setAttribute("_is",e.getAttribute("is")),e.removeAttribute("is"))}}else if(8===e.nodeType&&"!✨!"===e.nodeValue){if(e?.parentNode?.closest&&e?.parentNode?.closest("[contenteditable]"))throw Error('Contenteditable can\'t have expressions inside them. Use <div contenteditable value="${...}"> instead.');let t,l=e.previousSibling;l||(l=Globals$1.i.createComment("Path:"+this.kt.length),e.parentNode.insertBefore(l,e)),!e.nextSibling||8===e.nextSibling.nodeType&&"!✨!"===e.nextSibling.textContent?(t=e,t.textContent="PathEnd:"+this.kt.length):(t=e.nextSibling,i.push(e));let s=new PathToNodes(l,t);this.kt.push(s),r++}else{if(3===e.nodeType&&"TEXTAREA"===e.parentNode?.tagName&&e.textContent.includes("\x3c!--!✨!--\x3e"))throw Error('Textarea can\'t have expressions inside them. Use <textarea value="${...}"> instead.');if(8===e.nodeType){let t=e.textContent.split(/[\ue000-\uf8ff]/g);for(let l=0;t.length-1>l;l++){let t=new Path(e.previousSibling,e);this.kt.push(t),r++}}else if(3===e.nodeType&&["SCRIPT","STYLE"].includes(e.parentNode?.nodeName)){let t=e.textContent.split(commentPlaceholder);if(t.length>1){let l=[];for(let s=0;t.length>s;s++){let i=Globals$1.i.createTextNode(t[s]);e.parentNode.insertBefore(i,e),s>0&&l.push(i)}for(let t,e=0;t=l[e];e++){let e=new PathToNodes(t.previousSibling,t);this.kt.push(e),r++}i.push(e)}}}if(i.map((t=>t.remove())),r!==t.length-1)throw Error("Could not parse expressions in template. Check for duplicate attributes or malformed html: "+t.join("${...}"));for(let t of this.kt)t.J&&(t.Z=[].indexOf.call(t.J.parentNode.childNodes,t.J)),t._=Path.get(t.V);this.zt()}static Dt(t){let e=[],l=new HtmlParser;for(let s=0;t.length>s;s++){let i=0,r=l.parse(t[s],((t,l,s)=>{if(i!==l){let r=t.slice(i,l);s===HtmlParser.rt&&(r=r.replace(/^<\/?[a-z][a-z0-9]*-[a-z0-9-]+/i,(t=>t+"-SOLARITE-PLACEHOLDER"))),e.push(r)}i=l}));t.length-1>s&&e.push(r===HtmlParser.Text?commentPlaceholder:String.fromCharCode(attribPlaceholder+s))}return e.join("")}zt(){this.scripts=[].map.call(this.fragment.querySelectorAll("scripts"),(t=>Path.get(t))),this.Vt=[].map.call(this.fragment.querySelectorAll("style"),(t=>Path.get(t)));let t=this.fragment.querySelectorAll("[id],[data-id]");for(let e of t){let t=e.getAttribute("data-id")||e.getAttribute("id");if(Globals$1.div.hasOwnProperty(t))throw Error(`<${e.tagName.toLowerCase()} id="${t}"> can't override existing HTMLElement id property.`)}this.Jt=[].map.call(t,(t=>Path.get(t)))}static get(t){let e=Globals$1.v.get(t);return e||(e=new Shell(t),Globals$1.v.set(t,e)),e}}const commentPlaceholder="\x3c!--!✨!--\x3e",attribPlaceholder=57344;class NodeGroup{ft;Gt;St;Ft;kt=[];Lt;It;K;Vt;Wt;root;constructor(t,e=null,l=null,s=null){if(this.ft=e?.D?.ft||this,this.Gt=e,this.Wt=t,this.It=t.Mt(),t.jt)this.St=this.Ft=Globals$1.i.createTextNode(t.html[0]);else{const e=Shell.get(t.html),i=e.fragment.cloneNode(!0);if(11===i.nodeType?(this.St=i.firstChild,this.Ft=i.lastChild):this.St=this.Ft=i,this instanceof RootNodeGroup){let t=0;if(this.options=s,i instanceof Text){if(!l)throw Error("Cannot create a standalone text node");this.root=l,i.nodeValue.length&&this.root.append(i)}else{if(l){let e;if(this.root=l,(Globals$1.l||l.childNodes.length)&&(e=Globals$1.i.createDocumentFragment(),e.append(...Globals$1.l||l.childNodes)),isReplaceEl(i,this.root.tagName)){this.root.append(...i.children[0].childNodes);for(let t of i.children[0].attributes)this.root.hasAttribute(t.name)||this.root.setAttribute(t.name,t.value);t=1}else 1===i.childNodes.length&&3===i.childNodes[0].nodeType&&""===i.childNodes[0].textContent||this.root.append(...i.childNodes);if(e){for(let t of l.querySelectorAll("slot[name]")){let l=t.getAttribute("name");if(l){let s=e.querySelectorAll(`[slot='${l}']`);t.append(...s)}}let t=l.querySelector("slot:not([name])");t?t.append(e):l.append(e)}}else{let e=getSingleEl(i);this.root=e||i,e&&(t=1)}this.Kt(this.root,e.kt,t),this.Zt(this.root,e,t)}this.St=this.Ft=this.root,Globals$1.p.set(this.root,this)}else e&&(e.kt.length&&this.Kt(i,e.kt),this.Zt(i,e))}}Ot(t,e=!0,l=!0){let s=this.kt,i=t.length,r=Array(s.length);for(let o,n=s.length-1;o=s[n];n--){if(0===n&&o instanceof PathToComponent&&o.V===this.getRootNode())continue;let s=o.q();if(r[n]=t.slice(i-s,i),i-=s,o instanceof PathToComponent){let t=r.slice(n+1,n+1+o.Rt.length);o.apply(t,!0,e)}else l&&o.apply(r[n])}l&&(this._t(),this.K=null)}Bt(t){}lt(){let t=this.K;if(t)return t;t=[];let e=this.St,l=this.Ft?.nextSibling;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.K=t,t}getRootNode(){return this.ft.root}qt(){return this.ft}Kt(t,e,l=0){let s=e.length;this.kt.length=s;for(let i=0;s>i;i++){let s=e[i].clone(t,l);s.D=this,this.kt[i]=s}}_t(){if(this.Vt)for(let[t,e]of this.Vt)e!==t.textContent&&Util.N(t,this.qt().root)}Zt(root,shell,pathOffset=0){let rootEl=this.ft.root;if(rootEl){let options=this.ft.options;if(!1!==options?.Jt)for(let t of shell.Jt){pathOffset&&(t=t.slice(0,-pathOffset));let e=Path.resolve(root,t);Util.A(rootEl,e)}if(!1!==options?.Vt){shell.Vt.length&&(this.Vt=new Map);for(let t of shell.Vt){pathOffset&&(t=t.slice(0,-pathOffset));let e=Path.resolve(root,t);1===rootEl.nodeType&&(Util.N(e,rootEl),this.Vt.set(e,e.textContent))}}if(!1!==options?.scripts)for(let path of shell.scripts){pathOffset&&(path=path.slice(0,-pathOffset));let script=Path.resolve(root,path);eval(script.textContent)}}}}function getSingleEl(t){let e=[];for(let l of t.childNodes)if(1===l.nodeType||3===l.nodeType&&l.textContent.trim().length){if(e.length)return null;e.push(l)}return e[0]}function isReplaceEl(t,e){return 1===t.children.length&&e.includes("-")&&t.children[0].tagName.replace("-SOLARITE-PLACEHOLDER","")===e}class RootNodeGroup extends NodeGroup{Xt}class Template{exprs=[];html=[];Yt;It;Lt;jt;constructor(t=[""],e=[]){this.html=t,this.exprs=e}toJSON(){return void 0===this.Yt&&(this.Yt=[getObjectId(this.html),this.exprs]),this.Yt}render(t=null,e={}){let l=t&&Globals$1.p.get(t);if(l||(l=new RootNodeGroup(this,null,t,e),t||(t=l.getRootNode()),Globals$1.p.set(t,l)),1!==this.html?.length||this.html[0]){let t=l.Lt,e=this.Ut();l.Ot(this.exprs,t!==e),l.Lt=e}else t.innerHTML="";return l.Xt=new Map,t}Ut(){return void 0===this.Lt&&(this.Lt=this.exprs.length?getObjectHash(this):this.html[0]),this.Lt}Mt(){return void 0===this.It&&(this.It=this.exprs.length?this.toJSON()[0]:this.html[0]),this.It}static Qt(t,e,l){const s=selfClosingTags.has(t.toLowerCase());let i=[],r=[],o="<"+t;if(e&&"object"==typeof e)for(let t in e){let l=e[t];"id"!==t&&"data-id"!==t?(o+=` ${t}=`,i.push(o),r.push(l),o=""):o+=` ${t}="${l}"`}if(!s){i.push(i.length>0?'"'===o?'">':">":o+">");for(let t of l)addChild(t,i,r)}return s?i.push(i.length>0?">":o+">"):i[i.length-1]+=`</${t}>`,new Template(i,r)}}const selfClosingTags=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),addChild=(t,e,l)=>{if(Array.isArray(t))for(let s of t)addChild(s,e,l);else{let s=!1;if(t instanceof Template)if(t.exprs.length>0)s=!0;else{const e=(t.html[0]||"").match(/^<([a-zA-Z][\w:-]*)/),l=e?e[1].toLowerCase():"";s=selfClosingTags.has(l)}if(s){e[e.length-1]+=t.html[0];for(let s=0;t.exprs.length>s;s++)l.push(t.exprs[s]),e.push(t.html[s+1]??"")}else l.push(t),e.push("")}};function toEl(t){if("string"==typeof t){let e=t;(e.match(/^\s^<\S+/)||e.match(/\S+>\s+$/))&&(e=e.trim());let l=Globals$1.i.createElement("template");l.innerHTML=e;let s=Util.F(l.content.childNodes);return 1===s.length?s[0]:l.content}if(t instanceof Template)return t.render();if(t&&"object"==typeof t){let e=t;if("Object"!==e.constructor.name)throw Error(`Solarate Web Component class ${e.constructor?.name} must extend HTMLElement.`);if(!Globals$1.m.has(e)){Globals$1.m.set(e,null),e[renderF]();let t=Globals$1.m.get(e);Globals$1.m.delete(e);for(let l in e)t[l]="function"==typeof e[l]?e[l].bind(t):e[l];return t}}throw Error("toEl() does not support argument of type: "+(t?typeof t:t))}let renderF="render";function h(t=void 0,...e){if(Array.isArray(arguments[0]))return new Template(arguments[0],e);if("string"==typeof arguments[0]||arguments[0]instanceof String){let t=arguments[0];if(!e.length||"object"!=typeof e[0]&&null!==e[0]){let e=t;return e.match(/^\s^</)&&(e=e.trim()),new Template([e],[])}{let l=t+"",s=e[0]||{},i=e.slice(1);return Template.Qt(l,s,i)}}if(arguments[0]instanceof HTMLElement||arguments[0]instanceof DocumentFragment){if(!(arguments[1]instanceof Template)){let t=arguments[0],e=arguments[1];t.shadowRoot&&(t.innerHTML="");let l=(l,...s)=>(Globals$1.$.add(t),new Template(l,s).render(t,e));return l}arguments[1].render(arguments[0],arguments[2])}else{if(!arguments.length)return(t,...e)=>toEl(h(t,...e));if("object"!=typeof arguments[0]||!Globals$1.m.has(arguments[0])){if(Util.L(arguments[0]))return new Template;throw Error("h() does not support argument of type: "+(arguments[0]?typeof arguments[0]:arguments[0]))}{let t=arguments[0];if("Object"!==t.constructor.name)throw Error(`Solarate Web Component class ${t.constructor?.name} must extend HTMLElement.`);if(!(arguments[1]instanceof Template))return((...e)=>{let l=h(...e).render();Globals$1.m.set(t,l)}).bind(t);{let e=arguments[1].render();Globals$1.m.set(t,e)}}}}function getArg(el,attributeName,defaultValue=void 0,type=ArgType.String){let val=defaultValue,attrVal=el.getAttribute(attributeName)||el.getAttribute(Util.O(attributeName));if(null!==attrVal&&(val=attrVal),Array.isArray(type))return type.includes(val)?val:void 0;if("function"==typeof type)return type.constructor?new type(val):type(val);if(type===ArgType.te){let t="string"==typeof val?val.toLowerCase():val;return!["false","0",!1,0,null,void 0,NaN].includes(t)&&(!(!["true",!0].includes(t)&&0===parseFloat(t))||void 0)}switch(type){case ArgType.ee:return parseInt(val);case ArgType.le:return parseFloat(val);case ArgType.String:return[void 0,null,!1].includes(val)?"":val+"";case ArgType.se:case ArgType.ie:if("string"!=typeof val||!val.length)return val;try{return type===ArgType.se?JSON.parse(val):eval(`(${val})`)}catch(t){return val}default:return val}}function setArgs(t,e,l){for(let s in e)this[s]=getArg(t,s,e[s],l[s]||ArgType.String)}var ArgType={te:"Bool",ee:"Int",le:"Float",String:"String",JSON:"Json",se:"Json",ie:"Eval"};function t(t){return new Template([t],[])}let HTMLElementAutoDefine=new Proxy(HTMLElement,{construct:(t,e,l)=>(Util.H(l),Reflect.construct(t,e,l))});class Solarite extends HTMLElementAutoDefine{constructor(t=null){if(super(),t){if("object"!=typeof t)throw Error("First argument to custom element constructor must be an object.");if(t&&!Object.keys(t).length){let e=Solarite.getAttribs(this);for(let l in e)t[l]=e[l]}}}render(){throw Error("render() is not defined for "+this.constructor.name)}renderFirstTime(){if(!Globals$1.$.has(this)){let t=Solarite.getAttribs(this);this.render(t)}}connectedCallback(){this.renderFirstTime()}static define(t=null){Util.H(this,t)}static getAttribs(t){let e=Util.P(t);for(let t in e){let l=e[t];l.startsWith("${")&&l.endsWith("}")&&(e[t]=JSON.parse(l.slice(2,-1)))}return e}}function assignFields(t,e,l=[]){for(let s in e||{})if(s in t&&!l.includes(s)){const l=Object.getOwnPropertyDescriptor(t,s)||Object.getOwnPropertyDescriptor(Object.getPrototypeOf(t),s);if(!l||l.writable||l.set){let l=e[s],i=t[s];t[s]="string"==typeof e[s]?"boolean"==typeof i?![!1,"false",0,"0"].includes(l):"number"==typeof i?+l:i instanceof Date?new Date(l):l:l}}}export default h;export{ArgType,Globals$1 as Globals,HtmlParser,NodeGroup,Shell,Solarite,Util as SolariteUtil,Template,assignFields,delve,getArg,h,h as r,setArgs,t,toEl};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solarite",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Solarite is a small (9KB min+gzip), fast, compilation-free JavaScript library for adding reactivity to native web components, so that updates require minimal re-rendering.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/Solarite.js",
|
package/src/PathToEvent.js
CHANGED
|
@@ -20,6 +20,14 @@ export default class PathToEvent extends PathToAttribValue {
|
|
|
20
20
|
assert(Array.isArray(exprs));
|
|
21
21
|
//#ENDIF
|
|
22
22
|
|
|
23
|
+
// Tested by Solariate.events.classicWithExpr
|
|
24
|
+
// We have expressions within a string attribute value that's not a Solarite event. E.g.
|
|
25
|
+
// <div onclick="alert(${1});"
|
|
26
|
+
if (this.attrValue?.length > 1) {
|
|
27
|
+
super.apply(exprs);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
// Don't bind events to component placeholders.
|
|
24
32
|
// PathToComponent will do the binding later when it instantiates the component.
|
|
25
33
|
if (this.isComponentAttrib && this.nodeMarker.tagName.endsWith('-SOLARITE-PLACEHOLDER'))
|
package/src/Shell.js
CHANGED
|
@@ -114,7 +114,12 @@ export default class Shell {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
placeholdersUsed += parts.length - 1;
|
|
117
|
-
|
|
117
|
+
try {
|
|
118
|
+
node.setAttribute(attr.name, parts.join(''));
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
throw new Error(`Error setting attribute "${attr.name}" on node <${node.tagName}>: ${e.message}`);
|
|
122
|
+
}
|
|
118
123
|
}
|
|
119
124
|
}
|
|
120
125
|
}
|
package/src/Solarite.d.ts
CHANGED
|
@@ -19,10 +19,11 @@ declare function h(el: HTMLElement | DocumentFragment, options?: RenderOptions):
|
|
|
19
19
|
declare function h(el: HTMLElement | DocumentFragment, template: Template, options?: RenderOptions): void;
|
|
20
20
|
declare function h(tag: string, props: object, ...children: any[]): Template; // JSX
|
|
21
21
|
declare function h(obj: {render: Function}): (htmlStrings: TemplateStringsArray, ...exprs: any[]) => void; // Rebound render
|
|
22
|
+
declare function h(): (htmlStrings: TemplateStringsArray, ...exprs: any[]) => Node|DocumentFragment;
|
|
22
23
|
|
|
23
24
|
export default h;
|
|
24
25
|
export {h};
|
|
25
|
-
export {h as r};
|
|
26
|
+
export {h as r}; // deprecated
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Solarite provides more features if your web component extends Solarite instead of HTMLElement. */
|
|
@@ -40,6 +41,12 @@ export class Solarite extends HTMLElement {
|
|
|
40
41
|
* Convert a template, string, or object into a DOM Node or Element. */
|
|
41
42
|
export function toEl(arg: string | Template | {render: () => void}): Node | HTMLElement | DocumentFragment;
|
|
42
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Assign fields from `src` to `dest` if they exist in `dest` and don't exist in `ignore`.
|
|
46
|
+
* When a value in `src` is a string and the existing value in `dest` is a boolean, number, or Date,
|
|
47
|
+
* it will be converted to that type. */
|
|
48
|
+
export function assignFields(dest: object, src: object|null, ignore?: string[]): void;
|
|
49
|
+
|
|
43
50
|
/**
|
|
44
51
|
* @deprecated
|
|
45
52
|
* Retrieve and cast an attribute value from an HTMLElement. */
|
package/src/Solarite.js
CHANGED
|
@@ -145,4 +145,142 @@ export class Solarite extends HTMLElementAutoDefine {
|
|
|
145
145
|
}
|
|
146
146
|
return result;
|
|
147
147
|
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
// TODO: Do we want to use this to get the tag name from the render() function, instead of having the user define it?
|
|
151
|
+
/**
|
|
152
|
+
* Get the tag name for a class, as defined by the tag used in render().
|
|
153
|
+
*
|
|
154
|
+
* This will parse the JavaScript code of the render() function to find the tag name.
|
|
155
|
+
* It will itarage every character, keeping track of quotes and comments so it can
|
|
156
|
+
* skip them until it finds the tag name passed to h(this)`<tagname>` inside the render() function.
|
|
157
|
+
*
|
|
158
|
+
* */
|
|
159
|
+
/*
|
|
160
|
+
static getTagName(Class) {
|
|
161
|
+
let code = Class.prototype.render.toString();
|
|
162
|
+
let i = 0;
|
|
163
|
+
while (i < code.length) {
|
|
164
|
+
let char = code[i];
|
|
165
|
+
let next = code[i + 1];
|
|
166
|
+
|
|
167
|
+
// Skip single line comments
|
|
168
|
+
if (char === '/' && next === '/') {
|
|
169
|
+
i = code.indexOf('\n', i);
|
|
170
|
+
if (i === -1) break;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
// Skip multi-line comments
|
|
174
|
+
if (char === '/' && next === '*') {
|
|
175
|
+
i = code.indexOf('*'+'/', i + 2);
|
|
176
|
+
if (i === -1) break;
|
|
177
|
+
i += 2;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
// Skip strings and template literals
|
|
181
|
+
if (char === "'" || char === '"' || char === '`') {
|
|
182
|
+
let quote = char;
|
|
183
|
+
i++;
|
|
184
|
+
while (i < code.length) {
|
|
185
|
+
if (code[i] === '\\') i += 2;
|
|
186
|
+
else if (code[i] === quote) { i++; break; }
|
|
187
|
+
else i++;
|
|
188
|
+
}
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
// Skip regex literals (simple heuristic)
|
|
192
|
+
if (char === '/') {
|
|
193
|
+
let prev = code.slice(Math.max(0, i - 10), i).trim();
|
|
194
|
+
// If / is preceded by something that indicates an operator or start of expression
|
|
195
|
+
if (/[=(,;:[!&|?]$|return$|yield$|case$/.test(prev)) {
|
|
196
|
+
i++;
|
|
197
|
+
while (i < code.length) {
|
|
198
|
+
if (code[i] === '\\') i += 2;
|
|
199
|
+
else if (code[i] === '[') { // Skip character classes
|
|
200
|
+
i++;
|
|
201
|
+
while (i < code.length && code[i] !== ']') {
|
|
202
|
+
if (code[i] === '\\') i += 2;
|
|
203
|
+
else i++;
|
|
204
|
+
}
|
|
205
|
+
i++;
|
|
206
|
+
}
|
|
207
|
+
else if (code[i] === '/') { i++; break; }
|
|
208
|
+
else i++;
|
|
209
|
+
}
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Check for h(this)`
|
|
214
|
+
if (char === 'h' && code.slice(i, i + 8) === 'h(this)`') {
|
|
215
|
+
i += 8;
|
|
216
|
+
// We are now inside the template literal.
|
|
217
|
+
// Skip whitespace and HTML comments
|
|
218
|
+
while (i < code.length) {
|
|
219
|
+
// Skip JS template literal end (shouldn't happen before tag, but for safety)
|
|
220
|
+
if (code[i] === '`') return null;
|
|
221
|
+
|
|
222
|
+
// Skip whitespace
|
|
223
|
+
if (/\s/.test(code[i])) { i++; continue; }
|
|
224
|
+
|
|
225
|
+
// Skip HTML comments <!-- ... -->
|
|
226
|
+
if (code.slice(i, i + 4) === '<!--') {
|
|
227
|
+
i = code.indexOf('-->', i + 4);
|
|
228
|
+
if (i === -1) return null;
|
|
229
|
+
i += 3;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Find the first tag
|
|
234
|
+
if (code[i] === '<') {
|
|
235
|
+
let start = ++i;
|
|
236
|
+
while (i < code.length && /[a-zA-Z0-9-]/.test(code[i])) i++;
|
|
237
|
+
return code.slice(start, i);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// If we encounter anything else (like text before a tag),
|
|
241
|
+
// we can keep looking or return null depending on how strict we want to be.
|
|
242
|
+
// For now, let's just skip non-tag characters.
|
|
243
|
+
i++;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
i++;
|
|
247
|
+
}
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
*/
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Assign fields from `src` to `dest` if they exist in `dest` and their names are not in the `ignore` list.
|
|
256
|
+
* When a value in `src` is a string and the existing value in `dest` is a boolean, number, or Date,
|
|
257
|
+
* it will be converted to that type.
|
|
258
|
+
* This is often used in class constructors that accept an object of arguments.
|
|
259
|
+
* @param {object} dest
|
|
260
|
+
* @param {?object} src
|
|
261
|
+
* @param {string[]} [ignore=[]] */
|
|
262
|
+
export function assignFields(dest, src, ignore=[]) {
|
|
263
|
+
for (let name in src || {}) {
|
|
264
|
+
if (name in dest && !ignore.includes(name)) {
|
|
265
|
+
const descriptor = Object.getOwnPropertyDescriptor(dest, name)
|
|
266
|
+
|| Object.getOwnPropertyDescriptor(Object.getPrototypeOf(dest), name); // Also find (parent?) setters. Is this necssary?
|
|
267
|
+
if (!descriptor || descriptor.writable || descriptor.set) {
|
|
268
|
+
let srcVal = src[name];
|
|
269
|
+
let destVal = dest[name];
|
|
270
|
+
if (typeof src[name] === 'string') {
|
|
271
|
+
if (typeof destVal === 'boolean') // empty string (when an attribute is present with no value) is true
|
|
272
|
+
dest[name] = ![false, 'false', 0, '0'].includes(srcVal);
|
|
273
|
+
else if (typeof destVal === 'number')
|
|
274
|
+
dest[name] = Number(srcVal);
|
|
275
|
+
else if (destVal instanceof Date) {
|
|
276
|
+
dest[name] = new Date(srcVal); // TODO: read it as UTC 0 by default.
|
|
277
|
+
}
|
|
278
|
+
else
|
|
279
|
+
dest[name] = srcVal;
|
|
280
|
+
}
|
|
281
|
+
else
|
|
282
|
+
dest[name] = srcVal;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
148
286
|
}
|
package/src/Template.js
CHANGED