solarite 0.1.0 → 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 +3 -2
- package/build/build.js +1 -1
- package/dist/Solarite-debug.js +1941 -2791
- package/dist/Solarite.js +1697 -2511
- package/dist/Solarite.min.js +3 -3
- package/dist/udomdiff-license.txt +18 -0
- package/docs/index.md +695 -235
- package/docs/js/Playground.js +1 -1
- package/docs/js/codemirror/codemirror6.js +3683 -3206
- package/docs/js/codemirror/themeSolarIce.js +2 -2
- package/docs/js/documentation.js +2 -2
- package/docs/js/ui/CodeEditor.js +183 -45
- package/docs/js/ui/FlexResizer.js +15 -5
- package/docs/js/util/Errors.js +11 -0
- package/docs/media/documentation.css +6 -3
- package/index.html +462 -26
- package/package.json +1 -1
- package/readme.md +11 -1
- package/src/solarite/ExprPath.js +422 -135
- package/src/solarite/Globals.js +53 -0
- package/src/solarite/NodeGroup.js +300 -388
- package/src/solarite/Shell.js +31 -33
- package/src/solarite/Solarite.js +17 -2
- package/src/solarite/Template.js +75 -25
- package/src/solarite/Util.js +131 -7
- package/src/solarite/createSolarite.js +32 -25
- package/src/solarite/getArg.js +12 -12
- package/src/solarite/hash.js +18 -35
- package/src/solarite/r.js +128 -118
- package/src/solarite/watch3.js +98 -0
- package/src/{solarite → unused}/NodeGroupManager.js +86 -224
- package/src/unused/onConnect.js +79 -0
- package/src/{solarite → unused}/watch.js +2 -2
- package/src/{solarite → unused}/watch2.js +4 -4
- package/src/{solarite → util}/MultiValueMap.js +23 -12
- package/src/util/WeakArray.js +33 -0
- package/tests/Solarite.test.js +1108 -166
- package/tests/Testimony.js +274 -67
- package/tests/index.html +6 -35
- package/tests/run.bat +2 -0
- package/tests/NodeGroup.test.js +0 -115
- package/tests/Shell.test.js +0 -75
package/tests/Solarite.test.js
CHANGED
|
@@ -1,17 +1,222 @@
|
|
|
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
|
-
import {watchGet, watchSet} from "../src/solarite/watch.js";
|
|
6
|
+
//import {watchGet, watchSet} from "../src/solarite/watch.js";
|
|
7
|
+
|
|
8
|
+
import {Solarite, r, getArg} from '../src/solarite/Solarite.js';
|
|
9
|
+
//import {Solarite, r, getArg} from '../dist/Solarite.min.js'; // This will help the Benchmark test warm up.
|
|
10
|
+
//import {watch} from "../src/solarite/watch2.js";
|
|
11
|
+
import watch3 from "../src/solarite/watch3.js";
|
|
12
|
+
//import NodeGroupManager from "../src/solarite/NodeGroupManager.js";
|
|
13
|
+
import NodeGroup from "../src/solarite/NodeGroup.js";
|
|
14
|
+
import Template from "../src/solarite/Template.js";
|
|
15
|
+
import Shell from "../src/solarite/Shell.js";
|
|
16
|
+
|
|
5
17
|
import Testimony, {assert} from './Testimony.js';
|
|
6
|
-
Testimony.enableJsDom();
|
|
7
18
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
19
|
+
// This function is used by the various tests.
|
|
20
|
+
window.getHtml = (item, includeComments=false) => {
|
|
21
|
+
if (!item)
|
|
22
|
+
return item;
|
|
23
|
+
|
|
24
|
+
if (item.fragment)
|
|
25
|
+
item = item.fragment; // Shell
|
|
26
|
+
if (item instanceof DocumentFragment)
|
|
27
|
+
item = [...item.childNodes]
|
|
28
|
+
|
|
29
|
+
else if (item.getNodes)
|
|
30
|
+
item = item.getNodes()
|
|
31
|
+
|
|
32
|
+
let result;
|
|
33
|
+
if (Array.isArray(item)) {
|
|
34
|
+
if (!includeComments)
|
|
35
|
+
item = item.filter(n => n.nodeType !==8)
|
|
36
|
+
|
|
37
|
+
result = item.map(n => n.nodeType === 8 ? `<!--${n.textContent}-->` : n.outerHTML || n.textContent).join('|');
|
|
38
|
+
}
|
|
39
|
+
else
|
|
40
|
+
result = item.outerHTML || item.textContent
|
|
41
|
+
|
|
42
|
+
if (!includeComments)
|
|
43
|
+
result = result.replace(/(<)!--(.*?)-->/g, '')
|
|
44
|
+
|
|
45
|
+
// Remove whitespace between tags, so we can write simpler tests.
|
|
46
|
+
return result.replace(/^\s+</g, '<').replace(/>\s+</g, '><').replace(/>\s+$/g, '>');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
//<editor-fold desc="shell">
|
|
52
|
+
/* ┌─────────────────╮
|
|
53
|
+
* | Shell |
|
|
54
|
+
* └─────────────────╯*/
|
|
55
|
+
Testimony.test('Solarite.Shell.empty', () => {
|
|
56
|
+
let shell = new Shell(['', ''])
|
|
57
|
+
assert.eq(getHtml(shell, true), '<!--ExprPath:0-->|<!--ExprPathEnd:0-->')
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
Testimony.test('Solarite.Shell.paragraph', () => {
|
|
61
|
+
let shell = new Shell(['<p>', '</p>'])
|
|
62
|
+
assert.eq(getHtml(shell, true), '<p><!--ExprPath:0--><!--ExprPathEnd:0--></p>')
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
Testimony.test('Solarite.Shell.nodeBefore', () => {
|
|
66
|
+
let shell = new Shell(['a', ''])
|
|
67
|
+
assert.eq(getHtml(shell, true), 'a|<!--ExprPathEnd:0-->')
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
Testimony.test('Solarite.Shell.nodeAfter', () => {
|
|
71
|
+
let shell = new Shell(['', 'b'])
|
|
72
|
+
assert.eq(getHtml(shell, true), '<!--ExprPath:0-->|b')
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
Testimony.test('Solarite.Shell.nodeBeforeAfter', () => {
|
|
76
|
+
let shell = new Shell(['a', 'b'])
|
|
77
|
+
assert.eq(getHtml(shell, true), 'a|b')
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
Testimony.test('Solarite.Shell.emptyTwoPaths', () => {
|
|
81
|
+
let shell = new Shell(['', '', ''])
|
|
82
|
+
assert.eq(getHtml(shell, true), '<!--ExprPath:0-->|<!--ExprPathEnd:0-->|<!--ExprPathEnd:1-->')
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
Testimony.test('Solarite.Shell.nodeBetweenPaths', () => {
|
|
86
|
+
let shell = new Shell(['', 'a', ''])
|
|
87
|
+
assert.eq(getHtml(shell, true), '<!--ExprPath:0-->|a|<!--ExprPathEnd:1-->')
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
Testimony.test('Solarite.Shell.nodesAroundPaths', () => {
|
|
91
|
+
let shell = new Shell(['a', 'b', 'c'])
|
|
92
|
+
assert.eq(getHtml(shell, true), 'a|b|c')
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
Testimony.test('Solarite.Shell.emptyTwoPathsNested', () => {
|
|
96
|
+
let shell = new Shell(['<p>', '', '</p>'])
|
|
97
|
+
assert.eq(getHtml(shell, true), '<p><!--ExprPath:0--><!--ExprPathEnd:0--><!--ExprPathEnd:1--></p>')
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
Testimony.test('Solarite.Shell.nodesAroundPathsNested', () => {
|
|
101
|
+
let shell = new Shell(['<p>a', 'b', 'c</p>'])
|
|
102
|
+
assert.eq(getHtml(shell, true), '<p>abc</p>')
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
// Testimony.test('Shell.emptySpacer', () => {
|
|
107
|
+
// let expr = 1;
|
|
108
|
+
// let shell = new Shell(['<input ', '', 'onclick=','>'])
|
|
109
|
+
// console.log(getHtml(shell, true))
|
|
110
|
+
// });
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
//</editor-fold>
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
//<editor-fold desc="nodegroup">
|
|
119
|
+
/* ┌─────────────────╮
|
|
120
|
+
* | NodeGroup |
|
|
121
|
+
* └─────────────────╯*/
|
|
122
|
+
Testimony.test('Solarite.NodeGroup.empty', () => {
|
|
123
|
+
|
|
124
|
+
let ng = new NodeGroup(new Template([``], []))
|
|
125
|
+
assert.eq(getHtml(ng), '')
|
|
126
|
+
|
|
127
|
+
ng.applyExprs([])
|
|
128
|
+
assert.eq(getHtml(ng), '')
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
Testimony.test('Solarite.NodeGroup.oneExpr', () => {
|
|
133
|
+
|
|
134
|
+
let ng = new NodeGroup(new Template([``, ``], ['1']))
|
|
135
|
+
assert.eq(getHtml(ng), '1')
|
|
136
|
+
|
|
137
|
+
ng.applyExprs([2])
|
|
138
|
+
assert.eq(getHtml(ng), '2')
|
|
139
|
+
|
|
140
|
+
ng.applyExprs([[3, 4, 5]])
|
|
141
|
+
assert.eq(getHtml(ng), '3|4|5')
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
Testimony.test('Solarite.NodeGroup.emptyAdjacent', () => {
|
|
145
|
+
let ng = new NodeGroup(new Template([``, ``, ``], ['1', '2']))
|
|
146
|
+
ng.verify();
|
|
147
|
+
|
|
148
|
+
assert.eq(getHtml(ng), '1|2')
|
|
149
|
+
|
|
150
|
+
ng.applyExprs([3, 4])
|
|
151
|
+
assert.eq(getHtml(ng), '3|4')
|
|
152
|
+
|
|
153
|
+
ng.applyExprs([[1, 2, 3], [4, 5, 6]])
|
|
154
|
+
assert.eq(getHtml(ng), '1|2|3|4|5|6')
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
Testimony.test('Solarite.NodeGroup.paragraph', () => {
|
|
159
|
+
let ng = new NodeGroup(new Template(['<p>', '</p>'], ['1']))
|
|
160
|
+
assert.eq(getHtml(ng), '<p>1</p>')
|
|
161
|
+
|
|
162
|
+
ng.applyExprs([2])
|
|
163
|
+
assert.eq(getHtml(ng), '<p>2</p>')
|
|
164
|
+
|
|
165
|
+
ng.applyExprs([[3, 4, 5]])
|
|
166
|
+
assert.eq(getHtml(ng), '<p>345</p>')
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
Testimony.test('Solarite.NodeGroup.node', () => {
|
|
170
|
+
let a = r('<p>a</p>')
|
|
171
|
+
let b = r('<p>b</p>')
|
|
172
|
+
let ng = new NodeGroup(new Template(['<div>', '</div>'], [a]))
|
|
173
|
+
|
|
174
|
+
assert.eq(getHtml(ng), '<div><p>a</p></div>')
|
|
175
|
+
|
|
176
|
+
ng.applyExprs([b]);
|
|
177
|
+
assert.eq(getHtml(ng), '<div><p>b</p></div>')
|
|
178
|
+
|
|
179
|
+
ng.applyExprs([1]);
|
|
180
|
+
assert.eq(getHtml(ng), '<div>1</div>')
|
|
181
|
+
|
|
182
|
+
ng.applyExprs([a]);
|
|
183
|
+
assert.eq(getHtml(ng), '<div><p>a</p></div>')
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
Testimony.test('Solarite.NodeGroup._nodeSwap', () => {
|
|
187
|
+
let a = r('<p>a</p>')
|
|
188
|
+
let b = r('<p>b</p>')
|
|
189
|
+
let ng = new NodeGroup(new Template(['<div>', '', '</div>'], [a, b]))
|
|
190
|
+
document.body.append(ng.startNode)
|
|
191
|
+
|
|
192
|
+
assert.eq(getHtml(ng), '<div><p>a</p><p>b</p></div>')
|
|
193
|
+
|
|
194
|
+
ng.applyExprs([b, a]);
|
|
195
|
+
assert.eq(getHtml(ng), '<div><p>b</p><p>a</p></div>');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
Testimony.test('Solarite.NodeGroup.arrayReverse', () => {
|
|
200
|
+
let list = [r('a'), r('b')];
|
|
201
|
+
|
|
202
|
+
let ng = new NodeGroup(new Template(['<div>', '</div>'], [list]))
|
|
203
|
+
ng.verify();
|
|
204
|
+
assert(getHtml(ng), '<div>ab</div')
|
|
205
|
+
|
|
206
|
+
list.reverse();
|
|
207
|
+
ng.applyExprs([list])
|
|
208
|
+
assert(getHtml(ng), '<div>ba</div')
|
|
209
|
+
});
|
|
210
|
+
//</editor-fold>
|
|
11
211
|
|
|
12
212
|
|
|
13
213
|
|
|
14
|
-
|
|
214
|
+
//<editor-fold desc="util">
|
|
215
|
+
/* ┌─────────────────╮
|
|
216
|
+
* | Util |
|
|
217
|
+
* └─────────────────╯*/
|
|
218
|
+
|
|
219
|
+
Testimony.test('Solarite.Util.htmlContext', () => {
|
|
15
220
|
assert.eq(htmlContext('<div class="test'), htmlContext.Attribute)
|
|
16
221
|
assert.eq(htmlContext('">hello '), htmlContext.Text);
|
|
17
222
|
assert.eq(htmlContext('<span data-attr="hi > there"'), htmlContext.Tag);
|
|
@@ -24,14 +229,21 @@ Testimony.test('Util.htmlContext', () => {
|
|
|
24
229
|
assert.eq(htmlContext('>'), htmlContext.Text);
|
|
25
230
|
});
|
|
26
231
|
|
|
27
|
-
Testimony.test('Util.camelToDashes', () => {
|
|
232
|
+
Testimony.test('Solarite.Util.camelToDashes', () => {
|
|
28
233
|
assert.eq(camelToDashes('ProperName'), 'proper-name');
|
|
29
234
|
assert.eq(camelToDashes('HTMLElement'), 'html-element');
|
|
30
235
|
assert.eq(camelToDashes('BigUI'), 'big-ui');
|
|
31
236
|
assert.eq(camelToDashes('UIForm'), 'ui-form');
|
|
32
237
|
assert.eq(camelToDashes('A100'), 'a-100');
|
|
33
238
|
});
|
|
239
|
+
//</editor-fold>
|
|
240
|
+
|
|
34
241
|
|
|
242
|
+
|
|
243
|
+
//<editor-fold desc="basic">
|
|
244
|
+
/* ┌─────────────────╮
|
|
245
|
+
* | Basic |
|
|
246
|
+
* └─────────────────╯*/
|
|
35
247
|
Testimony.test('Solarite.basic.empty', () => {
|
|
36
248
|
class A extends HTMLElement {
|
|
37
249
|
constructor() {
|
|
@@ -153,20 +365,27 @@ Testimony.test('Solarite.basic.createElement', () => {
|
|
|
153
365
|
a.render();
|
|
154
366
|
assert.eq(getHtml(a), `<r-35><div>Hello!</div></r-35>`);
|
|
155
367
|
});
|
|
368
|
+
//</editor-fold>
|
|
369
|
+
|
|
156
370
|
|
|
157
371
|
|
|
158
|
-
|
|
372
|
+
//<editor-fold desc="expr">
|
|
373
|
+
/* ┌─────────────────╮
|
|
374
|
+
* | Expr |
|
|
375
|
+
* └─────────────────╯*/
|
|
159
376
|
Testimony.test('Solarite.expr.staticString', () => {
|
|
160
|
-
class R40 extends
|
|
377
|
+
class R40 extends HTMLElement {
|
|
161
378
|
render() {
|
|
162
|
-
r(this)`Solarite ${'
|
|
379
|
+
r(this)`Solarite ${'Test'} Component`
|
|
163
380
|
}
|
|
164
381
|
}
|
|
382
|
+
customElements.define('r-40', R40);
|
|
165
383
|
|
|
166
384
|
let a = new R40();
|
|
385
|
+
a.render();
|
|
167
386
|
document.body.append(a);
|
|
168
387
|
|
|
169
|
-
assert.eq(getHtml(a), '<r-40>Solarite
|
|
388
|
+
assert.eq(getHtml(a), '<r-40>Solarite Test Component</r-40>');
|
|
170
389
|
|
|
171
390
|
a.remove();
|
|
172
391
|
});
|
|
@@ -190,7 +409,6 @@ Testimony.test('Solarite.expr.htmlString', () => {
|
|
|
190
409
|
assert.eq(getHtml(a), '<r-42>This text is <b>Bold</b>!</r-42>');
|
|
191
410
|
});
|
|
192
411
|
|
|
193
|
-
|
|
194
412
|
Testimony.test('Solarite.expr.table', () => {
|
|
195
413
|
|
|
196
414
|
class R43 extends Solarite {
|
|
@@ -217,7 +435,13 @@ Testimony.test('Solarite.expr.documentFragment', () => {
|
|
|
217
435
|
}
|
|
218
436
|
}
|
|
219
437
|
|
|
220
|
-
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();
|
|
221
445
|
assert.eq(getHtml(a), '<r-44>This text is <b>Bold</b><i>Italic</i>!</r-44>');
|
|
222
446
|
});
|
|
223
447
|
|
|
@@ -446,7 +670,6 @@ Testimony.test('Solarite.expr.staticElement', () => {
|
|
|
446
670
|
assert.eq(getHtml(a), '<r-74>Field: <input></r-74>');
|
|
447
671
|
});
|
|
448
672
|
|
|
449
|
-
|
|
450
673
|
Testimony.test('Solarite.expr.varText', () => {
|
|
451
674
|
class A extends Solarite {
|
|
452
675
|
value = 'Apple';
|
|
@@ -472,8 +695,6 @@ Testimony.test('Solarite.expr.varText', () => {
|
|
|
472
695
|
assert.eq(a.childNodes.length, 3);
|
|
473
696
|
});
|
|
474
697
|
|
|
475
|
-
|
|
476
|
-
|
|
477
698
|
Testimony.test('Solarite.expr.cyclicRef', () => {
|
|
478
699
|
|
|
479
700
|
|
|
@@ -499,15 +720,14 @@ Testimony.test('Solarite.expr.cyclicRef', () => {
|
|
|
499
720
|
a.render();
|
|
500
721
|
assert.eq(getHtml(a), '<r-100>The fruit is Cherry!</r-100>');
|
|
501
722
|
});
|
|
723
|
+
//</editor-fold>
|
|
502
724
|
|
|
503
725
|
|
|
504
726
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
// Loop:
|
|
727
|
+
//<editor-fold desc="loop">
|
|
728
|
+
/* ┌─────────────────╮
|
|
729
|
+
* | Loop |
|
|
730
|
+
* └─────────────────╯*/
|
|
511
731
|
Testimony.test('Solarite.loop.strings', () => {
|
|
512
732
|
class A extends Solarite {
|
|
513
733
|
fruits = ['Apple', 'Banana'];
|
|
@@ -543,7 +763,6 @@ Testimony.test('Solarite.loop.strings', () => {
|
|
|
543
763
|
assert.eq(getHtml(a), '<r-200>Apple</r-200>');
|
|
544
764
|
});
|
|
545
765
|
|
|
546
|
-
|
|
547
766
|
Testimony.test('Solarite.loop.paragraphs', () => {
|
|
548
767
|
class A extends Solarite {
|
|
549
768
|
fruits = ['Apple', 'Banana'];
|
|
@@ -554,7 +773,8 @@ Testimony.test('Solarite.loop.paragraphs', () => {
|
|
|
554
773
|
}
|
|
555
774
|
customElements.define('r-210', A);
|
|
556
775
|
let a = new A();
|
|
557
|
-
|
|
776
|
+
|
|
777
|
+
a.render();
|
|
558
778
|
|
|
559
779
|
assert.eq(getHtml(a), '<r-210><p>Apple</p><p>Banana</p></r-210>');
|
|
560
780
|
|
|
@@ -563,6 +783,7 @@ Testimony.test('Solarite.loop.paragraphs', () => {
|
|
|
563
783
|
assert.eq(getHtml(a), '<r-210><p>Apple</p><p>Banana</p><p>Cherry</p></r-210>');
|
|
564
784
|
|
|
565
785
|
a.fruits.pop();
|
|
786
|
+
window.debug = true;
|
|
566
787
|
a.render();
|
|
567
788
|
assert.eq(getHtml(a), '<r-210><p>Apple</p><p>Banana</p></r-210>');
|
|
568
789
|
|
|
@@ -581,8 +802,7 @@ Testimony.test('Solarite.loop.paragraphs', () => {
|
|
|
581
802
|
a.remove();
|
|
582
803
|
});
|
|
583
804
|
|
|
584
|
-
|
|
585
|
-
Testimony.test('Solarite.loop.paragraphsBefore', () => {
|
|
805
|
+
Testimony.test('Solarite.loop.paragraphsBefore', `Same as above, but with another element afterward.`, () => {
|
|
586
806
|
class A extends Solarite {
|
|
587
807
|
fruits = ['Apple', 'Banana'];
|
|
588
808
|
|
|
@@ -619,6 +839,54 @@ Testimony.test('Solarite.loop.paragraphsBefore', () => {
|
|
|
619
839
|
a.remove();
|
|
620
840
|
});
|
|
621
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
|
+
|
|
622
890
|
Testimony.test('Solarite.loop.eventBindings', async () => {
|
|
623
891
|
await new Promise((resolve, reject) => {
|
|
624
892
|
let callCount = 0;
|
|
@@ -653,7 +921,7 @@ Testimony.test('Solarite.loop.eventBindings', async () => {
|
|
|
653
921
|
|
|
654
922
|
});
|
|
655
923
|
|
|
656
|
-
|
|
924
|
+
// TODO: Why is this called pathCache? What does it test?
|
|
657
925
|
Testimony.test('Solarite.loop.pathCache', () => {
|
|
658
926
|
|
|
659
927
|
class R216 extends Solarite {
|
|
@@ -670,15 +938,13 @@ Testimony.test('Solarite.loop.pathCache', () => {
|
|
|
670
938
|
}
|
|
671
939
|
|
|
672
940
|
let a = new R216();
|
|
673
|
-
document.body.append(a);
|
|
674
941
|
a.render();
|
|
675
942
|
assert.eq(getHtml(a), `<r-216><p>Item</p><p>Item</p></r-216>`);
|
|
676
943
|
|
|
677
944
|
a.fruits.shift();
|
|
945
|
+
window.debug = true;
|
|
678
946
|
a.render();
|
|
679
947
|
assert.eq(getHtml(a), `<r-216><p>Item</p></r-216>`);
|
|
680
|
-
|
|
681
|
-
a.remove();
|
|
682
948
|
});
|
|
683
949
|
|
|
684
950
|
Testimony.test('Solarite.loop.nested', () => {
|
|
@@ -728,6 +994,7 @@ Testimony.test('Solarite.loop.nested', () => {
|
|
|
728
994
|
|
|
729
995
|
a.pets.reverse();
|
|
730
996
|
a.fruits.reverse();
|
|
997
|
+
window.debug = true;
|
|
731
998
|
a.render();
|
|
732
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>`);
|
|
733
1000
|
|
|
@@ -803,7 +1070,6 @@ Testimony.test('Solarite.loop.nested2', () => {
|
|
|
803
1070
|
a.remove();
|
|
804
1071
|
});
|
|
805
1072
|
|
|
806
|
-
|
|
807
1073
|
Testimony.test('Solarite.loop.nested3', `Move items from one sublist to another.`, () => {
|
|
808
1074
|
|
|
809
1075
|
class A225 extends Solarite {
|
|
@@ -825,6 +1091,7 @@ Testimony.test('Solarite.loop.nested3', `Move items from one sublist to another.
|
|
|
825
1091
|
|
|
826
1092
|
let a = new A225();
|
|
827
1093
|
document.body.append(a);
|
|
1094
|
+
window.debug = true;
|
|
828
1095
|
a.render();
|
|
829
1096
|
|
|
830
1097
|
let cherry = a.fruitGroups[1].pop();
|
|
@@ -834,15 +1101,12 @@ Testimony.test('Solarite.loop.nested3', `Move items from one sublist to another.
|
|
|
834
1101
|
|
|
835
1102
|
let banana = a.fruitGroups[1].pop();
|
|
836
1103
|
a.fruitGroups[0].push(banana);
|
|
837
|
-
//window.debug = true;
|
|
838
1104
|
a.render();
|
|
839
|
-
|
|
1105
|
+
|
|
840
1106
|
window.verify = false;
|
|
841
1107
|
a.remove();
|
|
842
1108
|
});
|
|
843
1109
|
|
|
844
|
-
|
|
845
|
-
|
|
846
1110
|
// Tried to make a simpler version of nested3, but it works fine:
|
|
847
1111
|
Testimony.test('Solarite.loop.nested4', () => {
|
|
848
1112
|
|
|
@@ -877,14 +1141,6 @@ Testimony.test('Solarite.loop.nested4', () => {
|
|
|
877
1141
|
a.remove();
|
|
878
1142
|
});
|
|
879
1143
|
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
1144
|
Testimony.test('Solarite.loop.nested5', () => {
|
|
889
1145
|
|
|
890
1146
|
// This test was originally created by reducing a failure in production code
|
|
@@ -904,7 +1160,7 @@ Testimony.test('Solarite.loop.nested5', () => {
|
|
|
904
1160
|
]
|
|
905
1161
|
|
|
906
1162
|
render() {
|
|
907
|
-
this
|
|
1163
|
+
r(this)`
|
|
908
1164
|
<a-227>${this.boxes.map(item =>
|
|
909
1165
|
r`${item.map(item2 =>
|
|
910
1166
|
r`<div title=${v}>${item2}</div>`
|
|
@@ -929,28 +1185,12 @@ Testimony.test('Solarite.loop.nested5', () => {
|
|
|
929
1185
|
]
|
|
930
1186
|
a.render();
|
|
931
1187
|
|
|
932
|
-
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>`);
|
|
933
1189
|
|
|
934
1190
|
window.verify = false;
|
|
935
1191
|
a.remove();
|
|
936
1192
|
});
|
|
937
1193
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
1194
|
Testimony.test('Solarite.loop.nestedConditional', () => {
|
|
955
1195
|
|
|
956
1196
|
let isGoodBoy = true;
|
|
@@ -1035,7 +1275,6 @@ Testimony.test('Solarite.loop.conditionalNested', () => {
|
|
|
1035
1275
|
a.remove();
|
|
1036
1276
|
});
|
|
1037
1277
|
|
|
1038
|
-
|
|
1039
1278
|
Testimony.test('Solarite.loop.tripleNested', 'Triple nested grid', () => {
|
|
1040
1279
|
|
|
1041
1280
|
class R250 extends Solarite {
|
|
@@ -1101,12 +1340,15 @@ Testimony.test('Solarite.loop.tripleNested', 'Triple nested grid', () => {
|
|
|
1101
1340
|
a.remove();
|
|
1102
1341
|
});
|
|
1103
1342
|
|
|
1343
|
+
//</editor-fold>
|
|
1104
1344
|
|
|
1105
1345
|
|
|
1106
1346
|
|
|
1107
1347
|
|
|
1108
|
-
|
|
1109
|
-
|
|
1348
|
+
//<editor-fold desc="embed">
|
|
1349
|
+
/* ┌─────────────────╮
|
|
1350
|
+
* | Embed |
|
|
1351
|
+
* └─────────────────╯*/
|
|
1110
1352
|
|
|
1111
1353
|
Testimony.test('Solarite.embed.styleStatic', () => {
|
|
1112
1354
|
let count = 0;
|
|
@@ -1159,7 +1401,6 @@ Testimony.test('Solarite.embed.optionsNoStyles', () => {
|
|
|
1159
1401
|
a.remove();
|
|
1160
1402
|
});
|
|
1161
1403
|
|
|
1162
|
-
|
|
1163
1404
|
Testimony.test('Solarite.embed.styleDynamic', () => {
|
|
1164
1405
|
let style1 = `:host { color: red }`
|
|
1165
1406
|
let style2 = `:host { font-weight: bold }`
|
|
@@ -1233,10 +1474,6 @@ Testimony.test('Solarite.embed.styleDynamicTag', () => {
|
|
|
1233
1474
|
a.remove();
|
|
1234
1475
|
});
|
|
1235
1476
|
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
1477
|
Testimony.test('Solarite.embed.svg', () => {
|
|
1241
1478
|
class R330 extends Solarite {
|
|
1242
1479
|
render() {
|
|
@@ -1314,8 +1551,16 @@ Testimony.test('Solarite.embed._scriptDynamic', () => {
|
|
|
1314
1551
|
delete window.scriptStaticCount;
|
|
1315
1552
|
});
|
|
1316
1553
|
|
|
1554
|
+
//</editor-fold>
|
|
1555
|
+
|
|
1317
1556
|
|
|
1318
1557
|
|
|
1558
|
+
|
|
1559
|
+
//<editor-fold desc="attrib">
|
|
1560
|
+
/* ┌─────────────────╮
|
|
1561
|
+
* | Attrib |
|
|
1562
|
+
* └─────────────────╯*/
|
|
1563
|
+
|
|
1319
1564
|
Testimony.test('Solarite.attrib.single', () => {
|
|
1320
1565
|
|
|
1321
1566
|
let val = 'one';
|
|
@@ -1385,7 +1630,6 @@ Testimony.test('Solarite.attrib.double', () => {
|
|
|
1385
1630
|
assert.eq(getHtml(a), `<r-420><div class="oneBtwoB">oneB</div></r-420>`)
|
|
1386
1631
|
});
|
|
1387
1632
|
|
|
1388
|
-
|
|
1389
1633
|
Testimony.test('Solarite.attrib.doubleAndText', () => {
|
|
1390
1634
|
|
|
1391
1635
|
let val1 = 'one';
|
|
@@ -1499,12 +1743,11 @@ Testimony.test('Solarite.attrib.toggle', () => {
|
|
|
1499
1743
|
assert.eq(getHtml(a), `<r-460><div></div></r-460>`)
|
|
1500
1744
|
});
|
|
1501
1745
|
|
|
1502
|
-
|
|
1503
1746
|
Testimony.test('Solarite.attrib.pseudoRoot', () => {
|
|
1504
1747
|
let title = 'Hello'
|
|
1505
1748
|
class R470 extends Solarite {
|
|
1506
1749
|
render() {
|
|
1507
|
-
this
|
|
1750
|
+
r(this)`<r-470 title="${title}">World</r-470>`
|
|
1508
1751
|
}
|
|
1509
1752
|
}
|
|
1510
1753
|
|
|
@@ -1522,7 +1765,6 @@ Testimony.test('Solarite.attrib.pseudoRoot', () => {
|
|
|
1522
1765
|
assert.eq(a.outerHTML, `<r-470>World</r-470>`)
|
|
1523
1766
|
});
|
|
1524
1767
|
|
|
1525
|
-
|
|
1526
1768
|
Testimony.test('Solarite.attrib.pseudoRoot2', 'Static attribute overrides.', () => {
|
|
1527
1769
|
let title = 'Hello'
|
|
1528
1770
|
class R472 extends Solarite {
|
|
@@ -1584,9 +1826,59 @@ Testimony.test('Solarite.attrib.multiple', '', () => {
|
|
|
1584
1826
|
assert.eq(getHtml(a), `<r-474><button onclick="" class="primary">Hello</button></r-474>`);
|
|
1585
1827
|
});
|
|
1586
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
|
+
|
|
1587
1875
|
|
|
1588
1876
|
|
|
1589
|
-
|
|
1877
|
+
//<editor-fold desc="comments">
|
|
1878
|
+
/* ┌─────────────────╮
|
|
1879
|
+
* | comments |
|
|
1880
|
+
* └─────────────────╯*/
|
|
1881
|
+
Testimony.test('Solarite.comments.one', () => {
|
|
1590
1882
|
|
|
1591
1883
|
class A480 extends Solarite {
|
|
1592
1884
|
render() {
|
|
@@ -1601,7 +1893,7 @@ Testimony.test('Solarite.comments', () => {
|
|
|
1601
1893
|
a.remove();
|
|
1602
1894
|
});
|
|
1603
1895
|
|
|
1604
|
-
Testimony.test('Solarite.
|
|
1896
|
+
Testimony.test('Solarite.comments.two', () => {
|
|
1605
1897
|
|
|
1606
1898
|
class A482 extends Solarite {
|
|
1607
1899
|
render() {
|
|
@@ -1614,32 +1906,72 @@ Testimony.test('Solarite.comments2', () => {
|
|
|
1614
1906
|
assert.eq(getHtml(a), `<a-482><div>3</div></a-482>`)
|
|
1615
1907
|
a.remove();
|
|
1616
1908
|
});
|
|
1909
|
+
//</editor-fold>
|
|
1617
1910
|
|
|
1618
1911
|
|
|
1619
1912
|
|
|
1620
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
|
+
})
|
|
1621
1923
|
|
|
1622
|
-
Testimony.test('Solarite.
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
}
|
|
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
|
+
})
|
|
1629
1930
|
|
|
1630
|
-
|
|
1631
|
-
|
|
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
|
+
})
|
|
1632
1937
|
|
|
1633
|
-
|
|
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>`)
|
|
1634
1954
|
});
|
|
1635
1955
|
|
|
1636
|
-
Testimony.test('Solarite.r.
|
|
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>`)
|
|
1960
|
+
});
|
|
1637
1961
|
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
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
|
+
});
|
|
1642
1967
|
|
|
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>`)
|
|
1974
|
+
})
|
|
1643
1975
|
|
|
1644
1976
|
|
|
1645
1977
|
|
|
@@ -1650,70 +1982,213 @@ Testimony.test('Solarite.r.element', () => {
|
|
|
1650
1982
|
assert.eq(getHtml(button), `<button>I'm a <b>better</b> button</button>`)
|
|
1651
1983
|
})
|
|
1652
1984
|
|
|
1985
|
+
Testimony.test('Solarite.r.standalone1', () => {
|
|
1986
|
+
let button = r({
|
|
1987
|
+
count: 0,
|
|
1653
1988
|
|
|
1989
|
+
inc() {
|
|
1990
|
+
this.count++;
|
|
1991
|
+
this.render();
|
|
1992
|
+
},
|
|
1654
1993
|
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
let result = r(
|
|
1658
|
-
() => r`<button onclick=${(ev, self)=>{count++; self.render()}}>I'm a ${count}X better button</button>`
|
|
1659
|
-
);
|
|
1660
|
-
result.inc = () => {
|
|
1661
|
-
count++;
|
|
1662
|
-
result.render();
|
|
1663
|
-
}
|
|
1664
|
-
return result;
|
|
1665
|
-
}
|
|
1666
|
-
|
|
1667
|
-
let button = betterButton(3);
|
|
1668
|
-
assert.eq(getHtml(button), `<button onclick="">I'm a 3X better button</button>`)
|
|
1669
|
-
|
|
1670
|
-
button.inc();
|
|
1671
|
-
assert.eq(getHtml(button), `<button onclick="">I'm a 4X better button</button>`)
|
|
1672
|
-
})
|
|
1673
|
-
|
|
1674
|
-
Testimony.test('Solarite.r.lightweightComponent2', () => {
|
|
1675
|
-
function betterButton(count=0) {
|
|
1676
|
-
let result = r(
|
|
1677
|
-
() => r`<button onclick=${(ev, self)=>{count++; self.render()}}>I'm a ${count}X better button</button>`
|
|
1678
|
-
);
|
|
1679
|
-
result.inc = () => {
|
|
1680
|
-
count++;
|
|
1681
|
-
result.render();
|
|
1994
|
+
render() {
|
|
1995
|
+
r(this)`<button onclick=${this.inc}>I've been clicked ${this.count} times.</button>`
|
|
1682
1996
|
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1997
|
+
});
|
|
1998
|
+
//document.body.append(button);
|
|
1685
1999
|
|
|
1686
|
-
|
|
1687
|
-
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>`)
|
|
1688
2001
|
|
|
1689
2002
|
button.inc();
|
|
1690
|
-
assert.eq(getHtml(button), `<button onclick="">I'
|
|
1691
|
-
})
|
|
2003
|
+
assert.eq(getHtml(button), `<button onclick="">I've been clicked 1 times.</button>`);
|
|
1692
2004
|
|
|
2005
|
+
button.dispatchEvent(new MouseEvent('click'));
|
|
2006
|
+
assert.eq(getHtml(button), `<button onclick="">I've been clicked 2 times.</button>`);
|
|
1693
2007
|
|
|
2008
|
+
//button.remove();
|
|
2009
|
+
});
|
|
1694
2010
|
|
|
2011
|
+
Testimony.test('Solarite.r.standalone2', () => {
|
|
2012
|
+
let list = r({
|
|
2013
|
+
items: [],
|
|
1695
2014
|
|
|
1696
|
-
|
|
2015
|
+
add() {
|
|
2016
|
+
this.items.push('Item ' + this.items.length);
|
|
2017
|
+
this.render();
|
|
2018
|
+
},
|
|
1697
2019
|
|
|
1698
|
-
class TR510 extends Solarite('tr') {
|
|
1699
2020
|
render() {
|
|
1700
|
-
this
|
|
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>`
|
|
1701
2029
|
}
|
|
1702
|
-
}
|
|
2030
|
+
});
|
|
1703
2031
|
|
|
1704
|
-
|
|
2032
|
+
//document.body.append(list);
|
|
1705
2033
|
|
|
1706
|
-
|
|
1707
|
-
document.body.append(table)
|
|
2034
|
+
assert.eq(getHtml(list), `<div><button onclick="">Add Item</button><hr></div>`);
|
|
1708
2035
|
|
|
1709
|
-
|
|
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();
|
|
1710
2040
|
|
|
1711
|
-
|
|
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>`);
|
|
1712
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();
|
|
1713
2050
|
});
|
|
1714
2051
|
|
|
2052
|
+
Testimony.test('Solarite.r.standaloneId', "Test id's on standalone elmenets.", () => {
|
|
2053
|
+
let list = r({
|
|
2054
|
+
items: [],
|
|
1715
2055
|
|
|
1716
|
-
|
|
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 }`);
|
|
2084
|
+
});
|
|
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: [],
|
|
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
|
+
});
|
|
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>
|
|
2164
|
+
|
|
2165
|
+
|
|
2166
|
+
|
|
2167
|
+
|
|
2168
|
+
//<editor-fold desc="component">
|
|
2169
|
+
/* ┌─────────────────╮
|
|
2170
|
+
* | Component |
|
|
2171
|
+
* └─────────────────╯*/
|
|
2172
|
+
Testimony.test('Solarite.component.tr', () => {
|
|
2173
|
+
|
|
2174
|
+
class TR510 extends Solarite('tr') {
|
|
2175
|
+
render() {
|
|
2176
|
+
this.html = r`<td>hello</td>`
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
let table = document.createElement('table')
|
|
2181
|
+
|
|
2182
|
+
table.append(new TR510())
|
|
2183
|
+
document.body.append(table)
|
|
2184
|
+
|
|
2185
|
+
assert.eq(table.outerHTML, `<table><tr is="tr-510"><td>hello</td></tr></table>`)
|
|
2186
|
+
|
|
2187
|
+
table.remove();
|
|
2188
|
+
|
|
2189
|
+
});
|
|
2190
|
+
|
|
2191
|
+
Testimony.test('Solarite.component.staticAttribs', () => {
|
|
1717
2192
|
// Note that all attribs become lowercase.
|
|
1718
2193
|
// Not sure how to prevent this w/o using an xml doctype.
|
|
1719
2194
|
class B512 extends Solarite {
|
|
@@ -1739,11 +2214,9 @@ Testimony.test('Solarite.component.staticAttribs', () => {
|
|
|
1739
2214
|
let a = new A512();
|
|
1740
2215
|
a.render();
|
|
1741
2216
|
|
|
1742
|
-
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>`);
|
|
1743
2218
|
});
|
|
1744
2219
|
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
2220
|
Testimony.test('Solarite.component.dynamicAttribs', 'Attribs specified via ${...}', () => {
|
|
1748
2221
|
|
|
1749
2222
|
class B513 extends Solarite {
|
|
@@ -1769,21 +2242,17 @@ Testimony.test('Solarite.component.dynamicAttribs', 'Attribs specified via ${...
|
|
|
1769
2242
|
let a = new A513();
|
|
1770
2243
|
a.render();
|
|
1771
2244
|
|
|
1772
|
-
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>`);
|
|
1773
2246
|
});
|
|
1774
2247
|
|
|
1775
2248
|
Testimony.test('Solarite.component.getArg', 'Attribs specified html when not nested in another Solarite component.', () => {
|
|
1776
|
-
|
|
1777
|
-
Solarite.getArgs = function(el) {
|
|
1778
|
-
debugger;
|
|
1779
|
-
return {};
|
|
1780
|
-
}
|
|
1781
|
-
|
|
2249
|
+
|
|
1782
2250
|
class B514 extends Solarite {
|
|
1783
2251
|
constructor({name, userid}={}) {
|
|
1784
2252
|
super();
|
|
1785
|
-
|
|
1786
|
-
this.
|
|
2253
|
+
|
|
2254
|
+
this.name = getArg(this, 'name', name);
|
|
2255
|
+
this.userId = getArg(this, 'userid', userid);
|
|
1787
2256
|
this.render();
|
|
1788
2257
|
}
|
|
1789
2258
|
|
|
@@ -1796,14 +2265,11 @@ Testimony.test('Solarite.component.getArg', 'Attribs specified html when not nes
|
|
|
1796
2265
|
|
|
1797
2266
|
let div = document.createElement('div');
|
|
1798
2267
|
div.innerHTML = `<b-514 name="User" userid="2"></b-514>`
|
|
1799
|
-
|
|
1800
|
-
assert.eq(div.outerHTML, `<div><b-514 name="User" userid="2"><!--
|
|
2268
|
+
|
|
2269
|
+
assert.eq(div.outerHTML, `<div><b-514 name="User" userid="2"><!--ExprPath:0-->User | 2<!--ExprPathEnd:1--></b-514></div>`)
|
|
1801
2270
|
|
|
1802
2271
|
});
|
|
1803
2272
|
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
2273
|
Testimony.test('Solarite.component.nested', () => {
|
|
1808
2274
|
|
|
1809
2275
|
let bRenderCount = 0;
|
|
@@ -1828,11 +2294,10 @@ Testimony.test('Solarite.component.nested', () => {
|
|
|
1828
2294
|
assert(!(a.firstChild instanceof B515))
|
|
1829
2295
|
|
|
1830
2296
|
a.render();
|
|
1831
|
-
|
|
2297
|
+
assert(a.firstChild instanceof B515);
|
|
1832
2298
|
assert.eq(getHtml(a), `<a-515><b-515><div>B</div></b-515></a-515>`);
|
|
1833
2299
|
})
|
|
1834
2300
|
|
|
1835
|
-
|
|
1836
2301
|
// Pass an object to the child.
|
|
1837
2302
|
Testimony.test('Solarite.component.nested2', () => {
|
|
1838
2303
|
|
|
@@ -1883,19 +2348,78 @@ Testimony.test('Solarite.component.nested2', () => {
|
|
|
1883
2348
|
a.title = 'Users2'
|
|
1884
2349
|
a.render();
|
|
1885
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>`)
|
|
1886
|
-
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.
|
|
1887
2352
|
|
|
1888
2353
|
a.remove();
|
|
1889
2354
|
});
|
|
1890
2355
|
|
|
2356
|
+
// Pass an object to the child.
|
|
2357
|
+
Testimony.test('Solarite.component.nestedNonSolarite', () => {
|
|
1891
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>`)
|
|
2390
|
+
|
|
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
|
+
});
|
|
1892
2412
|
|
|
1893
2413
|
// TODO: This redraws every tr on every update.
|
|
1894
2414
|
// Maybe that can be fixed when keying is supported?
|
|
1895
2415
|
Testimony.test('Solarite.component.nestedTrLoop', () => {
|
|
1896
2416
|
|
|
1897
2417
|
function tableRow(user) {
|
|
1898
|
-
let tr = r(
|
|
2418
|
+
let tr = r({
|
|
2419
|
+
render() {
|
|
2420
|
+
r(this)`<tr><td>${user.name}</td><td>${user.email}</td></tr>`
|
|
2421
|
+
}
|
|
2422
|
+
})
|
|
1899
2423
|
return tr;
|
|
1900
2424
|
}
|
|
1901
2425
|
|
|
@@ -1929,7 +2453,6 @@ Testimony.test('Solarite.component.nestedTrLoop', () => {
|
|
|
1929
2453
|
table.remove();
|
|
1930
2454
|
});
|
|
1931
2455
|
|
|
1932
|
-
|
|
1933
2456
|
Testimony.test('Solarite.component.nestedComponentTrLoop', () => {
|
|
1934
2457
|
|
|
1935
2458
|
class TR540 extends Solarite('tr') {
|
|
@@ -1973,16 +2496,20 @@ Testimony.test('Solarite.component.nestedComponentTrLoop', () => {
|
|
|
1973
2496
|
|
|
1974
2497
|
table.remove();
|
|
1975
2498
|
});
|
|
2499
|
+
//</editor-fold>
|
|
1976
2500
|
|
|
1977
2501
|
|
|
1978
2502
|
|
|
1979
|
-
// Slots
|
|
1980
2503
|
|
|
2504
|
+
//<editor-fold desc="slots">
|
|
2505
|
+
/* ┌─────────────────╮
|
|
2506
|
+
* | Slots |
|
|
2507
|
+
* └─────────────────╯*/
|
|
1981
2508
|
Testimony.test('Solarite.slots.basic', () => {
|
|
1982
2509
|
|
|
1983
2510
|
class S10 extends Solarite {
|
|
1984
2511
|
render() {
|
|
1985
|
-
this
|
|
2512
|
+
r(this)`<div>slot content:<slot></slot></div>`
|
|
1986
2513
|
}
|
|
1987
2514
|
}
|
|
1988
2515
|
S10.define();
|
|
@@ -2013,9 +2540,31 @@ Testimony.test('Solarite.slots.named', () => {
|
|
|
2013
2540
|
});
|
|
2014
2541
|
|
|
2015
2542
|
|
|
2016
|
-
|
|
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
|
+
|
|
2017
2562
|
|
|
2018
|
-
|
|
2563
|
+
|
|
2564
|
+
//<editor-fold desc="events">
|
|
2565
|
+
/* ┌─────────────────╮
|
|
2566
|
+
* | Events |
|
|
2567
|
+
* └─────────────────╯*/
|
|
2019
2568
|
Testimony.test('Solarite.events.classic', () => {
|
|
2020
2569
|
|
|
2021
2570
|
class Ev10 extends Solarite {
|
|
@@ -2113,10 +2662,110 @@ Testimony.test('Solarite.events.onComponent', 'Event attrib on root component',
|
|
|
2113
2662
|
assert.eq(a.count, '2');
|
|
2114
2663
|
});
|
|
2115
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>
|
|
2761
|
+
|
|
2116
2762
|
|
|
2117
2763
|
|
|
2118
|
-
// Binding
|
|
2119
2764
|
|
|
2765
|
+
//<editor-fold desc="binding">
|
|
2766
|
+
/* ┌─────────────────╮
|
|
2767
|
+
* | Binding |
|
|
2768
|
+
* └─────────────────╯*/
|
|
2120
2769
|
Testimony.test('Solarite.binding.input', () => {
|
|
2121
2770
|
|
|
2122
2771
|
class B10 extends Solarite {
|
|
@@ -2265,8 +2914,6 @@ Testimony.test('Solarite.binding.selectDynamic', () => {
|
|
|
2265
2914
|
b.remove();
|
|
2266
2915
|
});
|
|
2267
2916
|
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
2917
|
Testimony.test('Solarite.binding.number', () => {
|
|
2271
2918
|
|
|
2272
2919
|
class B40 extends Solarite {
|
|
@@ -2295,8 +2942,45 @@ Testimony.test('Solarite.binding.number', () => {
|
|
|
2295
2942
|
b.remove();
|
|
2296
2943
|
});
|
|
2297
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
|
+
|
|
2298
2978
|
|
|
2299
2979
|
|
|
2980
|
+
//<editor-fold desc="watch">
|
|
2981
|
+
/* ┌─────────────────╮
|
|
2982
|
+
* | Watch |
|
|
2983
|
+
* └─────────────────╯*/
|
|
2300
2984
|
/*
|
|
2301
2985
|
Testimony.test('Solarite.watched.watchSet', () => {
|
|
2302
2986
|
|
|
@@ -2837,19 +3521,121 @@ Testimony.test('Solarite.watch2._forEachSpliceInsert', () => {
|
|
|
2837
3521
|
|
|
2838
3522
|
|
|
2839
3523
|
|
|
3524
|
+
Testimony.test('Solarite.watch3.primitive', () => {
|
|
3525
|
+
|
|
3526
|
+
class W100 extends HTMLElement {
|
|
3527
|
+
|
|
3528
|
+
constructor() {
|
|
3529
|
+
super();
|
|
3530
|
+
watch3(this, 'name', 'Fred');
|
|
3531
|
+
|
|
3532
|
+
|
|
3533
|
+
this.render();
|
|
3534
|
+
}
|
|
3535
|
+
|
|
3536
|
+
render() {
|
|
3537
|
+
r(this)`<w-100>${this.name + '!'}</w-100>`;
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
customElements.define('w-100', W100);
|
|
3541
|
+
|
|
3542
|
+
let a = new W100();
|
|
3543
|
+
document.body.append(a);
|
|
3544
|
+
assert(a.outerHTML, `<w-100>Fred!</w-100>`);
|
|
3545
|
+
|
|
3546
|
+
a.name = 'Jim';
|
|
3547
|
+
assert(a.outerHTML, `<w-100>Jim!</w-100>`);
|
|
3548
|
+
|
|
3549
|
+
a.remove();
|
|
3550
|
+
});
|
|
3551
|
+
|
|
2840
3552
|
|
|
3553
|
+
Testimony.test('Solarite.watch3._nodes', () => {
|
|
2841
3554
|
|
|
3555
|
+
class W110 extends HTMLElement {
|
|
3556
|
+
name = 'Fred';
|
|
3557
|
+
name2 = 'White';
|
|
2842
3558
|
|
|
3559
|
+
constructor() {
|
|
3560
|
+
super();
|
|
3561
|
+
watch3(this, 'name');
|
|
3562
|
+
this.render();
|
|
3563
|
+
}
|
|
2843
3564
|
|
|
3565
|
+
render() {
|
|
3566
|
+
r(this)`<w-110>${() => r`<div>${this.name + '!'}</div>`} ${this.name2}</w-110>`;
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
customElements.define('w-110', W110);
|
|
2844
3570
|
|
|
3571
|
+
let a = new W110();
|
|
3572
|
+
document.body.append(a);
|
|
3573
|
+
assert(a.outerHTML, `<w-110><div>Fred!</div> White</w-110>`);
|
|
2845
3574
|
|
|
3575
|
+
a.name = 'Jim';
|
|
3576
|
+
assert(a.outerHTML, `<w-110><div>Jim!</div> White</w-110>`);
|
|
2846
3577
|
|
|
3578
|
+
a.name2 = 'Brown'
|
|
3579
|
+
a.render();
|
|
3580
|
+
assert(a.outerHTML, `<w-110><div>Jim!</div> Brown</w-110>`);
|
|
2847
3581
|
|
|
3582
|
+
a.remove();
|
|
3583
|
+
});
|
|
3584
|
+
//</editor-fold>
|
|
2848
3585
|
|
|
2849
3586
|
|
|
2850
|
-
Testimony.test('Solarite.full.treeItems', () => {
|
|
2851
3587
|
|
|
2852
|
-
|
|
3588
|
+
|
|
3589
|
+
//<editor-fold desc="full">
|
|
3590
|
+
/* ┌─────────────────╮
|
|
3591
|
+
* | Full |
|
|
3592
|
+
* └─────────────────╯*/
|
|
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
|
+
}
|
|
3601
|
+
|
|
3602
|
+
addItem() {
|
|
3603
|
+
this.items.push({name: '', qty: 0});
|
|
3604
|
+
this.render();
|
|
3605
|
+
}
|
|
3606
|
+
|
|
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'
|
|
2853
3639
|
|
|
2854
3640
|
class TreeItem extends Solarite {
|
|
2855
3641
|
|
|
@@ -2866,13 +3652,13 @@ Testimony.test('Solarite.full.treeItems', () => {
|
|
|
2866
3652
|
}
|
|
2867
3653
|
|
|
2868
3654
|
render() {
|
|
2869
|
-
this
|
|
3655
|
+
r(this)`
|
|
2870
3656
|
<tree-item>
|
|
2871
3657
|
<style>
|
|
2872
3658
|
:host #childItems { padding-left: 20px }
|
|
2873
3659
|
</style>
|
|
2874
3660
|
<div onclick="${this.toggleChildren}">${this.titleText}</div>
|
|
2875
|
-
<div
|
|
3661
|
+
<div hidden="${!this.showChildren}">
|
|
2876
3662
|
${this.childItems}
|
|
2877
3663
|
</div>
|
|
2878
3664
|
</tree-item>`;
|
|
@@ -2894,3 +3680,159 @@ Testimony.test('Solarite.full.treeItems', () => {
|
|
|
2894
3680
|
});
|
|
2895
3681
|
|
|
2896
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
|
+
|