solarite 0.1.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/build/build.bat +3 -0
- package/build/build.js +139 -0
- package/build/lib/rollup.min.js +11 -0
- package/build/lib/source-map.min.js +1 -0
- package/build/lib/terser.min.js +1 -0
- package/dist/Solarite-debug.js +4143 -0
- package/dist/Solarite.js +3740 -0
- package/dist/Solarite.min.js +4 -0
- package/docs/index.md +423 -0
- package/docs/js/Playground.js +184 -0
- package/docs/js/codemirror/codemirror6.js +32036 -0
- package/docs/js/codemirror/themeSolarIce.js +312 -0
- package/docs/js/documentation.js +32 -0
- package/docs/js/ui/CodeEditor.js +840 -0
- package/docs/js/ui/DarkToggle.js +52 -0
- package/docs/js/ui/FlexResizer.js +142 -0
- package/docs/js/util/Draggable2.js +151 -0
- package/docs/js/util/Errors.js +9 -0
- package/docs/js/util/Html.js +147 -0
- package/docs/js/util/Icons.js +623 -0
- package/docs/js/util/Input.js +253 -0
- package/docs/js/util/Util.js +88 -0
- package/docs/js/util/delve.js +43 -0
- package/docs/media/FiraCode400.woff2 +0 -0
- package/docs/media/cabin-latin-700.woff2 +0 -0
- package/docs/media/documentation.css +93 -0
- package/docs/media/eternium.css +1123 -0
- package/docs/media/solarite-machine.webp +0 -0
- package/index.html +325 -0
- package/package.json +33 -0
- package/readme.md +3 -0
- package/src/solarite/ExprPath.js +554 -0
- package/src/solarite/MultiValueMap.js +65 -0
- package/src/solarite/NodeGroup.js +706 -0
- package/src/solarite/NodeGroupManager.js +582 -0
- package/src/solarite/Shell.js +307 -0
- package/src/solarite/Solarite.js +19 -0
- package/src/solarite/Template.js +85 -0
- package/src/solarite/Util.js +264 -0
- package/src/solarite/createSolarite.js +267 -0
- package/src/solarite/getArg.js +99 -0
- package/src/solarite/hash.js +101 -0
- package/src/solarite/r.js +143 -0
- package/src/solarite/udomdiff.js +233 -0
- package/src/solarite/watch.js +302 -0
- package/src/solarite/watch2.js +439 -0
- package/src/unused/FastLookupArray.js +54 -0
- package/src/unused/Hashes.js +339 -0
- package/src/unused/InUse.test.js +92 -0
- package/src/unused/InUseMap.js +98 -0
- package/src/unused/LinkedList.js +117 -0
- package/src/unused/LinkedList.test.js +115 -0
- package/src/unused/Perf.js +47 -0
- package/src/unused/Template.js +108 -0
- package/src/util/Errors.js +9 -0
- package/src/util/Util.js +88 -0
- package/src/util/delve.js +43 -0
- package/tests/Benchmark.test.js +319 -0
- package/tests/NodeGroup.test.js +115 -0
- package/tests/Shell.test.js +75 -0
- package/tests/Solarite.test.js +2896 -0
- package/tests/Testimony.js +602 -0
- package/tests/index.html +75 -0
|
@@ -0,0 +1,2896 @@
|
|
|
1
|
+
// noinspection DuplicatedCode
|
|
2
|
+
|
|
3
|
+
import {camelToDashes, htmlContext} from "../src/solarite/Util.js";
|
|
4
|
+
import {watchGet, watchSet} from "../src/solarite/watch.js";
|
|
5
|
+
import Testimony, {assert} from './Testimony.js';
|
|
6
|
+
Testimony.enableJsDom();
|
|
7
|
+
|
|
8
|
+
import {Solarite, r} from '../src/solarite/Solarite.js';
|
|
9
|
+
//import {Red, r, Perf} from '../dist/Solarite.min.js'; // This will help the Benchmark test warm up.
|
|
10
|
+
import {watch} from "../src/solarite/watch2.js";
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Testimony.test('Util.htmlContext', () => {
|
|
15
|
+
assert.eq(htmlContext('<div class="test'), htmlContext.Attribute)
|
|
16
|
+
assert.eq(htmlContext('">hello '), htmlContext.Text);
|
|
17
|
+
assert.eq(htmlContext('<span data-attr="hi > there"'), htmlContext.Tag);
|
|
18
|
+
assert.eq(htmlContext(` attr='`), htmlContext.Attribute);
|
|
19
|
+
assert.eq(htmlContext(`'`), htmlContext.Tag);
|
|
20
|
+
assert.eq(htmlContext(' attr='), htmlContext.Attribute);
|
|
21
|
+
assert.eq(htmlContext('a'), htmlContext.Attribute);
|
|
22
|
+
assert.eq(htmlContext(' '), htmlContext.Tag);
|
|
23
|
+
assert.eq(htmlContext(' attr='), htmlContext.Attribute);
|
|
24
|
+
assert.eq(htmlContext('>'), htmlContext.Text);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
Testimony.test('Util.camelToDashes', () => {
|
|
28
|
+
assert.eq(camelToDashes('ProperName'), 'proper-name');
|
|
29
|
+
assert.eq(camelToDashes('HTMLElement'), 'html-element');
|
|
30
|
+
assert.eq(camelToDashes('BigUI'), 'big-ui');
|
|
31
|
+
assert.eq(camelToDashes('UIForm'), 'ui-form');
|
|
32
|
+
assert.eq(camelToDashes('A100'), 'a-100');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
Testimony.test('Solarite.basic.empty', () => {
|
|
36
|
+
class A extends HTMLElement {
|
|
37
|
+
constructor() {
|
|
38
|
+
super();
|
|
39
|
+
this.render();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
render() {
|
|
43
|
+
r(this)``
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
customElements.define('r-10', A);
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
let a = new A();
|
|
50
|
+
assert.eq(getHtml(a), '<r-10></r-10>');
|
|
51
|
+
assert.eq(a.childNodes.length, 0);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
Testimony.test('Solarite.basic.empty2', () => {
|
|
56
|
+
|
|
57
|
+
class R11 extends Solarite {
|
|
58
|
+
constructor(args) {
|
|
59
|
+
super();
|
|
60
|
+
// console.log(args)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
render() {
|
|
64
|
+
this.html = r`<r-11></r-11>`
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
R11.define();
|
|
68
|
+
|
|
69
|
+
let a = r(`<r-11 title="Hello"></r-11>`);
|
|
70
|
+
assert.eq(a.outerHTML, `<r-11 title="Hello"></r-11>`);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
Testimony.test('Solarite.basic.text', () => {
|
|
76
|
+
class A extends Solarite {
|
|
77
|
+
render() {
|
|
78
|
+
r(this)`Here's Solarite <Component>` // apostophe, <>, and and unicode.
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
customElements.define('r-15', A);
|
|
82
|
+
|
|
83
|
+
let a = new A();
|
|
84
|
+
document.body.append(a); // Calls render()
|
|
85
|
+
|
|
86
|
+
assert.eq(getHtml(a), '<r-15>Here\'s Solarite <Component></r-15>');
|
|
87
|
+
assert.eq(a.childNodes.length, 1);
|
|
88
|
+
|
|
89
|
+
a.remove();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
Testimony.test('Solarite.basic.manualRender', () => {
|
|
94
|
+
|
|
95
|
+
let children1, children2;
|
|
96
|
+
|
|
97
|
+
class A extends Solarite {
|
|
98
|
+
constructor() {
|
|
99
|
+
super();
|
|
100
|
+
children1 = [...this.childNodes]
|
|
101
|
+
this.render();
|
|
102
|
+
children2 = [...this.childNodes]
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
render() {
|
|
106
|
+
r(this)`Solarite Component`
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
customElements.define('r-20', A);
|
|
110
|
+
|
|
111
|
+
let a = new A();
|
|
112
|
+
|
|
113
|
+
assert.eq(children1.length, 0);
|
|
114
|
+
assert.eq(children2.length, 1);
|
|
115
|
+
assert.eq(children2[0].textContent, 'Solarite Component');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
Testimony.test('Solarite.basic.pseudoRoot', () => {
|
|
121
|
+
class R30 extends Solarite {
|
|
122
|
+
render() {
|
|
123
|
+
this.html = r`<r-30 title="Hello">World</r-30>`
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let a = new R30();
|
|
128
|
+
a.render();
|
|
129
|
+
|
|
130
|
+
assert.eq(getHtml(a), `<r-30 title="Hello">World</r-30>`)
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
Testimony.test('Solarite.basic.createElement', () => {
|
|
135
|
+
class R35 extends Solarite {
|
|
136
|
+
constructor() {
|
|
137
|
+
super();
|
|
138
|
+
//this.render(); // If uncommented, we get browser error:
|
|
139
|
+
// "Uncaught DOMException: Failed to construct 'CustomElement': The result must not have children"
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
render() {
|
|
143
|
+
this.html = r`<div>Hello!</div>`
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
R35.define();
|
|
147
|
+
|
|
148
|
+
let a = document.createElement('r-35');
|
|
149
|
+
|
|
150
|
+
assert.eq(getHtml(a), `<r-35></r-35>`); // Not rendered yet.
|
|
151
|
+
assert(a instanceof Solarite);
|
|
152
|
+
|
|
153
|
+
a.render();
|
|
154
|
+
assert.eq(getHtml(a), `<r-35><div>Hello!</div></r-35>`);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
// Expr
|
|
159
|
+
Testimony.test('Solarite.expr.staticString', () => {
|
|
160
|
+
class R40 extends Solarite {
|
|
161
|
+
render() {
|
|
162
|
+
r(this)`Solarite ${'🟥'} Component`
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let a = new R40();
|
|
167
|
+
document.body.append(a);
|
|
168
|
+
|
|
169
|
+
assert.eq(getHtml(a), '<r-40>Solarite 🟥 Component</r-40>');
|
|
170
|
+
|
|
171
|
+
a.remove();
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
Testimony.test('Solarite.expr.htmlString', () => {
|
|
176
|
+
|
|
177
|
+
class A extends Solarite {
|
|
178
|
+
constructor() {
|
|
179
|
+
super();
|
|
180
|
+
this.render();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
render() {
|
|
184
|
+
r(this)`This text is ${r(`<b>Bold</b>`)}!`
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
A.define('r-42');
|
|
188
|
+
|
|
189
|
+
let a = new A();
|
|
190
|
+
assert.eq(getHtml(a), '<r-42>This text is <b>Bold</b>!</r-42>');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
Testimony.test('Solarite.expr.table', () => {
|
|
195
|
+
|
|
196
|
+
class R43 extends Solarite {
|
|
197
|
+
constructor() {
|
|
198
|
+
super();
|
|
199
|
+
this.render();
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
render() {
|
|
203
|
+
r(this)`<table><tr>${r(`<td>Table Cell</td>`)}</tr></table>`
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
let a = new R43();
|
|
207
|
+
|
|
208
|
+
assert.eq(getHtml(a), `<r-43><table><tbody><tr><td>Table Cell</td></tr></tbody></table></r-43>`)
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
Testimony.test('Solarite.expr.documentFragment', () => {
|
|
213
|
+
|
|
214
|
+
class R44 extends Solarite {
|
|
215
|
+
render() {
|
|
216
|
+
r(this)`This text is ${r(`<b>Bold</b><i>Italic</i>`)}!`
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let a = new R44({render:true}); // auto render on construct.
|
|
221
|
+
assert.eq(getHtml(a), '<r-44>This text is <b>Bold</b><i>Italic</i>!</r-44>');
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
Testimony.test('Solarite.expr.undefined', () => {
|
|
225
|
+
class A extends Solarite {
|
|
226
|
+
constructor() {
|
|
227
|
+
super();
|
|
228
|
+
this.render();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
render() {
|
|
232
|
+
r(this)`${this.valueless}` // Make sure it renders undefined as ''
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
customElements.define('r-80', A);
|
|
236
|
+
|
|
237
|
+
let a = new A();
|
|
238
|
+
assert.eq(getHtml(a), '<r-80></r-80>');
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
Testimony.test('Solarite.expr.staticNumber', () => {
|
|
242
|
+
class A extends Solarite {
|
|
243
|
+
constructor() {
|
|
244
|
+
super();
|
|
245
|
+
this.render();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
render() {
|
|
249
|
+
r(this)`Solarite ${123} Component`
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
customElements.define('r-46', A);
|
|
253
|
+
|
|
254
|
+
let a = new A();
|
|
255
|
+
assert.eq(getHtml(a), '<r-46>Solarite 123 Component</r-46>');
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
Testimony.test('Solarite.expr.staticDate', () => {
|
|
260
|
+
class A extends Solarite {
|
|
261
|
+
constructor() {
|
|
262
|
+
super();
|
|
263
|
+
this.render();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
render() {
|
|
267
|
+
r(this)`${new Date('2010-02-01 00:00:00').getUTCFullYear()}`
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
customElements.define('r-50', A);
|
|
271
|
+
|
|
272
|
+
let a = new A();
|
|
273
|
+
assert.eq(getHtml(a), '<r-50>2010</r-50>');
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
Testimony.test('Solarite.expr.staticArray', () => {
|
|
277
|
+
class A extends Solarite {
|
|
278
|
+
constructor() {
|
|
279
|
+
super();
|
|
280
|
+
this.render();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
render() {
|
|
284
|
+
r(this)`Items: ${[1, 2, 3]}`
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
customElements.define('r-52', A);
|
|
288
|
+
|
|
289
|
+
let a = new A();
|
|
290
|
+
assert.eq(getHtml(a), '<r-52>Items: 123</r-52>');
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
Testimony.test('Solarite.expr.array', () => {
|
|
295
|
+
class A extends Solarite {
|
|
296
|
+
fruits = ['Apple', 'Banana'];
|
|
297
|
+
|
|
298
|
+
render() {
|
|
299
|
+
r(this)`${this.fruits}`
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
customElements.define('r-60', A);
|
|
303
|
+
let a = new A();
|
|
304
|
+
|
|
305
|
+
document.body.append(a);
|
|
306
|
+
assert.eq(getHtml(a), '<r-60>AppleBanana</r-60>');
|
|
307
|
+
|
|
308
|
+
a.fruits.push('Cherry');
|
|
309
|
+
a.render();
|
|
310
|
+
assert.eq(getHtml(a), '<r-60>AppleBananaCherry</r-60>');
|
|
311
|
+
|
|
312
|
+
a.fruits.pop();
|
|
313
|
+
a.render();
|
|
314
|
+
assert.eq(getHtml(a), '<r-60>AppleBanana</r-60>');
|
|
315
|
+
|
|
316
|
+
a.fruits.shift();
|
|
317
|
+
a.render();
|
|
318
|
+
assert.eq(getHtml(a), '<r-60>Banana</r-60>');
|
|
319
|
+
|
|
320
|
+
a.remove();
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
Testimony.test('Solarite.expr.arrayReverse', () => {
|
|
325
|
+
class A extends Solarite {
|
|
326
|
+
fruits = ['Apple', 'Banana', 'Cherry', 'Dragonfruit'];
|
|
327
|
+
|
|
328
|
+
render() {
|
|
329
|
+
r(this)`${this.fruits}`
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
customElements.define('r-62', A);
|
|
333
|
+
let a = new A();
|
|
334
|
+
|
|
335
|
+
a.render();
|
|
336
|
+
assert.eq(getHtml(a), '<r-62>AppleBananaCherryDragonfruit</r-62>');
|
|
337
|
+
|
|
338
|
+
a.fruits.reverse();
|
|
339
|
+
a.render();
|
|
340
|
+
assert.eq(getHtml(a), '<r-62>DragonfruitCherryBananaApple</r-62>');
|
|
341
|
+
|
|
342
|
+
a.fruits.reverse();
|
|
343
|
+
a.render();
|
|
344
|
+
assert.eq(getHtml(a), '<r-62>AppleBananaCherryDragonfruit</r-62>');
|
|
345
|
+
|
|
346
|
+
a.fruits.shift();
|
|
347
|
+
a.render();
|
|
348
|
+
assert.eq(getHtml(a), '<r-62>BananaCherryDragonfruit</r-62>');
|
|
349
|
+
|
|
350
|
+
a.fruits.reverse();
|
|
351
|
+
a.render();
|
|
352
|
+
assert.eq(getHtml(a), '<r-62>DragonfruitCherryBanana</r-62>');
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
Testimony.test('Solarite.expr.twoArrays', () => {
|
|
358
|
+
class A extends Solarite {
|
|
359
|
+
fruits = ['Apple'];
|
|
360
|
+
pets = ['Cat'];
|
|
361
|
+
|
|
362
|
+
render() {
|
|
363
|
+
r(this)`${this.fruits}${this.pets}`
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
customElements.define('r-65', A);
|
|
367
|
+
let a = new A();
|
|
368
|
+
|
|
369
|
+
a.render();
|
|
370
|
+
assert.eq(getHtml(a), '<r-65>AppleCat</r-65>');
|
|
371
|
+
|
|
372
|
+
a.fruits.push('Banana');
|
|
373
|
+
a.render();
|
|
374
|
+
assert.eq(getHtml(a), '<r-65>AppleBananaCat</r-65>');
|
|
375
|
+
|
|
376
|
+
a.pets.push('Dog');
|
|
377
|
+
a.render();
|
|
378
|
+
assert.eq(getHtml(a), '<r-65>AppleBananaCatDog</r-65>');
|
|
379
|
+
|
|
380
|
+
a.pets.reverse();
|
|
381
|
+
a.fruits.reverse();
|
|
382
|
+
a.render();
|
|
383
|
+
assert.eq(getHtml(a), '<r-65>BananaAppleDogCat</r-65>');
|
|
384
|
+
|
|
385
|
+
a.pets.reverse();
|
|
386
|
+
a.fruits.reverse();
|
|
387
|
+
a.render();
|
|
388
|
+
assert.eq(getHtml(a), '<r-65>AppleBananaCatDog</r-65>');
|
|
389
|
+
|
|
390
|
+
a.fruits.shift();
|
|
391
|
+
a.render();
|
|
392
|
+
assert.eq(getHtml(a), '<r-65>BananaCatDog</r-65>');
|
|
393
|
+
|
|
394
|
+
a.fruits.shift();
|
|
395
|
+
a.render();
|
|
396
|
+
assert.eq(getHtml(a), '<r-65>CatDog</r-65>');
|
|
397
|
+
|
|
398
|
+
a.pets.shift();
|
|
399
|
+
a.render();
|
|
400
|
+
assert.eq(getHtml(a), '<r-65>Dog</r-65>');
|
|
401
|
+
|
|
402
|
+
a.pets.shift();
|
|
403
|
+
a.render();
|
|
404
|
+
assert.eq(getHtml(a), '<r-65></r-65>');
|
|
405
|
+
|
|
406
|
+
a.fruits.push('Apple');
|
|
407
|
+
a.render();
|
|
408
|
+
assert.eq(getHtml(a), '<r-65>Apple</r-65>');
|
|
409
|
+
|
|
410
|
+
a.pets.push('Cat');
|
|
411
|
+
a.render();
|
|
412
|
+
assert.eq(getHtml(a), '<r-65>AppleCat</r-65>');
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
Testimony.test('Solarite.expr.staticFunction', () => {
|
|
416
|
+
class A extends Solarite {
|
|
417
|
+
constructor() {
|
|
418
|
+
super();
|
|
419
|
+
this.render();
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
render() {
|
|
423
|
+
r(this)`Items: ${() => [1, 2, 3]}`
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
customElements.define('r-70', A);
|
|
427
|
+
|
|
428
|
+
let a = new A();
|
|
429
|
+
assert.eq(getHtml(a), '<r-70>Items: 123</r-70>');
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
Testimony.test('Solarite.expr.staticElement', () => {
|
|
433
|
+
class A extends Solarite {
|
|
434
|
+
constructor() {
|
|
435
|
+
super();
|
|
436
|
+
this.render();
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
render() {
|
|
440
|
+
r(this)`Field: ${document.createElement('input')}`
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
customElements.define('r-74', A);
|
|
444
|
+
|
|
445
|
+
let a = new A();
|
|
446
|
+
assert.eq(getHtml(a), '<r-74>Field: <input></r-74>');
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
Testimony.test('Solarite.expr.varText', () => {
|
|
451
|
+
class A extends Solarite {
|
|
452
|
+
value = 'Apple';
|
|
453
|
+
|
|
454
|
+
render() { r(this)`The fruit is ${this.value}!` }
|
|
455
|
+
}
|
|
456
|
+
customElements.define('r-90', A);
|
|
457
|
+
|
|
458
|
+
let a = new A();
|
|
459
|
+
a.render();
|
|
460
|
+
|
|
461
|
+
assert.eq(getHtml(a), '<r-90>The fruit is Apple!</r-90>');
|
|
462
|
+
assert.eq(a.childNodes.length, 3);
|
|
463
|
+
|
|
464
|
+
a.value = 'Banana';
|
|
465
|
+
a.render();
|
|
466
|
+
assert.eq(getHtml(a), '<r-90>The fruit is Banana!</r-90>');
|
|
467
|
+
assert.eq(a.childNodes.length, 3);
|
|
468
|
+
|
|
469
|
+
a.value = 'Cherry';
|
|
470
|
+
a.render();
|
|
471
|
+
assert.eq(getHtml(a), '<r-90>The fruit is Cherry!</r-90>');
|
|
472
|
+
assert.eq(a.childNodes.length, 3);
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
Testimony.test('Solarite.expr.cyclicRef', () => {
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
class R100 extends Solarite {
|
|
481
|
+
value = { name: 'Apple', self: null };
|
|
482
|
+
|
|
483
|
+
render() {
|
|
484
|
+
this.html = r`The fruit is ${this.value.name}!`
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
let a = new R100();
|
|
489
|
+
a.value.self = a; // cyclic reference.
|
|
490
|
+
a.render();
|
|
491
|
+
|
|
492
|
+
assert.eq(getHtml(a), '<r-100>The fruit is Apple!</r-100>');
|
|
493
|
+
|
|
494
|
+
a.value.name = 'Banana';
|
|
495
|
+
a.render();
|
|
496
|
+
assert.eq(getHtml(a), '<r-100>The fruit is Banana!</r-100>');
|
|
497
|
+
|
|
498
|
+
a.value.name = 'Cherry';
|
|
499
|
+
a.render();
|
|
500
|
+
assert.eq(getHtml(a), '<r-100>The fruit is Cherry!</r-100>');
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
// Loop:
|
|
511
|
+
Testimony.test('Solarite.loop.strings', () => {
|
|
512
|
+
class A extends Solarite {
|
|
513
|
+
fruits = ['Apple', 'Banana'];
|
|
514
|
+
|
|
515
|
+
render() {
|
|
516
|
+
r(this)`${this.fruits.map(fruit => fruit)}`
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
customElements.define('r-200', A);
|
|
520
|
+
let a = new A();
|
|
521
|
+
|
|
522
|
+
a.render();
|
|
523
|
+
assert.eq(getHtml(a), '<r-200>AppleBanana</r-200>');
|
|
524
|
+
|
|
525
|
+
a.fruits.push('Cherry');
|
|
526
|
+
a.render();
|
|
527
|
+
assert.eq(getHtml(a), '<r-200>AppleBananaCherry</r-200>');
|
|
528
|
+
|
|
529
|
+
a.fruits.pop();
|
|
530
|
+
a.render();
|
|
531
|
+
assert.eq(getHtml(a), '<r-200>AppleBanana</r-200>');
|
|
532
|
+
|
|
533
|
+
a.fruits.shift();
|
|
534
|
+
a.render();
|
|
535
|
+
assert.eq(getHtml(a), '<r-200>Banana</r-200>');
|
|
536
|
+
|
|
537
|
+
a.fruits.shift();
|
|
538
|
+
a.render();
|
|
539
|
+
assert.eq(getHtml(a), '<r-200></r-200>');
|
|
540
|
+
|
|
541
|
+
a.fruits.push('Apple');
|
|
542
|
+
a.render();
|
|
543
|
+
assert.eq(getHtml(a), '<r-200>Apple</r-200>');
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
Testimony.test('Solarite.loop.paragraphs', () => {
|
|
548
|
+
class A extends Solarite {
|
|
549
|
+
fruits = ['Apple', 'Banana'];
|
|
550
|
+
|
|
551
|
+
render() {
|
|
552
|
+
r(this)`${this.fruits.map(fruit => r`<p>${fruit}</p>`)}`
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
customElements.define('r-210', A);
|
|
556
|
+
let a = new A();
|
|
557
|
+
document.body.append(a);
|
|
558
|
+
|
|
559
|
+
assert.eq(getHtml(a), '<r-210><p>Apple</p><p>Banana</p></r-210>');
|
|
560
|
+
|
|
561
|
+
a.fruits.push('Cherry');
|
|
562
|
+
a.render();
|
|
563
|
+
assert.eq(getHtml(a), '<r-210><p>Apple</p><p>Banana</p><p>Cherry</p></r-210>');
|
|
564
|
+
|
|
565
|
+
a.fruits.pop();
|
|
566
|
+
a.render();
|
|
567
|
+
assert.eq(getHtml(a), '<r-210><p>Apple</p><p>Banana</p></r-210>');
|
|
568
|
+
|
|
569
|
+
a.fruits.shift();
|
|
570
|
+
a.render();
|
|
571
|
+
assert.eq(getHtml(a), '<r-210><p>Banana</p></r-210>');
|
|
572
|
+
|
|
573
|
+
a.fruits.shift();
|
|
574
|
+
a.render();
|
|
575
|
+
assert.eq(getHtml(a), '<r-210></r-210>');
|
|
576
|
+
|
|
577
|
+
a.fruits.push('Apple');
|
|
578
|
+
a.render();
|
|
579
|
+
assert.eq(getHtml(a), '<r-210><p>Apple</p></r-210>');
|
|
580
|
+
|
|
581
|
+
a.remove();
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
Testimony.test('Solarite.loop.paragraphsBefore', () => {
|
|
586
|
+
class A extends Solarite {
|
|
587
|
+
fruits = ['Apple', 'Banana'];
|
|
588
|
+
|
|
589
|
+
render() {
|
|
590
|
+
r(this)`${this.fruits.map(fruit => r`<p>${fruit}</p>`)}<hr>`
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
customElements.define('r-212', A);
|
|
594
|
+
let a = new A();
|
|
595
|
+
document.body.append(a);
|
|
596
|
+
|
|
597
|
+
assert.eq(getHtml(a), '<r-212><p>Apple</p><p>Banana</p><hr></r-212>');
|
|
598
|
+
|
|
599
|
+
a.fruits.push('Cherry');
|
|
600
|
+
a.render();
|
|
601
|
+
assert.eq(getHtml(a), '<r-212><p>Apple</p><p>Banana</p><p>Cherry</p><hr></r-212>');
|
|
602
|
+
|
|
603
|
+
a.fruits.pop();
|
|
604
|
+
a.render();
|
|
605
|
+
assert.eq(getHtml(a), '<r-212><p>Apple</p><p>Banana</p><hr></r-212>');
|
|
606
|
+
|
|
607
|
+
a.fruits.shift();
|
|
608
|
+
a.render();
|
|
609
|
+
assert.eq(getHtml(a), '<r-212><p>Banana</p><hr></r-212>');
|
|
610
|
+
|
|
611
|
+
a.fruits.shift();
|
|
612
|
+
a.render();
|
|
613
|
+
assert.eq(getHtml(a), '<r-212><hr></r-212>');
|
|
614
|
+
|
|
615
|
+
a.fruits.push('Apple');
|
|
616
|
+
a.render();
|
|
617
|
+
assert.eq(getHtml(a), '<r-212><p>Apple</p><hr></r-212>');
|
|
618
|
+
|
|
619
|
+
a.remove();
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
Testimony.test('Solarite.loop.eventBindings', async () => {
|
|
623
|
+
await new Promise((resolve, reject) => {
|
|
624
|
+
let callCount = 0;
|
|
625
|
+
|
|
626
|
+
class R215 extends Solarite {
|
|
627
|
+
fruits = ['Apple', 'Banana'];
|
|
628
|
+
|
|
629
|
+
checkFruit(fruit, i) {
|
|
630
|
+
assert.eq(i, 0)
|
|
631
|
+
|
|
632
|
+
callCount++;
|
|
633
|
+
if (callCount===2)
|
|
634
|
+
resolve();
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
render() {
|
|
638
|
+
this.html = r`${this.fruits.map((fruit, i) => r`<p onclick="${() => this.checkFruit(fruit, i)}">${fruit}</p>`)}`
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
let a = new R215();
|
|
643
|
+
document.body.append(a);
|
|
644
|
+
a.firstElementChild.dispatchEvent(new MouseEvent('click'))
|
|
645
|
+
|
|
646
|
+
a.fruits.shift();
|
|
647
|
+
a.render();
|
|
648
|
+
a.firstElementChild.dispatchEvent(new MouseEvent('click'))
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
a.remove();
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
Testimony.test('Solarite.loop.pathCache', () => {
|
|
658
|
+
|
|
659
|
+
class R216 extends Solarite {
|
|
660
|
+
pets = ['Cat'];
|
|
661
|
+
fruits = ['Apple', 'Banana'];
|
|
662
|
+
|
|
663
|
+
render() {
|
|
664
|
+
r(this)`${this.pets.map(pet =>
|
|
665
|
+
r`${this.fruits.map(fruit =>
|
|
666
|
+
r`<p>Item</p>`
|
|
667
|
+
)}`
|
|
668
|
+
)}`
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
let a = new R216();
|
|
673
|
+
document.body.append(a);
|
|
674
|
+
a.render();
|
|
675
|
+
assert.eq(getHtml(a), `<r-216><p>Item</p><p>Item</p></r-216>`);
|
|
676
|
+
|
|
677
|
+
a.fruits.shift();
|
|
678
|
+
a.render();
|
|
679
|
+
assert.eq(getHtml(a), `<r-216><p>Item</p></r-216>`);
|
|
680
|
+
|
|
681
|
+
a.remove();
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
Testimony.test('Solarite.loop.nested', () => {
|
|
685
|
+
|
|
686
|
+
class A extends Solarite {
|
|
687
|
+
pets = ['Cat', 'Dog'];
|
|
688
|
+
fruits = ['Apple', 'Banana'];
|
|
689
|
+
|
|
690
|
+
render() {
|
|
691
|
+
r(this)`${this.pets.map(pet =>
|
|
692
|
+
r`${this.fruits.map(fruit =>
|
|
693
|
+
r`<p>${pet} eats ${fruit}</p>`
|
|
694
|
+
)}`
|
|
695
|
+
)}`
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
customElements.define('r-220', A);
|
|
699
|
+
|
|
700
|
+
let a = new A();
|
|
701
|
+
document.body.append(a);
|
|
702
|
+
a.render();
|
|
703
|
+
assert.eq(getHtml(a), `<r-220><p>Cat eats Apple</p><p>Cat eats Banana</p><p>Dog eats Apple</p><p>Dog eats Banana</p></r-220>`);
|
|
704
|
+
|
|
705
|
+
a.fruits.shift();
|
|
706
|
+
a.render();
|
|
707
|
+
assert.eq(getHtml(a), `<r-220><p>Cat eats Banana</p><p>Dog eats Banana</p></r-220>`);
|
|
708
|
+
|
|
709
|
+
a.fruits.unshift('Apricot');
|
|
710
|
+
a.render();
|
|
711
|
+
assert.eq(getHtml(a), `<r-220><p>Cat eats Apricot</p><p>Cat eats Banana</p><p>Dog eats Apricot</p><p>Dog eats Banana</p></r-220>`);
|
|
712
|
+
|
|
713
|
+
a.pets.pop();
|
|
714
|
+
a.render();
|
|
715
|
+
assert.eq(getHtml(a), `<r-220><p>Cat eats Apricot</p><p>Cat eats Banana</p></r-220>`);
|
|
716
|
+
|
|
717
|
+
a.pets.unshift('Bird');
|
|
718
|
+
a.render();
|
|
719
|
+
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>`);
|
|
720
|
+
|
|
721
|
+
a.pets.reverse();
|
|
722
|
+
a.render();
|
|
723
|
+
assert.eq(getHtml(a), `<r-220><p>Cat eats Apricot</p><p>Cat eats Banana</p><p>Bird eats Apricot</p><p>Bird eats Banana</p></r-220>`);
|
|
724
|
+
|
|
725
|
+
a.fruits.reverse();
|
|
726
|
+
a.render();
|
|
727
|
+
assert.eq(getHtml(a), `<r-220><p>Cat eats Banana</p><p>Cat eats Apricot</p><p>Bird eats Banana</p><p>Bird eats Apricot</p></r-220>`);
|
|
728
|
+
|
|
729
|
+
a.pets.reverse();
|
|
730
|
+
a.fruits.reverse();
|
|
731
|
+
a.render();
|
|
732
|
+
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
|
+
|
|
734
|
+
a.pets.pop();
|
|
735
|
+
a.render();
|
|
736
|
+
assert.eq(getHtml(a), `<r-220><p>Bird eats Apricot</p><p>Bird eats Banana</p></r-220>`);
|
|
737
|
+
|
|
738
|
+
a.pets.pop();
|
|
739
|
+
a.render();
|
|
740
|
+
assert.eq(getHtml(a), `<r-220></r-220>`);
|
|
741
|
+
|
|
742
|
+
a.remove();
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
Testimony.test('Solarite.loop.nested2', () => {
|
|
746
|
+
|
|
747
|
+
class A extends Solarite {
|
|
748
|
+
fruits = ['Apple', 'Banana'];
|
|
749
|
+
pets = ['Cat', 'Dog'];
|
|
750
|
+
|
|
751
|
+
render() {
|
|
752
|
+
r(this)`${this.pets.map(pet =>
|
|
753
|
+
r`<div>${this.fruits.map(fruit =>
|
|
754
|
+
r`<p>${pet} eats ${fruit}</p>`
|
|
755
|
+
)}</div>`
|
|
756
|
+
)}`
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
customElements.define('r-224', A);
|
|
760
|
+
|
|
761
|
+
let a = new A();
|
|
762
|
+
document.body.append(a);
|
|
763
|
+
a.render();
|
|
764
|
+
assert.eq(getHtml(a), `<r-224><div><p>Cat eats Apple</p><p>Cat eats Banana</p></div><div><p>Dog eats Apple</p><p>Dog eats Banana</p></div></r-224>`);
|
|
765
|
+
|
|
766
|
+
a.fruits.shift();
|
|
767
|
+
a.render();
|
|
768
|
+
assert.eq(getHtml(a), `<r-224><div><p>Cat eats Banana</p></div><div><p>Dog eats Banana</p></div></r-224>`);
|
|
769
|
+
|
|
770
|
+
a.fruits.unshift('Apricot');
|
|
771
|
+
a.render();
|
|
772
|
+
assert.eq(getHtml(a), `<r-224><div><p>Cat eats Apricot</p><p>Cat eats Banana</p></div><div><p>Dog eats Apricot</p><p>Dog eats Banana</p></div></r-224>`);
|
|
773
|
+
|
|
774
|
+
a.pets.pop(); // remove Dog.
|
|
775
|
+
a.render();
|
|
776
|
+
assert.eq(getHtml(a), `<r-224><div><p>Cat eats Apricot</p><p>Cat eats Banana</p></div></r-224>`);
|
|
777
|
+
|
|
778
|
+
a.pets.unshift('Bird');
|
|
779
|
+
a.render();
|
|
780
|
+
assert.eq(getHtml(a), `<r-224><div><p>Bird eats Apricot</p><p>Bird eats Banana</p></div><div><p>Cat eats Apricot</p><p>Cat eats Banana</p></div></r-224>`);
|
|
781
|
+
|
|
782
|
+
a.pets.reverse();
|
|
783
|
+
a.render();
|
|
784
|
+
assert.eq(getHtml(a), `<r-224><div><p>Cat eats Apricot</p><p>Cat eats Banana</p></div><div><p>Bird eats Apricot</p><p>Bird eats Banana</p></div></r-224>`);
|
|
785
|
+
|
|
786
|
+
a.fruits.reverse();
|
|
787
|
+
a.render();
|
|
788
|
+
assert.eq(getHtml(a), `<r-224><div><p>Cat eats Banana</p><p>Cat eats Apricot</p></div><div><p>Bird eats Banana</p><p>Bird eats Apricot</p></div></r-224>`);
|
|
789
|
+
|
|
790
|
+
a.pets.reverse();
|
|
791
|
+
a.fruits.reverse();
|
|
792
|
+
a.render();
|
|
793
|
+
assert.eq(getHtml(a), `<r-224><div><p>Bird eats Apricot</p><p>Bird eats Banana</p></div><div><p>Cat eats Apricot</p><p>Cat eats Banana</p></div></r-224>`);
|
|
794
|
+
|
|
795
|
+
a.pets.pop();
|
|
796
|
+
a.render();
|
|
797
|
+
assert.eq(getHtml(a), `<r-224><div><p>Bird eats Apricot</p><p>Bird eats Banana</p></div></r-224>`);
|
|
798
|
+
|
|
799
|
+
a.pets.pop();
|
|
800
|
+
a.render();
|
|
801
|
+
assert.eq(getHtml(a), `<r-224></r-224>`);
|
|
802
|
+
|
|
803
|
+
a.remove();
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
Testimony.test('Solarite.loop.nested3', `Move items from one sublist to another.`, () => {
|
|
808
|
+
|
|
809
|
+
class A225 extends Solarite {
|
|
810
|
+
fruitGroups = [
|
|
811
|
+
['Apple'],
|
|
812
|
+
['Banana', 'Cherry']
|
|
813
|
+
];
|
|
814
|
+
|
|
815
|
+
render() {
|
|
816
|
+
r(this)`${this.fruitGroups.map(fruitGroup =>
|
|
817
|
+
r`<div>${fruitGroup.map(fruit =>
|
|
818
|
+
r`<span>${fruit}</span>`
|
|
819
|
+
)}</div>`
|
|
820
|
+
)}`
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
A225.define();
|
|
824
|
+
window.verify = true;
|
|
825
|
+
|
|
826
|
+
let a = new A225();
|
|
827
|
+
document.body.append(a);
|
|
828
|
+
a.render();
|
|
829
|
+
|
|
830
|
+
let cherry = a.fruitGroups[1].pop();
|
|
831
|
+
a.fruitGroups[0].push(cherry);
|
|
832
|
+
a.render();
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
let banana = a.fruitGroups[1].pop();
|
|
836
|
+
a.fruitGroups[0].push(banana);
|
|
837
|
+
//window.debug = true;
|
|
838
|
+
a.render();
|
|
839
|
+
|
|
840
|
+
window.verify = false;
|
|
841
|
+
a.remove();
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
// Tried to make a simpler version of nested3, but it works fine:
|
|
847
|
+
Testimony.test('Solarite.loop.nested4', () => {
|
|
848
|
+
|
|
849
|
+
class A226 extends Solarite {
|
|
850
|
+
fruits1 = ['Apple']
|
|
851
|
+
fruits2 = ['Banana', 'Cherry']
|
|
852
|
+
|
|
853
|
+
render() {
|
|
854
|
+
this.html = r`
|
|
855
|
+
<div>${this.fruits1.map(fruit => r`<span>${fruit}</span>`)}</div>
|
|
856
|
+
<div>${this.fruits2.map(fruit => r`<span>${fruit}</span>`)}</div>`
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
A226.define();
|
|
860
|
+
window.verify = true;
|
|
861
|
+
|
|
862
|
+
let a = new A226();
|
|
863
|
+
document.body.append(a);
|
|
864
|
+
a.render();
|
|
865
|
+
|
|
866
|
+
let cherry = a.fruits2.pop();
|
|
867
|
+
a.fruits1.push(cherry);
|
|
868
|
+
a.render();
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
let banana = a.fruits2.pop();
|
|
872
|
+
a.fruits1.push(banana);
|
|
873
|
+
//window.debug = true;
|
|
874
|
+
a.render();
|
|
875
|
+
|
|
876
|
+
window.verify = false;
|
|
877
|
+
a.remove();
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
Testimony.test('Solarite.loop.nested5', () => {
|
|
889
|
+
|
|
890
|
+
// This test was originally created by reducing a failure in production code
|
|
891
|
+
// to the simplest version.
|
|
892
|
+
// The problem was that NodeGroupManager.findAndDeleteClose() was trying to
|
|
893
|
+
// delete the old exactKey, but it didn't exist because it had already been assigned.
|
|
894
|
+
// Commenting out the assert() fixed the problem.
|
|
895
|
+
|
|
896
|
+
// v could also be a function to trigger this same test.
|
|
897
|
+
// Since functions are new on each render().
|
|
898
|
+
let v = 'F1';
|
|
899
|
+
|
|
900
|
+
class A227 extends Solarite {
|
|
901
|
+
boxes = [
|
|
902
|
+
["A"],
|
|
903
|
+
["A", "B"]
|
|
904
|
+
]
|
|
905
|
+
|
|
906
|
+
render() {
|
|
907
|
+
this.html = r`
|
|
908
|
+
<a-227>${this.boxes.map(item =>
|
|
909
|
+
r`${item.map(item2 =>
|
|
910
|
+
r`<div title=${v}>${item2}</div>`
|
|
911
|
+
)}`
|
|
912
|
+
)}</a-227>`;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
A227.define();
|
|
916
|
+
|
|
917
|
+
//window.verify = true;
|
|
918
|
+
|
|
919
|
+
let a = new A227();
|
|
920
|
+
document.body.append(a); // calls render()
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
v = 'F2';
|
|
926
|
+
a.boxes = [
|
|
927
|
+
["A", "B"],
|
|
928
|
+
['A']
|
|
929
|
+
]
|
|
930
|
+
a.render();
|
|
931
|
+
|
|
932
|
+
assert.eq(a.outerHTML, `<a-227><!--PathStart:0--><!--PathStart:0--><div title="F2"><!--PathStart:1-->A<!--PathEnd:1--></div><div title="F2"><!--PathStart:1-->B<!--PathEnd:1--></div><!--PathEnd:0--><!--PathStart:0--><div title="F2"><!--PathStart:1-->A<!--PathEnd:1--></div><!--PathEnd:0--><!--PathEnd:0--></a-227>`);
|
|
933
|
+
|
|
934
|
+
window.verify = false;
|
|
935
|
+
a.remove();
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
Testimony.test('Solarite.loop.nestedConditional', () => {
|
|
955
|
+
|
|
956
|
+
let isGoodBoy = true;
|
|
957
|
+
|
|
958
|
+
class R227 extends Solarite {
|
|
959
|
+
pets = ['Cat', 'Dog'];
|
|
960
|
+
fruits = ['Apple', 'Banana'];
|
|
961
|
+
|
|
962
|
+
render() {
|
|
963
|
+
r(this)`${this.pets.map(pet =>
|
|
964
|
+
r`${this.fruits.map(fruit =>
|
|
965
|
+
isGoodBoy
|
|
966
|
+
? r`<p>${pet} prepares ${fruit}</p>`
|
|
967
|
+
: r`<p>${pet} eats ${fruit}</p>`
|
|
968
|
+
)}`
|
|
969
|
+
)}`
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
let a = new R227;
|
|
973
|
+
|
|
974
|
+
document.body.append(a);
|
|
975
|
+
assert.eq(getHtml(a), `<r-227><p>Cat prepares Apple</p><p>Cat prepares Banana</p><p>Dog prepares Apple</p><p>Dog prepares Banana</p></r-227>`);
|
|
976
|
+
|
|
977
|
+
isGoodBoy = false;
|
|
978
|
+
a.render();
|
|
979
|
+
assert.eq(getHtml(a), `<r-227><p>Cat eats Apple</p><p>Cat eats Banana</p><p>Dog eats Apple</p><p>Dog eats Banana</p></r-227>`);
|
|
980
|
+
|
|
981
|
+
isGoodBoy = true;
|
|
982
|
+
a.render();
|
|
983
|
+
assert.eq(getHtml(a), `<r-227><p>Cat prepares Apple</p><p>Cat prepares Banana</p><p>Dog prepares Apple</p><p>Dog prepares Banana</p></r-227>`);
|
|
984
|
+
|
|
985
|
+
a.fruits.pop();
|
|
986
|
+
isGoodBoy = false;
|
|
987
|
+
a.render();
|
|
988
|
+
assert.eq(getHtml(a), `<r-227><p>Cat eats Apple</p><p>Dog eats Apple</p></r-227>`);
|
|
989
|
+
|
|
990
|
+
a.remove();
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
Testimony.test('Solarite.loop.conditionalNested', () => {
|
|
994
|
+
|
|
995
|
+
class R240 extends Solarite {
|
|
996
|
+
pets = [
|
|
997
|
+
{
|
|
998
|
+
name: 'Cat',
|
|
999
|
+
activities: ['Sleep', 'Eat', 'Pur']
|
|
1000
|
+
},
|
|
1001
|
+
{
|
|
1002
|
+
name: 'Dog',
|
|
1003
|
+
activities: ['Frolic', 'Fetch']
|
|
1004
|
+
}
|
|
1005
|
+
];
|
|
1006
|
+
|
|
1007
|
+
render() {
|
|
1008
|
+
this.html =
|
|
1009
|
+
r`${this.pets.map(pet =>
|
|
1010
|
+
pet.activities.map(activity =>
|
|
1011
|
+
activity.length >= 5
|
|
1012
|
+
? r`<p>${pet.name} will ${activity}.</p>`
|
|
1013
|
+
: ``
|
|
1014
|
+
)
|
|
1015
|
+
)}`
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
let a = new R240();
|
|
1019
|
+
document.body.append(a);
|
|
1020
|
+
|
|
1021
|
+
assert.eq(getHtml(a), `<r-240><p>Cat will Sleep.</p><p>Dog will Frolic.</p><p>Dog will Fetch.</p></r-240>`);
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
a.pets[0].activities[0] = 'Doze'; // Less than 5 characters.
|
|
1025
|
+
a.render()
|
|
1026
|
+
assert.eq(getHtml(a), `<r-240><p>Dog will Frolic.</p><p>Dog will Fetch.</p></r-240>`);
|
|
1027
|
+
//assert.eq(Refract.elsCreated, []);
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
a.pets[0].activities[0] = 'Slumber';
|
|
1031
|
+
a.render()
|
|
1032
|
+
assert.eq(getHtml(a), `<r-240><p>Cat will Slumber.</p><p>Dog will Frolic.</p><p>Dog will Fetch.</p></r-240>`);
|
|
1033
|
+
//assert.eq(Refract.elsCreated, ["<p>", "Cat", " will ", "Slumber", "."]);
|
|
1034
|
+
|
|
1035
|
+
a.remove();
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
Testimony.test('Solarite.loop.tripleNested', 'Triple nested grid', () => {
|
|
1040
|
+
|
|
1041
|
+
class R250 extends Solarite {
|
|
1042
|
+
rows = [[[0]]];
|
|
1043
|
+
|
|
1044
|
+
render() {
|
|
1045
|
+
this.html = r`${this.rows.map(row =>
|
|
1046
|
+
r`${row.map(items =>
|
|
1047
|
+
r`${items.map(item =>
|
|
1048
|
+
r`${item}`
|
|
1049
|
+
)}`
|
|
1050
|
+
)}`
|
|
1051
|
+
)}`
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
let a = new R250();
|
|
1056
|
+
document.body.append(a);
|
|
1057
|
+
assert.eq(getHtml(a), `<r-250>0</r-250>`);
|
|
1058
|
+
|
|
1059
|
+
a.rows[0][0][0] = 4;
|
|
1060
|
+
a.render();
|
|
1061
|
+
assert.eq(getHtml(a), `<r-250>4</r-250>`);
|
|
1062
|
+
|
|
1063
|
+
a.rows = [];
|
|
1064
|
+
a.render();
|
|
1065
|
+
assert.eq(getHtml(a), `<r-250></r-250>`);
|
|
1066
|
+
|
|
1067
|
+
a.rows = [
|
|
1068
|
+
[[1,2],[3,4]],
|
|
1069
|
+
[[5,6],[7,8]]
|
|
1070
|
+
];
|
|
1071
|
+
a.render()
|
|
1072
|
+
assert.eq(getHtml(a), `<r-250>12345678</r-250>`);
|
|
1073
|
+
|
|
1074
|
+
let p1 = r('<p>1</p')
|
|
1075
|
+
let p2 = r('<p>2</p')
|
|
1076
|
+
let p3 = r('<p>3</p')
|
|
1077
|
+
let p4 = r('<p>4</p')
|
|
1078
|
+
let p5 = r('<p>5</p')
|
|
1079
|
+
let p6 = r('<p>6</p')
|
|
1080
|
+
let p7 = r('<p>7</p')
|
|
1081
|
+
let p8 = r('<p>8</p')
|
|
1082
|
+
|
|
1083
|
+
a.rows = [
|
|
1084
|
+
[[p1,p2],[p3,p4]],
|
|
1085
|
+
[[p5,p6],[p7,p8]]
|
|
1086
|
+
];
|
|
1087
|
+
a.render()
|
|
1088
|
+
assert.eq(getHtml(a), `<r-250><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p></r-250>`);
|
|
1089
|
+
|
|
1090
|
+
a.rows = [
|
|
1091
|
+
[[p8,p7],[p6,p5]],
|
|
1092
|
+
[[p4,p3],[p2,p1]]
|
|
1093
|
+
];
|
|
1094
|
+
a.render()
|
|
1095
|
+
assert.eq(getHtml(a), `<r-250><p>8</p><p>7</p><p>6</p><p>5</p><p>4</p><p>3</p><p>2</p><p>1</p></r-250>`);
|
|
1096
|
+
|
|
1097
|
+
a.rows = [];
|
|
1098
|
+
a.render();
|
|
1099
|
+
assert.eq(getHtml(a), `<r-250></r-250>`);
|
|
1100
|
+
|
|
1101
|
+
a.remove();
|
|
1102
|
+
});
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
|
|
1111
|
+
Testimony.test('Solarite.embed.styleStatic', () => {
|
|
1112
|
+
let count = 0;
|
|
1113
|
+
|
|
1114
|
+
class R300 extends Solarite {
|
|
1115
|
+
render() {
|
|
1116
|
+
this.html = r`
|
|
1117
|
+
<style>
|
|
1118
|
+
:host { color: blue }
|
|
1119
|
+
</style>
|
|
1120
|
+
Text that should be blue.
|
|
1121
|
+
${count}
|
|
1122
|
+
`;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
let a = new R300();
|
|
1127
|
+
document.body.append(a);
|
|
1128
|
+
|
|
1129
|
+
assert.eq(a.querySelector('style').textContent.trim(), `r-300[data-style="1"] { color: blue }`)
|
|
1130
|
+
|
|
1131
|
+
// Make sure styleid isn't incremented on render.
|
|
1132
|
+
count++;
|
|
1133
|
+
a.render();
|
|
1134
|
+
assert.eq(a.querySelector('style').textContent.trim(), `r-300[data-style="1"] { color: blue }`)
|
|
1135
|
+
|
|
1136
|
+
a.remove();
|
|
1137
|
+
});
|
|
1138
|
+
|
|
1139
|
+
Testimony.test('Solarite.embed.optionsNoStyles', () => {
|
|
1140
|
+
let count = 0;
|
|
1141
|
+
|
|
1142
|
+
class R310 extends Solarite {
|
|
1143
|
+
render() {
|
|
1144
|
+
let options = {styles: false};
|
|
1145
|
+
r(this, options)`
|
|
1146
|
+
<style>
|
|
1147
|
+
:host { color: blue }
|
|
1148
|
+
</style>
|
|
1149
|
+
Text that should be blue.
|
|
1150
|
+
${count}
|
|
1151
|
+
`;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
let a = new R310();
|
|
1156
|
+
document.body.append(a);
|
|
1157
|
+
assert.eq(a.querySelector('style').textContent.trim(), `:host { color: blue }`)
|
|
1158
|
+
|
|
1159
|
+
a.remove();
|
|
1160
|
+
});
|
|
1161
|
+
|
|
1162
|
+
|
|
1163
|
+
Testimony.test('Solarite.embed.styleDynamic', () => {
|
|
1164
|
+
let style1 = `:host { color: red }`
|
|
1165
|
+
let style2 = `:host { font-weight: bold }`
|
|
1166
|
+
|
|
1167
|
+
class R320 extends Solarite {
|
|
1168
|
+
render() {
|
|
1169
|
+
this.html = r`
|
|
1170
|
+
<style>
|
|
1171
|
+
${style1} ${style2}
|
|
1172
|
+
</style>
|
|
1173
|
+
Text that should be bold and red.
|
|
1174
|
+
`;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
let a = new R320();
|
|
1179
|
+
document.body.append(a);
|
|
1180
|
+
|
|
1181
|
+
assert.eq(a.querySelector('style').textContent.trim(), `r-320[data-style="1"] { color: red } r-320[data-style="1"] { font-weight: bold }`)
|
|
1182
|
+
|
|
1183
|
+
style1 = `:host { color: gold }`
|
|
1184
|
+
a.render();
|
|
1185
|
+
assert.eq(a.querySelector('style').textContent.trim(), `r-320[data-style="1"] { color: gold } r-320[data-style="1"] { font-weight: bold }`)
|
|
1186
|
+
|
|
1187
|
+
a.remove();
|
|
1188
|
+
});
|
|
1189
|
+
|
|
1190
|
+
Testimony.test('Solarite.embed.styleDynamicNoSpaces', () => {
|
|
1191
|
+
let style1 = `:host { color: red }`
|
|
1192
|
+
let style2 = `:host { font-weight: bold }`
|
|
1193
|
+
|
|
1194
|
+
class R322 extends Solarite {
|
|
1195
|
+
render() {
|
|
1196
|
+
this.html = r`
|
|
1197
|
+
<style>${style1}${style2}</style>
|
|
1198
|
+
Text that should be bold and red.
|
|
1199
|
+
`;
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
let a = new R322();
|
|
1204
|
+
document.body.append(a);
|
|
1205
|
+
|
|
1206
|
+
assert.eq(a.querySelector('style').childNodes.length, 5) // includes zero-length text node placeholders inserted.
|
|
1207
|
+
assert.eq(a.querySelector('style').textContent, `r-322[data-style="1"] { color: red }r-322[data-style="1"] { font-weight: bold }`)
|
|
1208
|
+
|
|
1209
|
+
style1 = `:host { color: gold }`
|
|
1210
|
+
a.render();
|
|
1211
|
+
assert.eq(a.querySelector('style').textContent.trim(), `r-322[data-style="1"] { color: gold }r-322[data-style="1"] { font-weight: bold }`)
|
|
1212
|
+
|
|
1213
|
+
a.remove();
|
|
1214
|
+
});
|
|
1215
|
+
|
|
1216
|
+
Testimony.test('Solarite.embed.styleDynamicTag', () => {
|
|
1217
|
+
let style1 = r`<style>:host { color: green }</style>`
|
|
1218
|
+
|
|
1219
|
+
class R325 extends Solarite {
|
|
1220
|
+
render() {
|
|
1221
|
+
this.html = r`${style1}Text.`;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
let a = new R325();
|
|
1226
|
+
document.body.append(a);
|
|
1227
|
+
assert.eq(getHtml(a), `<r-325 data-style="1"><style>r-325[data-style="1"] { color: green }</style>Text.</r-325>`)
|
|
1228
|
+
|
|
1229
|
+
style1 = r`<style>:host { color: orangered }</style>`
|
|
1230
|
+
a.render();
|
|
1231
|
+
assert.eq(getHtml(a), `<r-325 data-style="1"><style>r-325[data-style="1"] { color: orangered }</style>Text.</r-325>`)
|
|
1232
|
+
|
|
1233
|
+
a.remove();
|
|
1234
|
+
});
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
Testimony.test('Solarite.embed.svg', () => {
|
|
1241
|
+
class R330 extends Solarite {
|
|
1242
|
+
render() {
|
|
1243
|
+
this.html = r`
|
|
1244
|
+
<div>
|
|
1245
|
+
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
|
|
1246
|
+
<circle cx="25" cy="25" r="25" fill="blue" />
|
|
1247
|
+
<rect x="50" y="50" width="50" height="100" fill="green" />
|
|
1248
|
+
</svg>
|
|
1249
|
+
</div>
|
|
1250
|
+
`;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
let a = new R330();
|
|
1255
|
+
document.body.append(a);
|
|
1256
|
+
|
|
1257
|
+
// Not sure how to test this, but it looks good visually.
|
|
1258
|
+
a.remove();
|
|
1259
|
+
});
|
|
1260
|
+
|
|
1261
|
+
Testimony.test('Solarite.embed.scriptStatic', () => {
|
|
1262
|
+
window.scriptStaticCount = 1;
|
|
1263
|
+
class R340 extends Solarite {
|
|
1264
|
+
render() {
|
|
1265
|
+
this.html = r`
|
|
1266
|
+
<div>
|
|
1267
|
+
<script>
|
|
1268
|
+
window.scriptStaticCount = 1;
|
|
1269
|
+
</script>
|
|
1270
|
+
</div>
|
|
1271
|
+
`;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
let a = new R340();
|
|
1276
|
+
a.render();
|
|
1277
|
+
assert.eq(window.scriptStaticCount, 1);
|
|
1278
|
+
|
|
1279
|
+
// Hasn't changed. Make sure it's nto re-run.
|
|
1280
|
+
a.render();
|
|
1281
|
+
assert.eq(window.scriptStaticCount, 1);
|
|
1282
|
+
|
|
1283
|
+
delete window.scriptStaticCount;
|
|
1284
|
+
});
|
|
1285
|
+
|
|
1286
|
+
// This feature is disabled because it doesn't seem useful.
|
|
1287
|
+
Testimony.test('Solarite.embed._scriptDynamic', () => {
|
|
1288
|
+
|
|
1289
|
+
let val = 1;
|
|
1290
|
+
class R350 extends Solarite {
|
|
1291
|
+
render() {
|
|
1292
|
+
this.html = r`
|
|
1293
|
+
<div>
|
|
1294
|
+
<script>
|
|
1295
|
+
window.scriptStaticCount = ${val};
|
|
1296
|
+
</script>
|
|
1297
|
+
</div>
|
|
1298
|
+
`;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
let a = new R350();
|
|
1303
|
+
a.render();
|
|
1304
|
+
assert.eq(window.scriptStaticCount, 1);
|
|
1305
|
+
|
|
1306
|
+
// Hasn't changed. Make sure it's not re-run.
|
|
1307
|
+
a.render();
|
|
1308
|
+
assert.eq(window.scriptStaticCount, 1);
|
|
1309
|
+
|
|
1310
|
+
val = 2;
|
|
1311
|
+
a.render();
|
|
1312
|
+
assert.eq(window.scriptStaticCount, 2);
|
|
1313
|
+
|
|
1314
|
+
delete window.scriptStaticCount;
|
|
1315
|
+
});
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
Testimony.test('Solarite.attrib.single', () => {
|
|
1320
|
+
|
|
1321
|
+
let val = 'one';
|
|
1322
|
+
|
|
1323
|
+
class R400 extends Solarite {
|
|
1324
|
+
render() {
|
|
1325
|
+
this.html = r`<div class="${val}">${val}</div>`;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
let a = new R400();
|
|
1330
|
+
a.render();
|
|
1331
|
+
|
|
1332
|
+
assert.eq(getHtml(a), `<r-400><div class="one">one</div></r-400>`)
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
val = 'two';
|
|
1336
|
+
a.render();
|
|
1337
|
+
assert.eq(getHtml(a), `<r-400><div class="two">two</div></r-400>`)
|
|
1338
|
+
});
|
|
1339
|
+
|
|
1340
|
+
Testimony.test('Solarite.attrib.singleAndText', () => {
|
|
1341
|
+
|
|
1342
|
+
let val = 'one';
|
|
1343
|
+
|
|
1344
|
+
class R410 extends Solarite {
|
|
1345
|
+
render() {
|
|
1346
|
+
this.html = r`<div class="before ${val} after">${val}</div>`;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
let a = new R410();
|
|
1351
|
+
a.render();
|
|
1352
|
+
|
|
1353
|
+
assert.eq(getHtml(a), `<r-410><div class="before one after">one</div></r-410>`);
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
val = 'two';
|
|
1357
|
+
a.render();
|
|
1358
|
+
assert.eq(getHtml(a), `<r-410><div class="before two after">two</div></r-410>`);
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
val = false;
|
|
1362
|
+
a.render();
|
|
1363
|
+
assert.eq(getHtml(a), `<r-410><div class="before after"></div></r-410>`);
|
|
1364
|
+
});
|
|
1365
|
+
|
|
1366
|
+
Testimony.test('Solarite.attrib.double', () => {
|
|
1367
|
+
|
|
1368
|
+
let val1 = 'one';
|
|
1369
|
+
let val2 = 'two';
|
|
1370
|
+
|
|
1371
|
+
class R420 extends Solarite {
|
|
1372
|
+
render() {
|
|
1373
|
+
this.html = r`<div class="${val1}${val2}">${val1}</div>`;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
let a = new R420();
|
|
1378
|
+
a.render();
|
|
1379
|
+
|
|
1380
|
+
assert.eq(getHtml(a), `<r-420><div class="onetwo">one</div></r-420>`)
|
|
1381
|
+
|
|
1382
|
+
val1 = 'oneB';
|
|
1383
|
+
val2 = 'twoB';
|
|
1384
|
+
a.render();
|
|
1385
|
+
assert.eq(getHtml(a), `<r-420><div class="oneBtwoB">oneB</div></r-420>`)
|
|
1386
|
+
});
|
|
1387
|
+
|
|
1388
|
+
|
|
1389
|
+
Testimony.test('Solarite.attrib.doubleAndText', () => {
|
|
1390
|
+
|
|
1391
|
+
let val1 = 'one';
|
|
1392
|
+
let val2 = 'two';
|
|
1393
|
+
|
|
1394
|
+
class R430 extends Solarite {
|
|
1395
|
+
render() {
|
|
1396
|
+
this.html = r`<div class="a ${val1} b ${val2} c">${val1}</div>`;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
let a = new R430();
|
|
1401
|
+
a.render();
|
|
1402
|
+
|
|
1403
|
+
assert.eq(getHtml(a), `<r-430><div class="a one b two c">one</div></r-430>`)
|
|
1404
|
+
|
|
1405
|
+
val1 = 'oneB';
|
|
1406
|
+
val2 = 'twoB';
|
|
1407
|
+
a.render();
|
|
1408
|
+
assert.eq(getHtml(a), `<r-430><div class="a oneB b twoB c">oneB</div></r-430>`)
|
|
1409
|
+
});
|
|
1410
|
+
|
|
1411
|
+
Testimony.test('Solarite.attrib.doubleAndText', () => {
|
|
1412
|
+
|
|
1413
|
+
let val1 = 'one';
|
|
1414
|
+
let val2 = 'two';
|
|
1415
|
+
|
|
1416
|
+
class R430 extends Solarite {
|
|
1417
|
+
render() {
|
|
1418
|
+
this.html = r`<div class="a ${val1} b ${val2} c">${val1}</div>`;
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
let a = new R430();
|
|
1423
|
+
a.render();
|
|
1424
|
+
|
|
1425
|
+
assert.eq(getHtml(a), `<r-430><div class="a one b two c">one</div></r-430>`)
|
|
1426
|
+
|
|
1427
|
+
val1 = 'oneB';
|
|
1428
|
+
val2 = 'twoB';
|
|
1429
|
+
a.render();
|
|
1430
|
+
assert.eq(getHtml(a), `<r-430><div class="a oneB b twoB c">oneB</div></r-430>`)
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
Testimony.test('Solarite.attrib.sparse', () => {
|
|
1434
|
+
|
|
1435
|
+
let isEdit = false;
|
|
1436
|
+
|
|
1437
|
+
class R440 extends Solarite {
|
|
1438
|
+
render() {
|
|
1439
|
+
this.html = r`<div ${isEdit && 'contenteditable'}>${isEdit && 'Editable!'}</div>`;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
let a = new R440();
|
|
1444
|
+
a.render();
|
|
1445
|
+
assert.eq(getHtml(a), `<r-440><div></div></r-440>`)
|
|
1446
|
+
|
|
1447
|
+
isEdit = true
|
|
1448
|
+
a.render();
|
|
1449
|
+
assert.eq(getHtml(a), `<r-440><div contenteditable="">Editable!</div></r-440>`)
|
|
1450
|
+
|
|
1451
|
+
isEdit = false
|
|
1452
|
+
a.render();
|
|
1453
|
+
assert.eq(getHtml(a), `<r-440><div></div></r-440>`)
|
|
1454
|
+
});
|
|
1455
|
+
|
|
1456
|
+
Testimony.test('Solarite.attrib.doubleSparse', () => {
|
|
1457
|
+
|
|
1458
|
+
let isEdit = false;
|
|
1459
|
+
|
|
1460
|
+
class R450 extends Solarite {
|
|
1461
|
+
render() {
|
|
1462
|
+
this.html = r`<div ${isEdit && 'contenteditable spellcheck="false"'}>${isEdit && 'Editable!'}</div>`;
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
let a = new R450();
|
|
1467
|
+
a.render();
|
|
1468
|
+
assert.eq(getHtml(a), `<r-450><div></div></r-450>`)
|
|
1469
|
+
|
|
1470
|
+
isEdit = true
|
|
1471
|
+
a.render();
|
|
1472
|
+
assert.eq(getHtml(a), `<r-450><div contenteditable="" spellcheck="false">Editable!</div></r-450>`)
|
|
1473
|
+
|
|
1474
|
+
isEdit = false
|
|
1475
|
+
a.render();
|
|
1476
|
+
assert.eq(getHtml(a), `<r-450><div></div></r-450>`)
|
|
1477
|
+
});
|
|
1478
|
+
|
|
1479
|
+
Testimony.test('Solarite.attrib.toggle', () => {
|
|
1480
|
+
|
|
1481
|
+
let isEdit = false;
|
|
1482
|
+
|
|
1483
|
+
class R460 extends Solarite {
|
|
1484
|
+
render() {
|
|
1485
|
+
this.html = r`<div contenteditable=${isEdit}>${isEdit && 'Editable!'}</div>`;
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
let a = new R460();
|
|
1490
|
+
a.render();
|
|
1491
|
+
assert.eq(getHtml(a), `<r-460><div></div></r-460>`)
|
|
1492
|
+
|
|
1493
|
+
isEdit = true
|
|
1494
|
+
a.render();
|
|
1495
|
+
assert.eq(getHtml(a), `<r-460><div contenteditable="">Editable!</div></r-460>`)
|
|
1496
|
+
|
|
1497
|
+
isEdit = false
|
|
1498
|
+
a.render();
|
|
1499
|
+
assert.eq(getHtml(a), `<r-460><div></div></r-460>`)
|
|
1500
|
+
});
|
|
1501
|
+
|
|
1502
|
+
|
|
1503
|
+
Testimony.test('Solarite.attrib.pseudoRoot', () => {
|
|
1504
|
+
let title = 'Hello'
|
|
1505
|
+
class R470 extends Solarite {
|
|
1506
|
+
render() {
|
|
1507
|
+
this.html = r`<r-470 title="${title}">World</r-470>`
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
let a = new R470();
|
|
1512
|
+
a.render();
|
|
1513
|
+
assert.eq(getHtml(a), `<r-470 title="Hello">World</r-470>`)
|
|
1514
|
+
|
|
1515
|
+
|
|
1516
|
+
title = 'Goodbye'
|
|
1517
|
+
a.render();
|
|
1518
|
+
assert.eq(a.outerHTML, `<r-470 title="Goodbye">World</r-470>`)
|
|
1519
|
+
|
|
1520
|
+
title = false
|
|
1521
|
+
a.render();
|
|
1522
|
+
assert.eq(a.outerHTML, `<r-470>World</r-470>`)
|
|
1523
|
+
});
|
|
1524
|
+
|
|
1525
|
+
|
|
1526
|
+
Testimony.test('Solarite.attrib.pseudoRoot2', 'Static attribute overrides.', () => {
|
|
1527
|
+
let title = 'Hello'
|
|
1528
|
+
class R472 extends Solarite {
|
|
1529
|
+
render() {
|
|
1530
|
+
this.html = r`<r-472 title="${title}" style="color: red">World</r-472>`
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
R472.define();
|
|
1534
|
+
|
|
1535
|
+
let b = r(`<r-472 style="color: green"></r-472>`);
|
|
1536
|
+
document.body.append(b);
|
|
1537
|
+
assert.eq(b.outerHTML, `<r-472 style="color: green" title="Hello">World</r-472>`);
|
|
1538
|
+
b.remove();
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
});
|
|
1542
|
+
|
|
1543
|
+
Testimony.test('Solarite.attrib.pseudoRoot3', 'Dynamic attribute overrides.', () => {
|
|
1544
|
+
let title = 'Hello'
|
|
1545
|
+
class R473 extends Solarite {
|
|
1546
|
+
render() {
|
|
1547
|
+
this.html = r`<r-473 title="${title}" style="color: red">World</r-473>`
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
R473.define();
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
let a = r(`<r-473 title="Goodbye"></r-473>`);
|
|
1554
|
+
document.body.append(a);
|
|
1555
|
+
|
|
1556
|
+
// Dynamic attributes take precedence
|
|
1557
|
+
assert.eq(a.outerHTML, `<r-473 title="Hello" style="color: red">World</r-473>`);
|
|
1558
|
+
|
|
1559
|
+
a.render();
|
|
1560
|
+
assert.eq(a.outerHTML, `<r-473 title="Hello" style="color: red">World</r-473>`);
|
|
1561
|
+
|
|
1562
|
+
|
|
1563
|
+
title = 'Blue';
|
|
1564
|
+
a.setAttribute('style', 'color: blue');
|
|
1565
|
+
|
|
1566
|
+
a.render();
|
|
1567
|
+
assert.eq(a.outerHTML, `<r-473 title="Blue" style="color: blue">World</r-473>`);
|
|
1568
|
+
|
|
1569
|
+
a.remove();
|
|
1570
|
+
});
|
|
1571
|
+
|
|
1572
|
+
Testimony.test('Solarite.attrib.multiple', '', () => {
|
|
1573
|
+
let button = 'Hello'
|
|
1574
|
+
class R474 extends Solarite {
|
|
1575
|
+
render() {
|
|
1576
|
+
this.html = r`
|
|
1577
|
+
<r-474><button ${'class="primary"'} onclick=${e => {}}>${button}</button></r-474>`
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
let a = new R474();
|
|
1582
|
+
a.render();
|
|
1583
|
+
|
|
1584
|
+
assert.eq(getHtml(a), `<r-474><button onclick="" class="primary">Hello</button></r-474>`);
|
|
1585
|
+
});
|
|
1586
|
+
|
|
1587
|
+
|
|
1588
|
+
|
|
1589
|
+
Testimony.test('Solarite.comments', () => {
|
|
1590
|
+
|
|
1591
|
+
class A480 extends Solarite {
|
|
1592
|
+
render() {
|
|
1593
|
+
this.html = r`
|
|
1594
|
+
<!--a-->
|
|
1595
|
+
<div></div>`
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
let a = new A480();
|
|
1599
|
+
document.body.append(a);
|
|
1600
|
+
assert.eq(getHtml(a), `<a-480><div></div></a-480>`);
|
|
1601
|
+
a.remove();
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
Testimony.test('Solarite.comments2', () => {
|
|
1605
|
+
|
|
1606
|
+
class A482 extends Solarite {
|
|
1607
|
+
render() {
|
|
1608
|
+
this.html = r`<div><!--${1} ${2}-->${3}</div>`
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
let a = new A482();
|
|
1612
|
+
|
|
1613
|
+
a.render();
|
|
1614
|
+
assert.eq(getHtml(a), `<a-482><div>3</div></a-482>`)
|
|
1615
|
+
a.remove();
|
|
1616
|
+
});
|
|
1617
|
+
|
|
1618
|
+
|
|
1619
|
+
|
|
1620
|
+
|
|
1621
|
+
|
|
1622
|
+
Testimony.test('Solarite.ids', () => {
|
|
1623
|
+
class R500 extends Solarite {
|
|
1624
|
+
one;
|
|
1625
|
+
render() {
|
|
1626
|
+
this.html = r`<div data-id="one"></div>`;
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
let a = new R500();
|
|
1631
|
+
a.render();
|
|
1632
|
+
|
|
1633
|
+
assert(a.one.tagName === 'DIV')
|
|
1634
|
+
});
|
|
1635
|
+
|
|
1636
|
+
Testimony.test('Solarite.r._createElement', () => {
|
|
1637
|
+
|
|
1638
|
+
let button = r()`<button>hi</button>`
|
|
1639
|
+
console.log(button.outerHTML)
|
|
1640
|
+
document.body.append(button);
|
|
1641
|
+
})
|
|
1642
|
+
|
|
1643
|
+
|
|
1644
|
+
|
|
1645
|
+
|
|
1646
|
+
Testimony.test('Solarite.r.element', () => {
|
|
1647
|
+
let adjective = 'better'
|
|
1648
|
+
let button = r()`<button>I'm a <b>${adjective}</b> button</button>`;
|
|
1649
|
+
|
|
1650
|
+
assert.eq(getHtml(button), `<button>I'm a <b>better</b> button</button>`)
|
|
1651
|
+
})
|
|
1652
|
+
|
|
1653
|
+
|
|
1654
|
+
|
|
1655
|
+
Testimony.test('Solarite.r.lightweightComponent', () => {
|
|
1656
|
+
function betterButton(count=0) {
|
|
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();
|
|
1682
|
+
}
|
|
1683
|
+
return result;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
let button = betterButton(3);
|
|
1687
|
+
assert.eq(getHtml(button), `<button onclick="">I'm a 3X better button</button>`)
|
|
1688
|
+
|
|
1689
|
+
button.inc();
|
|
1690
|
+
assert.eq(getHtml(button), `<button onclick="">I'm a 4X better button</button>`)
|
|
1691
|
+
})
|
|
1692
|
+
|
|
1693
|
+
|
|
1694
|
+
|
|
1695
|
+
|
|
1696
|
+
Testimony.test('Solarite.component.tr', () => {
|
|
1697
|
+
|
|
1698
|
+
class TR510 extends Solarite('tr') {
|
|
1699
|
+
render() {
|
|
1700
|
+
this.html = r`<td>hello</td>`
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
let table = document.createElement('table')
|
|
1705
|
+
|
|
1706
|
+
table.append(new TR510())
|
|
1707
|
+
document.body.append(table)
|
|
1708
|
+
|
|
1709
|
+
assert.eq(table.outerHTML, `<table><tr is="tr-510"><td>hello</td></tr></table>`)
|
|
1710
|
+
|
|
1711
|
+
table.remove();
|
|
1712
|
+
|
|
1713
|
+
});
|
|
1714
|
+
|
|
1715
|
+
|
|
1716
|
+
Testimony.test('Solarite.component.staticAttribs', () => {
|
|
1717
|
+
// Note that all attribs become lowercase.
|
|
1718
|
+
// Not sure how to prevent this w/o using an xml doctype.
|
|
1719
|
+
class B512 extends Solarite {
|
|
1720
|
+
constructor({name, userid}={}) {
|
|
1721
|
+
super();
|
|
1722
|
+
this.name = name;
|
|
1723
|
+
this.userId = userid;
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
render() {
|
|
1727
|
+
this.html = r`<b-512>${this.name} | ${this.userId}</b-512>`
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
B512.define();
|
|
1731
|
+
|
|
1732
|
+
class A512 extends Solarite {
|
|
1733
|
+
render() {
|
|
1734
|
+
this.html = r`<div><b-512 name="User" userId="2"></b-512></div>`;
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
A512.define();
|
|
1738
|
+
|
|
1739
|
+
let a = new A512();
|
|
1740
|
+
a.render();
|
|
1741
|
+
|
|
1742
|
+
assert.eq(a.outerHTML, `<a-512><div><b-512 name="User" userid="2"><!--PathStart:0-->User | 2<!--PathEnd:1--></b-512></div></a-512>`);
|
|
1743
|
+
});
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
|
|
1747
|
+
Testimony.test('Solarite.component.dynamicAttribs', 'Attribs specified via ${...}', () => {
|
|
1748
|
+
|
|
1749
|
+
class B513 extends Solarite {
|
|
1750
|
+
constructor({name, userid}={}) {
|
|
1751
|
+
super();
|
|
1752
|
+
this.name = name;
|
|
1753
|
+
this.userId = userid;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
render() {
|
|
1757
|
+
this.html = r`<b-513>${this.name} | ${this.userId}</b-513>`
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
B513.define();
|
|
1761
|
+
|
|
1762
|
+
class A513 extends Solarite {
|
|
1763
|
+
render() {
|
|
1764
|
+
this.html = r`<div><b-513 name="${'User'}" userId="${2}"></b-513></div>`;
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
A513.define();
|
|
1768
|
+
|
|
1769
|
+
let a = new A513();
|
|
1770
|
+
a.render();
|
|
1771
|
+
|
|
1772
|
+
assert.eq(a.outerHTML, `<a-513><div><b-513 name="User" userid="2"><!--PathStart:0-->User | 2<!--PathEnd:1--></b-513></div></a-513>`);
|
|
1773
|
+
});
|
|
1774
|
+
|
|
1775
|
+
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
|
+
|
|
1782
|
+
class B514 extends Solarite {
|
|
1783
|
+
constructor({name, userid}={}) {
|
|
1784
|
+
super();
|
|
1785
|
+
this.name = this.getArg('name', name);
|
|
1786
|
+
this.userId = this.getArg('userid', userid);
|
|
1787
|
+
this.render();
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
render() {
|
|
1791
|
+
this.html = r`<b-514>${this.name} | ${this.userId}</b-514>`
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
B514.define();
|
|
1795
|
+
|
|
1796
|
+
|
|
1797
|
+
let div = document.createElement('div');
|
|
1798
|
+
div.innerHTML = `<b-514 name="User" userid="2"></b-514>`
|
|
1799
|
+
|
|
1800
|
+
assert.eq(div.outerHTML, `<div><b-514 name="User" userid="2"><!--PathStart:0-->User | 2<!--PathEnd:1--></b-514></div>`)
|
|
1801
|
+
|
|
1802
|
+
});
|
|
1803
|
+
|
|
1804
|
+
|
|
1805
|
+
|
|
1806
|
+
|
|
1807
|
+
Testimony.test('Solarite.component.nested', () => {
|
|
1808
|
+
|
|
1809
|
+
let bRenderCount = 0;
|
|
1810
|
+
|
|
1811
|
+
class B515 extends Solarite {
|
|
1812
|
+
render() {
|
|
1813
|
+
this.html = r`<div>B</div>`;
|
|
1814
|
+
bRenderCount++;
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
B515.define();
|
|
1818
|
+
|
|
1819
|
+
|
|
1820
|
+
class A515 extends Solarite {
|
|
1821
|
+
render() {
|
|
1822
|
+
this.html =
|
|
1823
|
+
r`<b-515></b-515>`
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
let a = new A515();
|
|
1828
|
+
assert(!(a.firstChild instanceof B515))
|
|
1829
|
+
|
|
1830
|
+
a.render();
|
|
1831
|
+
assert(a.firstChild instanceof B515);
|
|
1832
|
+
assert.eq(getHtml(a), `<a-515><b-515><div>B</div></b-515></a-515>`);
|
|
1833
|
+
})
|
|
1834
|
+
|
|
1835
|
+
|
|
1836
|
+
// Pass an object to the child.
|
|
1837
|
+
Testimony.test('Solarite.component.nested2', () => {
|
|
1838
|
+
|
|
1839
|
+
let bRenderCount = 0;
|
|
1840
|
+
class B520 extends Solarite {
|
|
1841
|
+
|
|
1842
|
+
constructor({user}={}) {
|
|
1843
|
+
super();
|
|
1844
|
+
this.user = user;
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
render(props={}) {
|
|
1848
|
+
if (props.user)
|
|
1849
|
+
this.user = props.user;
|
|
1850
|
+
this.html = r`<div>Name:</div><div>${this.user.name}</div><div>Email:</div><div>${this.user.email}</div>`;
|
|
1851
|
+
bRenderCount++;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
}
|
|
1855
|
+
B520.define();
|
|
1856
|
+
|
|
1857
|
+
class A520 extends Solarite {
|
|
1858
|
+
title = 'Users'
|
|
1859
|
+
user = {name: 'John', email: 'john@example.com'};
|
|
1860
|
+
render() {
|
|
1861
|
+
r(this)`${this.title}<b-520 user="${this.user}"></b-520>`
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
let a = new A520();
|
|
1866
|
+
document.body.append(a);
|
|
1867
|
+
assert.eq(getHtml(a), `<a-520>Users<b-520 user=""><div>Name:</div><div>John</div><div>Email:</div><div>john@example.com</div></b-520></a-520>`)
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
a.user = {name: 'Fred', email: 'fred@example.com'};
|
|
1871
|
+
a.render();
|
|
1872
|
+
assert.eq(getHtml(a), `<a-520>Users<b-520 user=""><div>Name:</div><div>Fred</div><div>Email:</div><div>fred@example.com</div></b-520></a-520>`)
|
|
1873
|
+
|
|
1874
|
+
|
|
1875
|
+
a.user.name = 'Barry'
|
|
1876
|
+
a.render();
|
|
1877
|
+
assert.eq(getHtml(a), `<a-520>Users<b-520 user=""><div>Name:</div><div>Barry</div><div>Email:</div><div>fred@example.com</div></b-520></a-520>`)
|
|
1878
|
+
|
|
1879
|
+
bRenderCount = 0
|
|
1880
|
+
a.render();
|
|
1881
|
+
assert.eq(bRenderCount, 0)
|
|
1882
|
+
|
|
1883
|
+
a.title = 'Users2'
|
|
1884
|
+
a.render();
|
|
1885
|
+
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.
|
|
1887
|
+
|
|
1888
|
+
a.remove();
|
|
1889
|
+
});
|
|
1890
|
+
|
|
1891
|
+
|
|
1892
|
+
|
|
1893
|
+
// TODO: This redraws every tr on every update.
|
|
1894
|
+
// Maybe that can be fixed when keying is supported?
|
|
1895
|
+
Testimony.test('Solarite.component.nestedTrLoop', () => {
|
|
1896
|
+
|
|
1897
|
+
function tableRow(user) {
|
|
1898
|
+
let tr = r(() => r`<tr><td>${user.name}</td><td>${user.email}</td></tr>`)
|
|
1899
|
+
return tr;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
class MyTable extends Solarite {
|
|
1903
|
+
users = [
|
|
1904
|
+
{name: 'John', email: 'john@example.com'},
|
|
1905
|
+
{name: 'Fred', email: 'fred@example.com'}
|
|
1906
|
+
]
|
|
1907
|
+
render() {
|
|
1908
|
+
this.html = r`<table><tbody>${this.users.map(user => tableRow(user))}</tbody></table>`
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
let table = new MyTable
|
|
1912
|
+
document.body.append(table)
|
|
1913
|
+
assert.eq(getHtml(table),
|
|
1914
|
+
`<my-table><table><tbody>`+
|
|
1915
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
1916
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
1917
|
+
`</tbody></table></my-table>`)
|
|
1918
|
+
|
|
1919
|
+
|
|
1920
|
+
table.users[1].name = 'Barry'
|
|
1921
|
+
|
|
1922
|
+
table.render();
|
|
1923
|
+
assert.eq(getHtml(table),
|
|
1924
|
+
`<my-table><table><tbody>` +
|
|
1925
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
1926
|
+
`<tr><td>Barry</td><td>fred@example.com</td></tr>` +
|
|
1927
|
+
`</tbody></table></my-table>`)
|
|
1928
|
+
|
|
1929
|
+
table.remove();
|
|
1930
|
+
});
|
|
1931
|
+
|
|
1932
|
+
|
|
1933
|
+
Testimony.test('Solarite.component.nestedComponentTrLoop', () => {
|
|
1934
|
+
|
|
1935
|
+
class TR540 extends Solarite('tr') {
|
|
1936
|
+
constructor({user}={}) {
|
|
1937
|
+
super();
|
|
1938
|
+
this.user = user;
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
render() {
|
|
1942
|
+
this.html = r`<td>${this.user.name}</td><td>${this.user.email}</td>`
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
TR540.define('tr-540');
|
|
1946
|
+
|
|
1947
|
+
class Table540 extends Solarite {
|
|
1948
|
+
|
|
1949
|
+
users = [
|
|
1950
|
+
{name: 'John', email: 'john@example.com'},
|
|
1951
|
+
{name: 'Fred', email: 'fred@example.com'}
|
|
1952
|
+
]
|
|
1953
|
+
render() {
|
|
1954
|
+
this.html = r`<table><tbody>${this.users.map(user => r`<tr is="tr-540" user="${user}"></tr>`)}</tbody></table>`
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
let table = new Table540
|
|
1958
|
+
document.body.append(table)
|
|
1959
|
+
assert.eq(getHtml(table),
|
|
1960
|
+
`<table-540><table><tbody>`+
|
|
1961
|
+
`<tr is="tr-540" user=""><td>John</td><td>john@example.com</td></tr>` +
|
|
1962
|
+
`<tr is="tr-540" user=""><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
1963
|
+
`</tbody></table></table-540>`)
|
|
1964
|
+
|
|
1965
|
+
|
|
1966
|
+
table.users[1].name = 'Barry'
|
|
1967
|
+
table.render();
|
|
1968
|
+
assert.eq(getHtml(table),
|
|
1969
|
+
`<table-540><table><tbody>` +
|
|
1970
|
+
`<tr is="tr-540" user=""><td>John</td><td>john@example.com</td></tr>` +
|
|
1971
|
+
`<tr is="tr-540" user=""><td>Barry</td><td>fred@example.com</td></tr>` +
|
|
1972
|
+
`</tbody></table></table-540>`)
|
|
1973
|
+
|
|
1974
|
+
table.remove();
|
|
1975
|
+
});
|
|
1976
|
+
|
|
1977
|
+
|
|
1978
|
+
|
|
1979
|
+
// Slots
|
|
1980
|
+
|
|
1981
|
+
Testimony.test('Solarite.slots.basic', () => {
|
|
1982
|
+
|
|
1983
|
+
class S10 extends Solarite {
|
|
1984
|
+
render() {
|
|
1985
|
+
this.html = r`<div>slot content:<slot></slot></div>`
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
S10.define();
|
|
1989
|
+
|
|
1990
|
+
let div = r('<div><s-10>test</s-10></div>')
|
|
1991
|
+
document.body.append(div);
|
|
1992
|
+
|
|
1993
|
+
assert.eq(div.outerHTML, `<div><s-10><div>slot content:<slot>test</slot></div></s-10></div>`)
|
|
1994
|
+
|
|
1995
|
+
div.remove();
|
|
1996
|
+
});
|
|
1997
|
+
|
|
1998
|
+
Testimony.test('Solarite.slots.named', () => {
|
|
1999
|
+
|
|
2000
|
+
class S20 extends Solarite {
|
|
2001
|
+
render() {
|
|
2002
|
+
this.html = r`<div>slot content:<slot name="one"></slot><slot></slot><slot name="two"></slot></div>`
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
S20.define();
|
|
2006
|
+
|
|
2007
|
+
let div = r('<div><s-20>zero<div slot="one">One</div><div slot="one">One Again</div><div slot="two">Two</div>Three</s-20></div>')
|
|
2008
|
+
document.body.append(div);
|
|
2009
|
+
|
|
2010
|
+
assert.eq(div.outerHTML, `<div><s-20><div>slot content:<slot name="one"><div slot="one">One</div><div slot="one">One Again</div></slot><slot>zeroThree</slot><slot name="two"><div slot="two">Two</div></slot></div></s-20></div>`)
|
|
2011
|
+
|
|
2012
|
+
div.remove();
|
|
2013
|
+
});
|
|
2014
|
+
|
|
2015
|
+
|
|
2016
|
+
// Events
|
|
2017
|
+
|
|
2018
|
+
// TODO:
|
|
2019
|
+
Testimony.test('Solarite.events.classic', () => {
|
|
2020
|
+
|
|
2021
|
+
class Ev10 extends Solarite {
|
|
2022
|
+
count = 1
|
|
2023
|
+
|
|
2024
|
+
render() {
|
|
2025
|
+
this.html = r`<input data-id="input" value=${this.count} oninput="this.count=el.count">`
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
let a = new Ev10();
|
|
2030
|
+
document.body.append(a);
|
|
2031
|
+
|
|
2032
|
+
|
|
2033
|
+
a.remove();
|
|
2034
|
+
});
|
|
2035
|
+
|
|
2036
|
+
|
|
2037
|
+
Testimony.test('Solarite.events.rebind', 'Ensure function is unbound/rebound on render', () => {
|
|
2038
|
+
|
|
2039
|
+
let assignCalls = 0;
|
|
2040
|
+
|
|
2041
|
+
class Ev20 extends Solarite {
|
|
2042
|
+
count = 1
|
|
2043
|
+
|
|
2044
|
+
assign(val) {
|
|
2045
|
+
this.count = val;
|
|
2046
|
+
assignCalls++;
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
render() {
|
|
2050
|
+
this.html = r`<input data-id="input" value=${this.count} oninput="${(e, el) => this.assign(el.value)}">`
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
Ev20.define();
|
|
2054
|
+
|
|
2055
|
+
let a = new Ev20();
|
|
2056
|
+
a.render();
|
|
2057
|
+
assert.eq(assignCalls, 0);
|
|
2058
|
+
a.firstChild.dispatchEvent(new Event('input'));
|
|
2059
|
+
assert.eq(assignCalls, 1);
|
|
2060
|
+
|
|
2061
|
+
a.render();
|
|
2062
|
+
a.firstChild.dispatchEvent(new Event('input'));
|
|
2063
|
+
assert.eq(assignCalls, 2);
|
|
2064
|
+
});
|
|
2065
|
+
|
|
2066
|
+
Testimony.test('Solarite.events.args', 'Ensure event function args are received', () => {
|
|
2067
|
+
|
|
2068
|
+
class Ev30 extends Solarite {
|
|
2069
|
+
count = 0
|
|
2070
|
+
|
|
2071
|
+
assign(val) {
|
|
2072
|
+
this.count = val;
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
render() {
|
|
2076
|
+
this.html = r`<input data-id="input" value='1' oninput="${(e, el) => this.assign(el.value)}">`
|
|
2077
|
+
}
|
|
2078
|
+
}
|
|
2079
|
+
Ev30.define();
|
|
2080
|
+
|
|
2081
|
+
let a = new Ev30();
|
|
2082
|
+
a.render();
|
|
2083
|
+
a.firstChild.dispatchEvent(new Event('input'));
|
|
2084
|
+
assert.eq(a.count, '1');
|
|
2085
|
+
|
|
2086
|
+
a.firstChild.value = '2';
|
|
2087
|
+
a.firstChild.dispatchEvent(new Event('input'));
|
|
2088
|
+
assert.eq(a.count, '2');
|
|
2089
|
+
});
|
|
2090
|
+
|
|
2091
|
+
Testimony.test('Solarite.events.onComponent', 'Event attrib on root component', () => {
|
|
2092
|
+
|
|
2093
|
+
class Ev40 extends Solarite {
|
|
2094
|
+
count = 0
|
|
2095
|
+
|
|
2096
|
+
assign(val) {
|
|
2097
|
+
this.count = val;
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
render() {
|
|
2101
|
+
this.html = r`<ev-40 oninput="${(e, el) => this.assign(el.firstChild.value)}"><input data-id="input" value='1'></ev-40>`
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
Ev40.define();
|
|
2105
|
+
|
|
2106
|
+
let a = new Ev40();
|
|
2107
|
+
a.render();
|
|
2108
|
+
a.firstChild.dispatchEvent(new Event('input', {bubbles: true}));
|
|
2109
|
+
assert.eq(a.count, '1');
|
|
2110
|
+
|
|
2111
|
+
a.firstChild.value = '2';
|
|
2112
|
+
a.firstChild.dispatchEvent(new Event('input', {bubbles: true}));
|
|
2113
|
+
assert.eq(a.count, '2');
|
|
2114
|
+
});
|
|
2115
|
+
|
|
2116
|
+
|
|
2117
|
+
|
|
2118
|
+
// Binding
|
|
2119
|
+
|
|
2120
|
+
Testimony.test('Solarite.binding.input', () => {
|
|
2121
|
+
|
|
2122
|
+
class B10 extends Solarite {
|
|
2123
|
+
count = 1
|
|
2124
|
+
|
|
2125
|
+
render() {
|
|
2126
|
+
this.html = r`<input data-id="input" value=${this.count} oninput=${[this, 'count']}>`
|
|
2127
|
+
|
|
2128
|
+
// Alternate syntax:
|
|
2129
|
+
// this.html = r`<input data-bind=${this.$.value}>`
|
|
2130
|
+
// this.html = r`<input value=${this.value} oninput=${el => this.value = el.value}>`
|
|
2131
|
+
// this.html = r`<input data-bind=${[this, 'value']}>`
|
|
2132
|
+
//you havethis.html = r`<input data-id="input" value=${this.count} oninput=${this.count}>` // requires this.render = this.render.bind(Proxy(this). Won't hash properly.
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
let b = new B10();
|
|
2137
|
+
document.body.append(b);
|
|
2138
|
+
assert.eq(b.input.value, '1')
|
|
2139
|
+
|
|
2140
|
+
b.count = 2
|
|
2141
|
+
b.render()
|
|
2142
|
+
assert.eq(b.input.value, '2')
|
|
2143
|
+
|
|
2144
|
+
b.input.value = 3;
|
|
2145
|
+
b.input.dispatchEvent(new Event('input', {
|
|
2146
|
+
bubbles: true,
|
|
2147
|
+
cancelable: true,
|
|
2148
|
+
}));
|
|
2149
|
+
assert.eq(b.count, '3')
|
|
2150
|
+
|
|
2151
|
+
b.remove();
|
|
2152
|
+
});
|
|
2153
|
+
|
|
2154
|
+
Testimony.test('Solarite.binding.inputReuse', () => {
|
|
2155
|
+
|
|
2156
|
+
class B12 extends Solarite {
|
|
2157
|
+
items = [1, 2, 3]
|
|
2158
|
+
|
|
2159
|
+
render() {
|
|
2160
|
+
this.html = r`${this.items.map(item => r`<input data-id="input" value=${item}>`)}`;
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
let b = new B12();
|
|
2165
|
+
document.body.append(b);
|
|
2166
|
+
|
|
2167
|
+
// Remove and re-add the input with a new value.
|
|
2168
|
+
b.items = [];
|
|
2169
|
+
b.render();
|
|
2170
|
+
|
|
2171
|
+
b.items = [4];
|
|
2172
|
+
b.render();
|
|
2173
|
+
|
|
2174
|
+
// Make sure it takes the new value.
|
|
2175
|
+
assert.eq(b.firstElementChild.value, '4');
|
|
2176
|
+
|
|
2177
|
+
b.remove();
|
|
2178
|
+
});
|
|
2179
|
+
|
|
2180
|
+
Testimony.test('Solarite.binding.textarea', () => {
|
|
2181
|
+
|
|
2182
|
+
class B20 extends Solarite {
|
|
2183
|
+
text = 1
|
|
2184
|
+
|
|
2185
|
+
render() {
|
|
2186
|
+
this.html = r`<textarea data-id="input" value=${this.text} oninput=${[this, 'text']}></textarea>`
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
let b = new B20();
|
|
2191
|
+
document.body.append(b);
|
|
2192
|
+
assert.eq(b.input.value, '1')
|
|
2193
|
+
|
|
2194
|
+
b.text = 2
|
|
2195
|
+
b.render()
|
|
2196
|
+
assert.eq(b.input.value, '2')
|
|
2197
|
+
|
|
2198
|
+
b.input.value = 3;
|
|
2199
|
+
b.input.dispatchEvent(new Event('input', {
|
|
2200
|
+
bubbles: true,
|
|
2201
|
+
cancelable: true,
|
|
2202
|
+
}));
|
|
2203
|
+
assert.eq(b.text, '3')
|
|
2204
|
+
|
|
2205
|
+
b.remove();
|
|
2206
|
+
});
|
|
2207
|
+
|
|
2208
|
+
// TODO: Set select.value when option children are rendered and don't exist when the value attrib is evaluated by ExprPath.applyValueAttrib()
|
|
2209
|
+
Testimony.test('Solarite.binding.select', () => {
|
|
2210
|
+
|
|
2211
|
+
class B30 extends Solarite {
|
|
2212
|
+
count = 1
|
|
2213
|
+
|
|
2214
|
+
render() {
|
|
2215
|
+
this.html = r`<select data-id="input" value=${this.count} onchange=${[this, 'count']}><option>1</option><option>2</option><option>3</option></select>`
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
let b = new B30();
|
|
2220
|
+
document.body.append(b);
|
|
2221
|
+
assert.eq(b.input.value, '1')
|
|
2222
|
+
|
|
2223
|
+
b.count = 2
|
|
2224
|
+
b.render()
|
|
2225
|
+
assert.eq(b.input.value, '2');
|
|
2226
|
+
|
|
2227
|
+
b.input.value = 3;
|
|
2228
|
+
b.input.dispatchEvent(new Event('change', {
|
|
2229
|
+
bubbles: true,
|
|
2230
|
+
cancelable: true,
|
|
2231
|
+
}));
|
|
2232
|
+
assert.eq(b.count, '3')
|
|
2233
|
+
|
|
2234
|
+
b.remove();
|
|
2235
|
+
});
|
|
2236
|
+
|
|
2237
|
+
Testimony.test('Solarite.binding.selectDynamic', () => {
|
|
2238
|
+
|
|
2239
|
+
class B32 extends Solarite {
|
|
2240
|
+
count = 1
|
|
2241
|
+
|
|
2242
|
+
render() {
|
|
2243
|
+
this.html = r`<select data-id="input" value=${this.count} onchange=${[this, 'count']}>${[1, 2, 3].map(item => r`<option>${item}</option>`)}</select>`
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
let b = new B32();
|
|
2248
|
+
document.body.append(b);
|
|
2249
|
+
assert.eq(b.input.value, '1')
|
|
2250
|
+
assert.eq(b.input.selectedIndex, 0);
|
|
2251
|
+
|
|
2252
|
+
b.count = 2
|
|
2253
|
+
b.render()
|
|
2254
|
+
assert.eq(b.input.value, '2');
|
|
2255
|
+
assert.eq(b.input.selectedIndex, 1);
|
|
2256
|
+
|
|
2257
|
+
b.input.value = 3;
|
|
2258
|
+
b.input.dispatchEvent(new Event('change', {
|
|
2259
|
+
bubbles: true,
|
|
2260
|
+
cancelable: true,
|
|
2261
|
+
}));
|
|
2262
|
+
assert.eq(b.count, '3')
|
|
2263
|
+
assert.eq(b.input.selectedIndex, 2);
|
|
2264
|
+
|
|
2265
|
+
b.remove();
|
|
2266
|
+
});
|
|
2267
|
+
|
|
2268
|
+
|
|
2269
|
+
|
|
2270
|
+
Testimony.test('Solarite.binding.number', () => {
|
|
2271
|
+
|
|
2272
|
+
class B40 extends Solarite {
|
|
2273
|
+
count = 1
|
|
2274
|
+
|
|
2275
|
+
render() {
|
|
2276
|
+
this.html = r`<input type="number" data-id="input" value=${this.count} oninput=${[this, 'count']}>`
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
let b = new B40();
|
|
2281
|
+
document.body.append(b);
|
|
2282
|
+
assert.eq(b.input.value, '1')
|
|
2283
|
+
|
|
2284
|
+
b.count = 2
|
|
2285
|
+
b.render()
|
|
2286
|
+
assert.eq(b.input.value, '2')
|
|
2287
|
+
|
|
2288
|
+
b.input.value = 3;
|
|
2289
|
+
b.input.dispatchEvent(new Event('input', {
|
|
2290
|
+
bubbles: true,
|
|
2291
|
+
cancelable: true,
|
|
2292
|
+
}));
|
|
2293
|
+
assert.eq(b.count, 3)
|
|
2294
|
+
|
|
2295
|
+
b.remove();
|
|
2296
|
+
});
|
|
2297
|
+
|
|
2298
|
+
|
|
2299
|
+
|
|
2300
|
+
/*
|
|
2301
|
+
Testimony.test('Solarite.watched.watchSet', () => {
|
|
2302
|
+
|
|
2303
|
+
class W10 extends Solarite {
|
|
2304
|
+
user = {
|
|
2305
|
+
name: 'John',
|
|
2306
|
+
email: 'john@example.com'
|
|
2307
|
+
}
|
|
2308
|
+
render() {
|
|
2309
|
+
this.html = r`
|
|
2310
|
+
<w-10>
|
|
2311
|
+
<div>${watchGet([this, 'user'], user => user.name + ' (user)')}</div>
|
|
2312
|
+
<div>${watchGet([this, 'user', 'email'])}</div>
|
|
2313
|
+
</w-10>`
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
let a = new W10();
|
|
2318
|
+
document.body.append(a);
|
|
2319
|
+
|
|
2320
|
+
// swap property on user.
|
|
2321
|
+
watchSet(a).user.name = 'Fred';
|
|
2322
|
+
a.renderWatched();
|
|
2323
|
+
//console.log(getHtml(a))
|
|
2324
|
+
assert.eq(getHtml(a), `<w-10><div>Fred (user)</div><div>john@example.com</div></w-10>`)
|
|
2325
|
+
|
|
2326
|
+
// Swap whole user.
|
|
2327
|
+
watchSet(a).user = {name: 'Fred', email: 'fred@example.com'};
|
|
2328
|
+
a.renderWatched();
|
|
2329
|
+
//console.log(getHtml(a))
|
|
2330
|
+
assert.eq(getHtml(a), `<w-10><div>Fred (user)</div><div>fred@example.com</div></w-10>`)
|
|
2331
|
+
|
|
2332
|
+
|
|
2333
|
+
a.remove();
|
|
2334
|
+
});
|
|
2335
|
+
|
|
2336
|
+
|
|
2337
|
+
|
|
2338
|
+
|
|
2339
|
+
|
|
2340
|
+
|
|
2341
|
+
Testimony.test('Solarite.watched.forEach', () => {
|
|
2342
|
+
|
|
2343
|
+
class Table650 extends Solarite {
|
|
2344
|
+
users = [
|
|
2345
|
+
{name: 'John', email: 'john@example.com'},
|
|
2346
|
+
{name: 'Fred', email: 'fred@example.com'}
|
|
2347
|
+
]
|
|
2348
|
+
render() {
|
|
2349
|
+
this.html = r`
|
|
2350
|
+
<table style="table-layout: fixed; width: 150px">
|
|
2351
|
+
<tbody>${
|
|
2352
|
+
forEach([this, 'users'], user =>
|
|
2353
|
+
r`<tr><td>${user.name}</td><td>${user.email}</td></tr>`
|
|
2354
|
+
)}
|
|
2355
|
+
</tbody>
|
|
2356
|
+
</table>`
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
let table = new Table650
|
|
2360
|
+
document.body.append(table)
|
|
2361
|
+
|
|
2362
|
+
assert.eq(getHtml(table),
|
|
2363
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2364
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2365
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2366
|
+
`</tbody></table></table-650>`)
|
|
2367
|
+
|
|
2368
|
+
// Watch one row, set property
|
|
2369
|
+
watchSet(table).users[1].name = 'Barry'
|
|
2370
|
+
|
|
2371
|
+
table.renderWatched();
|
|
2372
|
+
assert.eq(getHtml(table),
|
|
2373
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2374
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2375
|
+
`<tr><td>Barry</td><td>fred@example.com</td></tr>` +
|
|
2376
|
+
`</tbody></table></table-650>`)
|
|
2377
|
+
|
|
2378
|
+
// Watch one row, set property twice
|
|
2379
|
+
watchSet(table).users[1].name = 'Bob'
|
|
2380
|
+
watchSet(table).users[1].name = 'Rob'
|
|
2381
|
+
table.renderWatched();
|
|
2382
|
+
assert.eq(getHtml(table),
|
|
2383
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2384
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2385
|
+
`<tr><td>Rob</td><td>fred@example.com</td></tr>` +
|
|
2386
|
+
`</tbody></table></table-650>`)
|
|
2387
|
+
|
|
2388
|
+
// Watch all rows, set property of one.
|
|
2389
|
+
watchSet(table).users[1].name = 'George'
|
|
2390
|
+
table.renderWatched();
|
|
2391
|
+
assert.eq(getHtml(table),
|
|
2392
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2393
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2394
|
+
`<tr><td>George</td><td>fred@example.com</td></tr>` +
|
|
2395
|
+
`</tbody></table></table-650>`)
|
|
2396
|
+
|
|
2397
|
+
// Watch whole object, set property of one.
|
|
2398
|
+
watchSet(table).users[1].name = 'Jim'
|
|
2399
|
+
table.renderWatched();
|
|
2400
|
+
assert.eq(getHtml(table),
|
|
2401
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2402
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2403
|
+
`<tr><td>Jim</td><td>fred@example.com</td></tr>` +
|
|
2404
|
+
`</tbody></table></table-650>`)
|
|
2405
|
+
|
|
2406
|
+
// Update entire row object
|
|
2407
|
+
watchSet(table).users[1] = {name: 'Ned', email: 'ned@example.com'}
|
|
2408
|
+
table.renderWatched();
|
|
2409
|
+
assert.eq(getHtml(table),
|
|
2410
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2411
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2412
|
+
`<tr><td>Ned</td><td>ned@example.com</td></tr>` +
|
|
2413
|
+
`</tbody></table></table-650>`)
|
|
2414
|
+
|
|
2415
|
+
table.remove();
|
|
2416
|
+
|
|
2417
|
+
});
|
|
2418
|
+
|
|
2419
|
+
|
|
2420
|
+
Testimony.test('Solarite.watched.forEachSpliceDelete', () => {
|
|
2421
|
+
|
|
2422
|
+
class W50 extends Solarite {
|
|
2423
|
+
users = [
|
|
2424
|
+
{name: 'John', email: 'john@example.com'},
|
|
2425
|
+
{name: 'Fred', email: 'fred@example.com'},
|
|
2426
|
+
{name: 'George', email: 'george@example.com'},
|
|
2427
|
+
{name: 'Bill', email: 'bill@example.com'}
|
|
2428
|
+
]
|
|
2429
|
+
render() {
|
|
2430
|
+
this.html = r`<table style="table-layout: fixed; width: 150px"><tbody>${forEach([this, 'users'], user => r`<tr><td>${user.name}</td><td>${user.email}</td></tr>`)}</tbody></table>`
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
let table = new W50
|
|
2434
|
+
document.body.append(table)
|
|
2435
|
+
|
|
2436
|
+
assert.eq(getHtml(table),
|
|
2437
|
+
`<w-50><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2438
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2439
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2440
|
+
`<tr><td>George</td><td>george@example.com</td></tr>` +
|
|
2441
|
+
`<tr><td>Bill</td><td>bill@example.com</td></tr>` +
|
|
2442
|
+
`</tbody></table></w-50>`)
|
|
2443
|
+
|
|
2444
|
+
|
|
2445
|
+
// Splice
|
|
2446
|
+
watchSet(table).users.splice(1, 2)
|
|
2447
|
+
table.renderWatched();
|
|
2448
|
+
assert.eq(getHtml(table),
|
|
2449
|
+
`<w-50><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2450
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2451
|
+
`<tr><td>Bill</td><td>bill@example.com</td></tr>` +
|
|
2452
|
+
`</tbody></table></w-50>`)
|
|
2453
|
+
|
|
2454
|
+
table.remove();
|
|
2455
|
+
});
|
|
2456
|
+
|
|
2457
|
+
Testimony.test('Solarite.watched.forEachSpliceInsert', () => {
|
|
2458
|
+
|
|
2459
|
+
class W60 extends Solarite {
|
|
2460
|
+
users = [
|
|
2461
|
+
{name: 'John', email: 'john@example.com'},
|
|
2462
|
+
{name: 'Fred', email: 'fred@example.com'}
|
|
2463
|
+
]
|
|
2464
|
+
render() {
|
|
2465
|
+
this.html = r`
|
|
2466
|
+
<table style="table-layout: fixed; width: 150px">
|
|
2467
|
+
<tbody>${forEach([this, 'users'], user =>
|
|
2468
|
+
r`<tr><td>${user.name}</td><td>${user.email}</td></tr>`
|
|
2469
|
+
)}
|
|
2470
|
+
</tbody>
|
|
2471
|
+
</table>`
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
let table = new W60
|
|
2475
|
+
document.body.append(table)
|
|
2476
|
+
|
|
2477
|
+
assert.eq(getHtml(table),
|
|
2478
|
+
`<w-60><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2479
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2480
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2481
|
+
`</tbody></table></w-60>`)
|
|
2482
|
+
|
|
2483
|
+
|
|
2484
|
+
// Splice
|
|
2485
|
+
watchSet(table).users.splice(1, 0, {name: 'George', email: 'george@example.com'})
|
|
2486
|
+
table.renderWatched();
|
|
2487
|
+
assert.eq(getHtml(table),
|
|
2488
|
+
`<w-60><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2489
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2490
|
+
`<tr><td>George</td><td>george@example.com</td></tr>` +
|
|
2491
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2492
|
+
`</tbody></table></w-60>`)
|
|
2493
|
+
|
|
2494
|
+
table.remove();
|
|
2495
|
+
});
|
|
2496
|
+
|
|
2497
|
+
|
|
2498
|
+
|
|
2499
|
+
|
|
2500
|
+
|
|
2501
|
+
// Experiment with a new syntax for watching.
|
|
2502
|
+
Testimony.test('Solarite.watched._$', () => {
|
|
2503
|
+
|
|
2504
|
+
class Table670 extends Solarite {
|
|
2505
|
+
title = 'Title';
|
|
2506
|
+
users = [
|
|
2507
|
+
{name: 'John', email: 'john@example.com'},
|
|
2508
|
+
{name: 'Fred', email: 'fred@example.com'}
|
|
2509
|
+
]
|
|
2510
|
+
render() {
|
|
2511
|
+
this.html = // r() can check for instanceof Proxy and convert it to something?
|
|
2512
|
+
r`${this.$.title}
|
|
2513
|
+
<table style="table-layout: fixed; width: 150px">
|
|
2514
|
+
<tbody>${this.$.users.map(user =>
|
|
2515
|
+
r`<tr><td>${user.name}</td><td>${user.email}</td></tr>`)}
|
|
2516
|
+
</tbody>
|
|
2517
|
+
</table>`
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
let table = new Table670
|
|
2521
|
+
document.body.append(table)
|
|
2522
|
+
|
|
2523
|
+
|
|
2524
|
+
table.$.title = 'test';
|
|
2525
|
+
table.$.users[1].name = 'Jim';
|
|
2526
|
+
|
|
2527
|
+
//table.remove();
|
|
2528
|
+
});
|
|
2529
|
+
|
|
2530
|
+
|
|
2531
|
+
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
Testimony.test('Solarite.watch2.set', () => {
|
|
2535
|
+
|
|
2536
|
+
class W10 extends Solarite {
|
|
2537
|
+
user = {
|
|
2538
|
+
name: 'John',
|
|
2539
|
+
email: 'john@example.com'
|
|
2540
|
+
}
|
|
2541
|
+
render() {
|
|
2542
|
+
this.html = r`
|
|
2543
|
+
<w-10>
|
|
2544
|
+
<div>${() => watch(this).user.name + ' (user)'}</div>
|
|
2545
|
+
<div>${() => watch(this).user.email}</div>
|
|
2546
|
+
</w-10>`
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
let a = new W10();
|
|
2551
|
+
document.body.append(a);
|
|
2552
|
+
|
|
2553
|
+
// swap property on user.
|
|
2554
|
+
watch(a).user.name = 'Fred';
|
|
2555
|
+
//console.log(getHtml(a))
|
|
2556
|
+
assert.eq(getHtml(a), `<w-10><div>Fred (user)</div><div>john@example.com</div></w-10>`)
|
|
2557
|
+
|
|
2558
|
+
// Swap whole user.
|
|
2559
|
+
watch(a).user = {name: 'Fred', email: 'fred@example.com'};
|
|
2560
|
+
//console.log(getHtml(a))
|
|
2561
|
+
assert.eq(getHtml(a), `<w-10><div>Fred (user)</div><div>fred@example.com</div></w-10>`)
|
|
2562
|
+
|
|
2563
|
+
|
|
2564
|
+
a.remove();
|
|
2565
|
+
});
|
|
2566
|
+
|
|
2567
|
+
*/
|
|
2568
|
+
|
|
2569
|
+
Testimony.test('Solarite.watch2._forEach', () => {
|
|
2570
|
+
|
|
2571
|
+
class Table650 extends Solarite {
|
|
2572
|
+
users = [
|
|
2573
|
+
{name: 'John', email: 'john@example.com'},
|
|
2574
|
+
{name: 'Fred', email: 'fred@example.com'}
|
|
2575
|
+
]
|
|
2576
|
+
render() {
|
|
2577
|
+
this.html = r`
|
|
2578
|
+
<table style="table-layout: fixed; width: 150px">
|
|
2579
|
+
<tbody>${
|
|
2580
|
+
watch(this).users.map(user =>
|
|
2581
|
+
r`<tr><td>${user.name}</td><td>${user.email}</td></tr>`
|
|
2582
|
+
)}
|
|
2583
|
+
</tbody>
|
|
2584
|
+
</table>`
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
let table = new Table650
|
|
2588
|
+
document.body.append(table)
|
|
2589
|
+
|
|
2590
|
+
assert.eq(getHtml(table),
|
|
2591
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2592
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2593
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2594
|
+
`</tbody></table></table-650>`)
|
|
2595
|
+
|
|
2596
|
+
// Watch one row, set property
|
|
2597
|
+
watch(table).users[1].name = 'Barry'
|
|
2598
|
+
|
|
2599
|
+
assert.eq(getHtml(table),
|
|
2600
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2601
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2602
|
+
`<tr><td>Barry</td><td>fred@example.com</td></tr>` +
|
|
2603
|
+
`</tbody></table></table-650>`)
|
|
2604
|
+
|
|
2605
|
+
// Watch one row, set property twice
|
|
2606
|
+
watch(table).users[1].name = 'Bob'
|
|
2607
|
+
watch(table).users[1].name = 'Rob'
|
|
2608
|
+
assert.eq(getHtml(table),
|
|
2609
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2610
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2611
|
+
`<tr><td>Rob</td><td>fred@example.com</td></tr>` +
|
|
2612
|
+
`</tbody></table></table-650>`)
|
|
2613
|
+
|
|
2614
|
+
|
|
2615
|
+
// Watch whole object, set property of one.
|
|
2616
|
+
watch(table).users[1].name = 'Jim'
|
|
2617
|
+
assert.eq(getHtml(table),
|
|
2618
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2619
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2620
|
+
`<tr><td>Jim</td><td>fred@example.com</td></tr>` +
|
|
2621
|
+
`</tbody></table></table-650>`)
|
|
2622
|
+
|
|
2623
|
+
// Update entire row object
|
|
2624
|
+
watch(table).users[1] = {name: 'Ned', email: 'ned@example.com'}
|
|
2625
|
+
assert.eq(getHtml(table),
|
|
2626
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2627
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2628
|
+
`<tr><td>Ned</td><td>ned@example.com</td></tr>` +
|
|
2629
|
+
`</tbody></table></table-650>`)
|
|
2630
|
+
|
|
2631
|
+
// Clear
|
|
2632
|
+
watch(table).users = [];
|
|
2633
|
+
assert.eq(getHtml(table),
|
|
2634
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2635
|
+
`</tbody></table></table-650>`)
|
|
2636
|
+
|
|
2637
|
+
|
|
2638
|
+
// This gets the wrong value via NodeGroupManager b/c we never update exactKeys.
|
|
2639
|
+
watch(table).users = [
|
|
2640
|
+
{name: 'John', email: 'john@example.com'},
|
|
2641
|
+
{name: 'Fred', email: 'fred@example.com'}
|
|
2642
|
+
];
|
|
2643
|
+
assert.eq(getHtml(table),
|
|
2644
|
+
`<table-650><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2645
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2646
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2647
|
+
`</tbody></table></table-650>`)
|
|
2648
|
+
|
|
2649
|
+
table.remove();
|
|
2650
|
+
|
|
2651
|
+
});
|
|
2652
|
+
|
|
2653
|
+
Testimony.test('Solarite.watch2._forEachSpliceDelete', () => {
|
|
2654
|
+
|
|
2655
|
+
class W50 extends Solarite {
|
|
2656
|
+
users = [
|
|
2657
|
+
{name: 'John', email: 'john@example.com'},
|
|
2658
|
+
{name: 'Fred', email: 'fred@example.com'},
|
|
2659
|
+
{name: 'George', email: 'george@example.com'},
|
|
2660
|
+
{name: 'Bill', email: 'bill@example.com'}
|
|
2661
|
+
]
|
|
2662
|
+
render() {
|
|
2663
|
+
this.html = r`<table style="table-layout: fixed; width: 150px"><tbody>${watch(this).users.map(user => r`<tr><td>${user.name}</td><td>${user.email}</td></tr>`)}</tbody></table>`
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
let table = new W50
|
|
2667
|
+
document.body.append(table)
|
|
2668
|
+
|
|
2669
|
+
assert.eq(getHtml(table),
|
|
2670
|
+
`<w-50><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2671
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2672
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2673
|
+
`<tr><td>George</td><td>george@example.com</td></tr>` +
|
|
2674
|
+
`<tr><td>Bill</td><td>bill@example.com</td></tr>` +
|
|
2675
|
+
`</tbody></table></w-50>`)
|
|
2676
|
+
|
|
2677
|
+
|
|
2678
|
+
// Splice middle.
|
|
2679
|
+
watch(table).users.splice(1, 2)
|
|
2680
|
+
assert.eq(getHtml(table),
|
|
2681
|
+
`<w-50><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2682
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2683
|
+
`<tr><td>Bill</td><td>bill@example.com</td></tr>` +
|
|
2684
|
+
`</tbody></table></w-50>`)
|
|
2685
|
+
|
|
2686
|
+
|
|
2687
|
+
// Splice to remove all.
|
|
2688
|
+
watch(table).users.splice(0, 2);
|
|
2689
|
+
assert.eq(getHtml(table),
|
|
2690
|
+
`<w-50><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2691
|
+
`</tbody></table></w-50>`)
|
|
2692
|
+
|
|
2693
|
+
table.remove();
|
|
2694
|
+
});
|
|
2695
|
+
|
|
2696
|
+
|
|
2697
|
+
Testimony.test('Solarite.watch2._forEachSpliceDeleteStart', () => {
|
|
2698
|
+
|
|
2699
|
+
class W55 extends Solarite {
|
|
2700
|
+
users = [
|
|
2701
|
+
{name: 'John', email: 'john@example.com'},
|
|
2702
|
+
{name: 'Fred', email: 'fred@example.com'},
|
|
2703
|
+
{name: 'George', email: 'george@example.com'},
|
|
2704
|
+
{name: 'Bill', email: 'bill@example.com'}
|
|
2705
|
+
]
|
|
2706
|
+
render() {
|
|
2707
|
+
this.html = r`${watch(this).users.map(user => r`<div>${user.name}|${user.email}</div>`)}`
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
let table = new W55
|
|
2711
|
+
document.body.append(table)
|
|
2712
|
+
|
|
2713
|
+
assert.eq(getHtml(table),
|
|
2714
|
+
`<w-55>`+
|
|
2715
|
+
`<div>John|john@example.com</div>` +
|
|
2716
|
+
`<div>Fred|fred@example.com</div>` +
|
|
2717
|
+
`<div>George|george@example.com</div>` +
|
|
2718
|
+
`<div>Bill|bill@example.com</div>` +
|
|
2719
|
+
`</w-55>`)
|
|
2720
|
+
|
|
2721
|
+
|
|
2722
|
+
// Splice start.
|
|
2723
|
+
watch(table).users.splice(0, 1)
|
|
2724
|
+
assert.eq(getHtml(table),
|
|
2725
|
+
`<w-55>`+
|
|
2726
|
+
`<div>Fred|fred@example.com</div>` +
|
|
2727
|
+
`<div>George|george@example.com</div>` +
|
|
2728
|
+
`<div>Bill|bill@example.com</div>` +
|
|
2729
|
+
`</w-55>`)
|
|
2730
|
+
|
|
2731
|
+
|
|
2732
|
+
// Splice start.
|
|
2733
|
+
watch(table).users.splice(0, 1)
|
|
2734
|
+
assert.eq(getHtml(table),
|
|
2735
|
+
`<w-55>`+
|
|
2736
|
+
`<div>George|george@example.com</div>` +
|
|
2737
|
+
`<div>Bill|bill@example.com</div>` +
|
|
2738
|
+
`</w-55>`)
|
|
2739
|
+
|
|
2740
|
+
|
|
2741
|
+
watch(table).users.splice(0, 1)
|
|
2742
|
+
assert.eq(getHtml(table),
|
|
2743
|
+
`<w-55>`+
|
|
2744
|
+
`<div>Bill|bill@example.com</div>` +
|
|
2745
|
+
`</w-55>`)
|
|
2746
|
+
|
|
2747
|
+
table.remove();
|
|
2748
|
+
});
|
|
2749
|
+
|
|
2750
|
+
Testimony.test('Solarite.watch2._forEachSpliceDeleteEvent', () => {
|
|
2751
|
+
|
|
2752
|
+
class W57 extends Solarite {
|
|
2753
|
+
users = [
|
|
2754
|
+
{name: 'John', email: 'john@example.com'},
|
|
2755
|
+
{name: 'Fred', email: 'fred@example.com'},
|
|
2756
|
+
{name: 'George', email: 'george@example.com'},
|
|
2757
|
+
{name: 'Bill', email: 'bill@example.com'}
|
|
2758
|
+
]
|
|
2759
|
+
|
|
2760
|
+
delete(user) {
|
|
2761
|
+
let idx = this.users.indexOf(user);
|
|
2762
|
+
assert(idx > 0)
|
|
2763
|
+
this.users.splice(idx, 1);
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
render() {
|
|
2767
|
+
this.html = r`${watch(this).users.map(user => r`<div onclick="${()=>this.delete(user)}">${user.name}|${user.email}</div>`)}`
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
let table = new W57
|
|
2771
|
+
document.body.append(table)
|
|
2772
|
+
|
|
2773
|
+
assert.eq(getHtml(table),
|
|
2774
|
+
`<w-57>`+
|
|
2775
|
+
`<div onclick="">John|john@example.com</div>` +
|
|
2776
|
+
`<div onclick="">Fred|fred@example.com</div>` +
|
|
2777
|
+
`<div onclick="">George|george@example.com</div>` +
|
|
2778
|
+
`<div onclick="">Bill|bill@example.com</div>` +
|
|
2779
|
+
`</w-57>`);
|
|
2780
|
+
|
|
2781
|
+
table.remove();
|
|
2782
|
+
});
|
|
2783
|
+
|
|
2784
|
+
Testimony.test('Solarite.watch2._forEachSpliceInsert', () => {
|
|
2785
|
+
|
|
2786
|
+
class W60 extends Solarite {
|
|
2787
|
+
users = [
|
|
2788
|
+
{name: 'John', email: 'john@example.com'},
|
|
2789
|
+
{name: 'Fred', email: 'fred@example.com'}
|
|
2790
|
+
]
|
|
2791
|
+
render() {
|
|
2792
|
+
this.html = r`
|
|
2793
|
+
<table style="table-layout: fixed; width: 150px">
|
|
2794
|
+
<tbody>${watch(this).users.map(user =>
|
|
2795
|
+
r`<tr><td>${user.name}</td><td>${user.email}</td></tr>`
|
|
2796
|
+
)}
|
|
2797
|
+
</tbody>
|
|
2798
|
+
</table>`
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
let table = new W60
|
|
2802
|
+
document.body.append(table)
|
|
2803
|
+
|
|
2804
|
+
assert.eq(getHtml(table),
|
|
2805
|
+
`<w-60><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2806
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2807
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2808
|
+
`</tbody></table></w-60>`)
|
|
2809
|
+
|
|
2810
|
+
|
|
2811
|
+
// Splice
|
|
2812
|
+
watch(table).users.splice(1, 0, {name: 'George', email: 'george@example.com'})
|
|
2813
|
+
assert.eq(getHtml(table),
|
|
2814
|
+
`<w-60><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2815
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2816
|
+
`<tr><td>George</td><td>george@example.com</td></tr>` +
|
|
2817
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2818
|
+
`</tbody></table></w-60>`)
|
|
2819
|
+
|
|
2820
|
+
// Splice to insert at end.
|
|
2821
|
+
watch(table).users.splice(3, 0, {name: 'Bill', email: 'bill@example.com'})
|
|
2822
|
+
assert.eq(getHtml(table),
|
|
2823
|
+
`<w-60><table style="table-layout: fixed; width: 150px"><tbody>`+
|
|
2824
|
+
`<tr><td>John</td><td>john@example.com</td></tr>` +
|
|
2825
|
+
`<tr><td>George</td><td>george@example.com</td></tr>` +
|
|
2826
|
+
`<tr><td>Fred</td><td>fred@example.com</td></tr>` +
|
|
2827
|
+
`<tr><td>Bill</td><td>bill@example.com</td></tr>` +
|
|
2828
|
+
`</tbody></table></w-60>`)
|
|
2829
|
+
|
|
2830
|
+
table.remove();
|
|
2831
|
+
});
|
|
2832
|
+
|
|
2833
|
+
|
|
2834
|
+
|
|
2835
|
+
|
|
2836
|
+
|
|
2837
|
+
|
|
2838
|
+
|
|
2839
|
+
|
|
2840
|
+
|
|
2841
|
+
|
|
2842
|
+
|
|
2843
|
+
|
|
2844
|
+
|
|
2845
|
+
|
|
2846
|
+
|
|
2847
|
+
|
|
2848
|
+
|
|
2849
|
+
|
|
2850
|
+
Testimony.test('Solarite.full.treeItems', () => {
|
|
2851
|
+
|
|
2852
|
+
//import '../src/RedComponent.js'
|
|
2853
|
+
|
|
2854
|
+
class TreeItem extends Solarite {
|
|
2855
|
+
|
|
2856
|
+
constructor(title, children=[]) {
|
|
2857
|
+
super();
|
|
2858
|
+
this.childItems = children;
|
|
2859
|
+
this.titleText = title;
|
|
2860
|
+
this.showChildren = true;
|
|
2861
|
+
}
|
|
2862
|
+
|
|
2863
|
+
toggleChildren() {
|
|
2864
|
+
this.showChildren = !this.showChildren
|
|
2865
|
+
this.render();
|
|
2866
|
+
}
|
|
2867
|
+
|
|
2868
|
+
render() {
|
|
2869
|
+
this.html = r`
|
|
2870
|
+
<tree-item>
|
|
2871
|
+
<style>
|
|
2872
|
+
:host #childItems { padding-left: 20px }
|
|
2873
|
+
</style>
|
|
2874
|
+
<div onclick="${this.toggleChildren}">${this.titleText}</div>
|
|
2875
|
+
<div id="childItems" hidden="${!this.showChildren}">
|
|
2876
|
+
${this.childItems}
|
|
2877
|
+
</div>
|
|
2878
|
+
</tree-item>`;
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
TreeItem.define();
|
|
2882
|
+
|
|
2883
|
+
let root = new TreeItem('Root', [
|
|
2884
|
+
new TreeItem('Folder 1', [
|
|
2885
|
+
new TreeItem('File 1'),
|
|
2886
|
+
new TreeItem('File 2'),
|
|
2887
|
+
new TreeItem('File 3')
|
|
2888
|
+
]),
|
|
2889
|
+
new TreeItem('Folder 2')
|
|
2890
|
+
])
|
|
2891
|
+
|
|
2892
|
+
document.body.append(root);
|
|
2893
|
+
root.remove();
|
|
2894
|
+
});
|
|
2895
|
+
|
|
2896
|
+
|