@lightningjs/blits 1.30.2 → 1.31.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.
Files changed (152) hide show
  1. package/CHANGELOG.md +1029 -1019
  2. package/LICENSE +202 -202
  3. package/NOTICE +12 -12
  4. package/README.md +33 -33
  5. package/bin/index.js +8 -8
  6. package/blits.d.ts +6 -6
  7. package/index.d.ts +1099 -1099
  8. package/index.js +28 -28
  9. package/package.json +57 -56
  10. package/public/assets/fps_sprite.base64.js +1 -1
  11. package/scripts/postpublish.js +59 -59
  12. package/scripts/prepublishOnly.js +84 -84
  13. package/scripts/prepush.js +78 -78
  14. package/src/announcer/announcer.js +162 -162
  15. package/src/announcer/speechSynthesis.js +107 -107
  16. package/src/application.js +100 -100
  17. package/src/component/base/announcer.js +27 -27
  18. package/src/component/base/events.js +69 -69
  19. package/src/component/base/index.js +33 -33
  20. package/src/component/base/methods.js +244 -244
  21. package/src/component/base/router.js +41 -41
  22. package/src/component/base/timeouts_intervals.js +99 -99
  23. package/src/component/base/utils.js +72 -72
  24. package/src/component/setup/computed.js +48 -48
  25. package/src/component/setup/index.js +62 -62
  26. package/src/component/setup/input.js +30 -30
  27. package/src/component/setup/methods.js +37 -37
  28. package/src/component/setup/props.js +62 -62
  29. package/src/component/setup/routes.js +42 -42
  30. package/src/component/setup/state.js +59 -59
  31. package/src/component/setup/watch.js +35 -35
  32. package/src/component.js +437 -437
  33. package/src/components/Circle.js +73 -73
  34. package/src/components/FPScounter.js +1510 -1510
  35. package/src/components/RouterView.js +81 -81
  36. package/src/components/Sprite.js +94 -94
  37. package/src/components/index.js +28 -28
  38. package/src/constants.js +21 -21
  39. package/src/engine.js +1 -1
  40. package/src/engines/L3/element.js +744 -744
  41. package/src/engines/L3/fontLoader.js +38 -38
  42. package/src/engines/L3/index.js +7 -7
  43. package/src/engines/L3/launch.js +123 -123
  44. package/src/engines/L3/shaderLoader.js +12 -12
  45. package/src/engines/index.js +1 -1
  46. package/src/focus.js +90 -90
  47. package/src/helpers/deepEqualArray.js +50 -50
  48. package/src/helpers/fetchJson.js +34 -34
  49. package/src/helpers/sequence.js +26 -26
  50. package/src/launch.js +123 -123
  51. package/src/lib/blitsfileconverter/blitsfileconverter.js +52 -52
  52. package/src/lib/codegenerator/generator.js +788 -788
  53. package/src/lib/colors/colors.js +92 -92
  54. package/src/lib/colors/htmlColors.js +168 -168
  55. package/src/lib/componentId.js +49 -49
  56. package/src/lib/eventListeners.js +123 -123
  57. package/src/lib/hooks.js +59 -59
  58. package/src/lib/lifecycle.js +85 -85
  59. package/src/lib/log.js +117 -117
  60. package/src/lib/precompiler/precompiler.js +73 -73
  61. package/src/lib/reactivity/effect.js +93 -93
  62. package/src/lib/reactivity/reactive.js +208 -208
  63. package/src/lib/reactivityguard/computedprops.js +218 -218
  64. package/src/lib/symbols.js +108 -108
  65. package/src/lib/templateparser/parser.js +386 -386
  66. package/src/lib/utils.js +27 -27
  67. package/src/plugin.js +27 -27
  68. package/src/plugins/appstate.js +26 -26
  69. package/src/plugins/index.js +20 -20
  70. package/src/plugins/language.js +152 -152
  71. package/src/plugins/log.js +25 -25
  72. package/src/plugins/theme.js +94 -94
  73. package/src/router/router.js +516 -514
  74. package/src/router/transitions/fadeIn.js +27 -27
  75. package/src/router/transitions/fadeInOut.js +33 -33
  76. package/src/router/transitions/index.js +21 -21
  77. package/src/router/transitions/slideIn.js +28 -28
  78. package/src/router/transitions/slideInOut.js +33 -33
  79. package/src/settings.js +40 -40
  80. package/vite/blitsFileConverter.js +67 -67
  81. package/vite/index.js +28 -28
  82. package/vite/msdfGenerator.js +269 -269
  83. package/vite/preCompiler.js +47 -42
  84. package/vite/reactivityGuard.js +45 -45
  85. package/vscode/data/template-attributes.json +589 -589
  86. package/.editorconfig +0 -7
  87. package/.eslintignore +0 -1
  88. package/.eslintrc.cjs +0 -65
  89. package/.github/workflows/comment-lint-results.yml +0 -125
  90. package/.github/workflows/comment-test-results.yml +0 -109
  91. package/.github/workflows/deploy-docs.yml +0 -27
  92. package/.github/workflows/run-blits-tests.yml +0 -142
  93. package/.github/workflows/run-lint.yml +0 -128
  94. package/.husky/pre-commit +0 -1
  95. package/.husky/pre-push +0 -1
  96. package/.vscode/extensions.json +0 -7
  97. package/.vscode/settings.json +0 -9
  98. package/COPYING +0 -1
  99. package/banner.png +0 -0
  100. package/docs/.nojekyll +0 -0
  101. package/docs/README.md +0 -19
  102. package/docs/_sidebar.md +0 -37
  103. package/docs/built-in/directives.md +0 -50
  104. package/docs/built-in/for-loop.md +0 -204
  105. package/docs/built-in/layout.md +0 -168
  106. package/docs/components/component_state.md +0 -90
  107. package/docs/components/computed_properties.md +0 -45
  108. package/docs/components/lifecycle_events.md +0 -42
  109. package/docs/components/methods.md +0 -45
  110. package/docs/components/props.md +0 -56
  111. package/docs/components/user_input.md +0 -186
  112. package/docs/components/utility_methods.md +0 -320
  113. package/docs/components/watchers.md +0 -34
  114. package/docs/essentials/application_root.md +0 -19
  115. package/docs/essentials/components.md +0 -68
  116. package/docs/essentials/displaying_images.md +0 -67
  117. package/docs/essentials/displaying_text.md +0 -135
  118. package/docs/essentials/element_attributes.md +0 -195
  119. package/docs/essentials/settings.md +0 -117
  120. package/docs/essentials/template_syntax.md +0 -83
  121. package/docs/getting_started/file_structure.md +0 -58
  122. package/docs/getting_started/getting_started.md +0 -45
  123. package/docs/getting_started/intro.md +0 -20
  124. package/docs/index.html +0 -47
  125. package/docs/performance/lazy-loading.md +0 -161
  126. package/docs/plugins/global_app_state.md +0 -98
  127. package/docs/plugins/language.md +0 -172
  128. package/docs/plugins/text-to-speech-announcer.md +0 -120
  129. package/docs/plugins/theme.md +0 -176
  130. package/docs/router/basics.md +0 -175
  131. package/docs/router/hooks.md +0 -70
  132. package/docs/router/transitions.md +0 -146
  133. package/docs/sidebar.json +0 -171
  134. package/docs/transitions_animations/transitions.md +0 -150
  135. package/jsconfig.json +0 -12
  136. package/src/component/setup/props.test.js +0 -238
  137. package/src/component.test.js +0 -388
  138. package/src/components/Circle.orig.js +0 -31
  139. package/src/components/FPScounter.orig.js +0 -121
  140. package/src/components/RouterView.orig.js +0 -54
  141. package/src/components/Sprite.orig.js +0 -58
  142. package/src/components/index.orig.js +0 -28
  143. package/src/engines/L3/element.test.js +0 -579
  144. package/src/helpers/deepEqualArray.test.js +0 -127
  145. package/src/lib/codegenerator/generator.test.js +0 -3801
  146. package/src/lib/colors/colors.test.js +0 -290
  147. package/src/lib/componentId.test.js +0 -84
  148. package/src/lib/eventListeners.test.js +0 -236
  149. package/src/lib/reactivity/effect.test.js +0 -35
  150. package/src/lib/reactivity/reactive.test.js +0 -27
  151. package/src/lib/templateparser/parser.test.js +0 -1411
  152. package/src/router/router.test.js +0 -473
@@ -1,3801 +0,0 @@
1
- /*
2
- * Copyright 2023 Comcast Cable Communications Management, LLC
3
- * Licensed under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License.
5
- * You may obtain a copy of the License at
6
- *
7
- * http://www.apache.org/licenses/LICENSE-2.0
8
- *
9
- * Unless required by applicable law or agreed to in writing, software
10
- * distributed under the License is distributed on an "AS IS" BASIS,
11
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- * See the License for the specific language governing permissions and
13
- * limitations under the License.
14
- *
15
- * SPDX-License-Identifier: Apache-2.0
16
- */
17
-
18
- import test from 'tape'
19
- import generator from './generator.js'
20
-
21
- const normalize = (str) => {
22
- return (
23
- str
24
- // remove comments
25
- .replace(/\s*\/\/.*\n/gi, '')
26
- // remove whitespaces
27
- .replace(/[\n\s\t]/gi, '')
28
- )
29
- }
30
-
31
- const scope = {
32
- components: {},
33
- }
34
-
35
- test('Type', (assert) => {
36
- const expected = 'function'
37
- const actual = typeof generator
38
-
39
- assert.equal(actual, expected, 'Generator should be a function')
40
- assert.end()
41
- })
42
-
43
- test('Returns an object with a render function and a context object', (assert) => {
44
- const result = generator.call(scope)
45
- const expected = 'object'
46
- const actual = typeof result
47
-
48
- assert.equal(actual, expected, 'Generator should return an object')
49
- assert.ok('render' in result, 'Generated object should have a render key')
50
- assert.ok('effects' in result, 'Generated object should have an effects key')
51
- assert.ok('context' in result, 'Generated object should have a context key')
52
- assert.end()
53
- })
54
-
55
- test('The render key is a function', (assert) => {
56
- const result = generator.call(scope)
57
- const expected = 'function'
58
- const actual = typeof result.render
59
-
60
- assert.equal(actual, expected, 'Render key should return a function')
61
- assert.end()
62
- })
63
-
64
- test('The effects key is an array (of functions)', (assert) => {
65
- const result = generator.call(scope)
66
- const actual = Array.isArray(result.effects)
67
-
68
- assert.ok(actual, 'Update key should return an Array')
69
- assert.end()
70
- })
71
-
72
- test('The contex key is an object', (assert) => {
73
- const result = generator.call(scope)
74
- const expected = 'object'
75
- const actual = typeof result.context
76
-
77
- assert.equal(actual, expected, 'Context key should return an object')
78
- assert.end()
79
- })
80
-
81
- test('Generate render and effect code for an empty template', (assert) => {
82
- const expectedRender = `
83
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
84
- const elms = []
85
- let componentType
86
- const rootComponent = component
87
- let propData
88
- let slotComponent
89
- let inSlot = false
90
- let slotChildCounter = 0
91
- return elms
92
- }
93
- `
94
-
95
- const actual = generator.call(scope)
96
-
97
- assert.equal(
98
- normalize(actual.render.toString()),
99
- normalize(expectedRender),
100
- 'Generator should return a render function with the correct code'
101
- )
102
- assert.ok(
103
- Array.isArray(actual.effects) && actual.effects.length === 0,
104
- 'Generator should return an empty effects array'
105
- )
106
- assert.end()
107
- })
108
-
109
- test('Generate render and effect code for a template with a single simple element', (assert) => {
110
- const templateObject = {
111
- children: [
112
- {
113
- [Symbol.for('componentType')]: 'Element',
114
- },
115
- ],
116
- }
117
-
118
- const expectedRender = `
119
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
120
- const elms = []
121
- let componentType
122
- const rootComponent = component
123
- let propData
124
- let slotComponent
125
- let inSlot = false
126
- let slotChildCounter = 0
127
- const elementConfig0 = {}
128
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
129
- elms[0].populate(elementConfig0)
130
- if (inSlot === true) {
131
- slotChildCounter -= 1
132
- }
133
- return elms
134
- }
135
- `
136
-
137
- const actual = generator.call(scope, templateObject)
138
-
139
- assert.equal(
140
- normalize(actual.render.toString()),
141
- normalize(expectedRender),
142
- 'Generator should return a render function with the correct code'
143
- )
144
- assert.ok(
145
- Array.isArray(actual.effects) && actual.effects.length === 0,
146
- 'Generator should return an empty effects array'
147
- )
148
- assert.end()
149
- })
150
-
151
- test('Generate code for a template with a simple element and a simple nested element', (assert) => {
152
- const templateObject = {
153
- children: [
154
- {
155
- [Symbol.for('componentType')]: 'Element',
156
- children: [
157
- {
158
- [Symbol.for('componentType')]: 'Element',
159
- },
160
- ],
161
- },
162
- ],
163
- }
164
-
165
- const expectedRender = `
166
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
167
- const elms = []
168
- let componentType
169
- const rootComponent = component
170
- let propData
171
- let slotComponent
172
- let inSlot = false
173
- let slotChildCounter = 0
174
- const elementConfig0 = {}
175
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
176
- elms[0].populate(elementConfig0)
177
- if (inSlot === true) {
178
- slotChildCounter -= 1
179
- }
180
- parent = elms[0]
181
- const elementConfig1 = {}
182
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
183
- elms[1].populate(elementConfig1)
184
- if (inSlot === true) {
185
- slotChildCounter -= 1
186
- }
187
- return elms
188
- }
189
- `
190
-
191
- const actual = generator.call(scope, templateObject)
192
-
193
- assert.equal(
194
- normalize(actual.render.toString()),
195
- normalize(expectedRender),
196
- 'Generator should return a render function with the correct code'
197
- )
198
- assert.ok(
199
- Array.isArray(actual.effects) && actual.effects.length === 0,
200
- 'Generator should return an empty effects array'
201
- )
202
- assert.end()
203
- })
204
-
205
- test('Generate code for a template with a single element with attributes', (assert) => {
206
- const templateObject = {
207
- children: [
208
- {
209
- [Symbol.for('componentType')]: 'Element',
210
- x: '10',
211
- y: '20',
212
- },
213
- ],
214
- }
215
-
216
- const expectedRender = `
217
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
218
- const elms = []
219
- let componentType
220
- const rootComponent = component
221
- let propData
222
- let slotComponent
223
- let inSlot = false
224
- let slotChildCounter = 0
225
- const elementConfig0 = {}
226
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
227
-
228
- elementConfig0['x'] = 10
229
- elementConfig0['y'] = 20
230
- elms[0].populate(elementConfig0)
231
- if (inSlot === true) {
232
- slotChildCounter -= 1
233
- }
234
- return elms
235
- }
236
- `
237
-
238
- const actual = generator.call(scope, templateObject)
239
-
240
- assert.equal(
241
- normalize(actual.render.toString()),
242
- normalize(expectedRender),
243
- 'Generator should return a render function with the correct code'
244
- )
245
- assert.ok(
246
- Array.isArray(actual.effects) && actual.effects.length === 0,
247
- 'Generator should return an empty effects array'
248
- )
249
- assert.end()
250
- })
251
-
252
- test('Generate code for a template with a single element with attributes with a boolean like value', (assert) => {
253
- const templateObject = {
254
- children: [
255
- {
256
- [Symbol.for('componentType')]: 'Element',
257
- one: 'true',
258
- two: 'false',
259
- },
260
- ],
261
- }
262
-
263
- const expectedRender = `
264
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
265
- const elms = []
266
- let componentType
267
- const rootComponent = component
268
- let propData
269
- let slotComponent
270
- let inSlot = false
271
- let slotChildCounter = 0
272
- const elementConfig0 = {}
273
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
274
- elementConfig0['one'] = true
275
- elementConfig0['two'] = false
276
- elms[0].populate(elementConfig0)
277
-
278
- if (inSlot === true) {
279
- slotChildCounter -= 1
280
- }
281
- return elms
282
- }
283
- `
284
-
285
- const actual = generator.call(scope, templateObject)
286
-
287
- assert.equal(
288
- normalize(actual.render.toString()),
289
- normalize(expectedRender),
290
- 'Generator should return a render function with the correct code'
291
- )
292
- assert.ok(
293
- Array.isArray(actual.effects) && actual.effects.length === 0,
294
- 'Generator should return an empty effects array'
295
- )
296
- assert.end()
297
- })
298
-
299
- test('Generate code for a template with a single element with attributes with numeric & alpha numeric value', (assert) => {
300
- const templateObject = {
301
- children: [
302
- {
303
- [Symbol.for('componentType')]: 'Element',
304
- x: '10e2',
305
- y: '100',
306
- h: '45%',
307
- w: '45.45%',
308
- one: 'Pure String',
309
- two: '123abc',
310
- three: '1E',
311
- four: 'E1',
312
- },
313
- ],
314
- }
315
-
316
- const expectedRender = `
317
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
318
- const elms = []
319
- let componentType
320
- const rootComponent = component
321
- let propData
322
- let slotComponent
323
- let inSlot = false
324
- let slotChildCounter = 0
325
- const elementConfig0 = {}
326
-
327
- elms[0] = this.element(
328
- { parent: parent || 'root' },
329
- inSlot === true ? slotComponent : component
330
- )
331
-
332
- elementConfig0['x'] = 1000
333
- elementConfig0['y'] = 100
334
- elementConfig0['h'] = parent.node.height * (45 / 100)
335
- elementConfig0['w'] = parent.node.width * (45.45 / 100)
336
- elementConfig0['one'] = "Pure String"
337
- elementConfig0['two'] = "123abc"
338
- elementConfig0['three'] = 1
339
- elementConfig0['four'] = "E1"
340
-
341
- elms[0].populate(elementConfig0)
342
-
343
- if (inSlot === true) {
344
- slotChildCounter -= 1
345
- }
346
-
347
- return elms
348
- }
349
- `
350
-
351
- const actual = generator.call(scope, templateObject)
352
- assert.equal(
353
- normalize(actual.render.toString()),
354
- normalize(expectedRender),
355
- 'Generator should return a render function with the correct code'
356
- )
357
- assert.ok(
358
- Array.isArray(actual.effects) && actual.effects.length === 0,
359
- 'Generator should return an empty effects array'
360
- )
361
- assert.end()
362
- })
363
-
364
- test('Generate code for a template with attributes and a nested element with attributes', (assert) => {
365
- const templateObject = {
366
- children: [
367
- {
368
- [Symbol.for('componentType')]: 'Element',
369
- x: '10',
370
- y: '20',
371
- children: [
372
- {
373
- [Symbol.for('componentType')]: 'Element',
374
- w: '100',
375
- h: '300',
376
- },
377
- ],
378
- },
379
- ],
380
- }
381
-
382
- const expectedRender = `
383
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
384
- const elms = []
385
- let componentType
386
- const rootComponent = component
387
- let propData
388
- let slotComponent
389
- let inSlot = false
390
- let slotChildCounter = 0
391
- const elementConfig0 = {}
392
-
393
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
394
- elementConfig0['x'] = 10
395
- elementConfig0['y'] = 20
396
- elms[0].populate(elementConfig0)
397
-
398
- if (inSlot === true) {
399
- slotChildCounter -= 1
400
- }
401
-
402
- parent = elms[0]
403
- const elementConfig1 = {}
404
-
405
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
406
- elementConfig1['w'] = 100
407
- elementConfig1['h'] = 300
408
- elms[1].populate(elementConfig1)
409
-
410
- if (inSlot === true) {
411
- slotChildCounter -= 1
412
- }
413
-
414
- return elms
415
- }
416
- `
417
-
418
- const actual = generator.call(scope, templateObject)
419
-
420
- assert.equal(
421
- normalize(actual.render.toString()),
422
- normalize(expectedRender),
423
- 'Generator should return a render function with the correct code'
424
- )
425
- assert.ok(
426
- Array.isArray(actual.effects) && actual.effects.length === 0,
427
- 'Generator should return an empty effects array'
428
- )
429
- assert.end()
430
- })
431
-
432
- test('Generate code for a template with attributes and 2 nested elements with attributes', (assert) => {
433
- const templateObject = {
434
- children: [
435
- {
436
- [Symbol.for('componentType')]: 'Element',
437
- x: '10',
438
- y: '20',
439
- children: [
440
- {
441
- [Symbol.for('componentType')]: 'Element',
442
- w: '100',
443
- h: '300',
444
- x: '0',
445
- },
446
- {
447
- [Symbol.for('componentType')]: 'Element',
448
- w: '100',
449
- h: '300',
450
- x: '50',
451
- },
452
- ],
453
- },
454
- ],
455
- }
456
-
457
- const expectedRender = `
458
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
459
- const elms = []
460
- let componentType
461
- const rootComponent = component
462
- let propData
463
- let slotComponent
464
- let inSlot = false
465
- let slotChildCounter = 0
466
- const elementConfig0 = {}
467
-
468
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
469
- elementConfig0['x'] = 10
470
- elementConfig0['y'] = 20
471
- elms[0].populate(elementConfig0)
472
-
473
- if (inSlot === true) {
474
- slotChildCounter -= 1
475
- }
476
-
477
- parent = elms[0]
478
- const elementConfig1 = {}
479
-
480
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
481
- elementConfig1['w'] = 100
482
- elementConfig1['h'] = 300
483
- elementConfig1['x'] = 0
484
- elms[1].populate(elementConfig1)
485
-
486
- if (inSlot === true) {
487
- slotChildCounter -= 1
488
- }
489
-
490
- parent = elms[0]
491
- const elementConfig2 = {}
492
-
493
- elms[2] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
494
- elementConfig2['w'] = 100
495
- elementConfig2['h'] = 300
496
- elementConfig2['x'] = 50
497
- elms[2].populate(elementConfig2)
498
-
499
- if (inSlot === true) {
500
- slotChildCounter -= 1
501
- }
502
-
503
- return elms
504
- }
505
- `
506
-
507
- const actual = generator.call(scope, templateObject)
508
-
509
- assert.equal(
510
- normalize(actual.render.toString()),
511
- normalize(expectedRender),
512
- 'Generator should return a render function with the correct code'
513
- )
514
- assert.ok(
515
- Array.isArray(actual.effects) && actual.effects.length === 0,
516
- 'Generator should return an empty effects array'
517
- )
518
- assert.end()
519
- })
520
-
521
- test('Generate code for a template with attributes and deep nested elements with attributes', (assert) => {
522
- const templateObject = {
523
- children: [
524
- {
525
- [Symbol.for('componentType')]: 'Element',
526
- x: '10',
527
- y: '20',
528
- children: [
529
- {
530
- [Symbol.for('componentType')]: 'Element',
531
- w: '100',
532
- h: '300',
533
- x: '0',
534
- },
535
- {
536
- [Symbol.for('componentType')]: 'Element',
537
- w: '100',
538
- h: '300',
539
- x: '50',
540
- children: [
541
- {
542
- [Symbol.for('componentType')]: 'Element',
543
- label: 'Hello',
544
- },
545
- {
546
- [Symbol.for('componentType')]: 'Element',
547
- label: 'World',
548
- },
549
- ],
550
- },
551
- ],
552
- },
553
- ],
554
- }
555
-
556
- const expectedRender = `
557
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
558
- const elms = []
559
- let componentType
560
- const rootComponent = component
561
- let propData
562
- let slotComponent
563
- let inSlot = false
564
- let slotChildCounter = 0
565
- const elementConfig0 = {}
566
-
567
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
568
- elementConfig0['x'] = 10
569
- elementConfig0['y'] = 20
570
- elms[0].populate(elementConfig0)
571
-
572
- if (inSlot === true) {
573
- slotChildCounter -= 1
574
- }
575
-
576
- parent = elms[0]
577
- const elementConfig1 = {}
578
-
579
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
580
- elementConfig1['w'] = 100
581
- elementConfig1['h'] = 300
582
- elementConfig1['x'] = 0
583
- elms[1].populate(elementConfig1)
584
-
585
- if (inSlot === true) {
586
- slotChildCounter -= 1
587
- }
588
-
589
- parent = elms[0]
590
- const elementConfig2 = {}
591
-
592
- elms[2] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
593
- elementConfig2['w'] = 100
594
- elementConfig2['h'] = 300
595
- elementConfig2['x'] = 50
596
- elms[2].populate(elementConfig2)
597
-
598
- if (inSlot === true) {
599
- slotChildCounter -= 1
600
- }
601
-
602
- parent = elms[2]
603
- const elementConfig3 = {}
604
-
605
- elms[3] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
606
- elementConfig3['label'] = "Hello"
607
- elms[3].populate(elementConfig3)
608
-
609
- if (inSlot === true) {
610
- slotChildCounter -= 1
611
- }
612
-
613
- parent = elms[2]
614
- const elementConfig4 = {}
615
-
616
- elms[4] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
617
- elementConfig4['label'] = "World"
618
- elms[4].populate(elementConfig4)
619
-
620
- if (inSlot === true) {
621
- slotChildCounter -= 1
622
- }
623
- return elms
624
- }
625
- `
626
-
627
- const actual = generator.call(scope, templateObject)
628
-
629
- assert.equal(
630
- normalize(actual.render.toString()),
631
- normalize(expectedRender),
632
- 'Generator should return a render function with the correct code'
633
- )
634
- assert.ok(
635
- Array.isArray(actual.effects) && actual.effects.length === 0,
636
- 'Generator should return an empty effects array'
637
- )
638
- assert.end()
639
- })
640
-
641
- test('Generate code for a template with simple dynamic attributes', (assert) => {
642
- const templateObject = {
643
- children: [
644
- {
645
- [Symbol.for('componentType')]: 'Element',
646
- x: '10',
647
- y: '20',
648
- ':w': '$foo',
649
- ':h': '$test',
650
- test: 'ok',
651
- },
652
- ],
653
- }
654
-
655
- const expectedRender = `
656
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
657
- const elms = []
658
- let componentType
659
- const rootComponent = component
660
- let propData
661
- let slotComponent
662
- let inSlot = false
663
- let slotChildCounter = 0
664
- const elementConfig0 = {}
665
-
666
- elms[0] = this.element( { parent: parent || 'root' }, inSlot === true ? slotComponent : component)
667
-
668
- elementConfig0['x'] = 10
669
- elementConfig0['y'] = 20
670
- elementConfig0['w'] = component.foo
671
- elementConfig0['h'] = component.test
672
- elementConfig0['test'] = "ok"
673
-
674
- elms[0].populate(elementConfig0)
675
-
676
- if (inSlot === true) {
677
- slotChildCounter -= 1
678
- }
679
-
680
- return elms
681
- }
682
- `
683
-
684
- const expectedEffect1 = `
685
- function anonymous(component, elms, context, components, rootComponent, effect) {
686
- elms[0].set('w', component.foo)
687
- }
688
- `
689
-
690
- const expectedEffect2 = `
691
- function anonymous(component, elms, context, components, rootComponent, effect) {
692
- elms[0].set('h', component.test)
693
- }
694
- `
695
-
696
- const actual = generator.call(scope, templateObject)
697
-
698
- assert.equal(
699
- normalize(actual.render.toString()),
700
- normalize(expectedRender),
701
- 'Generator should return a render function with the correct code'
702
- )
703
- assert.ok(
704
- Array.isArray(actual.effects) && actual.effects.length === 2,
705
- 'Generator should return an effects array with 2 items'
706
- )
707
- assert.equal(
708
- normalize(actual.effects[0].toString()),
709
- normalize(expectedEffect1),
710
- 'Generator should return first render function with the correct code'
711
- )
712
- assert.equal(
713
- normalize(actual.effects[1].toString()),
714
- normalize(expectedEffect2),
715
- 'Generator should return second render function with the correct code'
716
- )
717
-
718
- assert.end()
719
- })
720
-
721
- test('Generate code for a template with an attribute with a dash', (assert) => {
722
- const templateObject = {
723
- children: [
724
- {
725
- [Symbol.for('componentType')]: 'Element',
726
- 'my-Attribute': 'does it work?',
727
- x: '10',
728
- y: '20',
729
- },
730
- ],
731
- }
732
-
733
- const expectedRender = `
734
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
735
- const elms = []
736
- let componentType
737
- const rootComponent = component
738
- let propData
739
- let slotComponent
740
- let inSlot = false
741
- let slotChildCounter = 0
742
- const elementConfig0 = {}
743
-
744
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
745
- elementConfig0['my-Attribute'] = "doesitwork?"
746
- elementConfig0['x'] = 10
747
- elementConfig0['y'] = 20
748
- elms[0].populate(elementConfig0)
749
- if (inSlot === true) {
750
- slotChildCounter -= 1
751
- }
752
-
753
- return elms
754
- }
755
- `
756
-
757
- const actual = generator.call(scope, templateObject)
758
-
759
- assert.equal(
760
- normalize(actual.render.toString()),
761
- normalize(expectedRender),
762
- 'Generator should return a render function with the correct code'
763
- )
764
- assert.ok(
765
- Array.isArray(actual.effects) && actual.effects.length === 0,
766
- 'Generator should return an empty effects array'
767
- )
768
- assert.end()
769
- })
770
-
771
- test('Generate code for a template with dynamic attributes with code to be evaluated', (assert) => {
772
- const templateObject = {
773
- children: [
774
- {
775
- [Symbol.for('componentType')]: 'Element',
776
- ':attribute1': '$foo * 2',
777
- ':attribute2': "$ok ? 'Yes' : 'No'",
778
- ':attribute3': "$text.split('').reverse().join('')",
779
- // ':attribute4': '$bar.foo * $blah.hello' => todo
780
- },
781
- ],
782
- }
783
-
784
- const expectedRender = `
785
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
786
- const elms = []
787
- let componentType
788
- const rootComponent = component
789
- let propData
790
- let slotComponent
791
- let inSlot = false
792
- let slotChildCounter = 0
793
- const elementConfig0 = {}
794
-
795
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
796
- elementConfig0['attribute1'] = component.foo * 2
797
- elementConfig0['attribute2'] = component.ok ? 'Yes' : 'No'
798
- elementConfig0['attribute3'] = component.text.split('').reverse().join('')
799
- elms[0].populate(elementConfig0)
800
- if (inSlot === true) {
801
- slotChildCounter -= 1
802
- }
803
-
804
- return elms
805
- }
806
- `
807
-
808
- const expectedEffect1 = `
809
- function anonymous(component, elms, context, components, rootComponent, effect) {
810
- elms[0].set('attribute1', component.foo * 2)
811
- }
812
- `
813
-
814
- const expectedEffect2 = `
815
- function anonymous(component, elms, context, components, rootComponent, effect) {
816
- elms[0].set('attribute2', component.ok ? 'Yes' : 'No')
817
- }
818
- `
819
-
820
- const expectedEffect3 = `
821
- function anonymous(component, elms, context, components, rootComponent, effect) {
822
- elms[0].set('attribute3', component.text.split('').reverse().join(''))
823
- }
824
- `
825
-
826
- const actual = generator.call(scope, templateObject)
827
-
828
- assert.equal(
829
- normalize(actual.render.toString()),
830
- normalize(expectedRender),
831
- 'Generator should return a render function with the correct code'
832
- )
833
- assert.ok(
834
- Array.isArray(actual.effects) && actual.effects.length === 3,
835
- 'Generator should return an effects array with 3 items'
836
- )
837
- assert.equal(
838
- normalize(actual.effects[0].toString()),
839
- normalize(expectedEffect1),
840
- 'Generator should return first effect function with the correct code'
841
- )
842
- assert.equal(
843
- normalize(actual.effects[1].toString()),
844
- normalize(expectedEffect2),
845
- 'Generator should return second effect function with the correct code'
846
- )
847
- assert.equal(
848
- normalize(actual.effects[2].toString()),
849
- normalize(expectedEffect3),
850
- 'Generator should return third effect function with the correct code'
851
- )
852
-
853
- assert.end()
854
- })
855
-
856
- test('Generate code for a template with attribute (object)', (assert) => {
857
- const templateObject = {
858
- children: [
859
- {
860
- [Symbol.for('componentType')]: 'Element',
861
- w: '100',
862
- h: '100',
863
- color: '{top: 0xff0000ff, bottom: 0x008000ff, left: 0xffff00ff }',
864
- },
865
- ],
866
- }
867
-
868
- const expectedRender = `
869
- function anonymous(parent,component,context,components,effect,getRaw,Log) {
870
- const elms = []
871
- let componentType
872
- const rootComponent = component
873
- let propData
874
- let slotComponent
875
- let inSlot = false
876
- let slotChildCounter = 0
877
- const elementConfig0 = {}
878
-
879
- elms[0] = this.element({parent: parent || 'root'}, inSlot === true ? slotComponent : component)
880
- elementConfig0['w'] = 100
881
- elementConfig0['h'] = 100
882
- elementConfig0['color'] = "{top: 0xff0000ff, bottom: 0x008000ff, left: 0xffff00ff}"
883
- elms[0].populate(elementConfig0)
884
- if (inSlot === true) {
885
- slotChildCounter -= 1
886
- }
887
-
888
- return elms
889
- }
890
- `
891
-
892
- const actual = generator.call(scope, templateObject)
893
- assert.equal(
894
- normalize(actual.render.toString()),
895
- normalize(expectedRender),
896
- 'Generator should return a render function with the correct code'
897
- )
898
- assert.ok(
899
- Array.isArray(actual.effects) && actual.effects.length === 0,
900
- 'Generator should return an empty effects array'
901
- )
902
-
903
- assert.end()
904
- })
905
-
906
- test('Generate code for a template with dynamic attribute (object)', (assert) => {
907
- const templateObject = {
908
- children: [
909
- {
910
- [Symbol.for('componentType')]: 'Element',
911
- w: '100',
912
- h: '100',
913
- color: '{top: $colorT, bottom: $colorB, left:$colorL}',
914
- },
915
- ],
916
- }
917
-
918
- const expectedRender = `
919
- function anonymous(parent,component,context,components,effect,getRaw,Log) {
920
- const elms = []
921
- let componentType
922
- const rootComponent = component
923
- let propData
924
- let slotComponent
925
- let inSlot = false
926
- let slotChildCounter = 0
927
- const elementConfig0 = {}
928
-
929
- elms[0] = this.element({parent: parent || 'root'}, inSlot === true ? slotComponent : component)
930
- elementConfig0['w'] = 100
931
- elementConfig0['h'] = 100
932
- elementConfig0['color'] = { top: component.colorT, bottom: component.colorB, left: component.colorL }
933
- elms[0].populate(elementConfig0)
934
- if (inSlot === true) {
935
- slotChildCounter -= 1
936
- }
937
-
938
- return elms
939
- }
940
- `
941
-
942
- const actual = generator.call(scope, templateObject)
943
-
944
- assert.equal(
945
- normalize(actual.render.toString()),
946
- normalize(expectedRender),
947
- 'Generator should return a render function with the correct code'
948
- )
949
- assert.ok(
950
- Array.isArray(actual.effects) && actual.effects.length === 0,
951
- 'Generator should return an empty effects array'
952
- )
953
-
954
- assert.end()
955
- })
956
-
957
- test('Generate code for a template with attribute (object) with mixed dynamic & static value', (assert) => {
958
- const templateObject = {
959
- children: [
960
- {
961
- [Symbol.for('componentType')]: 'Element',
962
- w: '100',
963
- h: '100',
964
- color: '{top: 0xff0000ff, bottom: $colorB, left: $colorL}',
965
- },
966
- ],
967
- }
968
-
969
- const expectedRender = `
970
- function anonymous(parent,component,context,components,effect,getRaw,Log) {
971
- const elms = []
972
- let componentType
973
- const rootComponent = component
974
- let propData
975
- let slotComponent
976
- let inSlot = false
977
- let slotChildCounter = 0
978
- const elementConfig0 = {}
979
-
980
- elms[0] = this.element({parent: parent || 'root'}, inSlot === true ? slotComponent : component)
981
- elementConfig0['w'] = 100
982
- elementConfig0['h'] = 100
983
- elementConfig0['color'] = { top: 0xff0000ff, bottom: component.colorB, left: component.colorL }
984
- elms[0].populate(elementConfig0)
985
- if (inSlot === true) {
986
- slotChildCounter -= 1
987
- }
988
-
989
- return elms
990
- }
991
- `
992
-
993
- const actual = generator.call(scope, templateObject)
994
-
995
- assert.equal(
996
- normalize(actual.render.toString()),
997
- normalize(expectedRender),
998
- 'Generator should return a render function with the correct code'
999
- )
1000
- assert.ok(
1001
- Array.isArray(actual.effects) && actual.effects.length === 0,
1002
- 'Generator should return an empty effects array'
1003
- )
1004
-
1005
- assert.end()
1006
- })
1007
-
1008
- test('Generate code for a template with @-listeners', (assert) => {
1009
- const templateObject = {
1010
- children: [
1011
- {
1012
- [Symbol.for('componentType')]: 'Element',
1013
- src: 'myImage.png',
1014
- '@loaded': '$loadedCallback',
1015
- '@error': '$errorCallback',
1016
- },
1017
- ],
1018
- }
1019
-
1020
- const expectedRender = `
1021
- function anonymous(parent, component, context, components, effect, getRaw,Log) {
1022
- const elms = []
1023
- let componentType
1024
- const rootComponent = component
1025
- let propData
1026
- let slotComponent
1027
- let inSlot = false
1028
- let slotChildCounter = 0
1029
- const elementConfig0 = {}
1030
-
1031
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1032
- elementConfig0['src'] = "myImage.png"
1033
- elementConfig0['@loaded'] = component['loadedCallback'] && component['loadedCallback'].bind(component)
1034
- elementConfig0['@error'] = component['errorCallback'] && component['errorCallback'].bind(component)
1035
- elms[0].populate(elementConfig0)
1036
- if (inSlot === true) {
1037
- slotChildCounter -= 1
1038
- }
1039
-
1040
- return elms
1041
- }
1042
- `
1043
-
1044
- const actual = generator.call(scope, templateObject)
1045
-
1046
- assert.equal(
1047
- normalize(actual.render.toString()),
1048
- normalize(expectedRender),
1049
- 'Generator should return a render function with the correct code'
1050
- )
1051
- assert.ok(
1052
- Array.isArray(actual.effects) && actual.effects.length === 0,
1053
- 'Generator should return an empty effects array'
1054
- )
1055
- assert.end()
1056
- })
1057
-
1058
- test('Generate code for a template with custom components', (assert) => {
1059
- const templateObject = {
1060
- children: [
1061
- {
1062
- [Symbol.for('componentType')]: 'Element',
1063
- children: [
1064
- {
1065
- [Symbol.for('componentType')]: 'Poster',
1066
- },
1067
- {
1068
- [Symbol.for('componentType')]: 'Poster',
1069
- },
1070
- ],
1071
- },
1072
- ],
1073
- }
1074
-
1075
- const scope = {
1076
- components: {
1077
- Poster: () => {},
1078
- },
1079
- }
1080
-
1081
- const expectedRender = `
1082
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
1083
- const elms = []
1084
- let componentType
1085
- const rootComponent = component
1086
- let propData
1087
- let slotComponent
1088
- let inSlot = false
1089
- let slotChildCounter = 0
1090
- const elementConfig0 = {}
1091
-
1092
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1093
- elms[0].populate(elementConfig0)
1094
- if (inSlot === true) {
1095
- slotChildCounter -= 1
1096
- }
1097
-
1098
- const cmp1 = (context.components && context.components['Poster']) || components['Poster']
1099
- parent = elms[0]
1100
- const elementConfig1 = {}
1101
-
1102
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1103
- const skip1 = []
1104
-
1105
- if (typeof cmp1 !== 'undefined') {
1106
- for (let key in cmp1[Symbol.for('config')].props) {
1107
- delete elementConfig1[cmp1[Symbol.for('config')].props[key]]
1108
- skip1.push(cmp1[Symbol.for('config')].props[key])
1109
- }
1110
- }
1111
-
1112
- elms[1].populate(elementConfig1)
1113
-
1114
- if (inSlot === true) {
1115
- slotChildCounter -= 1
1116
- }
1117
- parent = elms[1]
1118
- const props2 = {}
1119
- componentType = props2['is'] || 'Poster'
1120
- let component2
1121
-
1122
- if (typeof componentType === 'string') {
1123
- component2 = context.components && context.components[componentType] || components[componentType]
1124
- if (!component2) {
1125
- throw new Error('Component "Poster" not found')
1126
- }
1127
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1128
- component2 = componentType
1129
- }
1130
-
1131
- elms[2] = component2.call(null, { props: props2 }, elms[1], component)
1132
-
1133
- if (elms[2][Symbol.for('slots')][0]) {
1134
- parent = elms[2][Symbol.for('slots')][0]
1135
- slotComponent = elms[2]
1136
- inSlot = true
1137
- } else {
1138
- parent = elms[2][Symbol.for('children')][0]
1139
- }
1140
- if (inSlot === true && slotChildCounter === 0) {
1141
- inSlot = false
1142
- }
1143
-
1144
- const cmp3 = (context.components && context.components['Poster']) || components['Poster']
1145
- parent = elms[0]
1146
- const elementConfig3 = {}
1147
-
1148
- elms[3] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1149
- const skip3 = []
1150
-
1151
- if (typeof cmp3 !== 'undefined') {
1152
- for (let key in cmp3[Symbol.for('config')].props) {
1153
- delete elementConfig3[cmp3[Symbol.for('config')].props[key]]
1154
- skip3.push(cmp3[Symbol.for('config')].props[key])
1155
- }
1156
- }
1157
-
1158
- elms[3].populate(elementConfig3)
1159
- if (inSlot === true) {
1160
- slotChildCounter -= 1
1161
- }
1162
-
1163
- parent = elms[3]
1164
- const props4 = {}
1165
- componentType = props4['is'] || 'Poster'
1166
- let component4
1167
-
1168
- if (typeof componentType === 'string') {
1169
- component4 = context.components && context.components[componentType] || components[componentType]
1170
- if (!component4) {
1171
- throw new Error('Component "Poster" not found')
1172
- }
1173
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1174
- component4 = componentType
1175
- }
1176
-
1177
- elms[4] = component4.call(null, { props: props4 }, elms[3], component)
1178
-
1179
- if (elms[4][Symbol.for('slots')][0]) {
1180
- parent = elms[4][Symbol.for('slots')][0]
1181
- slotComponent = elms[4]
1182
- inSlot = true
1183
- } else {
1184
- parent = elms[4][Symbol.for('children')][0]
1185
- }
1186
-
1187
- if (inSlot === true && slotChildCounter === 0) {
1188
- inSlot = false
1189
- }
1190
-
1191
- return elms
1192
- }
1193
- `
1194
-
1195
- const actual = generator.call(scope, templateObject)
1196
-
1197
- assert.equal(
1198
- normalize(actual.render.toString()),
1199
- normalize(expectedRender),
1200
- 'Generator should return a render function with the correct code'
1201
- )
1202
- assert.ok(
1203
- Array.isArray(actual.effects) && actual.effects.length === 0,
1204
- 'Generator should return an empty effects array'
1205
- )
1206
-
1207
- assert.end()
1208
- })
1209
-
1210
- test('Generate code for a template with an unregistered custom component', (assert) => {
1211
- const templateObject = {
1212
- children: [
1213
- {
1214
- [Symbol.for('componentType')]: 'Element',
1215
- children: [
1216
- {
1217
- [Symbol.for('componentType')]: 'Poster',
1218
- },
1219
- {
1220
- [Symbol.for('componentType')]: 'Poster2',
1221
- },
1222
- ],
1223
- },
1224
- ],
1225
- }
1226
-
1227
- const scope = {
1228
- components: {
1229
- Poster: () => {},
1230
- },
1231
- }
1232
-
1233
- const expectedRender = `
1234
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
1235
- const elms = []
1236
- let componentType
1237
- const rootComponent = component
1238
- let propData
1239
- let slotComponent
1240
- let inSlot = false
1241
- let slotChildCounter = 0
1242
- const elementConfig0 = {}
1243
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1244
- elms[0].populate(elementConfig0)
1245
- if (inSlot === true) {
1246
- slotChildCounter -= 1
1247
- }
1248
-
1249
- const cmp1 = (context.components && context.components['Poster']) || components['Poster']
1250
- parent = elms[0]
1251
- const elementConfig1 = {}
1252
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1253
- const skip1 = []
1254
- if (typeof cmp1 !== 'undefined') {
1255
- for (let key in cmp1[Symbol.for('config')].props) {
1256
- delete elementConfig1[cmp1[Symbol.for('config')].props[key]]
1257
- skip1.push(cmp1[Symbol.for('config')].props[key])
1258
- }
1259
- }
1260
- elms[1].populate(elementConfig1)
1261
- if (inSlot === true) {
1262
- slotChildCounter -= 1
1263
- }
1264
- parent = elms[1]
1265
- const props2 = {}
1266
- componentType = props2['is'] || 'Poster'
1267
- let component2
1268
- if (typeof componentType === 'string') {
1269
- component2 = context.components && context.components[componentType] || components[componentType]
1270
- if (!component2) {
1271
- throw new Error('Component "Poster" not found')
1272
- }
1273
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1274
- component2 = componentType
1275
- }
1276
- elms[2] = component2.call(null, { props: props2 }, elms[1], component)
1277
- if (elms[2][Symbol.for('slots')][0]) {
1278
- parent = elms[2][Symbol.for('slots')][0]
1279
- slotComponent = elms[2]
1280
- inSlot = true
1281
- } else {
1282
- parent = elms[2][Symbol.for('children')][0]
1283
- }
1284
-
1285
- if (inSlot === true && slotChildCounter === 0) {
1286
- inSlot = false
1287
- }
1288
-
1289
- const cmp3 = (context.components && context.components['Poster2']) || components['Poster2']
1290
- parent = elms[0]
1291
- const elementConfig3 = {}
1292
- elms[3] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1293
- const skip3 = []
1294
- if (typeof cmp3 !== 'undefined') {
1295
- for (let key in cmp3[Symbol.for('config')].props) {
1296
- delete elementConfig3[cmp3[Symbol.for('config')].props[key]]
1297
- skip3.push(cmp3[Symbol.for('config')].props[key])
1298
- }
1299
- }
1300
- elms[3].populate(elementConfig3)
1301
- if (inSlot === true) {
1302
- slotChildCounter -= 1
1303
- }
1304
- parent = elms[3]
1305
- const props4 = {}
1306
- componentType = props4['is'] || 'Poster2'
1307
- let component4
1308
- if (typeof componentType === 'string') {
1309
- component4 = context.components && context.components[componentType] || components[componentType]
1310
- if (!component4) {
1311
- throw new Error('Component "Poster2" not found')
1312
- }
1313
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1314
- component4 = componentType
1315
- }
1316
- elms[4] = component4.call(null, { props: props4 }, elms[3], component)
1317
- if (elms[4][Symbol.for('slots')][0]) {
1318
- parent = elms[4][Symbol.for('slots')][0]
1319
- slotComponent = elms[4]
1320
- inSlot = true
1321
- } else {
1322
- parent = elms[4][Symbol.for('children')][0]
1323
- }
1324
-
1325
- if (inSlot === true && slotChildCounter === 0) {
1326
- inSlot = false
1327
- }
1328
-
1329
- return elms
1330
- }
1331
- `
1332
-
1333
- const actual = generator.call(scope, templateObject)
1334
-
1335
- assert.equal(
1336
- normalize(actual.render.toString()),
1337
- normalize(expectedRender),
1338
- 'Generator should return a render function with the correct code'
1339
- )
1340
- assert.ok(
1341
- Array.isArray(actual.effects) && actual.effects.length === 0,
1342
- 'Generator should return an empty effects array'
1343
- )
1344
-
1345
- assert.end()
1346
- })
1347
-
1348
- test('Generate code for a template with custom components with arguments', (assert) => {
1349
- const templateObject = {
1350
- children: [
1351
- {
1352
- [Symbol.for('componentType')]: 'Element',
1353
- children: [
1354
- {
1355
- [Symbol.for('componentType')]: 'Poster',
1356
- x: '10',
1357
- },
1358
- {
1359
- [Symbol.for('componentType')]: 'Poster',
1360
- x: '100',
1361
- img: '$img',
1362
- },
1363
- ],
1364
- },
1365
- ],
1366
- }
1367
-
1368
- const scope = {
1369
- components: {
1370
- Poster: () => {},
1371
- },
1372
- }
1373
-
1374
- const expectedRender = `
1375
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
1376
- const elms = []
1377
- let componentType
1378
- const rootComponent = component
1379
- let propData
1380
- let slotComponent
1381
- let inSlot = false
1382
- let slotChildCounter = 0
1383
- const elementConfig0 = {}
1384
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1385
- elms[0].populate(elementConfig0)
1386
- if (inSlot === true) {
1387
- slotChildCounter -= 1
1388
- }
1389
-
1390
- const cmp1 = (context.components && context.components['Poster']) || components['Poster']
1391
- parent = elms[0]
1392
- const elementConfig1 = {}
1393
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1394
- elementConfig1['x'] = 10
1395
- const skip1 = []
1396
- if (typeof cmp1 !== 'undefined') {
1397
- for (let key in cmp1[Symbol.for('config')].props) {
1398
- delete elementConfig1[cmp1[Symbol.for('config')].props[key]]
1399
- skip1.push(cmp1[Symbol.for('config')].props[key])
1400
- }
1401
- }
1402
- elms[1].populate(elementConfig1)
1403
- if (inSlot === true) {
1404
- slotChildCounter -= 1
1405
- }
1406
-
1407
- parent = elms[1]
1408
- const props2 = {}
1409
- props2['x'] = 10
1410
- componentType = props2['is'] || 'Poster'
1411
- let component2
1412
- if (typeof componentType === 'string') {
1413
- component2 = context.components && context.components[componentType] || components[componentType]
1414
- if (!component2) {
1415
- throw new Error('Component "Poster" not found')
1416
- }
1417
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1418
- component2 = componentType
1419
- }
1420
- elms[2] = component2.call(null, { props: props2 }, elms[1], component)
1421
- if (elms[2][Symbol.for('slots')][0]) {
1422
- parent = elms[2][Symbol.for('slots')][0]
1423
- slotComponent = elms[2]
1424
- inSlot = true
1425
- } else {
1426
- parent = elms[2][Symbol.for('children')][0]
1427
- }
1428
-
1429
- if (inSlot === true && slotChildCounter === 0) {
1430
- inSlot = false
1431
- }
1432
- const cmp3 = (context.components && context.components['Poster']) || components['Poster']
1433
- parent = elms[0]
1434
- const elementConfig3 = {}
1435
- elms[3] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1436
- elementConfig3['x'] = 100
1437
- elementConfig3['img'] = component.img
1438
- const skip3 = []
1439
- if (typeof cmp3 !== 'undefined') {
1440
- for (let key in cmp3[Symbol.for('config')].props) {
1441
- delete elementConfig3[cmp3[Symbol.for('config')].props[key]]
1442
- skip3.push(cmp3[Symbol.for('config')].props[key])
1443
- }
1444
- }
1445
- elms[3].populate(elementConfig3)
1446
- if (inSlot === true) {
1447
- slotChildCounter -= 1
1448
- }
1449
- parent = elms[3]
1450
- const props4 = {}
1451
- props4['x'] = 100
1452
- props4['img'] = component.img
1453
- componentType = props4['is'] || 'Poster'
1454
- let component4
1455
- if (typeof componentType === 'string') {
1456
- component4 = context.components && context.components[componentType] || components[componentType]
1457
- if (!component4) {
1458
- throw new Error('Component "Poster" not found')
1459
- }
1460
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1461
- component4 = componentType
1462
- }
1463
- elms[4] = component4.call(null, { props: props4 }, elms[3], component)
1464
- if (elms[4][Symbol.for('slots')][0]) {
1465
- parent = elms[4][Symbol.for('slots')][0]
1466
- slotComponent = elms[4]
1467
- inSlot = true
1468
- } else {
1469
- parent = elms[4][Symbol.for('children')][0]
1470
- }
1471
-
1472
- if (inSlot === true && slotChildCounter === 0) {
1473
- inSlot = false
1474
- }
1475
-
1476
- return elms
1477
- }
1478
- `
1479
-
1480
- const actual = generator.call(scope, templateObject)
1481
-
1482
- assert.equal(
1483
- normalize(actual.render.toString()),
1484
- normalize(expectedRender),
1485
- 'Generator should return a render function with the correct code'
1486
- )
1487
- assert.ok(
1488
- Array.isArray(actual.effects) && actual.effects.length === 0,
1489
- 'Generator should return an empty effects array'
1490
- )
1491
-
1492
- assert.end()
1493
- })
1494
-
1495
- test('Generate code for a template with custom components with argument value as numeric & alpha numeric', (assert) => {
1496
- const templateObject = {
1497
- children: [
1498
- {
1499
- [Symbol.for('componentType')]: 'Element',
1500
- children: [
1501
- {
1502
- [Symbol.for('componentType')]: 'Poster',
1503
- x: '10e2',
1504
- y: '100',
1505
- h: '45%',
1506
- w: '45.45%',
1507
- one: 'Pure String',
1508
- two: '123abc',
1509
- three: '1E',
1510
- four: 'E1',
1511
- },
1512
- ],
1513
- },
1514
- ],
1515
- }
1516
-
1517
- const scope = {
1518
- components: {
1519
- Poster: () => {},
1520
- },
1521
- }
1522
-
1523
- const expectedRender = `
1524
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
1525
- const elms = []
1526
- let componentType
1527
- const rootComponent = component
1528
- let propData
1529
- let slotComponent
1530
- let inSlot = false
1531
- let slotChildCounter = 0
1532
- const elementConfig0 = {}
1533
-
1534
- elms[0] = this.element(
1535
- { parent: parent || 'root' },
1536
- inSlot === true ? slotComponent : component
1537
- )
1538
- elms[0].populate(elementConfig0)
1539
-
1540
- if (inSlot === true) {
1541
- slotChildCounter -= 1
1542
- }
1543
-
1544
- const cmp1 = (context.components && context.components['Poster']) || components['Poster']
1545
- parent = elms[0]
1546
- const elementConfig1 = {}
1547
-
1548
- elms[1] = this.element(
1549
- { parent: parent || 'root' },
1550
- inSlot === true ? slotComponent : component
1551
- )
1552
-
1553
- elementConfig1['x'] = 1000
1554
- elementConfig1['y'] = 100
1555
- elementConfig1['h'] = parent.node.height * (45 / 100)
1556
- elementConfig1['w'] = parent.node.width * (45.45 / 100)
1557
- elementConfig1['one'] = "PureString"
1558
- elementConfig1['two'] = "123abc"
1559
- elementConfig1['three'] = 1
1560
- elementConfig1['four'] = "E1"
1561
-
1562
- const skip1 = []
1563
- if (typeof cmp1 !== 'undefined') {
1564
- for (let key in cmp1[Symbol.for('config')].props) {
1565
- delete elementConfig1[cmp1[Symbol.for('config')].props[key]]
1566
- skip1.push(cmp1[Symbol.for('config')].props[key])
1567
- }
1568
- }
1569
-
1570
- elms[1].populate(elementConfig1)
1571
-
1572
- if (inSlot === true) {
1573
- slotChildCounter -= 1
1574
- }
1575
-
1576
- parent = elms[1]
1577
- const props2 = {}
1578
-
1579
- props2['x'] = 1000
1580
- props2['y'] = 100
1581
- props2['h'] = parent.node.height * (45 / 100)
1582
- props2['w'] = parent.node.width * (45.45 / 100)
1583
- props2['one'] = "PureString"
1584
- props2['two'] = "123abc"
1585
- props2['three'] = 1
1586
- props2['four'] = "E1"
1587
-
1588
- componentType = props2['is'] || 'Poster'
1589
- let component2
1590
-
1591
- if (typeof componentType === 'string') {
1592
- component2 = context.components && context.components[componentType] || components[componentType]
1593
- if (!component2) {
1594
- throw new Error('Component "Poster" not found')
1595
- }
1596
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1597
- component2 = componentType
1598
- }
1599
-
1600
- elms[2] = component2.call(null, { props: props2 }, elms[1], component)
1601
-
1602
- if (elms[2][Symbol.for('slots')][0]) {
1603
- parent = elms[2][Symbol.for('slots')][0]
1604
- slotComponent = elms[2]
1605
- inSlot = true
1606
- } else {
1607
- parent = elms[2][Symbol.for('children')][0]
1608
- }
1609
-
1610
- if (inSlot === true && slotChildCounter === 0) {
1611
- inSlot = false
1612
- }
1613
-
1614
- return elms
1615
- }
1616
- `
1617
-
1618
- const actual = generator.call(scope, templateObject)
1619
-
1620
- assert.equal(
1621
- normalize(actual.render.toString()),
1622
- normalize(expectedRender),
1623
- 'Generator should return a render function with the correct code'
1624
- )
1625
- assert.ok(
1626
- Array.isArray(actual.effects) && actual.effects.length === 0,
1627
- 'Generator should return an empty effects array'
1628
- )
1629
-
1630
- assert.end()
1631
- })
1632
-
1633
- test('Generate code for a template with custom components with reactive props', (assert) => {
1634
- const templateObject = {
1635
- children: [
1636
- {
1637
- [Symbol.for('componentType')]: 'Element',
1638
- children: [
1639
- {
1640
- [Symbol.for('componentType')]: 'Poster',
1641
- x: '10',
1642
- ':img': '$image',
1643
- },
1644
- {
1645
- [Symbol.for('componentType')]: 'Poster',
1646
- x: '100',
1647
- ':img': '$image',
1648
- },
1649
- ],
1650
- },
1651
- ],
1652
- }
1653
-
1654
- const scope = {
1655
- components: {
1656
- Poster: () => {},
1657
- },
1658
- }
1659
-
1660
- const expectedRender = `
1661
- function anonymous(parent,component,context,components,effect,getRaw,Log) {
1662
- const elms = []
1663
- let componentType
1664
- const rootComponent = component
1665
- let propData
1666
- let slotComponent
1667
- let inSlot = false
1668
- let slotChildCounter = 0
1669
- const elementConfig0 = {}
1670
- elms[0] = this.element({parent: parent || 'root'}, inSlot === true ? slotComponent : component)
1671
- elms[0].populate(elementConfig0)
1672
- if (inSlot === true) {
1673
- slotChildCounter -= 1
1674
- }
1675
-
1676
- const cmp1 = (context.components && context.components['Poster']) || components['Poster']
1677
- parent = elms[0]
1678
- const elementConfig1 = {}
1679
- elms[1] = this.element({parent: parent || 'root'}, inSlot === true ? slotComponent : component)
1680
- elementConfig1['x'] = 10
1681
- elementConfig1['img'] = component.image
1682
- const skip1 = []
1683
- if(typeof cmp1 !== 'undefined') {
1684
- for(let key in cmp1[Symbol.for('config')].props) {
1685
- delete elementConfig1[cmp1[Symbol.for('config')].props[key]]
1686
- skip1.push(cmp1[Symbol.for('config')].props[key])
1687
- }
1688
- }
1689
- elms[1].populate(elementConfig1)
1690
- if (inSlot === true) {
1691
- slotChildCounter -= 1
1692
- }
1693
-
1694
- parent = elms[1]
1695
- const props2 = {}
1696
- props2['x'] = 10
1697
- propData = component.image
1698
- if (Array.isArray(propData) === true) {
1699
- propData = getRaw(propData).slice(0)
1700
- }
1701
- props2['img'] = propData
1702
- componentType = props2['is'] || 'Poster'
1703
- let component2
1704
- if(typeof componentType === 'string') {
1705
- component2 = context.components && context.components[componentType] || components[componentType]
1706
- if(!component2) {
1707
- throw new Error('Component "Poster" not found')
1708
- }
1709
- } else if(typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1710
- component2 = componentType
1711
- }
1712
- elms[2] = component2.call(null, {props: props2}, elms[1], component)
1713
- if (elms[2][Symbol.for('slots')][0]) {
1714
- parent = elms[2][Symbol.for('slots')][0]
1715
- slotComponent = elms[2]
1716
- inSlot = true
1717
- } else {
1718
- parent = elms[2][Symbol.for('children')][0]
1719
- }
1720
-
1721
- if (inSlot === true && slotChildCounter === 0) {
1722
- inSlot = false
1723
- }
1724
-
1725
- const cmp3 = (context.components && context.components['Poster']) || components['Poster']
1726
- parent = elms[0]
1727
- const elementConfig3 = {}
1728
- elms[3] = this.element({parent: parent || 'root'}, inSlot === true ? slotComponent : component)
1729
- elementConfig3['x'] = 100
1730
- elementConfig3['img'] = component.image
1731
- const skip3 = []
1732
- if(typeof cmp3 !== 'undefined') {
1733
- for(let key in cmp3[Symbol.for('config')].props) {
1734
- delete elementConfig3[cmp3[Symbol.for('config')].props[key]]
1735
- skip3.push(cmp3[Symbol.for('config')].props[key])
1736
- }
1737
- }
1738
- elms[3].populate(elementConfig3)
1739
- if (inSlot === true) {
1740
- slotChildCounter -= 1
1741
- }
1742
-
1743
- parent = elms[3]
1744
- const props4 = {}
1745
- props4['x'] = 100
1746
- propData = component.image
1747
- if (Array.isArray(propData) === true) {
1748
- propData = getRaw(propData).slice(0)
1749
- }
1750
- props4['img'] = propData
1751
- componentType = props4['is'] || 'Poster'
1752
- let component4
1753
- if(typeof componentType === 'string') {
1754
- component4 = context.components && context.components[componentType] || components[componentType]
1755
- if(!component4) {
1756
- throw new Error('Component "Poster" not found')
1757
- }
1758
- } else if(typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1759
- component4 = componentType
1760
- }
1761
- elms[4] = component4.call(null, {props: props4}, elms[3], component)
1762
- if (elms[4][Symbol.for('slots')][0]) {
1763
- parent = elms[4][Symbol.for('slots')][0]
1764
- slotComponent = elms[4]
1765
- inSlot = true
1766
- } else {
1767
- parent = elms[4][Symbol.for('children')][0]
1768
- }
1769
-
1770
- if (inSlot === true && slotChildCounter === 0) {
1771
- inSlot = false
1772
- }
1773
-
1774
- return elms
1775
- }
1776
- `
1777
-
1778
- const expectedEffect1 = `
1779
- function anonymous(component, elms, context, components, rootComponent, effect) {
1780
- if (typeof skip1 === 'undefined' || skip1.indexOf('img') === -1)
1781
- elms[1].set('img', component.image)
1782
- }
1783
- `
1784
-
1785
- const expectedEffect2 = `
1786
- function anonymous(component,elms,context,components,rootComponent,effect) {
1787
- elms[2][Symbol.for('props')]['img'] = component.image
1788
- }
1789
- `
1790
-
1791
- const expectedEffect3 = `
1792
- function anonymous(component, elms, context, components, rootComponent, effect) {
1793
- if (typeof skip3 === 'undefined' || skip3.indexOf('img') === -1)
1794
- elms[3].set('img', component.image)
1795
- }
1796
- `
1797
-
1798
- const expectedEffect4 = `
1799
- function anonymous(component,elms,context,components,rootComponent,effect) {
1800
- elms[4][Symbol.for('props')]['img'] = component.image
1801
- }
1802
- `
1803
-
1804
- const actual = generator.call(scope, templateObject)
1805
-
1806
- assert.equal(
1807
- normalize(actual.render.toString()),
1808
- normalize(expectedRender),
1809
- 'Generator should return a render function with the correct code'
1810
- )
1811
-
1812
- assert.ok(
1813
- Array.isArray(actual.effects) && actual.effects.length === 4,
1814
- 'Generator should return an effects array with 4 functions'
1815
- )
1816
-
1817
- assert.equal(
1818
- normalize(actual.effects[0].toString()),
1819
- normalize(expectedEffect1),
1820
- 'Generator should return an effect function that sets the value on the node'
1821
- )
1822
-
1823
- assert.equal(
1824
- normalize(actual.effects[1].toString()),
1825
- normalize(expectedEffect2),
1826
- 'Generator should return an effect function that updates a prop on the first custom component'
1827
- )
1828
-
1829
- assert.equal(
1830
- normalize(actual.effects[2].toString()),
1831
- normalize(expectedEffect3),
1832
- 'Generator should return an effect function that sets the value on the node'
1833
- )
1834
-
1835
- assert.equal(
1836
- normalize(actual.effects[3].toString()),
1837
- normalize(expectedEffect4),
1838
- 'Generator should return an effect function that updates a prop on the second custom component'
1839
- )
1840
-
1841
- assert.end()
1842
- })
1843
-
1844
- test('Generate code for a template with a transition attributes', (assert) => {
1845
- const templateObject = {
1846
- children: [
1847
- {
1848
- ':x': '{transition: $myX}',
1849
- ':y': '{transition: {value: $myY, duration: 600}}',
1850
- [Symbol.for('componentType')]: 'Element',
1851
- },
1852
- ],
1853
- }
1854
-
1855
- const expectedRender = `
1856
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
1857
- const elms = []
1858
- let componentType
1859
- const rootComponent = component
1860
- let propData
1861
- let slotComponent
1862
- let inSlot = false
1863
- let slotChildCounter = 0
1864
- const elementConfig0 = {}
1865
-
1866
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1867
- elementConfig0['x'] = {transition:component.myX}
1868
- elementConfig0['y'] = {transition:{value:component.myY,duration:600}}
1869
- elms[0].populate(elementConfig0)
1870
-
1871
- if (inSlot === true) {
1872
- slotChildCounter -= 1
1873
- }
1874
-
1875
- return elms
1876
- }
1877
- `
1878
- const actual = generator.call(scope, templateObject)
1879
-
1880
- assert.equal(
1881
- normalize(actual.render.toString()),
1882
- normalize(expectedRender),
1883
- 'Generator should return a render function with the correct code'
1884
- )
1885
- assert.ok(
1886
- Array.isArray(actual.effects) && actual.effects.length !== 0,
1887
- 'Generator should not return an empty effects array'
1888
- )
1889
- assert.end()
1890
- })
1891
-
1892
- test('Generate code for a template with slot content', (assert) => {
1893
- const scope = {
1894
- components: {
1895
- Page: () => {},
1896
- },
1897
- }
1898
-
1899
- const templateObject = {
1900
- children: [
1901
- {
1902
- [Symbol.for('componentType')]: 'Element',
1903
- children: [
1904
- {
1905
- [Symbol.for('componentType')]: 'Page',
1906
- w: '1920',
1907
- h: '1080',
1908
- children: [
1909
- {
1910
- [Symbol.for('componentType')]: 'Element',
1911
- x: '100',
1912
- y: '$y',
1913
- ':rotation': '$rotate',
1914
- },
1915
- ],
1916
- },
1917
- ],
1918
- },
1919
- ],
1920
- }
1921
-
1922
- const expectedRender = `
1923
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
1924
- const elms = []
1925
- let componentType
1926
- const rootComponent = component
1927
- let propData
1928
- let slotComponent
1929
- let inSlot = false
1930
- let slotChildCounter = 0
1931
- const elementConfig0 = {}
1932
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1933
- elms[0].populate(elementConfig0)
1934
- if (inSlot === true) {
1935
- slotChildCounter -= 1
1936
- }
1937
-
1938
- const cmp1 = (context.components && context.components['Page']) || components['Page']
1939
- parent = elms[0]
1940
- const elementConfig1 = {}
1941
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1942
- elementConfig1['w'] = 1920
1943
- elementConfig1['h'] = 1080
1944
- const skip1 = []
1945
- if (typeof cmp1 !== 'undefined') {
1946
- for (let key in cmp1[Symbol.for('config')].props) {
1947
- delete elementConfig1[cmp1[Symbol.for('config')].props[key]]
1948
- skip1.push(cmp1[Symbol.for('config')].props[key])
1949
- }
1950
- }
1951
- elms[1].populate(elementConfig1)
1952
- if (inSlot === true) {
1953
- slotChildCounter -= 1
1954
- }
1955
-
1956
- parent = elms[1]
1957
- const props2 = {}
1958
- props2['w'] = 1920
1959
- props2['h'] = 1080
1960
- componentType = props2['is'] || 'Page'
1961
- let component2
1962
- if (typeof componentType === 'string') {
1963
- component2 = context.components && context.components[componentType] || components[componentType]
1964
- if (!component2) {
1965
- throw new Error('Component "Page" not found')
1966
- }
1967
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
1968
- component2 = componentType
1969
- }
1970
- elms[2] = component2.call(null, { props: props2 }, elms[1], component)
1971
- if (elms[2][Symbol.for('slots')][0]) {
1972
- parent = elms[2][Symbol.for('slots')][0]
1973
- slotComponent = elms[2]
1974
- inSlot = true
1975
- } else {
1976
- parent = elms[2][Symbol.for('children')][0]
1977
- }
1978
- if (inSlot === true) {
1979
- slotChildCounter = 1 + 1
1980
- }
1981
-
1982
- const elementConfig3 = {}
1983
- elms[3] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1984
- elms[3].populate(elementConfig3)
1985
- if (inSlot === true) {
1986
- slotChildCounter -= 1
1987
- }
1988
-
1989
- parent = elms[3]
1990
- const elementConfig4 = {}
1991
- elms[4] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
1992
- elementConfig4['x'] = 100
1993
- elementConfig4['y'] = component.y
1994
- elementConfig4['rotation'] = component.rotate
1995
- elms[4].populate(elementConfig4)
1996
- if (inSlot === true) {
1997
- slotChildCounter -= 1
1998
- }
1999
-
2000
- if (inSlot === true && slotChildCounter === 0) {
2001
- inSlot = false
2002
- }
2003
-
2004
- return elms
2005
- }
2006
- `
2007
-
2008
- const expectedEffect1 = `
2009
- function anonymous(component,elms,context,components,rootComponent,effect){
2010
- elms[4].set('rotation', component.rotate)
2011
- }
2012
- `
2013
-
2014
- const actual = generator.call(scope, templateObject)
2015
-
2016
- assert.equal(
2017
- normalize(actual.render.toString()),
2018
- normalize(expectedRender),
2019
- 'Generator should return a render function with the correct code'
2020
- )
2021
-
2022
- assert.ok(
2023
- Array.isArray(actual.effects) && actual.effects.length === 1,
2024
- 'Generator should return an effects array with 1 item'
2025
- )
2026
-
2027
- assert.equal(
2028
- normalize(actual.effects[0].toString()),
2029
- normalize(expectedEffect1),
2030
- 'Generator should return an effect function for the reactive rotation attribute'
2031
- )
2032
-
2033
- assert.end()
2034
- })
2035
-
2036
- test('Generate code for a template with slot content, using a named slot', (assert) => {
2037
- const scope = {
2038
- components: {
2039
- Page: () => {},
2040
- },
2041
- }
2042
-
2043
- const templateObject = {
2044
- children: [
2045
- {
2046
- [Symbol.for('componentType')]: 'Element',
2047
- children: [
2048
- {
2049
- [Symbol.for('componentType')]: 'Page',
2050
- w: '1920',
2051
- h: '1080',
2052
- children: [
2053
- {
2054
- [Symbol.for('componentType')]: 'Element',
2055
- x: '100',
2056
- y: '$y',
2057
- slot: 'mySlot',
2058
- },
2059
- ],
2060
- },
2061
- ],
2062
- },
2063
- ],
2064
- }
2065
-
2066
- const expectedRender = `
2067
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2068
- const elms = []
2069
- let componentType
2070
- const rootComponent = component
2071
- let propData
2072
- let slotComponent
2073
- let inSlot = false
2074
- let slotChildCounter = 0
2075
- const elementConfig0 = {}
2076
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2077
- elms[0].populate(elementConfig0)
2078
- if (inSlot === true) {
2079
- slotChildCounter -= 1
2080
- }
2081
-
2082
- const cmp1 = (context.components && context.components['Page']) || components['Page']
2083
- parent = elms[0]
2084
- const elementConfig1 = {}
2085
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2086
- elementConfig1['w'] = 1920
2087
- elementConfig1['h'] = 1080
2088
- const skip1 = []
2089
- if (typeof cmp1 !== 'undefined') {
2090
- for (let key in cmp1[Symbol.for('config')].props) {
2091
- delete elementConfig1[cmp1[Symbol.for('config')].props[key]]
2092
- skip1.push(cmp1[Symbol.for('config')].props[key])
2093
- }
2094
- }
2095
- elms[1].populate(elementConfig1)
2096
- if (inSlot === true) {
2097
- slotChildCounter -= 1
2098
- }
2099
-
2100
- parent = elms[1]
2101
- const props2 = {}
2102
- props2['w'] = 1920
2103
- props2['h'] = 1080
2104
- componentType = props2['is'] || 'Page'
2105
- let component2
2106
- if (typeof componentType === 'string') {
2107
- component2 = context.components && context.components[componentType] || components[componentType]
2108
- if (!component2) {
2109
- throw new Error('Component "Page" not found')
2110
- }
2111
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
2112
- component2 = componentType
2113
- }
2114
- elms[2] = component2.call(null, { props: props2 }, elms[1], component)
2115
- if (elms[2][Symbol.for('slots')][0]) {
2116
- parent = elms[2][Symbol.for('slots')][0]
2117
- slotComponent = elms[2]
2118
- inSlot = true
2119
- } else {
2120
- parent = elms[2][Symbol.for('children')][0]
2121
- }
2122
-
2123
- if (inSlot === true) {
2124
- slotChildCounter = 1 + 1
2125
- }
2126
-
2127
- const elementConfig3 = {}
2128
- elms[3] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2129
- elms[3].populate(elementConfig3)
2130
- if (inSlot === true) {
2131
- slotChildCounter -= 1
2132
- }
2133
-
2134
- parent = elms[3]
2135
- const elementConfig4 = {}
2136
- elms[4] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2137
- elementConfig4['x'] = 100
2138
- elementConfig4['y'] = component.y
2139
- elementConfig4['parent'] = slotComponent[Symbol.for('slots')] !== undefined &&
2140
- Array.isArray(slotComponent[Symbol.for('slots')]) === true &&
2141
- slotComponent[Symbol.for('slots')].filter(slot => slot.ref === 'mySlot').shift() || parent
2142
- elementConfig4['slot'] = "mySlot"
2143
- elms[4].populate(elementConfig4)
2144
-
2145
- if (inSlot === true) {
2146
- slotChildCounter -= 1
2147
- }
2148
-
2149
- if (inSlot === true && slotChildCounter === 0) {
2150
- inSlot = false
2151
- }
2152
-
2153
- return elms
2154
- }
2155
- `
2156
-
2157
- const actual = generator.call(scope, templateObject)
2158
-
2159
- assert.equal(
2160
- normalize(actual.render.toString()),
2161
- normalize(expectedRender),
2162
- 'Generator should return a render function with the correct code'
2163
- )
2164
-
2165
- assert.ok(
2166
- Array.isArray(actual.effects) && actual.effects.length === 0,
2167
- 'Generator should return an empty effects array'
2168
- )
2169
-
2170
- assert.end()
2171
- })
2172
-
2173
- test('Generate code for a template with a slot', (assert) => {
2174
- const templateObject = {
2175
- children: [
2176
- {
2177
- [Symbol.for('componentType')]: 'Element',
2178
- children: [
2179
- {
2180
- [Symbol.for('componentType')]: 'Element',
2181
- w: '1920',
2182
- h: '1080',
2183
- children: [
2184
- {
2185
- [Symbol.for('componentType')]: 'Slot',
2186
- x: '100',
2187
- y: '$y',
2188
- },
2189
- ],
2190
- },
2191
- ],
2192
- },
2193
- ],
2194
- }
2195
-
2196
- const expectedRender = `
2197
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2198
- const elms = []
2199
- let componentType
2200
- const rootComponent = component
2201
- let propData
2202
- let slotComponent
2203
- let inSlot = false
2204
- let slotChildCounter = 0
2205
- const elementConfig0 = {}
2206
-
2207
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2208
- elms[0].populate(elementConfig0)
2209
-
2210
- if (inSlot === true) {
2211
- slotChildCounter -= 1
2212
- }
2213
- parent = elms[0]
2214
- const elementConfig1 = {}
2215
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2216
- elementConfig1['w'] = 1920
2217
- elementConfig1['h'] = 1080
2218
- elms[1].populate(elementConfig1)
2219
-
2220
- if (inSlot === true) {
2221
- slotChildCounter -= 1
2222
- }
2223
-
2224
- parent = elms[1]
2225
- const elementConfig2 = {}
2226
- elms[2] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2227
- elementConfig2[Symbol.for('isSlot')] = true
2228
- elementConfig2['x'] = 100
2229
- elementConfig2['y'] = component.y
2230
- elms[2].populate(elementConfig2)
2231
- if (inSlot === true) {
2232
- slotChildCounter -= 1
2233
- }
2234
-
2235
- return elms
2236
- }
2237
- `
2238
-
2239
- const actual = generator.call(scope, templateObject)
2240
-
2241
- assert.equal(
2242
- normalize(actual.render.toString()),
2243
- normalize(expectedRender),
2244
- 'Generator should return a render function with the correct code'
2245
- )
2246
-
2247
- assert.ok(
2248
- Array.isArray(actual.effects) && actual.effects.length === 0,
2249
- 'Generator should return an empty effects array'
2250
- )
2251
-
2252
- assert.end()
2253
- })
2254
-
2255
- test('Generate code for a template with inline Text', (assert) => {
2256
- const templateObject = {
2257
- children: [
2258
- {
2259
- [Symbol.for('componentType')]: 'Element',
2260
- children: [
2261
- {
2262
- [Symbol.for('componentType')]: 'Text',
2263
- content: 'Hello Blits!',
2264
- },
2265
- ],
2266
- },
2267
- ],
2268
- }
2269
-
2270
- const expectedRender = `
2271
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2272
- const elms = []
2273
- let componentType
2274
- const rootComponent = component
2275
- let propData
2276
- let slotComponent
2277
- let inSlot = false
2278
- let slotChildCounter = 0
2279
- const elementConfig0 = {}
2280
-
2281
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2282
- elms[0].populate(elementConfig0)
2283
-
2284
- if (inSlot === true) {
2285
- slotChildCounter -= 1
2286
- }
2287
-
2288
- parent = elms[0]
2289
- const elementConfig1 = {}
2290
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2291
- elementConfig1['content'] = 'HelloBlits!'
2292
- elementConfig1['__textnode'] = true
2293
- elms[1].populate(elementConfig1)
2294
- if (inSlot === true) {
2295
- slotChildCounter -= 1
2296
- }
2297
-
2298
- return elms
2299
- }
2300
- `
2301
-
2302
- const actual = generator.call(scope, templateObject)
2303
-
2304
- assert.equal(
2305
- normalize(actual.render.toString()),
2306
- normalize(expectedRender),
2307
- 'Generator should return a render function with the correct code'
2308
- )
2309
- assert.ok(
2310
- Array.isArray(actual.effects) && actual.effects.length === 0,
2311
- 'Generator should return an empty effects array'
2312
- )
2313
- assert.end()
2314
- })
2315
-
2316
- test('Generate code for a template with inline dynamic Text', (assert) => {
2317
- const templateObject = {
2318
- children: [
2319
- {
2320
- [Symbol.for('componentType')]: 'Element',
2321
- children: [
2322
- {
2323
- [Symbol.for('componentType')]: 'Text',
2324
- content: '$myText',
2325
- },
2326
- ],
2327
- },
2328
- ],
2329
- }
2330
-
2331
- const expectedRender = `
2332
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2333
- const elms = []
2334
- let componentType
2335
- const rootComponent = component
2336
- let propData
2337
- let slotComponent
2338
- let inSlot = false
2339
- let slotChildCounter = 0
2340
- const elementConfig0 = {}
2341
-
2342
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2343
- elms[0].populate(elementConfig0)
2344
-
2345
- if (inSlot === true) {
2346
- slotChildCounter -= 1
2347
- }
2348
-
2349
- parent = elms[0]
2350
- const elementConfig1 = {}
2351
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2352
- elementConfig1['content'] = component.myText
2353
- elementConfig1['__textnode'] = true
2354
- elms[1].populate(elementConfig1)
2355
-
2356
- if (inSlot === true) {
2357
- slotChildCounter -= 1
2358
- }
2359
-
2360
- return elms
2361
- }
2362
- `
2363
-
2364
- const actual = generator.call(scope, templateObject)
2365
-
2366
- assert.equal(
2367
- normalize(actual.render.toString()),
2368
- normalize(expectedRender),
2369
- 'Generator should return a render function with the correct code'
2370
- )
2371
- assert.ok(
2372
- Array.isArray(actual.effects) && actual.effects.length === 0,
2373
- 'Generator should return an empty effects array'
2374
- )
2375
- assert.end()
2376
- })
2377
-
2378
- test('Generate code for a template with inline dynamic Text embedded in static text', (assert) => {
2379
- const templateObject = {
2380
- children: [
2381
- {
2382
- [Symbol.for('componentType')]: 'Element',
2383
- children: [
2384
- {
2385
- [Symbol.for('componentType')]: 'Text',
2386
- content: 'Hello {{$firstname}} {{$lastname}}, how are you?',
2387
- },
2388
- ],
2389
- },
2390
- ],
2391
- }
2392
-
2393
- const expectedRender = `
2394
- function anonymous(parent,component,context,components,effect,getRaw,Log) {
2395
- const elms = []
2396
- let componentType
2397
- const rootComponent = component
2398
- let propData
2399
- let slotComponent
2400
- let inSlot = false
2401
- let slotChildCounter = 0
2402
- const elementConfig0 = {}
2403
-
2404
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2405
- elms[0].populate(elementConfig0)
2406
- if(inSlot === true) {
2407
- slotChildCounter -= 1
2408
- }
2409
-
2410
- parent = elms[0]
2411
- const elementConfig1 = {}
2412
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2413
- elementConfig1['content'] = 'Hello '+component.firstname+' '+component.lastname+', how are you?'
2414
- elementConfig1['__textnode'] = true
2415
- elms[1].populate(elementConfig1)
2416
-
2417
- if(inSlot === true) {
2418
- slotChildCounter -= 1
2419
- }
2420
-
2421
- return elms
2422
- }
2423
- `
2424
-
2425
- const actual = generator.call(scope, templateObject)
2426
-
2427
- assert.equal(
2428
- normalize(actual.render.toString()),
2429
- normalize(expectedRender),
2430
- 'Generator should return a render function with the correct code'
2431
- )
2432
- assert.ok(
2433
- Array.isArray(actual.effects) && actual.effects.length === 0,
2434
- 'Generator should return an empty effects array'
2435
- )
2436
- assert.end()
2437
- })
2438
-
2439
- test('Generate code for a template with a single element with attributes with percentages', (assert) => {
2440
- const templateObject = {
2441
- children: [
2442
- {
2443
- [Symbol.for('componentType')]: 'Element',
2444
- w: '1920',
2445
- h: '1080',
2446
- children: [
2447
- {
2448
- [Symbol.for('componentType')]: 'Element',
2449
- w: '50%',
2450
- h: '40%',
2451
- x: '10%',
2452
- y: '20%',
2453
- },
2454
- ],
2455
- },
2456
- ],
2457
- }
2458
-
2459
- const expectedRender = `
2460
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2461
- const elms = []
2462
- let componentType
2463
- const rootComponent = component
2464
- let propData
2465
- let slotComponent
2466
- let inSlot = false
2467
- let slotChildCounter = 0
2468
- const elementConfig0 = {}
2469
-
2470
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2471
- elementConfig0['w'] = 1920
2472
- elementConfig0['h'] = 1080
2473
- elms[0].populate(elementConfig0)
2474
-
2475
- if(inSlot === true) {
2476
- slotChildCounter -= 1
2477
- }
2478
-
2479
- parent = elms[0]
2480
- const elementConfig1 = {}
2481
- elms[1] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2482
- elementConfig1['w'] = parent.node.width * (50 / 100)
2483
- elementConfig1['h'] = parent.node.height * (40 / 100)
2484
- elementConfig1['x'] = parent.node.width * (10 / 100)
2485
- elementConfig1['y'] = parent.node.height * (20 / 100)
2486
- elms[1].populate(elementConfig1)
2487
- if(inSlot === true) {
2488
- slotChildCounter -= 1
2489
- }
2490
-
2491
- return elms
2492
- }
2493
- `
2494
-
2495
- const actual = generator.call(scope, templateObject)
2496
-
2497
- assert.equal(
2498
- normalize(actual.render.toString()),
2499
- normalize(expectedRender),
2500
- 'Generator should return a render function with the correct code'
2501
- )
2502
- assert.ok(
2503
- Array.isArray(actual.effects) && actual.effects.length === 0,
2504
- 'Generator should return an empty effects array'
2505
- )
2506
- assert.end()
2507
- })
2508
-
2509
- test('Generate code for a template with a simple for-loop on an Element', (assert) => {
2510
- const templateObject = {
2511
- children: [
2512
- {
2513
- [Symbol.for('componentType')]: 'Element',
2514
- children: [
2515
- {
2516
- [Symbol.for('componentType')]: 'Element',
2517
- ':for': 'item in $items',
2518
- },
2519
- ],
2520
- },
2521
- ],
2522
- }
2523
-
2524
- const expectedRender = `
2525
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2526
- const elms = []
2527
- let componentType
2528
- const rootComponent = component
2529
- let propData
2530
- let slotComponent
2531
- let inSlot = false
2532
- let slotChildCounter = 0
2533
- const elementConfig0 = {}
2534
- elms[0] = this.element({ parent: parent || 'root' },inSlot === true ? slotComponent : component)
2535
- elms[0].populate(elementConfig0)
2536
- if (inSlot === true) {
2537
- slotChildCounter -= 1
2538
- }
2539
-
2540
- parent = elms[0]
2541
- const created1 = []
2542
- let from1
2543
- let to1
2544
- const forloop1 = (collection = [], elms, created) => {
2545
- const rawCollection = getRaw(collection)
2546
- const keys = new Set()
2547
- let l = rawCollection.length
2548
- const range = {} || {}
2549
-
2550
- from1 = range['from'] || 0
2551
- to1 = 'to' in range ? range['to'] : rawCollection.length
2552
-
2553
- while (l--) {
2554
- const item = rawCollection[l]
2555
- if (l < to1 && l >= from1) {
2556
- keys.add('' + l)
2557
- }
2558
- }
2559
-
2560
- let i = created.length
2561
- while (i--) {
2562
- if (keys.has(created[i]) === false) {
2563
- const key = created[i]
2564
- elms[1][key] && elms[1][key].destroy()
2565
- delete elms[1][key]
2566
- }
2567
- }
2568
- created.length = 0
2569
- const length = rawCollection.length
2570
- const effects = []
2571
- for (let __index = 0; __index < length; __index++) {
2572
- if (__index < from1 || __index >= to1) continue
2573
- const scope = Object.create(component)
2574
- parent = elms[0]
2575
- scope['item'] = rawCollection[__index]
2576
- scope['undefined'] = __index
2577
- scope['key'] = '' + __index
2578
- created.push(scope.key)
2579
- parent = elms[0]
2580
- if (elms[1] === undefined) {
2581
- elms[1] = {}
2582
- }
2583
- const elementConfig1 = {}
2584
- if (elms[1][scope.key] === undefined) {
2585
- elms[1][scope.key] = this.element({ parent: parent || 'root' },inSlot === true ? slotComponent : component)
2586
- }
2587
- if (elms[1][scope.key].nodeId === undefined) {
2588
- elms[1][scope.key].populate(elementConfig1)
2589
- if (inSlot === true) {
2590
- slotChildCounter -= 1
2591
- }
2592
- }
2593
- }
2594
- return effects
2595
- }
2596
-
2597
- let forEffects1
2598
-
2599
- effect(() => {
2600
- component[Symbol.for('removeGlobalEffects')](forEffects1)
2601
- forEffects1 = null
2602
- forEffects1 = forloop1(component.items, elms, created1)
2603
- }, ['items',])
2604
- return elms
2605
- }
2606
- `
2607
-
2608
- const actual = generator.call(scope, templateObject)
2609
-
2610
- assert.equal(
2611
- normalize(actual.render.toString()),
2612
- normalize(expectedRender),
2613
- 'Generator should return a render function with the correct code'
2614
- )
2615
-
2616
- assert.ok(
2617
- Array.isArray(actual.effects) && actual.effects.length === 0,
2618
- 'Generator should return an empty effect array'
2619
- )
2620
-
2621
- assert.end()
2622
- })
2623
-
2624
- test('Generate code for a template with a simple for-loop on an Element, Using data from appState plugin', (assert) => {
2625
- const templateObject = {
2626
- children: [
2627
- {
2628
- [Symbol.for('componentType')]: 'Element',
2629
- children: [
2630
- {
2631
- [Symbol.for('componentType')]: 'Element',
2632
- ':for': 'item in $$appState.list',
2633
- },
2634
- ],
2635
- },
2636
- ],
2637
- }
2638
-
2639
- const expectedRender = `
2640
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2641
- const elms = []
2642
- let componentType
2643
- const rootComponent = component
2644
- let propData
2645
- let slotComponent
2646
- let inSlot = false
2647
- let slotChildCounter = 0
2648
- const elementConfig0 = {}
2649
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2650
- elms[0].populate(elementConfig0)
2651
- if (inSlot === true) {
2652
- slotChildCounter -= 1
2653
- }
2654
-
2655
- parent = elms[0]
2656
- const created1 = []
2657
- let from1
2658
- let to1
2659
- const forloop1 = (collection = [], elms, created) => {
2660
- const rawCollection = getRaw(collection)
2661
- const keys = new Set()
2662
- let l = rawCollection.length
2663
- const range = {} || {}
2664
-
2665
- from1 = range['from'] || 0
2666
- to1 = 'to' in range ? range['to'] : rawCollection.length
2667
-
2668
- while (l--) {
2669
- const item = rawCollection[l]
2670
- if (l < to1 && l >= from1) {
2671
- keys.add('' + l)
2672
- }
2673
- }
2674
-
2675
- let i = created.length
2676
- while (i--) {
2677
- if (keys.has(created[i]) === false) {
2678
- const key = created[i]
2679
- elms[1][key] && elms[1][key].destroy()
2680
- delete elms[1][key]
2681
- }
2682
- }
2683
- created.length = 0
2684
- const length = rawCollection.length
2685
- const effects = []
2686
- for (let __index = 0; __index < length; __index++) {
2687
- if (__index < from1 || __index >= to1) continue
2688
- const scope = Object.create(component)
2689
- parent = elms[0]
2690
- scope['item'] = rawCollection[__index]
2691
- scope['undefined'] = __index
2692
- scope['key'] = '' + __index
2693
- created.push(scope.key)
2694
- parent = elms[0]
2695
- if (elms[1] === undefined) {
2696
- elms[1] = {}
2697
- }
2698
- const elementConfig1 = {}
2699
- if (elms[1][scope.key] === undefined) {
2700
- elms[1][scope.key] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2701
- }
2702
- if (elms[1][scope.key].nodeId === undefined) {
2703
- elms[1][scope.key].populate(elementConfig1)
2704
- if (inSlot === true) {
2705
- slotChildCounter -= 1
2706
- }
2707
- }
2708
- }
2709
- return effects
2710
- }
2711
-
2712
- let forEffects1
2713
-
2714
- effect(() => {
2715
- component[Symbol.for('removeGlobalEffects')](forEffects1)
2716
- forEffects1 = null
2717
- forEffects1 = forloop1(component.$appState.list, elms, created1)
2718
- }, ['list',])
2719
- return elms
2720
- }
2721
- `
2722
-
2723
- const actual = generator.call(scope, templateObject)
2724
-
2725
- assert.equal(
2726
- normalize(actual.render.toString()),
2727
- normalize(expectedRender),
2728
- 'Generator should return a render function with the correct code using data from appState plugin'
2729
- )
2730
-
2731
- assert.ok(
2732
- Array.isArray(actual.effects) && actual.effects.length === 0,
2733
- 'Generator should return an empty effect array'
2734
- )
2735
-
2736
- assert.end()
2737
- })
2738
-
2739
- test('Generate code for a template with a simple for-loop on an Element, Using data from nested state property', (assert) => {
2740
- const templateObject = {
2741
- children: [
2742
- {
2743
- [Symbol.for('componentType')]: 'Element',
2744
- children: [
2745
- {
2746
- [Symbol.for('componentType')]: 'Element',
2747
- ':for': 'item in $content.data',
2748
- },
2749
- ],
2750
- },
2751
- ],
2752
- }
2753
-
2754
- const expectedRender = `
2755
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2756
- const elms = []
2757
- let componentType
2758
- const rootComponent = component
2759
- let propData
2760
- let slotComponent
2761
- let inSlot = false
2762
- let slotChildCounter = 0
2763
- const elementConfig0 = {}
2764
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2765
- elms[0].populate(elementConfig0)
2766
- if (inSlot === true) {
2767
- slotChildCounter -= 1
2768
- }
2769
-
2770
- parent = elms[0]
2771
- const created1 = []
2772
- let from1
2773
- let to1
2774
- const forloop1 = (collection = [], elms, created) => {
2775
- const rawCollection = getRaw(collection)
2776
- const keys = new Set()
2777
- let l = rawCollection.length
2778
- const range = {} || {}
2779
-
2780
- from1 = range['from'] || 0
2781
- to1 = 'to' in range ? range['to'] : rawCollection.length
2782
-
2783
- while (l--) {
2784
- const item = rawCollection[l]
2785
- if (l < to1 && l >= from1) {
2786
- keys.add('' + l)
2787
- }
2788
- }
2789
-
2790
- let i = created.length
2791
- while (i--) {
2792
- if (keys.has(created[i]) === false) {
2793
- const key = created[i]
2794
- elms[1][key] && elms[1][key].destroy()
2795
- delete elms[1][key]
2796
- }
2797
- }
2798
- created.length = 0
2799
- const length = rawCollection.length
2800
- const effects = []
2801
-
2802
- for (let __index = 0; __index < length; __index++) {
2803
- if (__index < from1 || __index >= to1) continue
2804
- const scope = Object.create(component)
2805
- parent = elms[0]
2806
- scope['item'] = rawCollection[__index]
2807
- scope['undefined'] = __index
2808
- scope['key'] = '' + __index
2809
- created.push(scope.key)
2810
- parent = elms[0]
2811
- if (elms[1] === undefined) {
2812
- elms[1] = {}
2813
- }
2814
- const elementConfig1 = {}
2815
- if (elms[1][scope.key] === undefined) {
2816
- elms[1][scope.key] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2817
- }
2818
- if (elms[1][scope.key].nodeId === undefined) {
2819
- elms[1][scope.key].populate(elementConfig1)
2820
- if (inSlot === true) {
2821
- slotChildCounter -= 1
2822
- }
2823
- }
2824
- }
2825
-
2826
- return effects
2827
- }
2828
-
2829
- let forEffects1
2830
-
2831
- effect(() => {
2832
- component[Symbol.for('removeGlobalEffects')](forEffects1)
2833
- forEffects1 = null
2834
- forEffects1 = forloop1(component.content.data, elms, created1)
2835
- }, ['data',])
2836
-
2837
- return elms
2838
- }
2839
- `
2840
-
2841
- const actual = generator.call(scope, templateObject)
2842
-
2843
- assert.equal(
2844
- normalize(actual.render.toString()),
2845
- normalize(expectedRender),
2846
- 'Generator should return a render function with the correct code using data from nested state property'
2847
- )
2848
-
2849
- assert.ok(
2850
- Array.isArray(actual.effects) && actual.effects.length === 0,
2851
- 'Generator should return an empty effect array'
2852
- )
2853
-
2854
- assert.end()
2855
- })
2856
-
2857
- test('Generate code for a template with a simple for-loop on an Element with a custom index key', (assert) => {
2858
- const templateObject = {
2859
- children: [
2860
- {
2861
- [Symbol.for('componentType')]: 'Element',
2862
- children: [
2863
- {
2864
- [Symbol.for('componentType')]: 'Element',
2865
- ':for': '(item, customIndex) in $items',
2866
- },
2867
- ],
2868
- },
2869
- ],
2870
- }
2871
-
2872
- const expectedRender = `
2873
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2874
- const elms = []
2875
- let componentType
2876
- const rootComponent = component
2877
- let propData
2878
- let slotComponent
2879
- let inSlot = false
2880
- let slotChildCounter = 0
2881
- const elementConfig0 = {}
2882
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2883
- elms[0].populate(elementConfig0)
2884
- if (inSlot === true) {
2885
- slotChildCounter -= 1
2886
- }
2887
-
2888
- parent = elms[0]
2889
- const created1 = []
2890
- let from1
2891
- let to1
2892
- const forloop1 = (collection = [], elms, created) => {
2893
- const rawCollection = getRaw(collection)
2894
- const keys = new Set()
2895
- let l = rawCollection.length
2896
- const range = {} || {}
2897
-
2898
- from1 = range['from'] || 0
2899
- to1 = 'to' in range ? range['to'] : rawCollection.length
2900
- while (l--) {
2901
- const item = rawCollection[l]
2902
- const customIndex = l
2903
- if (l < to1 && l >= from1) {
2904
- keys.add('' + l)
2905
- }
2906
- }
2907
-
2908
- let i = created.length
2909
- while (i--) {
2910
- if (keys.has(created[i]) === false) {
2911
- const key = created[i]
2912
- elms[1][key] && elms[1][key].destroy()
2913
- delete elms[1][key]
2914
- }
2915
- }
2916
- created.length = 0
2917
- const length = rawCollection.length
2918
- const effects = []
2919
- for (let __index = 0; __index < length; __index++) {
2920
- if (__index < from1 || __index >= to1) continue
2921
- const scope = Object.create(component)
2922
- parent = elms[0]
2923
- scope['item'] = rawCollection[__index]
2924
- scope['customIndex'] = __index
2925
- scope['key'] = '' + __index
2926
- created.push(scope.key)
2927
- parent = elms[0]
2928
- if (elms[1] === undefined) {
2929
- elms[1] = {}
2930
- }
2931
- const elementConfig1 = {}
2932
- if (elms[1][scope.key] === undefined) {
2933
- elms[1][scope.key] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
2934
- }
2935
- if (elms[1][scope.key].nodeId === undefined) {
2936
- elms[1][scope.key].populate(elementConfig1)
2937
- if (inSlot === true) {
2938
- slotChildCounter -= 1
2939
- }
2940
- }
2941
- }
2942
-
2943
- return effects
2944
- }
2945
-
2946
- let forEffects1
2947
-
2948
- effect(() => {
2949
- component[Symbol.for('removeGlobalEffects')](forEffects1)
2950
- forEffects1 = null
2951
- forEffects1 = forloop1(component.items, elms, created1)
2952
- }, ['items',])
2953
-
2954
- return elms
2955
- }
2956
- `
2957
-
2958
- const actual = generator.call(scope, templateObject)
2959
-
2960
- assert.equal(
2961
- normalize(actual.render.toString()),
2962
- normalize(expectedRender),
2963
- 'Generator should return a render function with the correct code'
2964
- )
2965
-
2966
- assert.ok(
2967
- Array.isArray(actual.effects) && actual.effects.length === 0,
2968
- 'Generator should return an empty effects array'
2969
- )
2970
-
2971
- assert.end()
2972
- })
2973
-
2974
- test('Generate code for a template with a simple for-loop on an Element with a key attribute', (assert) => {
2975
- const templateObject = {
2976
- children: [
2977
- {
2978
- [Symbol.for('componentType')]: 'Element',
2979
- children: [
2980
- {
2981
- [Symbol.for('componentType')]: 'Element',
2982
- ':for': 'item in $items',
2983
- key: '$item.id',
2984
- },
2985
- ],
2986
- },
2987
- ],
2988
- }
2989
-
2990
- const expectedRender = `
2991
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
2992
- const elms = []
2993
- let componentType
2994
- const rootComponent = component
2995
- let propData
2996
- let slotComponent
2997
- let inSlot = false
2998
- let slotChildCounter = 0
2999
- const elementConfig0 = {}
3000
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3001
- elms[0].populate(elementConfig0)
3002
- if (inSlot === true) {
3003
- slotChildCounter -= 1
3004
- }
3005
-
3006
- parent = elms[0]
3007
- const created1 = []
3008
- let from1
3009
- let to1
3010
- const forloop1 = (collection = [], elms, created) => {
3011
- const rawCollection = getRaw(collection)
3012
- const keys = new Set()
3013
- let l = rawCollection.length
3014
- const range = {} || {}
3015
-
3016
- from1 = range['from'] || 0
3017
- to1 = 'to' in range ? range['to'] : rawCollection.length
3018
- while (l--) {
3019
- const item = rawCollection[l]
3020
- if (l < to1 && l >= from1) {
3021
- keys.add('' + item.id)
3022
- }
3023
- }
3024
-
3025
- let i = created.length
3026
- while (i--) {
3027
- if (keys.has(created[i]) === false) {
3028
- const key = created[i]
3029
- elms[1][key] && elms[1][key].destroy()
3030
- delete elms[1][key]
3031
- }
3032
- }
3033
- created.length = 0
3034
- const length = rawCollection.length
3035
- const effects = []
3036
- for (let __index = 0; __index < length; __index++) {
3037
- if (__index < from1 || __index >= to1) continue
3038
- const scope = Object.create(component)
3039
- parent = elms[0]
3040
- scope['item'] = rawCollection[__index]
3041
- scope['undefined'] = __index
3042
- scope['key'] = '' + scope.item.id
3043
- created.push(scope.key)
3044
- parent = elms[0]
3045
- if (elms[1] === undefined) {
3046
- elms[1] = {}
3047
- }
3048
- const elementConfig1 = {}
3049
- if (elms[1][scope.key] === undefined) {
3050
- elms[1][scope.key] = this.element({ parent: parent || 'root' },inSlot === true ? slotComponent : component)
3051
- }
3052
- if (elms[1][scope.key].nodeId === undefined) {
3053
- elms[1][scope.key].populate(elementConfig1)
3054
- if (inSlot === true) {
3055
- slotChildCounter -= 1
3056
- }
3057
- }
3058
- }
3059
-
3060
- return effects
3061
- }
3062
-
3063
- let forEffects1
3064
-
3065
- effect(() => {
3066
- component[Symbol.for('removeGlobalEffects')](forEffects1)
3067
- forEffects1 = null
3068
- forEffects1 = forloop1(component.items, elms, created1)
3069
- }, ['items',])
3070
-
3071
- return elms
3072
- }
3073
- `
3074
-
3075
- const actual = generator.call(scope, templateObject)
3076
-
3077
- assert.equal(
3078
- normalize(actual.render.toString()),
3079
- normalize(expectedRender),
3080
- 'Generator should return a render function with the correct code'
3081
- )
3082
-
3083
- assert.ok(
3084
- Array.isArray(actual.effects) && actual.effects.length === 0,
3085
- 'Generator should return an empty effects array'
3086
- )
3087
-
3088
- assert.end()
3089
- })
3090
-
3091
- test('Generate code for a template with a simple for-loop on a Component with a key attribute and a custom index', (assert) => {
3092
- const templateObject = {
3093
- children: [
3094
- {
3095
- [Symbol.for('componentType')]: 'Element',
3096
- children: [
3097
- {
3098
- [Symbol.for('componentType')]: 'ListItem',
3099
- ':for': '(item, myIndex) in $items',
3100
- key: 'item.id',
3101
- },
3102
- ],
3103
- },
3104
- ],
3105
- }
3106
-
3107
- const expectedRender = `
3108
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
3109
- const elms = []
3110
- let componentType
3111
- const rootComponent = component
3112
- let propData
3113
- let slotComponent
3114
- let inSlot = false
3115
- let slotChildCounter = 0
3116
- const elementConfig0 = {}
3117
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3118
- elms[0].populate(elementConfig0)
3119
- if (inSlot === true) {
3120
- slotChildCounter -= 1
3121
- }
3122
-
3123
- parent = elms[0]
3124
- const created1 = []
3125
- let from1
3126
- let to1
3127
- const forloop1 = (collection = [], elms, created) => {
3128
- const rawCollection = getRaw(collection)
3129
- const keys = new Set()
3130
- let l = rawCollection.length
3131
- const range = {} || {}
3132
-
3133
- from1 = range['from'] || 0
3134
- to1 = 'to' in range ? range['to'] : rawCollection.length
3135
-
3136
- while (l--) {
3137
- const item = rawCollection[l]
3138
- const myIndex = l
3139
- if (l < to1 && l >= from1) {
3140
- keys.add('' + item.id)
3141
- }
3142
- }
3143
-
3144
- let i = created.length
3145
- while (i--) {
3146
- if (keys.has(created[i]) === false) {
3147
- const key = created[i]
3148
- elms[1][key] && elms[1][key].destroy()
3149
- delete elms[1][key]
3150
- elms[2][key] && elms[2][key].destroy()
3151
- delete elms[2][key]
3152
- }
3153
- }
3154
- created.length = 0
3155
- const length = rawCollection.length
3156
- const effects = []
3157
- for (let __index = 0; __index < length; __index++) {
3158
- if (__index < from1 || __index >= to1) continue
3159
-
3160
- const scope = Object.create(component)
3161
- parent = elms[0]
3162
- scope['item'] = rawCollection[__index]
3163
- scope['myIndex'] = __index
3164
- scope['key'] = '' + item.id
3165
- created.push(scope.key)
3166
- const cmp1 = (context.components && context.components['ListItem']) || components['ListItem']
3167
- if (elms[1] === undefined) {
3168
- elms[1] = {}
3169
- }
3170
- const elementConfig1 = {}
3171
- if (elms[1][scope.key] === undefined) {
3172
- elms[1][scope.key] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3173
- }
3174
- const skip1 = []
3175
- if (typeof cmp1 !== 'undefined') {
3176
- for (let key in cmp1[Symbol.for('config')].props) {
3177
- delete elementConfig1[cmp1[Symbol.for('config')].props[key]]
3178
- skip1.push(cmp1[Symbol.for('config')].props[key])
3179
- }
3180
- }
3181
- if (elms[1][scope.key].nodeId === undefined) {
3182
- elms[1][scope.key].populate(elementConfig1)
3183
- if (inSlot === true) {
3184
- slotChildCounter -= 1
3185
- }
3186
- }
3187
- if (elms[2] === undefined) {
3188
- elms[2] = {}
3189
- }
3190
- parent = elms[1][scope.key]
3191
- const props2 = {}
3192
- if (elms[2][scope.key] === undefined) {
3193
- componentType = props2['is'] || 'ListItem'
3194
- let component2
3195
- if (typeof componentType === 'string') {
3196
- component2 = context.components && context.components[componentType] || components[componentType]
3197
- if (!component2) {
3198
- throw new Error('Component "ListItem" not found')
3199
- }
3200
- } else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
3201
- component2 = componentType
3202
- }
3203
- elms[2][scope.key] = component2.call(null, { props: props2 }, elms[1][scope.key], component)
3204
- if (elms[2][scope.key][Symbol.for('slots')][0]) {
3205
- parent = elms[2][scope.key][Symbol.for('slots')][0]
3206
- slotComponent = elms[2][scope.key]
3207
- inSlot = true
3208
- } else {
3209
- parent = elms[2][scope.key][Symbol.for('children')][0]
3210
- }
3211
- }
3212
- }
3213
-
3214
- return effects
3215
- }
3216
-
3217
- let forEffects1
3218
-
3219
- effect(() => {
3220
- component[Symbol.for('removeGlobalEffects')](forEffects1)
3221
- forEffects1 = null
3222
- forEffects1 = forloop1(component.items, elms, created1)
3223
- }, ['items',])
3224
-
3225
- return elms
3226
- }
3227
- `
3228
-
3229
- const actual = generator.call(scope, templateObject)
3230
-
3231
- assert.equal(
3232
- normalize(actual.render.toString()),
3233
- normalize(expectedRender),
3234
- 'Generator should return a render function with the correct code'
3235
- )
3236
-
3237
- assert.ok(
3238
- Array.isArray(actual.effects) && actual.effects.length === 0,
3239
- 'Generator should return an empty effects array'
3240
- )
3241
-
3242
- assert.end()
3243
- })
3244
-
3245
- test('Generate code for a template with a simple for-loop on an Element with an automatic ref attribute', (assert) => {
3246
- const templateObject = {
3247
- children: [
3248
- {
3249
- [Symbol.for('componentType')]: 'Element',
3250
- children: [
3251
- {
3252
- [Symbol.for('componentType')]: 'Element',
3253
- ':for': 'item in $items',
3254
- key: 'item.id',
3255
- ref: 'myref',
3256
- },
3257
- ],
3258
- },
3259
- ],
3260
- }
3261
-
3262
- const expectedRender = `
3263
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
3264
- const elms = []
3265
- let componentType
3266
- const rootComponent = component
3267
- let propData
3268
- let slotComponent
3269
- let inSlot = false
3270
- let slotChildCounter = 0
3271
- const elementConfig0 = {}
3272
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3273
- elms[0].populate(elementConfig0)
3274
- if (inSlot === true) {
3275
- slotChildCounter -= 1
3276
- }
3277
-
3278
- parent = elms[0]
3279
- const created1 = []
3280
- let from1
3281
- let to1
3282
- const forloop1 = (collection = [], elms, created) => {
3283
- const rawCollection = getRaw(collection)
3284
- const keys = new Set()
3285
- let l = rawCollection.length
3286
- const range = {} || {}
3287
-
3288
- from1 = range['from'] || 0
3289
- to1 = 'to' in range ? range['to'] : rawCollection.length
3290
-
3291
- while (l--) {
3292
- const item = rawCollection[l]
3293
- if (l < to1 && l >= from1) {
3294
- keys.add('' + item.id)
3295
- }
3296
- }
3297
-
3298
- let i = created.length
3299
- while (i--) {
3300
- if (keys.has(created[i]) === false) {
3301
- const key = created[i]
3302
- elms[1][key] && elms[1][key].destroy()
3303
- delete elms[1][key]
3304
- }
3305
- }
3306
- created.length = 0
3307
- const length = rawCollection.length
3308
- const effects = []
3309
- for (let __index = 0; __index < length; __index++) {
3310
- if (__index < from1 || __index >= to1) continue
3311
- const scope = Object.create(component)
3312
- parent = elms[0]
3313
- scope['item'] = rawCollection[__index]
3314
- scope['undefined'] = __index
3315
- scope['key'] = '' + item.id
3316
- scope['__ref'] = 'myref' + __index
3317
- created.push(scope.key)
3318
- parent = elms[0]
3319
- if (elms[1] === undefined) {
3320
- elms[1] = {}
3321
- }
3322
- const elementConfig1 = {}
3323
- if (elms[1][scope.key] === undefined) {
3324
- elms[1][scope.key] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3325
- }
3326
- elementConfig1['ref'] = scope.__ref
3327
- if (elms[1][scope.key].nodeId === undefined) {
3328
- elms[1][scope.key].populate(elementConfig1)
3329
- if (inSlot === true) {
3330
- slotChildCounter -= 1
3331
- }
3332
- }
3333
- }
3334
-
3335
- return effects
3336
- }
3337
-
3338
- let forEffects1
3339
-
3340
- effect(() => {
3341
- component[Symbol.for('removeGlobalEffects')](forEffects1)
3342
- forEffects1 = null
3343
- forEffects1 = forloop1(component.items, elms, created1)
3344
- }, ['items', ])
3345
-
3346
- return elms
3347
- }
3348
- `
3349
-
3350
- const actual = generator.call(scope, templateObject)
3351
-
3352
- assert.equal(
3353
- normalize(actual.render.toString()),
3354
- normalize(expectedRender),
3355
- 'Generator should return a render function with the correct code'
3356
- )
3357
-
3358
- assert.ok(
3359
- Array.isArray(actual.effects) && actual.effects.length === 0,
3360
- 'Generator should return an effects array with 1 function'
3361
- )
3362
-
3363
- assert.end()
3364
- })
3365
-
3366
- test('Generate code for a template with double $$ (i.e. referencing a Blits plugin)', (assert) => {
3367
- const templateObject = {
3368
- children: [
3369
- {
3370
- [Symbol.for('componentType')]: 'Text',
3371
- ':content': "$$language.translate('hello')",
3372
- },
3373
- ],
3374
- }
3375
-
3376
- const expectedRender = `
3377
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
3378
- const elms = []
3379
- let componentType
3380
- const rootComponent = component
3381
- let propData
3382
- let slotComponent
3383
- let inSlot = false
3384
- let slotChildCounter = 0
3385
- const elementConfig0 = {}
3386
-
3387
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3388
- elementConfig0['content'] = component.$language.translate('hello')
3389
- elementConfig0['__textnode'] = true
3390
- elms[0].populate(elementConfig0)
3391
-
3392
- if (inSlot === true) {
3393
- slotChildCounter -= 1
3394
- }
3395
-
3396
- return elms
3397
- }
3398
- `
3399
-
3400
- const expectedEffect1 = `
3401
- function anonymous(component, elms, context, components, rootComponent, effect) {
3402
- elms[0].set('content', component.$language.translate('hello'))
3403
- }
3404
- `
3405
-
3406
- const actual = generator.call(scope, templateObject)
3407
-
3408
- assert.equal(
3409
- normalize(actual.render.toString()),
3410
- normalize(expectedRender),
3411
- 'Generator should return a render function with the correct code'
3412
- )
3413
- assert.ok(
3414
- Array.isArray(actual.effects) && actual.effects.length === 1,
3415
- 'Generator should return an effects array with 1 item'
3416
- )
3417
- assert.equal(
3418
- normalize(actual.effects[0].toString()),
3419
- normalize(expectedEffect1),
3420
- 'Generator should return first render function with the correct code'
3421
- )
3422
-
3423
- assert.end()
3424
- })
3425
-
3426
- test('Generate code for a template with verification of dynamic attributes', (assert) => {
3427
- const templateObject = {
3428
- children: [
3429
- {
3430
- [Symbol.for('componentType')]: 'Element',
3431
- w: '$eWidth',
3432
- h: '$eHeight',
3433
- },
3434
- ],
3435
- }
3436
-
3437
- const expectedRender = `
3438
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
3439
- const elms = []
3440
- let componentType
3441
- const rootComponent = component
3442
- let propData
3443
- let slotComponent
3444
- let inSlot = false
3445
- let slotChildCounter = 0
3446
-
3447
- function propInComponent(prop, kind = "dynamic") {
3448
- const property = prop.includes('.') ? prop.split('.')[0] : prop
3449
- if (kind === 'reactive' || prop.includes('.') === false) {
3450
- if (property in component === false) {
3451
- Log.warn('Property ' + property + ' was accessed during render but is not defined on instance')
3452
- }
3453
- } else {
3454
- const nestedKeys = prop.split('.')
3455
- let base = component
3456
- for (let i = 0; i < nestedKeys.length; i++) {
3457
- if (base[nestedKeys[i]] === undefined) {
3458
- Log.warn('Property ' + nestedKeys.slice(0, i + 1).join('.') + ' was accessed during render but is not defined on instance')
3459
- }
3460
- base = base[nestedKeys[i]]
3461
- }
3462
- }
3463
- }
3464
-
3465
- const elementConfig0 = {}
3466
-
3467
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3468
-
3469
- propInComponent('eWidth', 'dynamic')
3470
- elementConfig0['w'] = component.eWidth
3471
- propInComponent('eHeight', 'dynamic')
3472
- elementConfig0['h'] = component.eHeight
3473
-
3474
- elms[0].populate(elementConfig0)
3475
-
3476
- if (inSlot === true) {
3477
- slotChildCounter -= 1
3478
- }
3479
-
3480
- return elms
3481
- }
3482
- `
3483
- const actual = generator.call(scope, templateObject, true)
3484
-
3485
- assert.equal(
3486
- normalize(actual.render.toString()),
3487
- normalize(expectedRender),
3488
- 'Generator should return a render function with the correct code'
3489
- )
3490
- assert.ok(
3491
- Array.isArray(actual.effects) && actual.effects.length === 0,
3492
- 'Generator should return an empty effects array'
3493
- )
3494
-
3495
- assert.end()
3496
- })
3497
-
3498
- test('Generate code for a template with verification of reactive attributes', (assert) => {
3499
- const templateObject = {
3500
- children: [
3501
- {
3502
- [Symbol.for('componentType')]: 'Element',
3503
- ':w': '$eWidth',
3504
- ':h': '$eHeight',
3505
- },
3506
- ],
3507
- }
3508
-
3509
- const expectedRender = `
3510
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
3511
- const elms = []
3512
- let componentType
3513
- const rootComponent = component
3514
- let propData
3515
- let slotComponent
3516
- let inSlot = false
3517
- let slotChildCounter = 0
3518
-
3519
- function propInComponent(prop, kind = "dynamic") {
3520
- const property = prop.includes('.') ? prop.split('.')[0] : prop
3521
- if (kind === 'reactive' || prop.includes('.') === false) {
3522
- if (property in component === false) {
3523
- Log.warn('Property ' + property + ' was accessed during render but is not defined on instance')
3524
- }
3525
- } else {
3526
- const nestedKeys = prop.split('.')
3527
- let base = component
3528
- for (let i = 0; i < nestedKeys.length; i++) {
3529
- if (base[nestedKeys[i]] === undefined) {
3530
- Log.warn('Property ' + nestedKeys.slice(0, i + 1).join('.') + ' was accessed during render but is not defined on instance')
3531
- }
3532
- base = base[nestedKeys[i]]
3533
- }
3534
- }
3535
- }
3536
-
3537
- const elementConfig0 = {}
3538
-
3539
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3540
-
3541
- propInComponent('eWidth', 'reactive')
3542
- elementConfig0['w'] = component.eWidth
3543
- propInComponent('eHeight', 'reactive')
3544
- elementConfig0['h'] = component.eHeight
3545
-
3546
- elms[0].populate(elementConfig0)
3547
-
3548
- if (inSlot === true) {
3549
- slotChildCounter -= 1
3550
- }
3551
-
3552
- return elms
3553
- }
3554
- `
3555
- const expectedEffect1 = `
3556
- function anonymous(component, elms, context, components, rootComponent, effect) {
3557
- elms[0].set('w', component.eWidth)
3558
- }
3559
- `
3560
-
3561
- const expectedEffect2 = `
3562
- function anonymous(component, elms, context, components, rootComponent, effect) {
3563
- elms[0].set('h', component.eHeight)
3564
- }
3565
- `
3566
-
3567
- const actual = generator.call(scope, templateObject, true)
3568
-
3569
- assert.equal(
3570
- normalize(actual.render.toString()),
3571
- normalize(expectedRender),
3572
- 'Generator should return a render function with the correct code'
3573
- )
3574
-
3575
- assert.ok(
3576
- Array.isArray(actual.effects) && actual.effects.length === 2,
3577
- 'Generator should return an effects array with 2 item'
3578
- )
3579
-
3580
- assert.equal(
3581
- normalize(actual.effects[0].toString()),
3582
- normalize(expectedEffect1),
3583
- 'Generator should return an effect function for the reactive eWidth attribute'
3584
- )
3585
-
3586
- assert.equal(
3587
- normalize(actual.effects[1].toString()),
3588
- normalize(expectedEffect2),
3589
- 'Generator should return an effect function for the reactive eHeight attribute'
3590
- )
3591
-
3592
- assert.end()
3593
- })
3594
-
3595
- test('Generate code for a template with attribute values verified against a nested state object', (assert) => {
3596
- const templateObject = {
3597
- children: [
3598
- {
3599
- [Symbol.for('componentType')]: 'Element',
3600
- x: '$position.x',
3601
- y: '$position.y',
3602
- ':w': '$size.w',
3603
- ':h': '$size.h',
3604
- },
3605
- ],
3606
- }
3607
-
3608
- const expectedRender = `
3609
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
3610
- const elms = []
3611
- let componentType
3612
- const rootComponent = component
3613
- let propData
3614
- let slotComponent
3615
- let inSlot = false
3616
- let slotChildCounter = 0
3617
-
3618
- function propInComponent(prop, kind = "dynamic") {
3619
- const property = prop.includes('.') ? prop.split('.')[0] : prop
3620
- if (kind === 'reactive' || prop.includes('.') === false) {
3621
- if (property in component === false) {
3622
- Log.warn('Property ' + property + ' was accessed during render but is not defined on instance')
3623
- }
3624
- } else {
3625
- const nestedKeys = prop.split('.')
3626
- let base = component
3627
- for (let i = 0; i < nestedKeys.length; i++) {
3628
- if (base[nestedKeys[i]] === undefined) {
3629
- Log.warn('Property ' + nestedKeys.slice(0, i + 1).join('.') + ' was accessed during render but is not defined on instance')
3630
- }
3631
- base = base[nestedKeys[i]]
3632
- }
3633
- }
3634
- }
3635
-
3636
- const elementConfig0 = {}
3637
-
3638
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3639
-
3640
- propInComponent('position.x', 'dynamic')
3641
- elementConfig0['x'] = component.position.x
3642
- propInComponent('position.y', 'dynamic')
3643
- elementConfig0['y'] = component.position.y
3644
- propInComponent('size', 'reactive')
3645
- elementConfig0['w'] = component.size.w
3646
- propInComponent('size', 'reactive')
3647
- elementConfig0['h'] = component.size.h
3648
-
3649
- elms[0].populate(elementConfig0)
3650
-
3651
- if (inSlot === true) {
3652
- slotChildCounter -= 1
3653
- }
3654
-
3655
- return elms
3656
- }
3657
- `
3658
- const expectedEffect1 = `
3659
- function anonymous(component, elms, context, components, rootComponent, effect) {
3660
- elms[0].set('w', component.size.w)
3661
- }
3662
- `
3663
-
3664
- const expectedEffect2 = `
3665
- function anonymous(component, elms, context, components, rootComponent, effect) {
3666
- elms[0].set('h', component.size.h)
3667
- }
3668
- `
3669
-
3670
- const actual = generator.call(scope, templateObject, true)
3671
-
3672
- assert.equal(
3673
- normalize(actual.render.toString()),
3674
- normalize(expectedRender),
3675
- 'Generator should return a render function with the correct code'
3676
- )
3677
-
3678
- assert.ok(
3679
- Array.isArray(actual.effects) && actual.effects.length === 2,
3680
- 'Generator should return an effects array with 2 item'
3681
- )
3682
-
3683
- assert.equal(
3684
- normalize(actual.effects[0].toString()),
3685
- normalize(expectedEffect1),
3686
- 'Generator should return an effect function for the reactive eWidth attribute'
3687
- )
3688
-
3689
- assert.equal(
3690
- normalize(actual.effects[1].toString()),
3691
- normalize(expectedEffect2),
3692
- 'Generator should return an effect function for the reactive eHeight attribute'
3693
- )
3694
-
3695
- assert.end()
3696
- })
3697
-
3698
- test('Generate code for a template with verification of attributes with Math calculations', (assert) => {
3699
- const templateObject = {
3700
- children: [
3701
- {
3702
- [Symbol.for('componentType')]: 'Element',
3703
- x: '$position.x * 100',
3704
- y: '$position.y + 100',
3705
- ':w': '$size.w * $correction ',
3706
- ':h': '$size.h + $borderY',
3707
- },
3708
- ],
3709
- }
3710
-
3711
- const expectedRender = `
3712
- function anonymous(parent, component, context, components, effect, getRaw, Log) {
3713
- const elms = []
3714
- let componentType
3715
- const rootComponent = component
3716
- let propData
3717
- let slotComponent
3718
- let inSlot = false
3719
- let slotChildCounter = 0
3720
-
3721
- function propInComponent(prop, kind = "dynamic") {
3722
- const property = prop.includes('.') ? prop.split('.')[0] : prop
3723
- if (kind === 'reactive' || prop.includes('.') === false) {
3724
- if (property in component === false) {
3725
- Log.warn('Property ' + property + ' was accessed during render but is not defined on instance')
3726
- }
3727
- } else {
3728
- const nestedKeys = prop.split('.')
3729
- let base = component
3730
- for (let i = 0; i < nestedKeys.length; i++) {
3731
- if (base[nestedKeys[i]] === undefined) {
3732
- Log.warn('Property ' + nestedKeys.slice(0, i + 1).join('.') + ' was accessed during render but is not defined on instance')
3733
- }
3734
- base = base[nestedKeys[i]]
3735
- }
3736
- }
3737
- }
3738
-
3739
- const elementConfig0 = {}
3740
-
3741
- elms[0] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
3742
-
3743
- propInComponent('position.x', 'dynamic')
3744
- elementConfig0['x'] = component.position.x * 100
3745
- propInComponent('position.y', 'dynamic')
3746
- elementConfig0['y'] = component.position.y + 100
3747
- propInComponent('size', 'reactive')
3748
- propInComponent('correction', 'reactive')
3749
- elementConfig0['w'] = component.size.w * component.correction
3750
- propInComponent('size', 'reactive')
3751
- propInComponent('borderY', 'reactive')
3752
- elementConfig0['h'] = component.size.h + component.borderY
3753
-
3754
- elms[0].populate(elementConfig0)
3755
-
3756
- if (inSlot === true) {
3757
- slotChildCounter -= 1
3758
- }
3759
-
3760
- return elms
3761
- }
3762
- `
3763
- const expectedEffect1 = `
3764
- function anonymous(component, elms, context, components, rootComponent, effect) {
3765
- elms[0].set('w', component.size.w * component.correction)
3766
- }
3767
- `
3768
-
3769
- const expectedEffect2 = `
3770
- function anonymous(component, elms, context, components, rootComponent, effect) {
3771
- elms[0].set('h', component.size.h + component.borderY)
3772
- }
3773
- `
3774
-
3775
- const actual = generator.call(scope, templateObject, true)
3776
-
3777
- assert.equal(
3778
- normalize(actual.render.toString()),
3779
- normalize(expectedRender),
3780
- 'Generator should return a render function with the correct code'
3781
- )
3782
-
3783
- assert.ok(
3784
- Array.isArray(actual.effects) && actual.effects.length === 2,
3785
- 'Generator should return an effects array with 2 item'
3786
- )
3787
-
3788
- assert.equal(
3789
- normalize(actual.effects[0].toString()),
3790
- normalize(expectedEffect1),
3791
- 'Generator should return an effect function for the reactive width attribute'
3792
- )
3793
-
3794
- assert.equal(
3795
- normalize(actual.effects[1].toString()),
3796
- normalize(expectedEffect2),
3797
- 'Generator should return an effect function for the reactive height attribute'
3798
- )
3799
-
3800
- assert.end()
3801
- })