solarite 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/benchmarks/naive/Solarite.min.js +4 -0
- package/benchmarks/naive/index.html +14 -0
- package/benchmarks/naive/main.js +339 -0
- package/benchmarks/naive/package-lock.json +13 -0
- package/benchmarks/naive/package.json +23 -0
- package/benchmarks/readme.md +48 -0
- package/build/build.bat +2 -2
- package/build/build.js +1 -1
- package/dist/Solarite-debug.js +1344 -1532
- package/dist/Solarite.js +1298 -1334
- package/dist/Solarite.min.js +3 -3
- package/dist/udomdiff-license.txt +18 -0
- package/docs/index.md +440 -130
- package/docs/js/Playground.js +1 -1
- package/docs/js/codemirror/codemirror6.js +3683 -3206
- package/docs/js/codemirror/themeSolarIce.js +1 -1
- package/docs/js/documentation.js +1 -1
- package/docs/js/ui/CodeEditor.js +183 -45
- package/docs/js/ui/FlexResizer.js +14 -3
- package/docs/js/util/Errors.js +11 -0
- package/docs/media/documentation.css +6 -3
- package/index.html +449 -30
- package/package.json +1 -1
- package/readme.md +1 -1
- package/src/solarite/ExprPath.js +349 -151
- package/src/solarite/Globals.js +43 -1
- package/src/solarite/NodeGroup.js +275 -293
- package/src/solarite/Shell.js +26 -28
- package/src/solarite/Solarite.js +12 -0
- package/src/solarite/Template.js +55 -128
- package/src/solarite/Util.js +131 -7
- package/src/solarite/createSolarite.js +14 -19
- package/src/solarite/getArg.js +1 -1
- package/src/solarite/hash.js +18 -35
- package/src/solarite/r.js +127 -127
- package/src/solarite/watch3.js +18 -11
- package/src/{solarite → unused}/NodeGroupManager.js +81 -109
- package/src/{solarite → unused}/watch.js +1 -1
- package/src/{solarite → unused}/watch2.js +1 -2
- package/src/{solarite → util}/MultiValueMap.js +18 -11
- package/src/util/WeakArray.js +33 -0
- package/tests/Solarite.test.js +862 -167
- package/tests/index.html +4 -2
- package/tests/run.bat +1 -1
- package/deno.lock +0 -176
package/tests/Solarite.test.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
// noinspection DuplicatedCode
|
|
2
2
|
|
|
3
|
+
// Broken tests will be annotated with FIXME
|
|
4
|
+
|
|
3
5
|
import {camelToDashes, htmlContext} from "../src/solarite/Util.js";
|
|
4
6
|
//import {watchGet, watchSet} from "../src/solarite/watch.js";
|
|
5
7
|
|
|
6
8
|
import {Solarite, r, getArg} from '../src/solarite/Solarite.js';
|
|
7
9
|
//import {Solarite, r, getArg} from '../dist/Solarite.min.js'; // This will help the Benchmark test warm up.
|
|
8
|
-
import {watch} from "../src/solarite/watch2.js";
|
|
10
|
+
//import {watch} from "../src/solarite/watch2.js";
|
|
9
11
|
import watch3 from "../src/solarite/watch3.js";
|
|
10
|
-
import NodeGroupManager from "../src/solarite/NodeGroupManager.js";
|
|
12
|
+
//import NodeGroupManager from "../src/solarite/NodeGroupManager.js";
|
|
11
13
|
import NodeGroup from "../src/solarite/NodeGroup.js";
|
|
12
14
|
import Template from "../src/solarite/Template.js";
|
|
13
15
|
import Shell from "../src/solarite/Shell.js";
|
|
14
16
|
|
|
15
17
|
import Testimony, {assert} from './Testimony.js';
|
|
16
18
|
|
|
17
|
-
|
|
18
19
|
// This function is used by the various tests.
|
|
19
20
|
window.getHtml = (item, includeComments=false) => {
|
|
20
21
|
if (!item)
|
|
@@ -33,7 +34,7 @@ window.getHtml = (item, includeComments=false) => {
|
|
|
33
34
|
if (!includeComments)
|
|
34
35
|
item = item.filter(n => n.nodeType !==8)
|
|
35
36
|
|
|
36
|
-
result = item.map(n => n.nodeType === 8 ? `<!--${n.textContent}-->` : n.outerHTML || n.textContent).join('|')
|
|
37
|
+
result = item.map(n => n.nodeType === 8 ? `<!--${n.textContent}-->` : n.outerHTML || n.textContent).join('|');
|
|
37
38
|
}
|
|
38
39
|
else
|
|
39
40
|
result = item.outerHTML || item.textContent
|
|
@@ -46,24 +47,29 @@ window.getHtml = (item, includeComments=false) => {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
|
|
50
|
+
|
|
51
|
+
//<editor-fold desc="shell">
|
|
52
|
+
/* ┌─────────────────╮
|
|
53
|
+
* | Shell |
|
|
54
|
+
* └─────────────────╯*/
|
|
49
55
|
Testimony.test('Solarite.Shell.empty', () => {
|
|
50
56
|
let shell = new Shell(['', ''])
|
|
51
|
-
assert.eq(getHtml(shell, true), '<!--
|
|
57
|
+
assert.eq(getHtml(shell, true), '<!--ExprPath:0-->|<!--ExprPathEnd:0-->')
|
|
52
58
|
});
|
|
53
59
|
|
|
54
60
|
Testimony.test('Solarite.Shell.paragraph', () => {
|
|
55
61
|
let shell = new Shell(['<p>', '</p>'])
|
|
56
|
-
assert.eq(getHtml(shell, true), '<p><!--
|
|
62
|
+
assert.eq(getHtml(shell, true), '<p><!--ExprPath:0--><!--ExprPathEnd:0--></p>')
|
|
57
63
|
});
|
|
58
64
|
|
|
59
65
|
Testimony.test('Solarite.Shell.nodeBefore', () => {
|
|
60
66
|
let shell = new Shell(['a', ''])
|
|
61
|
-
assert.eq(getHtml(shell, true), 'a|<!--
|
|
67
|
+
assert.eq(getHtml(shell, true), 'a|<!--ExprPathEnd:0-->')
|
|
62
68
|
});
|
|
63
69
|
|
|
64
70
|
Testimony.test('Solarite.Shell.nodeAfter', () => {
|
|
65
71
|
let shell = new Shell(['', 'b'])
|
|
66
|
-
assert.eq(getHtml(shell, true), '<!--
|
|
72
|
+
assert.eq(getHtml(shell, true), '<!--ExprPath:0-->|b')
|
|
67
73
|
});
|
|
68
74
|
|
|
69
75
|
Testimony.test('Solarite.Shell.nodeBeforeAfter', () => {
|
|
@@ -73,12 +79,12 @@ Testimony.test('Solarite.Shell.nodeBeforeAfter', () => {
|
|
|
73
79
|
|
|
74
80
|
Testimony.test('Solarite.Shell.emptyTwoPaths', () => {
|
|
75
81
|
let shell = new Shell(['', '', ''])
|
|
76
|
-
assert.eq(getHtml(shell, true), '<!--
|
|
82
|
+
assert.eq(getHtml(shell, true), '<!--ExprPath:0-->|<!--ExprPathEnd:0-->|<!--ExprPathEnd:1-->')
|
|
77
83
|
});
|
|
78
84
|
|
|
79
85
|
Testimony.test('Solarite.Shell.nodeBetweenPaths', () => {
|
|
80
86
|
let shell = new Shell(['', 'a', ''])
|
|
81
|
-
assert.eq(getHtml(shell, true), '<!--
|
|
87
|
+
assert.eq(getHtml(shell, true), '<!--ExprPath:0-->|a|<!--ExprPathEnd:1-->')
|
|
82
88
|
});
|
|
83
89
|
|
|
84
90
|
Testimony.test('Solarite.Shell.nodesAroundPaths', () => {
|
|
@@ -88,7 +94,7 @@ Testimony.test('Solarite.Shell.nodesAroundPaths', () => {
|
|
|
88
94
|
|
|
89
95
|
Testimony.test('Solarite.Shell.emptyTwoPathsNested', () => {
|
|
90
96
|
let shell = new Shell(['<p>', '', '</p>'])
|
|
91
|
-
assert.eq(getHtml(shell, true), '<p><!--
|
|
97
|
+
assert.eq(getHtml(shell, true), '<p><!--ExprPath:0--><!--ExprPathEnd:0--><!--ExprPathEnd:1--></p>')
|
|
92
98
|
});
|
|
93
99
|
|
|
94
100
|
Testimony.test('Solarite.Shell.nodesAroundPathsNested', () => {
|
|
@@ -105,10 +111,17 @@ Testimony.test('Solarite.Shell.nodesAroundPathsNested', () => {
|
|
|
105
111
|
|
|
106
112
|
|
|
107
113
|
|
|
114
|
+
//</editor-fold>
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
//<editor-fold desc="nodegroup">
|
|
119
|
+
/* ┌─────────────────╮
|
|
120
|
+
* | NodeGroup |
|
|
121
|
+
* └─────────────────╯*/
|
|
108
122
|
Testimony.test('Solarite.NodeGroup.empty', () => {
|
|
109
|
-
let ngm = new NodeGroupManager(document.body);
|
|
110
123
|
|
|
111
|
-
let ng = new NodeGroup(new Template([``], [])
|
|
124
|
+
let ng = new NodeGroup(new Template([``], []))
|
|
112
125
|
assert.eq(getHtml(ng), '')
|
|
113
126
|
|
|
114
127
|
ng.applyExprs([])
|
|
@@ -117,9 +130,8 @@ Testimony.test('Solarite.NodeGroup.empty', () => {
|
|
|
117
130
|
|
|
118
131
|
|
|
119
132
|
Testimony.test('Solarite.NodeGroup.oneExpr', () => {
|
|
120
|
-
let ngm = new NodeGroupManager(document.body);
|
|
121
133
|
|
|
122
|
-
let ng = new NodeGroup(new Template([``, ``], ['1'])
|
|
134
|
+
let ng = new NodeGroup(new Template([``, ``], ['1']))
|
|
123
135
|
assert.eq(getHtml(ng), '1')
|
|
124
136
|
|
|
125
137
|
ng.applyExprs([2])
|
|
@@ -130,8 +142,7 @@ Testimony.test('Solarite.NodeGroup.oneExpr', () => {
|
|
|
130
142
|
});
|
|
131
143
|
|
|
132
144
|
Testimony.test('Solarite.NodeGroup.emptyAdjacent', () => {
|
|
133
|
-
let
|
|
134
|
-
let ng = new NodeGroup(new Template([``, ``, ``], ['1', '2']), ngm)
|
|
145
|
+
let ng = new NodeGroup(new Template([``, ``, ``], ['1', '2']))
|
|
135
146
|
ng.verify();
|
|
136
147
|
|
|
137
148
|
assert.eq(getHtml(ng), '1|2')
|
|
@@ -145,8 +156,7 @@ Testimony.test('Solarite.NodeGroup.emptyAdjacent', () => {
|
|
|
145
156
|
|
|
146
157
|
|
|
147
158
|
Testimony.test('Solarite.NodeGroup.paragraph', () => {
|
|
148
|
-
let
|
|
149
|
-
let ng = new NodeGroup(new Template(['<p>', '</p>'], ['1']), ngm)
|
|
159
|
+
let ng = new NodeGroup(new Template(['<p>', '</p>'], ['1']))
|
|
150
160
|
assert.eq(getHtml(ng), '<p>1</p>')
|
|
151
161
|
|
|
152
162
|
ng.applyExprs([2])
|
|
@@ -157,10 +167,9 @@ Testimony.test('Solarite.NodeGroup.paragraph', () => {
|
|
|
157
167
|
});
|
|
158
168
|
|
|
159
169
|
Testimony.test('Solarite.NodeGroup.node', () => {
|
|
160
|
-
let ngm = new NodeGroupManager(document.body);
|
|
161
170
|
let a = r('<p>a</p>')
|
|
162
171
|
let b = r('<p>b</p>')
|
|
163
|
-
let ng = new NodeGroup(new Template(['<div>', '</div>'], [a])
|
|
172
|
+
let ng = new NodeGroup(new Template(['<div>', '</div>'], [a]))
|
|
164
173
|
|
|
165
174
|
assert.eq(getHtml(ng), '<div><p>a</p></div>')
|
|
166
175
|
|
|
@@ -175,10 +184,9 @@ Testimony.test('Solarite.NodeGroup.node', () => {
|
|
|
175
184
|
});
|
|
176
185
|
|
|
177
186
|
Testimony.test('Solarite.NodeGroup._nodeSwap', () => {
|
|
178
|
-
let ngm = new NodeGroupManager(document.body);
|
|
179
187
|
let a = r('<p>a</p>')
|
|
180
188
|
let b = r('<p>b</p>')
|
|
181
|
-
let ng = new NodeGroup(new Template(['<div>', '', '</div>'], [a, b])
|
|
189
|
+
let ng = new NodeGroup(new Template(['<div>', '', '</div>'], [a, b]))
|
|
182
190
|
document.body.append(ng.startNode)
|
|
183
191
|
|
|
184
192
|
assert.eq(getHtml(ng), '<div><p>a</p><p>b</p></div>')
|
|
@@ -189,10 +197,9 @@ Testimony.test('Solarite.NodeGroup._nodeSwap', () => {
|
|
|
189
197
|
|
|
190
198
|
|
|
191
199
|
Testimony.test('Solarite.NodeGroup.arrayReverse', () => {
|
|
192
|
-
let ngm = new NodeGroupManager(document.body);
|
|
193
200
|
let list = [r('a'), r('b')];
|
|
194
201
|
|
|
195
|
-
let ng = new NodeGroup(new Template(['<div>', '</div>'], [list])
|
|
202
|
+
let ng = new NodeGroup(new Template(['<div>', '</div>'], [list]))
|
|
196
203
|
ng.verify();
|
|
197
204
|
assert(getHtml(ng), '<div>ab</div')
|
|
198
205
|
|
|
@@ -200,7 +207,14 @@ Testimony.test('Solarite.NodeGroup.arrayReverse', () => {
|
|
|
200
207
|
ng.applyExprs([list])
|
|
201
208
|
assert(getHtml(ng), '<div>ba</div')
|
|
202
209
|
});
|
|
210
|
+
//</editor-fold>
|
|
211
|
+
|
|
212
|
+
|
|
203
213
|
|
|
214
|
+
//<editor-fold desc="util">
|
|
215
|
+
/* ┌─────────────────╮
|
|
216
|
+
* | Util |
|
|
217
|
+
* └─────────────────╯*/
|
|
204
218
|
|
|
205
219
|
Testimony.test('Solarite.Util.htmlContext', () => {
|
|
206
220
|
assert.eq(htmlContext('<div class="test'), htmlContext.Attribute)
|
|
@@ -222,7 +236,14 @@ Testimony.test('Solarite.Util.camelToDashes', () => {
|
|
|
222
236
|
assert.eq(camelToDashes('UIForm'), 'ui-form');
|
|
223
237
|
assert.eq(camelToDashes('A100'), 'a-100');
|
|
224
238
|
});
|
|
239
|
+
//</editor-fold>
|
|
225
240
|
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
//<editor-fold desc="basic">
|
|
244
|
+
/* ┌─────────────────╮
|
|
245
|
+
* | Basic |
|
|
246
|
+
* └─────────────────╯*/
|
|
226
247
|
Testimony.test('Solarite.basic.empty', () => {
|
|
227
248
|
class A extends HTMLElement {
|
|
228
249
|
constructor() {
|
|
@@ -344,20 +365,27 @@ Testimony.test('Solarite.basic.createElement', () => {
|
|
|
344
365
|
a.render();
|
|
345
366
|
assert.eq(getHtml(a), `<r-35><div>Hello!</div></r-35>`);
|
|
346
367
|
});
|
|
368
|
+
//</editor-fold>
|
|
347
369
|
|
|
348
370
|
|
|
349
|
-
|
|
371
|
+
|
|
372
|
+
//<editor-fold desc="expr">
|
|
373
|
+
/* ┌─────────────────╮
|
|
374
|
+
* | Expr |
|
|
375
|
+
* └─────────────────╯*/
|
|
350
376
|
Testimony.test('Solarite.expr.staticString', () => {
|
|
351
|
-
class R40 extends
|
|
377
|
+
class R40 extends HTMLElement {
|
|
352
378
|
render() {
|
|
353
|
-
r(this)`Solarite ${'
|
|
379
|
+
r(this)`Solarite ${'Test'} Component`
|
|
354
380
|
}
|
|
355
381
|
}
|
|
382
|
+
customElements.define('r-40', R40);
|
|
356
383
|
|
|
357
384
|
let a = new R40();
|
|
385
|
+
a.render();
|
|
358
386
|
document.body.append(a);
|
|
359
387
|
|
|
360
|
-
assert.eq(getHtml(a), '<r-40>Solarite
|
|
388
|
+
assert.eq(getHtml(a), '<r-40>Solarite Test Component</r-40>');
|
|
361
389
|
|
|
362
390
|
a.remove();
|
|
363
391
|
});
|
|
@@ -381,7 +409,6 @@ Testimony.test('Solarite.expr.htmlString', () => {
|
|
|
381
409
|
assert.eq(getHtml(a), '<r-42>This text is <b>Bold</b>!</r-42>');
|
|
382
410
|
});
|
|
383
411
|
|
|
384
|
-
|
|
385
412
|
Testimony.test('Solarite.expr.table', () => {
|
|
386
413
|
|
|
387
414
|
class R43 extends Solarite {
|
|
@@ -408,7 +435,13 @@ Testimony.test('Solarite.expr.documentFragment', () => {
|
|
|
408
435
|
}
|
|
409
436
|
}
|
|
410
437
|
|
|
411
|
-
let a = new R44(
|
|
438
|
+
let a = new R44(); // auto render on construct.
|
|
439
|
+
|
|
440
|
+
a.render();
|
|
441
|
+
assert.eq(getHtml(a), '<r-44>This text is <b>Bold</b><i>Italic</i>!</r-44>');
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
a.render();
|
|
412
445
|
assert.eq(getHtml(a), '<r-44>This text is <b>Bold</b><i>Italic</i>!</r-44>');
|
|
413
446
|
});
|
|
414
447
|
|
|
@@ -637,7 +670,6 @@ Testimony.test('Solarite.expr.staticElement', () => {
|
|
|
637
670
|
assert.eq(getHtml(a), '<r-74>Field: <input></r-74>');
|
|
638
671
|
});
|
|
639
672
|
|
|
640
|
-
|
|
641
673
|
Testimony.test('Solarite.expr.varText', () => {
|
|
642
674
|
class A extends Solarite {
|
|
643
675
|
value = 'Apple';
|
|
@@ -663,8 +695,6 @@ Testimony.test('Solarite.expr.varText', () => {
|
|
|
663
695
|
assert.eq(a.childNodes.length, 3);
|
|
664
696
|
});
|
|
665
697
|
|
|
666
|
-
|
|
667
|
-
|
|
668
698
|
Testimony.test('Solarite.expr.cyclicRef', () => {
|
|
669
699
|
|
|
670
700
|
|
|
@@ -690,15 +720,14 @@ Testimony.test('Solarite.expr.cyclicRef', () => {
|
|
|
690
720
|
a.render();
|
|
691
721
|
assert.eq(getHtml(a), '<r-100>The fruit is Cherry!</r-100>');
|
|
692
722
|
});
|
|
723
|
+
//</editor-fold>
|
|
693
724
|
|
|
694
725
|
|
|
695
726
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
// Loop:
|
|
727
|
+
//<editor-fold desc="loop">
|
|
728
|
+
/* ┌─────────────────╮
|
|
729
|
+
* | Loop |
|
|
730
|
+
* └─────────────────╯*/
|
|
702
731
|
Testimony.test('Solarite.loop.strings', () => {
|
|
703
732
|
class A extends Solarite {
|
|
704
733
|
fruits = ['Apple', 'Banana'];
|
|
@@ -734,7 +763,6 @@ Testimony.test('Solarite.loop.strings', () => {
|
|
|
734
763
|
assert.eq(getHtml(a), '<r-200>Apple</r-200>');
|
|
735
764
|
});
|
|
736
765
|
|
|
737
|
-
|
|
738
766
|
Testimony.test('Solarite.loop.paragraphs', () => {
|
|
739
767
|
class A extends Solarite {
|
|
740
768
|
fruits = ['Apple', 'Banana'];
|
|
@@ -745,7 +773,8 @@ Testimony.test('Solarite.loop.paragraphs', () => {
|
|
|
745
773
|
}
|
|
746
774
|
customElements.define('r-210', A);
|
|
747
775
|
let a = new A();
|
|
748
|
-
|
|
776
|
+
|
|
777
|
+
a.render();
|
|
749
778
|
|
|
750
779
|
assert.eq(getHtml(a), '<r-210><p>Apple</p><p>Banana</p></r-210>');
|
|
751
780
|
|
|
@@ -754,6 +783,7 @@ Testimony.test('Solarite.loop.paragraphs', () => {
|
|
|
754
783
|
assert.eq(getHtml(a), '<r-210><p>Apple</p><p>Banana</p><p>Cherry</p></r-210>');
|
|
755
784
|
|
|
756
785
|
a.fruits.pop();
|
|
786
|
+
window.debug = true;
|
|
757
787
|
a.render();
|
|
758
788
|
assert.eq(getHtml(a), '<r-210><p>Apple</p><p>Banana</p></r-210>');
|
|
759
789
|
|
|
@@ -772,8 +802,7 @@ Testimony.test('Solarite.loop.paragraphs', () => {
|
|
|
772
802
|
a.remove();
|
|
773
803
|
});
|
|
774
804
|
|
|
775
|
-
|
|
776
|
-
Testimony.test('Solarite.loop.paragraphsBefore', () => {
|
|
805
|
+
Testimony.test('Solarite.loop.paragraphsBefore', `Same as above, but with another element afterward.`, () => {
|
|
777
806
|
class A extends Solarite {
|
|
778
807
|
fruits = ['Apple', 'Banana'];
|
|
779
808
|
|
|
@@ -810,6 +839,54 @@ Testimony.test('Solarite.loop.paragraphsBefore', () => {
|
|
|
810
839
|
a.remove();
|
|
811
840
|
});
|
|
812
841
|
|
|
842
|
+
Testimony.test('Solarite.loop.continuity', `Make sure elements are reused in a consistent way.`, () => {
|
|
843
|
+
class A extends Solarite {
|
|
844
|
+
fruits = ['Apple', 'Banana'];
|
|
845
|
+
|
|
846
|
+
render() {
|
|
847
|
+
r(this)`${this.fruits.map(fruit => r`<p>${fruit}</p>`)}`
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
customElements.define('a-213', A);
|
|
851
|
+
let a = new A();
|
|
852
|
+
document.body.append(a);
|
|
853
|
+
a.render();
|
|
854
|
+
assert.eq(getHtml(a), '<a-213><p>Apple</p><p>Banana</p></a-213>');
|
|
855
|
+
|
|
856
|
+
let apple = a.children[0];
|
|
857
|
+
let banana = a.children[1];
|
|
858
|
+
a.fruits.shift();
|
|
859
|
+
a.render();
|
|
860
|
+
assert.eq(getHtml(a), '<a-213><p>Banana</p></a-213>');
|
|
861
|
+
assert.eq(a.children[0], banana);
|
|
862
|
+
|
|
863
|
+
a.fruits.pop();
|
|
864
|
+
a.render();
|
|
865
|
+
assert.eq(getHtml(a), '<a-213></a-213>');
|
|
866
|
+
|
|
867
|
+
// We get back the same element.
|
|
868
|
+
a.fruits.push('Apple');
|
|
869
|
+
a.render();
|
|
870
|
+
assert.eq(getHtml(a), '<a-213><p>Apple</p></a-213>');
|
|
871
|
+
assert.eq(a.children[0], apple);
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
a.fruits.push('Banana');
|
|
875
|
+
a.render();
|
|
876
|
+
assert.eq(getHtml(a), '<a-213><p>Apple</p><p>Banana</p></a-213>');
|
|
877
|
+
assert.eq(a.children[0], apple);
|
|
878
|
+
assert.eq(a.children[1], banana);
|
|
879
|
+
|
|
880
|
+
// Make sure we maintain continuity after adding to the beginning.
|
|
881
|
+
a.fruits.unshift('Cherry');
|
|
882
|
+
a.render();
|
|
883
|
+
assert.eq(getHtml(a), '<a-213><p>Cherry</p><p>Apple</p><p>Banana</p></a-213>');
|
|
884
|
+
assert.eq(a.children[1], apple);
|
|
885
|
+
assert.eq(a.children[2], banana);
|
|
886
|
+
|
|
887
|
+
a.remove();
|
|
888
|
+
});
|
|
889
|
+
|
|
813
890
|
Testimony.test('Solarite.loop.eventBindings', async () => {
|
|
814
891
|
await new Promise((resolve, reject) => {
|
|
815
892
|
let callCount = 0;
|
|
@@ -844,7 +921,7 @@ Testimony.test('Solarite.loop.eventBindings', async () => {
|
|
|
844
921
|
|
|
845
922
|
});
|
|
846
923
|
|
|
847
|
-
|
|
924
|
+
// TODO: Why is this called pathCache? What does it test?
|
|
848
925
|
Testimony.test('Solarite.loop.pathCache', () => {
|
|
849
926
|
|
|
850
927
|
class R216 extends Solarite {
|
|
@@ -861,15 +938,13 @@ Testimony.test('Solarite.loop.pathCache', () => {
|
|
|
861
938
|
}
|
|
862
939
|
|
|
863
940
|
let a = new R216();
|
|
864
|
-
document.body.append(a);
|
|
865
941
|
a.render();
|
|
866
942
|
assert.eq(getHtml(a), `<r-216><p>Item</p><p>Item</p></r-216>`);
|
|
867
943
|
|
|
868
944
|
a.fruits.shift();
|
|
945
|
+
window.debug = true;
|
|
869
946
|
a.render();
|
|
870
947
|
assert.eq(getHtml(a), `<r-216><p>Item</p></r-216>`);
|
|
871
|
-
|
|
872
|
-
a.remove();
|
|
873
948
|
});
|
|
874
949
|
|
|
875
950
|
Testimony.test('Solarite.loop.nested', () => {
|
|
@@ -919,6 +994,7 @@ Testimony.test('Solarite.loop.nested', () => {
|
|
|
919
994
|
|
|
920
995
|
a.pets.reverse();
|
|
921
996
|
a.fruits.reverse();
|
|
997
|
+
window.debug = true;
|
|
922
998
|
a.render();
|
|
923
999
|
assert.eq(getHtml(a), `<r-220><p>Bird eats Apricot</p><p>Bird eats Banana</p><p>Cat eats Apricot</p><p>Cat eats Banana</p></r-220>`);
|
|
924
1000
|
|
|
@@ -994,7 +1070,6 @@ Testimony.test('Solarite.loop.nested2', () => {
|
|
|
994
1070
|
a.remove();
|
|
995
1071
|
});
|
|
996
1072
|
|
|
997
|
-
|
|
998
1073
|
Testimony.test('Solarite.loop.nested3', `Move items from one sublist to another.`, () => {
|
|
999
1074
|
|
|
1000
1075
|
class A225 extends Solarite {
|
|
@@ -1016,6 +1091,7 @@ Testimony.test('Solarite.loop.nested3', `Move items from one sublist to another.
|
|
|
1016
1091
|
|
|
1017
1092
|
let a = new A225();
|
|
1018
1093
|
document.body.append(a);
|
|
1094
|
+
window.debug = true;
|
|
1019
1095
|
a.render();
|
|
1020
1096
|
|
|
1021
1097
|
let cherry = a.fruitGroups[1].pop();
|
|
@@ -1025,15 +1101,12 @@ Testimony.test('Solarite.loop.nested3', `Move items from one sublist to another.
|
|
|
1025
1101
|
|
|
1026
1102
|
let banana = a.fruitGroups[1].pop();
|
|
1027
1103
|
a.fruitGroups[0].push(banana);
|
|
1028
|
-
//window.debug = true;
|
|
1029
1104
|
a.render();
|
|
1030
|
-
|
|
1105
|
+
|
|
1031
1106
|
window.verify = false;
|
|
1032
1107
|
a.remove();
|
|
1033
1108
|
});
|
|
1034
1109
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
1110
|
// Tried to make a simpler version of nested3, but it works fine:
|
|
1038
1111
|
Testimony.test('Solarite.loop.nested4', () => {
|
|
1039
1112
|
|
|
@@ -1068,14 +1141,6 @@ Testimony.test('Solarite.loop.nested4', () => {
|
|
|
1068
1141
|
a.remove();
|
|
1069
1142
|
});
|
|
1070
1143
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
1144
|
Testimony.test('Solarite.loop.nested5', () => {
|
|
1080
1145
|
|
|
1081
1146
|
// This test was originally created by reducing a failure in production code
|
|
@@ -1095,7 +1160,7 @@ Testimony.test('Solarite.loop.nested5', () => {
|
|
|
1095
1160
|
]
|
|
1096
1161
|
|
|
1097
1162
|
render() {
|
|
1098
|
-
this
|
|
1163
|
+
r(this)`
|
|
1099
1164
|
<a-227>${this.boxes.map(item =>
|
|
1100
1165
|
r`${item.map(item2 =>
|
|
1101
1166
|
r`<div title=${v}>${item2}</div>`
|
|
@@ -1120,28 +1185,12 @@ Testimony.test('Solarite.loop.nested5', () => {
|
|
|
1120
1185
|
]
|
|
1121
1186
|
a.render();
|
|
1122
1187
|
|
|
1123
|
-
assert.eq(a.outerHTML, `<a-227><!--
|
|
1188
|
+
assert.eq(a.outerHTML, `<a-227><!--ExprPath:0--><!--ExprPath:0--><div title="F2"><!--ExprPath:1-->A<!--ExprPathEnd:1--></div><div title="F2"><!--ExprPath:1-->B<!--ExprPathEnd:1--></div><!--ExprPathEnd:0--><!--ExprPath:0--><div title="F2"><!--ExprPath:1-->A<!--ExprPathEnd:1--></div><!--ExprPathEnd:0--><!--ExprPathEnd:0--></a-227>`);
|
|
1124
1189
|
|
|
1125
1190
|
window.verify = false;
|
|
1126
1191
|
a.remove();
|
|
1127
1192
|
});
|
|
1128
1193
|
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
1194
|
Testimony.test('Solarite.loop.nestedConditional', () => {
|
|
1146
1195
|
|
|
1147
1196
|
let isGoodBoy = true;
|
|
@@ -1226,7 +1275,6 @@ Testimony.test('Solarite.loop.conditionalNested', () => {
|
|
|
1226
1275
|
a.remove();
|
|
1227
1276
|
});
|
|
1228
1277
|
|
|
1229
|
-
|
|
1230
1278
|
Testimony.test('Solarite.loop.tripleNested', 'Triple nested grid', () => {
|
|
1231
1279
|
|
|
1232
1280
|
class R250 extends Solarite {
|
|
@@ -1292,12 +1340,15 @@ Testimony.test('Solarite.loop.tripleNested', 'Triple nested grid', () => {
|
|
|
1292
1340
|
a.remove();
|
|
1293
1341
|
});
|
|
1294
1342
|
|
|
1343
|
+
//</editor-fold>
|
|
1295
1344
|
|
|
1296
1345
|
|
|
1297
1346
|
|
|
1298
1347
|
|
|
1299
|
-
|
|
1300
|
-
|
|
1348
|
+
//<editor-fold desc="embed">
|
|
1349
|
+
/* ┌─────────────────╮
|
|
1350
|
+
* | Embed |
|
|
1351
|
+
* └─────────────────╯*/
|
|
1301
1352
|
|
|
1302
1353
|
Testimony.test('Solarite.embed.styleStatic', () => {
|
|
1303
1354
|
let count = 0;
|
|
@@ -1350,7 +1401,6 @@ Testimony.test('Solarite.embed.optionsNoStyles', () => {
|
|
|
1350
1401
|
a.remove();
|
|
1351
1402
|
});
|
|
1352
1403
|
|
|
1353
|
-
|
|
1354
1404
|
Testimony.test('Solarite.embed.styleDynamic', () => {
|
|
1355
1405
|
let style1 = `:host { color: red }`
|
|
1356
1406
|
let style2 = `:host { font-weight: bold }`
|
|
@@ -1424,10 +1474,6 @@ Testimony.test('Solarite.embed.styleDynamicTag', () => {
|
|
|
1424
1474
|
a.remove();
|
|
1425
1475
|
});
|
|
1426
1476
|
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
1477
|
Testimony.test('Solarite.embed.svg', () => {
|
|
1432
1478
|
class R330 extends Solarite {
|
|
1433
1479
|
render() {
|
|
@@ -1505,8 +1551,16 @@ Testimony.test('Solarite.embed._scriptDynamic', () => {
|
|
|
1505
1551
|
delete window.scriptStaticCount;
|
|
1506
1552
|
});
|
|
1507
1553
|
|
|
1554
|
+
//</editor-fold>
|
|
1555
|
+
|
|
1508
1556
|
|
|
1509
1557
|
|
|
1558
|
+
|
|
1559
|
+
//<editor-fold desc="attrib">
|
|
1560
|
+
/* ┌─────────────────╮
|
|
1561
|
+
* | Attrib |
|
|
1562
|
+
* └─────────────────╯*/
|
|
1563
|
+
|
|
1510
1564
|
Testimony.test('Solarite.attrib.single', () => {
|
|
1511
1565
|
|
|
1512
1566
|
let val = 'one';
|
|
@@ -1576,7 +1630,6 @@ Testimony.test('Solarite.attrib.double', () => {
|
|
|
1576
1630
|
assert.eq(getHtml(a), `<r-420><div class="oneBtwoB">oneB</div></r-420>`)
|
|
1577
1631
|
});
|
|
1578
1632
|
|
|
1579
|
-
|
|
1580
1633
|
Testimony.test('Solarite.attrib.doubleAndText', () => {
|
|
1581
1634
|
|
|
1582
1635
|
let val1 = 'one';
|
|
@@ -1690,12 +1743,11 @@ Testimony.test('Solarite.attrib.toggle', () => {
|
|
|
1690
1743
|
assert.eq(getHtml(a), `<r-460><div></div></r-460>`)
|
|
1691
1744
|
});
|
|
1692
1745
|
|
|
1693
|
-
|
|
1694
1746
|
Testimony.test('Solarite.attrib.pseudoRoot', () => {
|
|
1695
1747
|
let title = 'Hello'
|
|
1696
1748
|
class R470 extends Solarite {
|
|
1697
1749
|
render() {
|
|
1698
|
-
this
|
|
1750
|
+
r(this)`<r-470 title="${title}">World</r-470>`
|
|
1699
1751
|
}
|
|
1700
1752
|
}
|
|
1701
1753
|
|
|
@@ -1713,7 +1765,6 @@ Testimony.test('Solarite.attrib.pseudoRoot', () => {
|
|
|
1713
1765
|
assert.eq(a.outerHTML, `<r-470>World</r-470>`)
|
|
1714
1766
|
});
|
|
1715
1767
|
|
|
1716
|
-
|
|
1717
1768
|
Testimony.test('Solarite.attrib.pseudoRoot2', 'Static attribute overrides.', () => {
|
|
1718
1769
|
let title = 'Hello'
|
|
1719
1770
|
class R472 extends Solarite {
|
|
@@ -1775,9 +1826,59 @@ Testimony.test('Solarite.attrib.multiple', '', () => {
|
|
|
1775
1826
|
assert.eq(getHtml(a), `<r-474><button onclick="" class="primary">Hello</button></r-474>`);
|
|
1776
1827
|
});
|
|
1777
1828
|
|
|
1829
|
+
Testimony.test('Solarite.attrib.ids1', () => {
|
|
1830
|
+
class R500 extends Solarite {
|
|
1831
|
+
one;
|
|
1832
|
+
render() {
|
|
1833
|
+
r(this)`<div data-id="one"></div>`;
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
let a = new R500();
|
|
1838
|
+
a.render();
|
|
1839
|
+
|
|
1840
|
+
assert(a.one.tagName === 'DIV')
|
|
1841
|
+
});
|
|
1842
|
+
|
|
1843
|
+
Testimony.test('Solarite.attrib.ids2', () => {
|
|
1844
|
+
class R510 extends Solarite {
|
|
1845
|
+
one;
|
|
1846
|
+
render() {
|
|
1847
|
+
r(this)`<div data-id="one"><p id="two"></p></div>`;
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
let a = new R510();
|
|
1852
|
+
a.render();
|
|
1853
|
+
|
|
1854
|
+
assert(a.one.tagName === 'DIV')
|
|
1855
|
+
assert(a.two.tagName === 'P')
|
|
1856
|
+
});
|
|
1857
|
+
|
|
1858
|
+
Testimony.test('Solarite.attrib.idsDelve', () => {
|
|
1859
|
+
class R520 extends Solarite {
|
|
1860
|
+
one;
|
|
1861
|
+
render() {
|
|
1862
|
+
r(this)`<div data-id="one"><p id="path.to.p"></p></div>`;
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
let a = new R520();
|
|
1867
|
+
a.render();
|
|
1868
|
+
|
|
1869
|
+
assert(a.one.tagName === 'DIV')
|
|
1870
|
+
assert(a.path.to.p.tagName === 'P')
|
|
1871
|
+
});
|
|
1872
|
+
//</editor-fold>
|
|
1873
|
+
|
|
1874
|
+
|
|
1778
1875
|
|
|
1779
1876
|
|
|
1780
|
-
|
|
1877
|
+
//<editor-fold desc="comments">
|
|
1878
|
+
/* ┌─────────────────╮
|
|
1879
|
+
* | comments |
|
|
1880
|
+
* └─────────────────╯*/
|
|
1881
|
+
Testimony.test('Solarite.comments.one', () => {
|
|
1781
1882
|
|
|
1782
1883
|
class A480 extends Solarite {
|
|
1783
1884
|
render() {
|
|
@@ -1792,7 +1893,7 @@ Testimony.test('Solarite.comments', () => {
|
|
|
1792
1893
|
a.remove();
|
|
1793
1894
|
});
|
|
1794
1895
|
|
|
1795
|
-
Testimony.test('Solarite.
|
|
1896
|
+
Testimony.test('Solarite.comments.two', () => {
|
|
1796
1897
|
|
|
1797
1898
|
class A482 extends Solarite {
|
|
1798
1899
|
render() {
|
|
@@ -1805,33 +1906,75 @@ Testimony.test('Solarite.comments2', () => {
|
|
|
1805
1906
|
assert.eq(getHtml(a), `<a-482><div>3</div></a-482>`)
|
|
1806
1907
|
a.remove();
|
|
1807
1908
|
});
|
|
1909
|
+
//</editor-fold>
|
|
1808
1910
|
|
|
1809
1911
|
|
|
1810
1912
|
|
|
1811
1913
|
|
|
1914
|
+
//<editor-fold desc="r">
|
|
1915
|
+
/* ┌─────────────────╮
|
|
1916
|
+
* | r |
|
|
1917
|
+
* └─────────────────╯*/
|
|
1918
|
+
Testimony.test('Solarite.r.staticElement', () => {
|
|
1919
|
+
let button = r(`<button>hi</button>`);
|
|
1920
|
+
assert(button instanceof HTMLElement); // Not a DocumentFragment
|
|
1921
|
+
assert.eq(getHtml(button), `<button>hi</button>`)
|
|
1922
|
+
})
|
|
1812
1923
|
|
|
1813
|
-
Testimony.test('Solarite.
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
}
|
|
1924
|
+
Testimony.test('Solarite.r.staticElement2', () => {
|
|
1925
|
+
let button = r(`
|
|
1926
|
+
<button>hi</button>`);
|
|
1927
|
+
assert(button instanceof HTMLElement); // Not a DocumentFragment
|
|
1928
|
+
assert.eq(getHtml(button), `<button>hi</button>`)
|
|
1929
|
+
})
|
|
1820
1930
|
|
|
1821
|
-
|
|
1822
|
-
|
|
1931
|
+
Testimony.test('Solarite.r.staticElement3', () => {
|
|
1932
|
+
let button = r(` <!-- comment -->
|
|
1933
|
+
<button>hi</button>`);
|
|
1934
|
+
assert(button instanceof HTMLElement); // Not a DocumentFragment
|
|
1935
|
+
assert.eq(getHtml(button), `<button>hi</button>`)
|
|
1936
|
+
})
|
|
1823
1937
|
|
|
1824
|
-
|
|
1938
|
+
Testimony.test('Solarite.r.staticElement4', () => {
|
|
1939
|
+
let button = r(` Hello`);
|
|
1940
|
+
assert(button instanceof Text);
|
|
1941
|
+
assert.eq(getHtml(button), ` Hello`)
|
|
1942
|
+
})
|
|
1943
|
+
|
|
1944
|
+
Testimony.test('Solarite.r.staticElement5', () => {
|
|
1945
|
+
let button = r(` <!--comment--> Hello`);
|
|
1946
|
+
assert(button instanceof Text);
|
|
1947
|
+
assert.eq(getHtml(button), ` Hello`)
|
|
1948
|
+
})
|
|
1949
|
+
|
|
1950
|
+
Testimony.test('Solarite.r.fragment', () => {
|
|
1951
|
+
let fragment = r(`Hello <button>hi</button>`);
|
|
1952
|
+
assert(fragment instanceof DocumentFragment);
|
|
1953
|
+
assert.eq(getHtml(fragment), `Hello |<button>hi</button>`)
|
|
1954
|
+
});
|
|
1955
|
+
|
|
1956
|
+
Testimony.test('Solarite.r.fragment2', () => {
|
|
1957
|
+
let fragment = r()`Hello <button>hi</button>`;
|
|
1958
|
+
assert(fragment instanceof DocumentFragment);
|
|
1959
|
+
assert.eq(getHtml(fragment), `Hello |<button>hi</button>`)
|
|
1825
1960
|
});
|
|
1826
1961
|
|
|
1827
|
-
Testimony.test('Solarite.r.
|
|
1962
|
+
Testimony.test('Solarite.r.staticElement3', () => {
|
|
1963
|
+
let button = r()`<button>hi</button>`;
|
|
1964
|
+
assert(button instanceof HTMLElement);
|
|
1965
|
+
assert.eq(getHtml(button), `<button>hi</button>`)
|
|
1966
|
+
});
|
|
1828
1967
|
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1968
|
+
Testimony.test('Solarite.r.staticElement4', () => {
|
|
1969
|
+
// with line return
|
|
1970
|
+
let button = r()`
|
|
1971
|
+
<button>hi</button>`;
|
|
1972
|
+
assert(button instanceof HTMLElement);
|
|
1973
|
+
assert.eq(getHtml(button), `<button>hi</button>`)
|
|
1832
1974
|
})
|
|
1833
1975
|
|
|
1834
1976
|
|
|
1977
|
+
|
|
1835
1978
|
Testimony.test('Solarite.r.element', () => {
|
|
1836
1979
|
let adjective = 'better'
|
|
1837
1980
|
let button = r()`<button>I'm a <b>${adjective}</b> button</button>`;
|
|
@@ -1839,56 +1982,193 @@ Testimony.test('Solarite.r.element', () => {
|
|
|
1839
1982
|
assert.eq(getHtml(button), `<button>I'm a <b>better</b> button</button>`)
|
|
1840
1983
|
})
|
|
1841
1984
|
|
|
1985
|
+
Testimony.test('Solarite.r.standalone1', () => {
|
|
1986
|
+
let button = r({
|
|
1987
|
+
count: 0,
|
|
1842
1988
|
|
|
1989
|
+
inc() {
|
|
1990
|
+
this.count++;
|
|
1991
|
+
this.render();
|
|
1992
|
+
},
|
|
1843
1993
|
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
// Pass a function to r() and it becomes the render() function.
|
|
1847
|
-
let result = r(
|
|
1848
|
-
() => r`<button onclick=${(ev, self)=>{count++; self.render()}}>I'm a ${count}X better button</button>`
|
|
1849
|
-
);
|
|
1850
|
-
result.inc = () => {
|
|
1851
|
-
count++;
|
|
1852
|
-
result.render();
|
|
1994
|
+
render() {
|
|
1995
|
+
r(this)`<button onclick=${this.inc}>I've been clicked ${this.count} times.</button>`
|
|
1853
1996
|
}
|
|
1854
|
-
|
|
1855
|
-
|
|
1997
|
+
});
|
|
1998
|
+
//document.body.append(button);
|
|
1856
1999
|
|
|
1857
|
-
|
|
1858
|
-
assert.eq(getHtml(button), `<button onclick="">I'm a 3X better button</button>`)
|
|
2000
|
+
assert.eq(getHtml(button), `<button onclick="">I've been clicked 0 times.</button>`)
|
|
1859
2001
|
|
|
1860
2002
|
button.inc();
|
|
1861
|
-
assert.eq(getHtml(button), `<button onclick="">I'
|
|
1862
|
-
})
|
|
2003
|
+
assert.eq(getHtml(button), `<button onclick="">I've been clicked 1 times.</button>`);
|
|
1863
2004
|
|
|
1864
|
-
|
|
2005
|
+
button.dispatchEvent(new MouseEvent('click'));
|
|
2006
|
+
assert.eq(getHtml(button), `<button onclick="">I've been clicked 2 times.</button>`);
|
|
1865
2007
|
|
|
1866
|
-
//
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
2008
|
+
//button.remove();
|
|
2009
|
+
});
|
|
2010
|
+
|
|
2011
|
+
Testimony.test('Solarite.r.standalone2', () => {
|
|
2012
|
+
let list = r({
|
|
2013
|
+
items: [],
|
|
2014
|
+
|
|
2015
|
+
add() {
|
|
2016
|
+
this.items.push('Item ' + this.items.length);
|
|
2017
|
+
this.render();
|
|
2018
|
+
},
|
|
2019
|
+
|
|
2020
|
+
render() {
|
|
2021
|
+
r(this)`
|
|
2022
|
+
<div>
|
|
2023
|
+
<button onclick=${this.add}>Add Item</button>
|
|
2024
|
+
<hr>
|
|
2025
|
+
${this.items.map(item => r`
|
|
2026
|
+
<p>${item}</p>
|
|
2027
|
+
`)}
|
|
2028
|
+
</div>`
|
|
1879
2029
|
}
|
|
1880
|
-
);
|
|
2030
|
+
});
|
|
1881
2031
|
|
|
1882
|
-
|
|
2032
|
+
//document.body.append(list);
|
|
1883
2033
|
|
|
1884
|
-
|
|
1885
|
-
|
|
2034
|
+
assert.eq(getHtml(list), `<div><button onclick="">Add Item</button><hr></div>`);
|
|
2035
|
+
|
|
2036
|
+
// At one point, rendering a standalone component the first time would re-render everything.
|
|
2037
|
+
// Here we make sure the hr element doesn't come back.
|
|
2038
|
+
list.querySelector('hr').remove();
|
|
2039
|
+
list.render();
|
|
2040
|
+
|
|
2041
|
+
assert.eq(getHtml(list), `<div><button onclick="">Add Item</button></div>`);
|
|
2042
|
+
|
|
2043
|
+
list.add();
|
|
2044
|
+
assert.eq(getHtml(list), `<div><button onclick="">Add Item</button><p>Item 0</p></div>`);
|
|
2045
|
+
|
|
2046
|
+
list.querySelector('button').dispatchEvent(new MouseEvent('click'));
|
|
2047
|
+
assert.eq(getHtml(list), `<div><button onclick="">Add Item</button><p>Item 0</p><p>Item 1</p></div>`);
|
|
2048
|
+
|
|
2049
|
+
//button.remove();
|
|
2050
|
+
});
|
|
2051
|
+
|
|
2052
|
+
Testimony.test('Solarite.r.standaloneId', "Test id's on standalone elmenets.", () => {
|
|
2053
|
+
let list = r({
|
|
2054
|
+
items: [],
|
|
2055
|
+
|
|
2056
|
+
add() {
|
|
2057
|
+
this.items.push('Item ' + this.items.length);
|
|
2058
|
+
this.render();
|
|
2059
|
+
},
|
|
2060
|
+
|
|
2061
|
+
render() {
|
|
2062
|
+
r(this)`
|
|
2063
|
+
<div>
|
|
2064
|
+
<button data-id="button" onclick=${this.add}>Add Item</button>
|
|
2065
|
+
</div>`
|
|
2066
|
+
}
|
|
2067
|
+
});
|
|
2068
|
+
|
|
2069
|
+
assert.eq(list.button.tagName, 'BUTTON');
|
|
2070
|
+
});
|
|
2071
|
+
|
|
2072
|
+
Testimony.test('Solarite.r.standaloneStyle', "Test id's on standalone elmenets.", () => {
|
|
2073
|
+
let box = r({
|
|
2074
|
+
render() {
|
|
2075
|
+
r(this)`
|
|
2076
|
+
<div>
|
|
2077
|
+
<style>:host { display: block; background: red; width: 20px; height: 20px }</style>
|
|
2078
|
+
</div>`
|
|
2079
|
+
}
|
|
2080
|
+
});
|
|
2081
|
+
|
|
2082
|
+
let styleId = box.getAttribute('data-style');
|
|
2083
|
+
assert.eq(box.firstElementChild.textContent, `div[data-style="${styleId}"] { display: block; background: red; width: 20px; height: 20px }`);
|
|
1886
2084
|
});
|
|
1887
2085
|
|
|
2086
|
+
Testimony.test('Solarite.r.standalone3', () => {
|
|
2087
|
+
|
|
2088
|
+
// Make sure a div inside a div doesn't replace the parent div.
|
|
2089
|
+
let list = r({
|
|
2090
|
+
items: [],
|
|
1888
2091
|
|
|
2092
|
+
render() {
|
|
2093
|
+
r(this)`
|
|
2094
|
+
<div>
|
|
2095
|
+
${this.items.map(item => r`
|
|
2096
|
+
<div>
|
|
2097
|
+
<input placeholder="Name" value=${item.name}>
|
|
2098
|
+
<input type="number" value=${item.qty}>
|
|
2099
|
+
<button onclick=${()=>this.removeItem(item)}>x</button>
|
|
2100
|
+
</div>
|
|
2101
|
+
`)}
|
|
2102
|
+
</div>`
|
|
2103
|
+
}
|
|
2104
|
+
});
|
|
1889
2105
|
|
|
2106
|
+
list.items.push({name: 'name', qty: 2});
|
|
2107
|
+
list.render();
|
|
2108
|
+
|
|
2109
|
+
assert.eq(getHtml(list), `<div><div><input placeholder="Name" value="name"><input type="number" value="2"><button onclick="">x</button></div></div>`);
|
|
2110
|
+
});
|
|
2111
|
+
|
|
2112
|
+
Testimony.test('Solarite.r.standaloneChild', () => {
|
|
2113
|
+
|
|
2114
|
+
function createItem(item) {
|
|
2115
|
+
return r({
|
|
2116
|
+
item: item,
|
|
2117
|
+
render(attribs = null) {
|
|
2118
|
+
// If attributes passed to constructor have changed.
|
|
2119
|
+
if (attribs)
|
|
2120
|
+
this.item = attribs.item;
|
|
2121
|
+
r(this)`
|
|
2122
|
+
<div>
|
|
2123
|
+
<b>${this.item.name}</b> - ${this.item.description}<br>
|
|
2124
|
+
</div>`
|
|
2125
|
+
}
|
|
2126
|
+
});
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
function createList(items) {
|
|
2130
|
+
return r({
|
|
2131
|
+
items: items,
|
|
2132
|
+
render() {
|
|
2133
|
+
r(this)`
|
|
2134
|
+
<div>
|
|
2135
|
+
${this.items.map(item =>
|
|
2136
|
+
createItem(item)
|
|
2137
|
+
)}
|
|
2138
|
+
</div>`
|
|
2139
|
+
}
|
|
2140
|
+
});
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
let list = createList([
|
|
2144
|
+
{
|
|
2145
|
+
name: 'English',
|
|
2146
|
+
description: 'See spot run.'
|
|
2147
|
+
},
|
|
2148
|
+
|
|
2149
|
+
{
|
|
2150
|
+
name: 'Science',
|
|
2151
|
+
description: 'Snails are mollusks.'
|
|
2152
|
+
}
|
|
2153
|
+
]);
|
|
2154
|
+
document.body.append(list);
|
|
2155
|
+
|
|
2156
|
+
list.items[0].name = 'PhysEd';
|
|
2157
|
+
list.render(); // calls NotesItem.render() with the new item.
|
|
2158
|
+
|
|
2159
|
+
assert.eq(getHtml(list), `<div><div><b>PhysEd</b> - See spot run.<br></div><div><b>Science</b> - Snails are mollusks.<br></div></div>`);
|
|
2160
|
+
|
|
2161
|
+
list.remove();
|
|
2162
|
+
});
|
|
2163
|
+
//</editor-fold>
|
|
1890
2164
|
|
|
1891
2165
|
|
|
2166
|
+
|
|
2167
|
+
|
|
2168
|
+
//<editor-fold desc="component">
|
|
2169
|
+
/* ┌─────────────────╮
|
|
2170
|
+
* | Component |
|
|
2171
|
+
* └─────────────────╯*/
|
|
1892
2172
|
Testimony.test('Solarite.component.tr', () => {
|
|
1893
2173
|
|
|
1894
2174
|
class TR510 extends Solarite('tr') {
|
|
@@ -1908,7 +2188,6 @@ Testimony.test('Solarite.component.tr', () => {
|
|
|
1908
2188
|
|
|
1909
2189
|
});
|
|
1910
2190
|
|
|
1911
|
-
|
|
1912
2191
|
Testimony.test('Solarite.component.staticAttribs', () => {
|
|
1913
2192
|
// Note that all attribs become lowercase.
|
|
1914
2193
|
// Not sure how to prevent this w/o using an xml doctype.
|
|
@@ -1935,11 +2214,9 @@ Testimony.test('Solarite.component.staticAttribs', () => {
|
|
|
1935
2214
|
let a = new A512();
|
|
1936
2215
|
a.render();
|
|
1937
2216
|
|
|
1938
|
-
assert.eq(a.outerHTML, `<a-512><div><b-512 name="User" userid="2"><!--
|
|
2217
|
+
assert.eq(a.outerHTML, `<a-512><div><b-512 name="User" userid="2"><!--ExprPath:0-->User | 2<!--ExprPathEnd:1--></b-512></div></a-512>`);
|
|
1939
2218
|
});
|
|
1940
2219
|
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
2220
|
Testimony.test('Solarite.component.dynamicAttribs', 'Attribs specified via ${...}', () => {
|
|
1944
2221
|
|
|
1945
2222
|
class B513 extends Solarite {
|
|
@@ -1965,7 +2242,7 @@ Testimony.test('Solarite.component.dynamicAttribs', 'Attribs specified via ${...
|
|
|
1965
2242
|
let a = new A513();
|
|
1966
2243
|
a.render();
|
|
1967
2244
|
|
|
1968
|
-
assert.eq(a.outerHTML, `<a-513><div><b-513 name="User" userid="2"><!--
|
|
2245
|
+
assert.eq(a.outerHTML, `<a-513><div><b-513 name="User" userid="2"><!--ExprPath:0-->User | 2<!--ExprPathEnd:1--></b-513></div></a-513>`);
|
|
1969
2246
|
});
|
|
1970
2247
|
|
|
1971
2248
|
Testimony.test('Solarite.component.getArg', 'Attribs specified html when not nested in another Solarite component.', () => {
|
|
@@ -1989,13 +2266,10 @@ Testimony.test('Solarite.component.getArg', 'Attribs specified html when not nes
|
|
|
1989
2266
|
let div = document.createElement('div');
|
|
1990
2267
|
div.innerHTML = `<b-514 name="User" userid="2"></b-514>`
|
|
1991
2268
|
|
|
1992
|
-
assert.eq(div.outerHTML, `<div><b-514 name="User" userid="2"><!--
|
|
2269
|
+
assert.eq(div.outerHTML, `<div><b-514 name="User" userid="2"><!--ExprPath:0-->User | 2<!--ExprPathEnd:1--></b-514></div>`)
|
|
1993
2270
|
|
|
1994
2271
|
});
|
|
1995
2272
|
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
2273
|
Testimony.test('Solarite.component.nested', () => {
|
|
2000
2274
|
|
|
2001
2275
|
let bRenderCount = 0;
|
|
@@ -2020,11 +2294,10 @@ Testimony.test('Solarite.component.nested', () => {
|
|
|
2020
2294
|
assert(!(a.firstChild instanceof B515))
|
|
2021
2295
|
|
|
2022
2296
|
a.render();
|
|
2023
|
-
|
|
2297
|
+
assert(a.firstChild instanceof B515);
|
|
2024
2298
|
assert.eq(getHtml(a), `<a-515><b-515><div>B</div></b-515></a-515>`);
|
|
2025
2299
|
})
|
|
2026
2300
|
|
|
2027
|
-
|
|
2028
2301
|
// Pass an object to the child.
|
|
2029
2302
|
Testimony.test('Solarite.component.nested2', () => {
|
|
2030
2303
|
|
|
@@ -2075,19 +2348,78 @@ Testimony.test('Solarite.component.nested2', () => {
|
|
|
2075
2348
|
a.title = 'Users2'
|
|
2076
2349
|
a.render();
|
|
2077
2350
|
assert.eq(getHtml(a), `<a-520>Users2<b-520 user=""><div>Name:</div><div>Barry</div><div>Email:</div><div>fred@example.com</div></b-520></a-520>`)
|
|
2078
|
-
assert.eq(bRenderCount, 0) // Value passed to b didn't change, so it shouldn't re-render.
|
|
2351
|
+
assert.eq(bRenderCount, 0); // Value passed to b didn't change, so it shouldn't re-render.
|
|
2079
2352
|
|
|
2080
2353
|
a.remove();
|
|
2081
2354
|
});
|
|
2082
2355
|
|
|
2356
|
+
// Pass an object to the child.
|
|
2357
|
+
Testimony.test('Solarite.component.nestedNonSolarite', () => {
|
|
2358
|
+
|
|
2359
|
+
let bRenderCount = 0;
|
|
2360
|
+
class B530 extends HTMLElement {
|
|
2361
|
+
|
|
2362
|
+
constructor({user}={}) {
|
|
2363
|
+
super();
|
|
2364
|
+
this.user = user;
|
|
2365
|
+
this.render();
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
render(props={}) {
|
|
2369
|
+
if (props.user)
|
|
2370
|
+
this.user = props.user;
|
|
2371
|
+
r(this)`<div>Name:</div><div>${this.user.name}</div><div>Email:</div><div>${this.user.email}</div>`;
|
|
2372
|
+
bRenderCount++;
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
customElements.define('b-530', B530);
|
|
2376
|
+
|
|
2377
|
+
class A530 extends HTMLElement {
|
|
2378
|
+
title = 'Users'
|
|
2379
|
+
user = {name: 'John', email: 'john@example.com'};
|
|
2380
|
+
render() {
|
|
2381
|
+
r(this)`${this.title}<b-530 user="${this.user}"></b-530>`
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
customElements.define('a-530', A530);
|
|
2385
|
+
|
|
2386
|
+
let a = new A530();
|
|
2387
|
+
a.render();
|
|
2388
|
+
document.body.append(a);
|
|
2389
|
+
assert.eq(getHtml(a), `<a-530>Users<b-530 user=""><div>Name:</div><div>John</div><div>Email:</div><div>john@example.com</div></b-530></a-530>`)
|
|
2083
2390
|
|
|
2084
2391
|
|
|
2392
|
+
a.user = {name: 'Fred', email: 'fred@example.com'};
|
|
2393
|
+
a.render();
|
|
2394
|
+
assert.eq(getHtml(a), `<a-530>Users<b-530 user=""><div>Name:</div><div>Fred</div><div>Email:</div><div>fred@example.com</div></b-530></a-530>`)
|
|
2395
|
+
|
|
2396
|
+
|
|
2397
|
+
a.user.name = 'Barry'
|
|
2398
|
+
a.render();
|
|
2399
|
+
assert.eq(getHtml(a), `<a-530>Users<b-530 user=""><div>Name:</div><div>Barry</div><div>Email:</div><div>fred@example.com</div></b-530></a-530>`)
|
|
2400
|
+
|
|
2401
|
+
bRenderCount = 0
|
|
2402
|
+
a.render();
|
|
2403
|
+
assert.eq(bRenderCount, 0)
|
|
2404
|
+
|
|
2405
|
+
a.title = 'Users2'
|
|
2406
|
+
a.render();
|
|
2407
|
+
assert.eq(getHtml(a), `<a-530>Users2<b-530 user=""><div>Name:</div><div>Barry</div><div>Email:</div><div>fred@example.com</div></b-530></a-530>`)
|
|
2408
|
+
assert.eq(bRenderCount, 0) // Value passed to b didn't change, so it shouldn't re-render.
|
|
2409
|
+
|
|
2410
|
+
a.remove();
|
|
2411
|
+
});
|
|
2412
|
+
|
|
2085
2413
|
// TODO: This redraws every tr on every update.
|
|
2086
2414
|
// Maybe that can be fixed when keying is supported?
|
|
2087
2415
|
Testimony.test('Solarite.component.nestedTrLoop', () => {
|
|
2088
2416
|
|
|
2089
2417
|
function tableRow(user) {
|
|
2090
|
-
let tr = r(
|
|
2418
|
+
let tr = r({
|
|
2419
|
+
render() {
|
|
2420
|
+
r(this)`<tr><td>${user.name}</td><td>${user.email}</td></tr>`
|
|
2421
|
+
}
|
|
2422
|
+
})
|
|
2091
2423
|
return tr;
|
|
2092
2424
|
}
|
|
2093
2425
|
|
|
@@ -2121,7 +2453,6 @@ Testimony.test('Solarite.component.nestedTrLoop', () => {
|
|
|
2121
2453
|
table.remove();
|
|
2122
2454
|
});
|
|
2123
2455
|
|
|
2124
|
-
|
|
2125
2456
|
Testimony.test('Solarite.component.nestedComponentTrLoop', () => {
|
|
2126
2457
|
|
|
2127
2458
|
class TR540 extends Solarite('tr') {
|
|
@@ -2165,16 +2496,20 @@ Testimony.test('Solarite.component.nestedComponentTrLoop', () => {
|
|
|
2165
2496
|
|
|
2166
2497
|
table.remove();
|
|
2167
2498
|
});
|
|
2499
|
+
//</editor-fold>
|
|
2168
2500
|
|
|
2169
2501
|
|
|
2170
2502
|
|
|
2171
|
-
// Slots
|
|
2172
2503
|
|
|
2504
|
+
//<editor-fold desc="slots">
|
|
2505
|
+
/* ┌─────────────────╮
|
|
2506
|
+
* | Slots |
|
|
2507
|
+
* └─────────────────╯*/
|
|
2173
2508
|
Testimony.test('Solarite.slots.basic', () => {
|
|
2174
2509
|
|
|
2175
2510
|
class S10 extends Solarite {
|
|
2176
2511
|
render() {
|
|
2177
|
-
this
|
|
2512
|
+
r(this)`<div>slot content:<slot></slot></div>`
|
|
2178
2513
|
}
|
|
2179
2514
|
}
|
|
2180
2515
|
S10.define();
|
|
@@ -2205,9 +2540,31 @@ Testimony.test('Solarite.slots.named', () => {
|
|
|
2205
2540
|
});
|
|
2206
2541
|
|
|
2207
2542
|
|
|
2208
|
-
|
|
2543
|
+
Testimony.test('Solarite.slots.slotless', `Add children even when no slots present.`, () => {
|
|
2544
|
+
|
|
2545
|
+
class S30 extends Solarite {
|
|
2546
|
+
render() {
|
|
2547
|
+
r(this)`<div>child1</div>`
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
S30.define();
|
|
2551
|
+
|
|
2552
|
+
let div = r('<div><s-30>child2<br>child4</s-30></div>')
|
|
2553
|
+
document.body.append(div);
|
|
2554
|
+
|
|
2555
|
+
assert.eq(div.outerHTML, `<div><s-30><div>child1</div>child2<br>child4</s-30></div>`)
|
|
2556
|
+
|
|
2557
|
+
div.remove();
|
|
2558
|
+
});
|
|
2559
|
+
//</editor-fold>
|
|
2560
|
+
|
|
2561
|
+
|
|
2209
2562
|
|
|
2210
|
-
|
|
2563
|
+
|
|
2564
|
+
//<editor-fold desc="events">
|
|
2565
|
+
/* ┌─────────────────╮
|
|
2566
|
+
* | Events |
|
|
2567
|
+
* └─────────────────╯*/
|
|
2211
2568
|
Testimony.test('Solarite.events.classic', () => {
|
|
2212
2569
|
|
|
2213
2570
|
class Ev10 extends Solarite {
|
|
@@ -2305,10 +2662,110 @@ Testimony.test('Solarite.events.onComponent', 'Event attrib on root component',
|
|
|
2305
2662
|
assert.eq(a.count, '2');
|
|
2306
2663
|
});
|
|
2307
2664
|
|
|
2665
|
+
Testimony.test('Solarite.events.onChild', () => {
|
|
2666
|
+
|
|
2667
|
+
class E50 extends HTMLElement {
|
|
2668
|
+
constructor() {
|
|
2669
|
+
super();
|
|
2670
|
+
this.items = [];
|
|
2671
|
+
this.render();
|
|
2672
|
+
}
|
|
2673
|
+
|
|
2674
|
+
addItem() {
|
|
2675
|
+
this.items.push(1);
|
|
2676
|
+
this.render();
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
render() {
|
|
2680
|
+
r(this)`
|
|
2681
|
+
<e-50>
|
|
2682
|
+
<button onclick=${this.addItem}>Add Item</button>
|
|
2683
|
+
</e-50>`
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
customElements.define('e-50', E50);
|
|
2687
|
+
|
|
2688
|
+
let e = new E50();
|
|
2689
|
+
e.querySelector('button').dispatchEvent(new MouseEvent('click'));
|
|
2690
|
+
assert.eq(e.items.length, 1);
|
|
2691
|
+
});
|
|
2692
|
+
|
|
2693
|
+
Testimony.test('Solarite.events.onExprChild', () => {
|
|
2694
|
+
|
|
2695
|
+
class E60 extends HTMLElement {
|
|
2696
|
+
constructor() {
|
|
2697
|
+
super();
|
|
2698
|
+
this.items = [];
|
|
2699
|
+
this.render();
|
|
2700
|
+
}
|
|
2701
|
+
|
|
2702
|
+
addItem() {
|
|
2703
|
+
this.items.push(1);
|
|
2704
|
+
this.render();
|
|
2705
|
+
}
|
|
2706
|
+
|
|
2707
|
+
render() {
|
|
2708
|
+
r(this)`
|
|
2709
|
+
<e-60>
|
|
2710
|
+
${r`<button onclick=${this.addItem}>Add Item</button>`}
|
|
2711
|
+
</e-60>`
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
customElements.define('e-60', E60);
|
|
2715
|
+
|
|
2716
|
+
let e = new E60();
|
|
2717
|
+
e.querySelector('button').dispatchEvent(new MouseEvent('click'));
|
|
2718
|
+
assert.eq(e.items.length, 1);
|
|
2719
|
+
});
|
|
2720
|
+
|
|
2721
|
+
Testimony.test('Solarite.events.loop', () => {
|
|
2722
|
+
|
|
2723
|
+
let lastButtonId = null;
|
|
2724
|
+
|
|
2725
|
+
class V70 extends Solarite {
|
|
2726
|
+
items = [{id: 1}, {id: 2}];
|
|
2727
|
+
|
|
2728
|
+
log(id) {
|
|
2729
|
+
lastButtonId = id;
|
|
2730
|
+
//console.log(id);
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
render() {
|
|
2734
|
+
r(this)`
|
|
2735
|
+
<v-70>
|
|
2736
|
+
${this.items.map(item => r`
|
|
2737
|
+
<button onclick=${[this.log, item.id]}>${item.id}</button>
|
|
2738
|
+
`)}
|
|
2739
|
+
</v-70>`
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
let v = new V70();
|
|
2744
|
+
document.body.append(v);
|
|
2745
|
+
|
|
2746
|
+
v.children[1].dispatchEvent(new MouseEvent('click'));
|
|
2747
|
+
assert.eq(lastButtonId, 2);
|
|
2748
|
+
|
|
2749
|
+
// This doesn't update the bound function to use 3.
|
|
2750
|
+
v.items.splice(1, 1); // remove 2.
|
|
2751
|
+
v.items.push({id: 3});
|
|
2752
|
+
window.debug = true;
|
|
2753
|
+
v.render();
|
|
2754
|
+
v.children[1].dispatchEvent(new MouseEvent('click'));
|
|
2755
|
+
assert.eq(lastButtonId, 3);
|
|
2756
|
+
|
|
2757
|
+
|
|
2758
|
+
//v.remove();
|
|
2759
|
+
});
|
|
2760
|
+
//</editor-fold>
|
|
2308
2761
|
|
|
2309
2762
|
|
|
2310
|
-
// Binding
|
|
2311
2763
|
|
|
2764
|
+
|
|
2765
|
+
//<editor-fold desc="binding">
|
|
2766
|
+
/* ┌─────────────────╮
|
|
2767
|
+
* | Binding |
|
|
2768
|
+
* └─────────────────╯*/
|
|
2312
2769
|
Testimony.test('Solarite.binding.input', () => {
|
|
2313
2770
|
|
|
2314
2771
|
class B10 extends Solarite {
|
|
@@ -2457,8 +2914,6 @@ Testimony.test('Solarite.binding.selectDynamic', () => {
|
|
|
2457
2914
|
b.remove();
|
|
2458
2915
|
});
|
|
2459
2916
|
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
2917
|
Testimony.test('Solarite.binding.number', () => {
|
|
2463
2918
|
|
|
2464
2919
|
class B40 extends Solarite {
|
|
@@ -2487,8 +2942,45 @@ Testimony.test('Solarite.binding.number', () => {
|
|
|
2487
2942
|
b.remove();
|
|
2488
2943
|
});
|
|
2489
2944
|
|
|
2945
|
+
// FIXME
|
|
2946
|
+
Testimony.test('Solarite.binding.number2', () => {
|
|
2947
|
+
|
|
2948
|
+
class B50 extends Solarite {
|
|
2949
|
+
count = 1
|
|
2950
|
+
|
|
2951
|
+
render() {
|
|
2952
|
+
r(this)`<input type="number" data-id="input" value=${[this, 'count']}>`
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2956
|
+
let b = new B50();
|
|
2957
|
+
document.body.append(b);
|
|
2958
|
+
assert.eq(b.input.value, '1')
|
|
2959
|
+
|
|
2960
|
+
b.count = 2;
|
|
2961
|
+
b.render();
|
|
2962
|
+
assert.eq(b.input.value, '2')
|
|
2963
|
+
|
|
2964
|
+
b.input.value = 3;
|
|
2965
|
+
b.input.dispatchEvent(new Event('input', {
|
|
2966
|
+
bubbles: true,
|
|
2967
|
+
cancelable: true,
|
|
2968
|
+
}));
|
|
2969
|
+
assert.eq(b.count, 3)
|
|
2970
|
+
|
|
2971
|
+
b.remove();
|
|
2972
|
+
});
|
|
2973
|
+
|
|
2974
|
+
|
|
2975
|
+
//</editor-fold>
|
|
2976
|
+
|
|
2977
|
+
|
|
2490
2978
|
|
|
2491
2979
|
|
|
2980
|
+
//<editor-fold desc="watch">
|
|
2981
|
+
/* ┌─────────────────╮
|
|
2982
|
+
* | Watch |
|
|
2983
|
+
* └─────────────────╯*/
|
|
2492
2984
|
/*
|
|
2493
2985
|
Testimony.test('Solarite.watched.watchSet', () => {
|
|
2494
2986
|
|
|
@@ -3032,16 +3524,17 @@ Testimony.test('Solarite.watch2._forEachSpliceInsert', () => {
|
|
|
3032
3524
|
Testimony.test('Solarite.watch3.primitive', () => {
|
|
3033
3525
|
|
|
3034
3526
|
class W100 extends HTMLElement {
|
|
3035
|
-
name = 'Fred';
|
|
3036
3527
|
|
|
3037
3528
|
constructor() {
|
|
3038
3529
|
super();
|
|
3039
|
-
watch3(this, 'name');
|
|
3530
|
+
watch3(this, 'name', 'Fred');
|
|
3531
|
+
|
|
3532
|
+
|
|
3040
3533
|
this.render();
|
|
3041
3534
|
}
|
|
3042
3535
|
|
|
3043
3536
|
render() {
|
|
3044
|
-
r(this)`<w-100>${
|
|
3537
|
+
r(this)`<w-100>${this.name + '!'}</w-100>`;
|
|
3045
3538
|
}
|
|
3046
3539
|
}
|
|
3047
3540
|
customElements.define('w-100', W100);
|
|
@@ -3057,7 +3550,7 @@ Testimony.test('Solarite.watch3.primitive', () => {
|
|
|
3057
3550
|
});
|
|
3058
3551
|
|
|
3059
3552
|
|
|
3060
|
-
Testimony.test('Solarite.watch3.
|
|
3553
|
+
Testimony.test('Solarite.watch3._nodes', () => {
|
|
3061
3554
|
|
|
3062
3555
|
class W110 extends HTMLElement {
|
|
3063
3556
|
name = 'Fred';
|
|
@@ -3088,15 +3581,61 @@ Testimony.test('Solarite.watch3.nodes', () => {
|
|
|
3088
3581
|
|
|
3089
3582
|
a.remove();
|
|
3090
3583
|
});
|
|
3584
|
+
//</editor-fold>
|
|
3091
3585
|
|
|
3092
3586
|
|
|
3093
3587
|
|
|
3094
3588
|
|
|
3589
|
+
//<editor-fold desc="full">
|
|
3590
|
+
/* ┌─────────────────╮
|
|
3591
|
+
* | Full |
|
|
3592
|
+
* └─────────────────╯*/
|
|
3095
3593
|
|
|
3594
|
+
Testimony.test('Solarite.full._todoList', () => {
|
|
3595
|
+
class ShoppingList extends HTMLElement {
|
|
3596
|
+
constructor(items=[]) {
|
|
3597
|
+
super();
|
|
3598
|
+
this.items = items;
|
|
3599
|
+
this.render();
|
|
3600
|
+
}
|
|
3096
3601
|
|
|
3097
|
-
|
|
3602
|
+
addItem() {
|
|
3603
|
+
this.items.push({name: '', qty: 0});
|
|
3604
|
+
this.render();
|
|
3605
|
+
}
|
|
3098
3606
|
|
|
3099
|
-
|
|
3607
|
+
removeItem(item) {
|
|
3608
|
+
this.items.splice(this.items.indexOf(item), 1);
|
|
3609
|
+
this.render();
|
|
3610
|
+
}
|
|
3611
|
+
|
|
3612
|
+
render() {
|
|
3613
|
+
r(this)`
|
|
3614
|
+
<shopping-list>
|
|
3615
|
+
<style>:host input { width: 80px }</style>
|
|
3616
|
+
|
|
3617
|
+
<button onclick=${this.addItem}>Add Item</button>
|
|
3618
|
+
|
|
3619
|
+
${this.items.map(item => r`
|
|
3620
|
+
<div>
|
|
3621
|
+
<input placeholder="Item" value=${item.name}
|
|
3622
|
+
oninput=${e => { // two-way binding
|
|
3623
|
+
item.name = e.target.value;
|
|
3624
|
+
this.render()
|
|
3625
|
+
}}>
|
|
3626
|
+
</div>
|
|
3627
|
+
`)}
|
|
3628
|
+
</shopping-list>`
|
|
3629
|
+
}
|
|
3630
|
+
}
|
|
3631
|
+
|
|
3632
|
+
customElements.define('shopping-list', ShoppingList);
|
|
3633
|
+
document.body.append(new ShoppingList()); // add <shopping-list> element
|
|
3634
|
+
});
|
|
3635
|
+
|
|
3636
|
+
Testimony.test('Solarite.full._treeItems', () => {
|
|
3637
|
+
|
|
3638
|
+
//import '../src/Solarite.js'
|
|
3100
3639
|
|
|
3101
3640
|
class TreeItem extends Solarite {
|
|
3102
3641
|
|
|
@@ -3141,3 +3680,159 @@ Testimony.test('Solarite.full.treeItems', () => {
|
|
|
3141
3680
|
});
|
|
3142
3681
|
|
|
3143
3682
|
|
|
3683
|
+
|
|
3684
|
+
|
|
3685
|
+
|
|
3686
|
+
// An attempt to create a simpler version that reproduces the same bug as full.misc.
|
|
3687
|
+
// but this version always works, and doesn't reproduce the issue.
|
|
3688
|
+
Testimony.test('Solarite.full._isc2', () => {
|
|
3689
|
+
let items = [
|
|
3690
|
+
{name: 'Apples', qty: 1},
|
|
3691
|
+
{name: 'Banans', qty: 2},
|
|
3692
|
+
{name: 'Cherries', qty: 3}
|
|
3693
|
+
]
|
|
3694
|
+
let toggle = false;
|
|
3695
|
+
|
|
3696
|
+
class Misc2 extends HTMLElement {
|
|
3697
|
+
render() {
|
|
3698
|
+
r(this)`
|
|
3699
|
+
<misc-2>
|
|
3700
|
+
${items.map(item => r`
|
|
3701
|
+
<div>
|
|
3702
|
+
${r`<span>${item.name}</span>`}
|
|
3703
|
+
${r`<span>${item.qty}</span>`}
|
|
3704
|
+
</div>`
|
|
3705
|
+
)}
|
|
3706
|
+
|
|
3707
|
+
</misc-2>`;
|
|
3708
|
+
}
|
|
3709
|
+
}
|
|
3710
|
+
|
|
3711
|
+
customElements.define('misc-2', Misc2);
|
|
3712
|
+
|
|
3713
|
+
let m = new Misc2();
|
|
3714
|
+
document.body.append(m);
|
|
3715
|
+
m.render();
|
|
3716
|
+
|
|
3717
|
+
|
|
3718
|
+
// let temp = items[0];
|
|
3719
|
+
// items[0] = items[1];
|
|
3720
|
+
// items[1] = temp;
|
|
3721
|
+
|
|
3722
|
+
// items[0].name = 'Bananas';
|
|
3723
|
+
// items[0].qty = 3;
|
|
3724
|
+
|
|
3725
|
+
//items[0] = items[1];
|
|
3726
|
+
|
|
3727
|
+
toggle = !toggle;
|
|
3728
|
+
|
|
3729
|
+
m.render();
|
|
3730
|
+
|
|
3731
|
+
toggle = !toggle;
|
|
3732
|
+
|
|
3733
|
+
m.render();
|
|
3734
|
+
|
|
3735
|
+
toggle = !toggle;
|
|
3736
|
+
|
|
3737
|
+
m.render();
|
|
3738
|
+
|
|
3739
|
+
});
|
|
3740
|
+
|
|
3741
|
+
|
|
3742
|
+
|
|
3743
|
+
|
|
3744
|
+
Testimony.test('Solarite.full._misc', () => {
|
|
3745
|
+
|
|
3746
|
+
class Misc1 extends HTMLElement {
|
|
3747
|
+
|
|
3748
|
+
items = [];
|
|
3749
|
+
options = [];
|
|
3750
|
+
|
|
3751
|
+
|
|
3752
|
+
|
|
3753
|
+
constructor(options) {
|
|
3754
|
+
super();
|
|
3755
|
+
this.options = options;
|
|
3756
|
+
this.items = items;
|
|
3757
|
+
|
|
3758
|
+
for (let product of this.items)
|
|
3759
|
+
for (let option of this.options)
|
|
3760
|
+
option[product.id + '_showOther'] = !!(product[option.name] && option.name !== product[option.name]);
|
|
3761
|
+
|
|
3762
|
+
this.render();
|
|
3763
|
+
}
|
|
3764
|
+
|
|
3765
|
+
async setValue(product, option, field, value) {
|
|
3766
|
+
product[field] = value;
|
|
3767
|
+
option[product.id + '_showOther'] = !!(value && option.name !== value);
|
|
3768
|
+
this.render();
|
|
3769
|
+
}
|
|
3770
|
+
|
|
3771
|
+
render() {
|
|
3772
|
+
r(this)`
|
|
3773
|
+
<misc-1>
|
|
3774
|
+
${this.items.map(item => r`
|
|
3775
|
+
<p>
|
|
3776
|
+
${this.options.map(option => r`
|
|
3777
|
+
<div style="display: flex">
|
|
3778
|
+
${r`<button onclick=${() => this.setValue(item, option, option.name, '')}>${option.name}</button>`}
|
|
3779
|
+
|
|
3780
|
+
${option[item.id + '_showOther'] && r`<input>`}
|
|
3781
|
+
</div>`
|
|
3782
|
+
)}
|
|
3783
|
+
</p>
|
|
3784
|
+
<br><br>
|
|
3785
|
+
`)}
|
|
3786
|
+
</misc-1>`;
|
|
3787
|
+
}
|
|
3788
|
+
}
|
|
3789
|
+
customElements.define('misc-1', Misc1);
|
|
3790
|
+
|
|
3791
|
+
let options = [
|
|
3792
|
+
{
|
|
3793
|
+
name: "a"
|
|
3794
|
+
},
|
|
3795
|
+
{
|
|
3796
|
+
name: "b"
|
|
3797
|
+
},
|
|
3798
|
+
{
|
|
3799
|
+
name: "c"
|
|
3800
|
+
}
|
|
3801
|
+
];
|
|
3802
|
+
let items = [
|
|
3803
|
+
{
|
|
3804
|
+
"id": 1,
|
|
3805
|
+
"a": 1,
|
|
3806
|
+
"b": 2,
|
|
3807
|
+
"c": 3
|
|
3808
|
+
},
|
|
3809
|
+
{
|
|
3810
|
+
"id": 2,
|
|
3811
|
+
"a": 1,
|
|
3812
|
+
"b": 2,
|
|
3813
|
+
"c": null
|
|
3814
|
+
}
|
|
3815
|
+
];
|
|
3816
|
+
let sp = new Misc1(options, items);
|
|
3817
|
+
document.body.append(sp);
|
|
3818
|
+
|
|
3819
|
+
sp.children[0].setAttribute('style', 'border: 1px solid red');
|
|
3820
|
+
|
|
3821
|
+
sp.children[0].children[0].querySelector('input').setAttribute('style', 'border: 3px solid #f80');
|
|
3822
|
+
sp.children[0].children[1].querySelector('input').setAttribute('style', 'border: 3px solid #fc0');
|
|
3823
|
+
sp.children[0].children[2].querySelector('input').setAttribute('style', 'border: 3px solid #660');
|
|
3824
|
+
|
|
3825
|
+
sp.children[1].setAttribute('style', 'border: 1px solid blue');
|
|
3826
|
+
|
|
3827
|
+
sp.children[3].children[0].setAttribute('style', 'border: 3px solid #0f8');
|
|
3828
|
+
sp.children[3].children[1].setAttribute('style', 'border: 3px solid #0fc');
|
|
3829
|
+
sp.children[3].children[2].setAttribute('style', 'border: 3px solid #0cf');
|
|
3830
|
+
|
|
3831
|
+
// Trigger bug:
|
|
3832
|
+
//sp.setValue(products[0], 'b', '');
|
|
3833
|
+
//sp.setValue(products[0], 'c', '');
|
|
3834
|
+
});
|
|
3835
|
+
|
|
3836
|
+
|
|
3837
|
+
//<editor-fold desc="full">
|
|
3838
|
+
|