@lightningjs/blits 1.14.1 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/docs/essentials/element_attributes.md +32 -0
- package/package.json +1 -1
- package/src/components/Circle.js +12 -1
- package/src/components/FPScounter.js +325 -42
- package/src/components/RouterView.js +12 -1
- package/src/components/Sprite.js +15 -4
- package/src/components/Sprite.orig.js +3 -3
- package/src/engines/L3/element.js +31 -0
- package/src/engines/L3/element.test.js +138 -4
- package/src/lib/codegenerator/generator.js +53 -17
- package/src/lib/reactivity/reactive.js +8 -8
- package/vite/blitsFileConverter.js +37 -8
- package/vite/preCompiler.js +5 -4
|
@@ -29,13 +29,24 @@ export default () =>
|
|
|
29
29
|
let componentType
|
|
30
30
|
const rootComponent = component
|
|
31
31
|
let propData
|
|
32
|
+
let slotComponent
|
|
33
|
+
let inSlot = false
|
|
34
|
+
let slotChildCounter = 0
|
|
32
35
|
const elementConfig0 = {}
|
|
33
36
|
|
|
34
|
-
elms[0] = this.element(
|
|
37
|
+
elms[0] = this.element(
|
|
38
|
+
{ parent: parent || 'root' },
|
|
39
|
+
inSlot === true ? slotComponent : component
|
|
40
|
+
)
|
|
35
41
|
|
|
36
42
|
elementConfig0['w'] = parent.node.width * (100 / 100)
|
|
37
43
|
elementConfig0['height'] = parent.node.height * (100 / 100)
|
|
38
44
|
elms[0].populate(elementConfig0)
|
|
45
|
+
|
|
46
|
+
if (inSlot === true) {
|
|
47
|
+
slotChildCounter -= 1
|
|
48
|
+
}
|
|
49
|
+
|
|
39
50
|
return elms
|
|
40
51
|
},
|
|
41
52
|
effects: [],
|
package/src/components/Sprite.js
CHANGED
|
@@ -28,15 +28,26 @@ export default () =>
|
|
|
28
28
|
let componentType
|
|
29
29
|
const rootComponent = component
|
|
30
30
|
let propData
|
|
31
|
+
let slotComponent
|
|
32
|
+
let inSlot = false
|
|
33
|
+
let slotChildCounter = 0
|
|
31
34
|
const elementConfig0 = {}
|
|
32
35
|
|
|
33
|
-
elms[0] = this.element(
|
|
36
|
+
elms[0] = this.element(
|
|
37
|
+
{ parent: parent || 'root' },
|
|
38
|
+
inSlot === true ? slotComponent : component
|
|
39
|
+
)
|
|
34
40
|
|
|
35
41
|
elementConfig0['w'] = parent.node.width * (100 / 100)
|
|
36
42
|
elementConfig0['h'] = parent.node.height * (100 / 100)
|
|
37
43
|
elementConfig0['texture'] = component.texture
|
|
38
44
|
elementConfig0['color'] = component.color
|
|
39
45
|
elms[0].populate(elementConfig0)
|
|
46
|
+
|
|
47
|
+
if (inSlot === true) {
|
|
48
|
+
slotChildCounter -= 1
|
|
49
|
+
}
|
|
50
|
+
|
|
40
51
|
return elms
|
|
41
52
|
},
|
|
42
53
|
effects: [
|
|
@@ -52,7 +63,7 @@ export default () =>
|
|
|
52
63
|
props: ['image', 'map', 'frame', 'color'],
|
|
53
64
|
state() {
|
|
54
65
|
return {
|
|
55
|
-
spriteTexture:
|
|
66
|
+
spriteTexture: null,
|
|
56
67
|
}
|
|
57
68
|
},
|
|
58
69
|
computed: {
|
|
@@ -62,7 +73,7 @@ export default () =>
|
|
|
62
73
|
? Object.assign({}, this.map.defaults || {}, this.map.frames[this.frame])
|
|
63
74
|
: this.map[this.frame]
|
|
64
75
|
|
|
65
|
-
if (this.spriteTexture && options) {
|
|
76
|
+
if (this.spriteTexture !== null && options) {
|
|
66
77
|
return this[symbols.renderer]().createTexture('SubTexture', {
|
|
67
78
|
texture: this.spriteTexture,
|
|
68
79
|
x: options.x,
|
|
@@ -74,7 +85,7 @@ export default () =>
|
|
|
74
85
|
},
|
|
75
86
|
},
|
|
76
87
|
hooks: {
|
|
77
|
-
|
|
88
|
+
init() {
|
|
78
89
|
this.spriteTexture = this[symbols.renderer]().createTexture('ImageTexture', {
|
|
79
90
|
src: this.image,
|
|
80
91
|
})
|
|
@@ -27,7 +27,7 @@ export default () =>
|
|
|
27
27
|
props: ['image', 'map', 'frame', 'color'],
|
|
28
28
|
state() {
|
|
29
29
|
return {
|
|
30
|
-
spriteTexture:
|
|
30
|
+
spriteTexture: null,
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
computed: {
|
|
@@ -37,7 +37,7 @@ export default () =>
|
|
|
37
37
|
? Object.assign({}, this.map.defaults || {}, this.map.frames[this.frame])
|
|
38
38
|
: this.map[this.frame]
|
|
39
39
|
|
|
40
|
-
if (this.spriteTexture && options) {
|
|
40
|
+
if (this.spriteTexture !== null && options) {
|
|
41
41
|
return this[symbols.renderer]().createTexture('SubTexture', {
|
|
42
42
|
texture: this.spriteTexture,
|
|
43
43
|
x: options.x,
|
|
@@ -49,7 +49,7 @@ export default () =>
|
|
|
49
49
|
},
|
|
50
50
|
},
|
|
51
51
|
hooks: {
|
|
52
|
-
|
|
52
|
+
init() {
|
|
53
53
|
this.spriteTexture = this[symbols.renderer]().createTexture('ImageTexture', {
|
|
54
54
|
src: this.image,
|
|
55
55
|
})
|
|
@@ -383,6 +383,37 @@ const propsTransformer = {
|
|
|
383
383
|
set content(v) {
|
|
384
384
|
this.props['text'] = '' + v
|
|
385
385
|
},
|
|
386
|
+
set placement(v) {
|
|
387
|
+
let x, y
|
|
388
|
+
if (typeof v === 'object' || (isObjectString(v) === true && (v = parseToObject(v)))) {
|
|
389
|
+
if ('x' in v === true) {
|
|
390
|
+
x = v.x
|
|
391
|
+
}
|
|
392
|
+
if ('y' in v === true) {
|
|
393
|
+
y = v.y
|
|
394
|
+
}
|
|
395
|
+
} else {
|
|
396
|
+
v === 'center' || v === 'right' ? (x = v) : (y = v)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Set X position
|
|
400
|
+
if (x === 'center') {
|
|
401
|
+
this.x = '50%'
|
|
402
|
+
this.props['mountX'] = 0.5
|
|
403
|
+
} else if (x === 'right') {
|
|
404
|
+
this.x = '100%'
|
|
405
|
+
this.props['mountX'] = 1
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Set Y position
|
|
409
|
+
if (y === 'middle') {
|
|
410
|
+
this.y = '50%'
|
|
411
|
+
this.props['mountY'] = 0.5
|
|
412
|
+
} else if (y === 'bottom') {
|
|
413
|
+
this.y = '100%'
|
|
414
|
+
this.props['mountY'] = 1
|
|
415
|
+
}
|
|
416
|
+
},
|
|
386
417
|
}
|
|
387
418
|
|
|
388
419
|
const Element = {
|
|
@@ -362,30 +362,164 @@ test('Element - Set `fit` property should not set not required keys', (assert) =
|
|
|
362
362
|
assert.end()
|
|
363
363
|
})
|
|
364
364
|
|
|
365
|
-
test('Element - Set `
|
|
365
|
+
test('Element - Set `placement` property with value `center`', (assert) => {
|
|
366
366
|
assert.capture(renderer, 'createNode', () => new EventEmitter())
|
|
367
367
|
const el = createElement()
|
|
368
368
|
|
|
369
|
-
el.set('
|
|
369
|
+
el.set('placement', 'center')
|
|
370
370
|
|
|
371
371
|
assert.equal(el.node['mountX'], 0.5, 'Node mountX parameter should set to 0.5')
|
|
372
372
|
assert.equal(el.props.props['mountX'], 0.5, 'Props mountX parameter should set to 0.5')
|
|
373
373
|
assert.equal(el.node['x'], 960, 'Node x parameter should set to half of parent node width, 960')
|
|
374
374
|
assert.equal(el.props.props['x'], 960, 'props x parameter should be set to 960')
|
|
375
|
+
assert.equal(
|
|
376
|
+
el.node['y'],
|
|
377
|
+
undefined,
|
|
378
|
+
'Node Y parameter should not be modified from default value'
|
|
379
|
+
)
|
|
375
380
|
|
|
376
381
|
assert.end()
|
|
377
382
|
})
|
|
378
383
|
|
|
379
|
-
test('Element - Set `
|
|
384
|
+
test('Element - Set `placement` property with value `right`', (assert) => {
|
|
380
385
|
assert.capture(renderer, 'createNode', () => new EventEmitter())
|
|
381
386
|
const el = createElement()
|
|
382
387
|
|
|
383
|
-
el.set('
|
|
388
|
+
el.set('placement', 'right')
|
|
384
389
|
|
|
385
390
|
assert.equal(el.node['mountX'], 1, 'Node mountX parameter should set to 1')
|
|
386
391
|
assert.equal(el.props.props['mountX'], 1, 'Props mountX parameter should set to 1')
|
|
387
392
|
assert.equal(el.node['x'], 1920, 'Node x parameter should set to parent node full width, 1920')
|
|
388
393
|
assert.equal(el.props.props['x'], 1920, 'props x parameter should be set to 1920')
|
|
394
|
+
assert.equal(
|
|
395
|
+
el.node['y'],
|
|
396
|
+
undefined,
|
|
397
|
+
'Node Y parameter should not be modified from default value'
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
assert.end()
|
|
401
|
+
})
|
|
402
|
+
|
|
403
|
+
test('Element - Set `placement` property with value `middle`', (assert) => {
|
|
404
|
+
assert.capture(renderer, 'createNode', () => new EventEmitter())
|
|
405
|
+
const el = createElement()
|
|
406
|
+
|
|
407
|
+
el.set('placement', 'middle')
|
|
408
|
+
|
|
409
|
+
assert.equal(el.node['mountY'], 0.5, 'Node mountY parameter should set to 0.5')
|
|
410
|
+
assert.equal(el.props.props['mountY'], 0.5, 'Props mountY parameter should set to 0.5')
|
|
411
|
+
assert.equal(el.node['y'], 540, 'Node Y parameter should set to half of parent node height, 540')
|
|
412
|
+
assert.equal(el.props.props['y'], 540, 'props Y parameter should be set to 540')
|
|
413
|
+
assert.equal(
|
|
414
|
+
el.node['x'],
|
|
415
|
+
undefined,
|
|
416
|
+
'Node X parameter should not be modified from default value'
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
assert.end()
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
test('Element - Set `placement` property with value `bottom`', (assert) => {
|
|
423
|
+
assert.capture(renderer, 'createNode', () => new EventEmitter())
|
|
424
|
+
const el = createElement()
|
|
425
|
+
|
|
426
|
+
el.set('placement', 'bottom')
|
|
427
|
+
|
|
428
|
+
assert.equal(el.node['mountY'], 1, 'Node mountY parameter should set to 1')
|
|
429
|
+
assert.equal(el.props.props['mountY'], 1, 'Props mountY parameter should set to 1')
|
|
430
|
+
assert.equal(el.node['y'], 1080, 'Node Y parameter should set to parent node full height, 1080')
|
|
431
|
+
assert.equal(el.props.props['y'], 1080, 'props Y parameter should be set to 1080')
|
|
432
|
+
assert.equal(
|
|
433
|
+
el.node['x'],
|
|
434
|
+
undefined,
|
|
435
|
+
'Node X parameter should not be modified from default value'
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
assert.end()
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
test('Element - Set `placement` property with value `bottom` & x = 300', (assert) => {
|
|
442
|
+
assert.capture(renderer, 'createNode', () => new EventEmitter())
|
|
443
|
+
const el = createElement()
|
|
444
|
+
|
|
445
|
+
el.set('placement', 'bottom')
|
|
446
|
+
|
|
447
|
+
assert.equal(el.node['mountY'], 1, 'Node mountY parameter should set to 1')
|
|
448
|
+
assert.equal(el.props.props['mountY'], 1, 'Props mountY parameter should set to 1')
|
|
449
|
+
assert.equal(el.node['y'], 1080, 'Node Y parameter should set to parent node full height, 1080')
|
|
450
|
+
assert.equal(el.props.props['y'], 1080, 'props Y parameter should be set to 1080')
|
|
451
|
+
|
|
452
|
+
el.set('x', 300)
|
|
453
|
+
|
|
454
|
+
assert.equal(el.node['x'], 300, 'Node x parameter should set custom value 300')
|
|
455
|
+
|
|
456
|
+
assert.end()
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
test('Element - Set `placement` property with object value `{x:"center", y:"middle"}`', (assert) => {
|
|
460
|
+
assert.capture(renderer, 'createNode', () => new EventEmitter())
|
|
461
|
+
const el = createElement()
|
|
462
|
+
|
|
463
|
+
el.set('placement', "{x:'center', y:'middle'}")
|
|
464
|
+
|
|
465
|
+
assert.equal(el.node['mountX'], 0.5, 'Node mountX parameter should set to 0.5')
|
|
466
|
+
assert.equal(el.props.props['mountX'], 0.5, 'Props mountX parameter should set to 0.5')
|
|
467
|
+
assert.equal(el.node['x'], 960, 'Node x parameter should set to half of parent node width, 960')
|
|
468
|
+
|
|
469
|
+
assert.equal(el.node['mountY'], 0.5, 'Node mountY parameter should set to 0.5')
|
|
470
|
+
assert.equal(el.props.props['mountY'], 0.5, 'Props mountY parameter should set to 0.5')
|
|
471
|
+
assert.equal(el.node['y'], 540, 'Node Y parameter should set to half of parent node height, 540')
|
|
472
|
+
|
|
473
|
+
assert.end()
|
|
474
|
+
})
|
|
475
|
+
|
|
476
|
+
test('Element - Set `placement` property with object value `{x:"center", y:"bottom"}`', (assert) => {
|
|
477
|
+
assert.capture(renderer, 'createNode', () => new EventEmitter())
|
|
478
|
+
const el = createElement()
|
|
479
|
+
|
|
480
|
+
el.set('placement', "{x:'center', y:'bottom'}")
|
|
481
|
+
|
|
482
|
+
assert.equal(el.node['mountX'], 0.5, 'Node mountX parameter should set to 0.5')
|
|
483
|
+
assert.equal(el.props.props['mountX'], 0.5, 'Props mountX parameter should set to 0.5')
|
|
484
|
+
assert.equal(el.node['x'], 960, 'Node x parameter should set to half of parent node width, 960')
|
|
485
|
+
|
|
486
|
+
assert.equal(el.node['mountY'], 1, 'Node mountY parameter should set to 1')
|
|
487
|
+
assert.equal(el.props.props['mountY'], 1, 'Props mountY parameter should set to 1')
|
|
488
|
+
assert.equal(el.node['y'], 1080, 'Node Y parameter should set to parent node full height , 1080')
|
|
489
|
+
|
|
490
|
+
assert.end()
|
|
491
|
+
})
|
|
492
|
+
|
|
493
|
+
test('Element - Set `placement` property with object value `{x:"right", y:"middle"}`', (assert) => {
|
|
494
|
+
assert.capture(renderer, 'createNode', () => new EventEmitter())
|
|
495
|
+
const el = createElement()
|
|
496
|
+
|
|
497
|
+
el.set('placement', "{x:'right', y:'middle'}")
|
|
498
|
+
|
|
499
|
+
assert.equal(el.node['mountX'], 1, 'Node mountX parameter should set to 1')
|
|
500
|
+
assert.equal(el.props.props['mountX'], 1, 'Props mountX parameter should set to 1')
|
|
501
|
+
assert.equal(el.node['x'], 1920, 'Node x parameter should set to parent node full width, 1920')
|
|
502
|
+
|
|
503
|
+
assert.equal(el.node['mountY'], 0.5, 'Node mountY parameter should set to 0.5')
|
|
504
|
+
assert.equal(el.props.props['mountY'], 0.5, 'Props mountY parameter should set to 0.5')
|
|
505
|
+
assert.equal(el.node['y'], 540, 'Node Y parameter should set to half of parent node height, 540')
|
|
506
|
+
|
|
507
|
+
assert.end()
|
|
508
|
+
})
|
|
509
|
+
|
|
510
|
+
test('Element - Set `placement` property with object value `{x:"right", y:"bottom"}`', (assert) => {
|
|
511
|
+
assert.capture(renderer, 'createNode', () => new EventEmitter())
|
|
512
|
+
const el = createElement()
|
|
513
|
+
|
|
514
|
+
el.set('placement', "{x:'right', y:'bottom'}")
|
|
515
|
+
|
|
516
|
+
assert.equal(el.node['mountX'], 1, 'Node mountX parameter should set to 1')
|
|
517
|
+
assert.equal(el.props.props['mountX'], 1, 'Props mountX parameter should set to 1')
|
|
518
|
+
assert.equal(el.node['x'], 1920, 'Node x parameter should set to parent node full width, 1920')
|
|
519
|
+
|
|
520
|
+
assert.equal(el.node['mountY'], 1, 'Node mountY parameter should set to 1')
|
|
521
|
+
assert.equal(el.props.props['mountY'], 1, 'Props mountY parameter should set to 1')
|
|
522
|
+
assert.equal(el.node['y'], 1080, 'Node Y parameter should set to parent node height, 1080')
|
|
389
523
|
|
|
390
524
|
assert.end()
|
|
391
525
|
})
|
|
@@ -24,6 +24,9 @@ export default function (templateObject = { children: [] }) {
|
|
|
24
24
|
'let componentType',
|
|
25
25
|
'const rootComponent = component',
|
|
26
26
|
'let propData',
|
|
27
|
+
'let slotComponent',
|
|
28
|
+
'let inSlot = false',
|
|
29
|
+
'let slotChildCounter = 0',
|
|
27
30
|
],
|
|
28
31
|
effectsCode: [],
|
|
29
32
|
context: { props: [], components: this.components },
|
|
@@ -79,7 +82,7 @@ const generateElementCode = function (
|
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
renderCode.push(`
|
|
82
|
-
${elm} = this.element({parent: parent || 'root'}, component)
|
|
85
|
+
${elm} = this.element({parent: parent || 'root'}, inSlot === true ? slotComponent : component)
|
|
83
86
|
`)
|
|
84
87
|
|
|
85
88
|
if (options.forloop) {
|
|
@@ -96,7 +99,7 @@ const generateElementCode = function (
|
|
|
96
99
|
Object.keys(templateObject).forEach((key) => {
|
|
97
100
|
if (key === 'slot') {
|
|
98
101
|
renderCode.push(`
|
|
99
|
-
elementConfig${counter}['parent'] = component[Symbol.for('slots')].filter(slot => slot.ref === '${templateObject.slot}').shift() || parent
|
|
102
|
+
elementConfig${counter}['parent'] = component[Symbol.for('slots')] !== undefined && Array.isArray(component[Symbol.for('slots')]) === true && component[Symbol.for('slots')].filter(slot => slot.ref === '${templateObject.slot}').shift() || parent
|
|
100
103
|
`)
|
|
101
104
|
}
|
|
102
105
|
|
|
@@ -149,6 +152,12 @@ const generateElementCode = function (
|
|
|
149
152
|
|
|
150
153
|
renderCode.push(`${elm}.populate(elementConfig${counter})`)
|
|
151
154
|
|
|
155
|
+
renderCode.push(`
|
|
156
|
+
if(inSlot === true) {
|
|
157
|
+
slotChildCounter -= 1
|
|
158
|
+
}
|
|
159
|
+
`)
|
|
160
|
+
|
|
152
161
|
if (options.forloop) {
|
|
153
162
|
renderCode.push('}')
|
|
154
163
|
}
|
|
@@ -247,7 +256,8 @@ const generateComponentCode = function (
|
|
|
247
256
|
|
|
248
257
|
if (${elm}[Symbol.for('slots')][0]) {
|
|
249
258
|
parent = ${elm}[Symbol.for('slots')][0]
|
|
250
|
-
|
|
259
|
+
slotComponent = ${elm}
|
|
260
|
+
inSlot = true
|
|
251
261
|
} else {
|
|
252
262
|
parent = ${elm}[Symbol.for('children')][0]
|
|
253
263
|
}
|
|
@@ -258,15 +268,24 @@ const generateComponentCode = function (
|
|
|
258
268
|
}
|
|
259
269
|
|
|
260
270
|
if (children) {
|
|
271
|
+
if (!options.forloop) {
|
|
272
|
+
renderCode.push(`
|
|
273
|
+
if(inSlot === true) {
|
|
274
|
+
slotChildCounter = ${children.length} + 1
|
|
275
|
+
}
|
|
276
|
+
`)
|
|
277
|
+
}
|
|
261
278
|
counter++
|
|
262
279
|
generateElementCode.call(this, { children }, false, { ...options })
|
|
263
280
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
281
|
+
|
|
282
|
+
if (!options.forloop) {
|
|
283
|
+
renderCode.push(`
|
|
284
|
+
if (inSlot === true && slotChildCounter === 0) {
|
|
285
|
+
inSlot = false
|
|
286
|
+
}
|
|
287
|
+
`)
|
|
288
|
+
}
|
|
270
289
|
}
|
|
271
290
|
|
|
272
291
|
const generateForLoopCode = function (templateObject, parent) {
|
|
@@ -288,7 +307,7 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
288
307
|
const result = regex.exec(forLoop)
|
|
289
308
|
|
|
290
309
|
// can be improved with a smarter regex
|
|
291
|
-
const [item, index
|
|
310
|
+
const [item, index] = result[1]
|
|
292
311
|
.replace('(', '')
|
|
293
312
|
.replace(')', '')
|
|
294
313
|
.split(/\s*,\s*/)
|
|
@@ -306,12 +325,15 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
306
325
|
ctx.renderCode.push(`parent = ${parent}`)
|
|
307
326
|
}
|
|
308
327
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
328
|
+
// If the index variable is not defined, the key attribute would not reference it.
|
|
329
|
+
if (index !== undefined) {
|
|
330
|
+
const indexRegex = new RegExp(`\\$${index}(?!['\\w])`)
|
|
331
|
+
const indexResult = indexRegex.exec(key)
|
|
332
|
+
if (Array.isArray(indexResult)) {
|
|
333
|
+
ctx.renderCode.push(
|
|
334
|
+
`console.warn(" Using '${index}' in the key, like key=${key}, is not recommended")`
|
|
335
|
+
)
|
|
336
|
+
}
|
|
315
337
|
}
|
|
316
338
|
|
|
317
339
|
const forStartCounter = counter
|
|
@@ -324,7 +346,14 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
324
346
|
let l = rawCollection.length
|
|
325
347
|
while(l--) {
|
|
326
348
|
const ${item} = rawCollection[l]
|
|
349
|
+
`)
|
|
350
|
+
// push reference of index variable
|
|
351
|
+
if (index !== undefined) {
|
|
352
|
+
ctx.renderCode.push(`
|
|
327
353
|
const ${index} = l
|
|
354
|
+
`)
|
|
355
|
+
}
|
|
356
|
+
ctx.renderCode.push(`
|
|
328
357
|
keys.add('' + ${interpolate(key, '') || 'l'})
|
|
329
358
|
}
|
|
330
359
|
`)
|
|
@@ -341,8 +370,15 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
341
370
|
for(let __index = 0; __index < length; __index++) {
|
|
342
371
|
const scope = Object.create(component)
|
|
343
372
|
parent = ${parent}
|
|
344
|
-
scope['${index}'] = __index
|
|
345
373
|
scope['${item}'] = rawCollection[__index]
|
|
374
|
+
`)
|
|
375
|
+
// If the index variable is declared, include it in the scope object
|
|
376
|
+
if (index !== '') {
|
|
377
|
+
ctx.renderCode.push(`
|
|
378
|
+
scope['${index}'] = __index
|
|
379
|
+
`)
|
|
380
|
+
}
|
|
381
|
+
ctx.renderCode.push(`
|
|
346
382
|
scope['key'] = '' + ${forKey || '__index'}
|
|
347
383
|
`)
|
|
348
384
|
if ('ref' in templateObject && templateObject.ref.indexOf('$') === -1) {
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import { ImageTexture, Texture } from '@lightningjs/renderer'
|
|
19
18
|
import { track, trigger, pauseTracking, resumeTracking } from './effect.js'
|
|
20
19
|
import symbols from '../symbols.js'
|
|
21
20
|
import deepEqualArray from '../../helpers/deepEqualArray.js'
|
|
@@ -30,14 +29,15 @@ export const getRaw = (value) => {
|
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
const reactiveProxy = (original, _parent = null, _key, global) => {
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
// only create a proxy for plain objects. Other classes, Blits components, renderer textures etc
|
|
33
|
+
// are returned unmodified and will not become reactive
|
|
34
|
+
if (
|
|
35
|
+
typeof original === 'object' &&
|
|
36
|
+
Array.isArray(original) === false &&
|
|
37
|
+
Object.getPrototypeOf(original) !== Object.prototype
|
|
38
|
+
) {
|
|
39
|
+
return original
|
|
39
40
|
}
|
|
40
|
-
|
|
41
41
|
// if original object is already a proxy, don't create a new one but return the existing one instead
|
|
42
42
|
const existingProxy = proxyMap.get(original)
|
|
43
43
|
if (existingProxy !== undefined) {
|
|
@@ -16,23 +16,52 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import blitsfileconverter from '../src/lib/blitsfileconverter/blitsfileconverter.js'
|
|
19
|
+
import path from 'node:path'
|
|
20
|
+
import fs from 'node:fs'
|
|
21
|
+
import { createRequire } from 'module'
|
|
19
22
|
|
|
20
23
|
export default function blitsFileType() {
|
|
21
24
|
return {
|
|
22
25
|
name: 'vite-plugin-blits-file-type',
|
|
23
26
|
enforce: 'pre',
|
|
24
|
-
|
|
27
|
+
|
|
28
|
+
resolveId(source, importer) {
|
|
29
|
+
if (source.endsWith('.blits')) {
|
|
30
|
+
return importer ? path.resolve(path.dirname(importer), source) : path.resolve(source)
|
|
31
|
+
}
|
|
32
|
+
return null
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
load(id) {
|
|
25
36
|
if (id.endsWith('.blits')) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
const source = fs.readFileSync(id, 'utf-8')
|
|
38
|
+
let code = blitsfileconverter(source)
|
|
39
|
+
|
|
40
|
+
// Check for TypeScript and transpile to JS if needed
|
|
41
|
+
if (/<script\s+lang=["']ts["']/.test(source)) {
|
|
42
|
+
// Resolve the local typescript dependency
|
|
43
|
+
const userRequire = createRequire(process.cwd() + '/')
|
|
44
|
+
let ts
|
|
45
|
+
try {
|
|
46
|
+
ts = userRequire('typescript')
|
|
47
|
+
} catch (err) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`\n\nThe file "${id}" contains \`lang="ts"\`, indicating it uses TypeScript. \nTo enable TypeScript support, please install the 'typescript' package as a dev dependency by running:\n\n` +
|
|
50
|
+
' npm install --save-dev typescript\n\n'
|
|
51
|
+
)
|
|
31
52
|
}
|
|
32
|
-
|
|
33
|
-
|
|
53
|
+
const transpiled = ts.transpileModule(code, {
|
|
54
|
+
compilerOptions: { target: ts.ScriptTarget.ESNext, module: ts.ModuleKind.ESNext },
|
|
55
|
+
})
|
|
56
|
+
code = transpiled.outputText
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
code,
|
|
61
|
+
map: null,
|
|
34
62
|
}
|
|
35
63
|
}
|
|
64
|
+
return null
|
|
36
65
|
},
|
|
37
66
|
}
|
|
38
67
|
}
|
package/vite/preCompiler.js
CHANGED
|
@@ -30,12 +30,13 @@ export default function () {
|
|
|
30
30
|
|
|
31
31
|
const fileExtension = path.extname(filePath)
|
|
32
32
|
|
|
33
|
-
// we should only precompile .js and .ts files
|
|
34
|
-
if (fileExtension === '.js' || fileExtension === '.ts') {
|
|
33
|
+
// we should only precompile .blits, .js and .ts files
|
|
34
|
+
if (fileExtension === '.js' || fileExtension === '.ts' || fileExtension === '.blits') {
|
|
35
35
|
return compiler(source, filePath)
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
|
|
38
|
+
// vite expects null if there is no modification
|
|
39
|
+
return null
|
|
39
40
|
},
|
|
40
41
|
}
|
|
41
42
|
}
|