@lightningjs/blits 2.0.0-beta.1 → 2.0.0-beta.4
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 +76 -0
- package/README.md +2 -0
- package/element-test-full.txt +0 -0
- package/index.d.ts +106 -13
- package/package.json +25 -4
- package/scripts/prepublishOnly.js +13 -4
- package/scripts/prepush.js +21 -1
- package/src/announcer/announcer.js +50 -4
- package/src/announcer/speechSynthesis.js +156 -37
- package/src/application.js +95 -3
- package/src/component/base/methods.js +5 -2
- package/src/component/base/router.js +6 -0
- package/src/component/base/timeouts_intervals.js +56 -0
- package/src/component/setup/routes.js +5 -0
- package/src/component/setup/state.js +2 -0
- package/src/component.js +64 -24
- package/src/components/Circle.js +5 -3
- package/src/components/FPScounter.js +1591 -1577
- package/src/components/RouterView.js +141 -124
- package/src/components/Sprite.js +29 -8
- package/src/components/index.js +0 -2
- package/src/engines/L3/element.js +101 -7
- package/src/engines/L3/launch.js +4 -1
- package/src/{focus.js → focus/focus.js} +6 -18
- package/src/focus/helpers.js +31 -0
- package/src/focus/hover.js +94 -0
- package/src/launch.js +1 -0
- package/src/lib/codegenerator/generator.js +44 -8
- package/src/lib/lifecycle.js +34 -3
- package/src/lib/log.js +4 -4
- package/src/lib/precompiler/precompiler.js +23 -14
- package/src/lib/reactivity/effect.js +3 -2
- package/src/lib/reactivityguard/computedprops.js +86 -15
- package/src/lib/shaders/shaders.js +2 -1
- package/src/lib/symbols.js +2 -0
- package/src/plugins/appstate.d.ts +26 -0
- package/src/plugins/index.d.ts +28 -0
- package/src/plugins/language.d.ts +37 -0
- package/src/plugins/storage/storage.d.ts +31 -0
- package/src/plugins/theme.d.ts +43 -0
- package/src/plugins/theme.js +30 -3
- package/src/router/router.js +78 -14
- package/test-output.txt +0 -0
- package/vite/preCompiler.js +15 -5
- package/vscode/data/template-attributes.json +335 -86
|
@@ -16,141 +16,158 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import Component from '../component.js'
|
|
19
|
-
import Router from '../router/router.js'
|
|
19
|
+
import Router, { state as routerState } from '../router/router.js'
|
|
20
20
|
import symbols from '../lib/symbols.js'
|
|
21
|
-
import Focus from '../focus.js'
|
|
21
|
+
import Focus from '../focus/focus.js'
|
|
22
22
|
|
|
23
23
|
let hashchangeHandler = null
|
|
24
24
|
|
|
25
|
+
/** @typedef {{ $input?: (event: any) => boolean, $focus?: (event: any) => void }} RouterViewParent */
|
|
26
|
+
|
|
25
27
|
export default () =>
|
|
26
|
-
Component(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
28
|
+
Component(
|
|
29
|
+
'RouterView',
|
|
30
|
+
/** @type {any} */ ({
|
|
31
|
+
/* eslint-disable no-unused-vars */
|
|
32
|
+
code: {
|
|
33
|
+
render: function anonymous(parent, component, context, components, effect, getRaw, Log) {
|
|
34
|
+
const elms = []
|
|
35
|
+
const validAttributes = [
|
|
36
|
+
'parent',
|
|
37
|
+
'rotation',
|
|
38
|
+
'w',
|
|
39
|
+
'width',
|
|
40
|
+
'h',
|
|
41
|
+
'height',
|
|
42
|
+
'x',
|
|
43
|
+
'y',
|
|
44
|
+
'z',
|
|
45
|
+
'zIndex',
|
|
46
|
+
'color',
|
|
47
|
+
'src',
|
|
48
|
+
'texture',
|
|
49
|
+
'fit',
|
|
50
|
+
'rtt',
|
|
51
|
+
'mount',
|
|
52
|
+
'pivot',
|
|
53
|
+
'scale',
|
|
54
|
+
'show',
|
|
55
|
+
'alpha',
|
|
56
|
+
'rounded',
|
|
57
|
+
'border',
|
|
58
|
+
'shadow',
|
|
59
|
+
'shader',
|
|
60
|
+
'clipping',
|
|
61
|
+
'overflow',
|
|
62
|
+
'font',
|
|
63
|
+
'size',
|
|
64
|
+
'maxwidth',
|
|
65
|
+
'maxheight',
|
|
66
|
+
'maxlines',
|
|
67
|
+
'textoverflow',
|
|
68
|
+
'letterspacing',
|
|
69
|
+
'lineheight',
|
|
70
|
+
'contain',
|
|
71
|
+
'align',
|
|
72
|
+
'content',
|
|
73
|
+
'placement',
|
|
74
|
+
'inspector-data',
|
|
75
|
+
'holder',
|
|
76
|
+
]
|
|
77
|
+
const elementConfigs = []
|
|
78
|
+
const forloops = []
|
|
79
|
+
const props = []
|
|
80
|
+
const created = []
|
|
81
|
+
const effects = {}
|
|
82
|
+
const skips = []
|
|
83
|
+
let componentType
|
|
84
|
+
let rootComponent = component
|
|
85
|
+
let propData
|
|
86
|
+
let slotComponent
|
|
87
|
+
let inSlot = false
|
|
88
|
+
let slotChildCounter = 0
|
|
89
|
+
let cmps = []
|
|
90
|
+
elementConfigs[0] = {}
|
|
91
|
+
elementConfigs[0]['___wrapper'] = true
|
|
86
92
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
elms[0] = this.element(
|
|
94
|
+
{ parent: parent || 'root' },
|
|
95
|
+
inSlot === true ? slotComponent : component
|
|
96
|
+
)
|
|
91
97
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
98
|
+
elementConfigs[0]['w'] = parent.node.w * (100 / 100)
|
|
99
|
+
elementConfigs[0]['height'] = parent.node.h * (100 / 100)
|
|
100
|
+
elms[0].populate(elementConfigs[0])
|
|
95
101
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
if (inSlot === true) {
|
|
103
|
+
slotChildCounter -= 1
|
|
104
|
+
}
|
|
99
105
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
106
|
+
return {
|
|
107
|
+
elms,
|
|
108
|
+
cleanup: () => {
|
|
109
|
+
rootComponent = null
|
|
110
|
+
propData = null
|
|
111
|
+
slotComponent = null
|
|
112
|
+
parent = null
|
|
113
|
+
component = null
|
|
114
|
+
cmps.length = 0
|
|
115
|
+
elms.length = 0
|
|
116
|
+
components.length = 0
|
|
117
|
+
elementConfigs.length = 0
|
|
118
|
+
forloops.length = 0
|
|
119
|
+
props.length = 0
|
|
120
|
+
skips.length = 0
|
|
121
|
+
},
|
|
122
|
+
skips,
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
effects: [],
|
|
126
|
+
context: {},
|
|
118
127
|
},
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
state() {
|
|
123
|
-
return {
|
|
124
|
-
activeView: null,
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
hooks: {
|
|
128
|
-
async ready() {
|
|
129
|
-
if (
|
|
130
|
-
this[symbols.parent][symbols.routerHooks] &&
|
|
131
|
-
this[symbols.parent][symbols.routerHooks].init
|
|
132
|
-
) {
|
|
133
|
-
await this[symbols.parent][symbols.routerHooks].init.apply(this[symbols.parent])
|
|
128
|
+
state() {
|
|
129
|
+
return {
|
|
130
|
+
activeView: null,
|
|
134
131
|
}
|
|
135
|
-
hashchangeHandler = () => Router.navigate.apply(this)
|
|
136
|
-
Router.navigate.apply(this)
|
|
137
|
-
window.addEventListener('hashchange', hashchangeHandler)
|
|
138
|
-
},
|
|
139
|
-
destroy() {
|
|
140
|
-
window.removeEventListener('hashchange', hashchangeHandler, false)
|
|
141
132
|
},
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
this.
|
|
145
|
-
|
|
133
|
+
hooks: {
|
|
134
|
+
async ready() {
|
|
135
|
+
const parent = this[symbols.parent]
|
|
136
|
+
if (parent && parent[symbols.routerHooks] && parent[symbols.routerHooks].init) {
|
|
137
|
+
await parent[symbols.routerHooks].init.apply(parent)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
hashchangeHandler = () => Router.navigate.apply(this)
|
|
141
|
+
Router.navigate.apply(this)
|
|
142
|
+
window.addEventListener('hashchange', hashchangeHandler)
|
|
143
|
+
},
|
|
144
|
+
destroy() {
|
|
145
|
+
window.removeEventListener('hashchange', hashchangeHandler, false)
|
|
146
|
+
},
|
|
147
|
+
focus() {
|
|
148
|
+
if (this.activeView && Focus.get() === this) {
|
|
149
|
+
this.activeView.$focus()
|
|
150
|
+
}
|
|
151
|
+
},
|
|
146
152
|
},
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
input: {
|
|
154
|
+
back(e) {
|
|
155
|
+
const parent = this[symbols.parent]
|
|
156
|
+
|
|
157
|
+
if (routerState.backNavigation === false) {
|
|
158
|
+
if (parent && parent.$input) {
|
|
159
|
+
parent.$input(e)
|
|
160
|
+
}
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const navigating = Router.back.call(this)
|
|
165
|
+
if (navigating === false) {
|
|
166
|
+
if (parent && parent.$focus) {
|
|
167
|
+
parent.$focus(e)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
},
|
|
154
171
|
},
|
|
155
|
-
}
|
|
156
|
-
|
|
172
|
+
})
|
|
173
|
+
)
|
package/src/components/Sprite.js
CHANGED
|
@@ -65,6 +65,7 @@ export default () =>
|
|
|
65
65
|
'content',
|
|
66
66
|
'placement',
|
|
67
67
|
'inspector-data',
|
|
68
|
+
'holder',
|
|
68
69
|
]
|
|
69
70
|
const elementConfigs = []
|
|
70
71
|
const forloops = []
|
|
@@ -80,6 +81,7 @@ export default () =>
|
|
|
80
81
|
let slotChildCounter = 0
|
|
81
82
|
let cmps = []
|
|
82
83
|
elementConfigs[0] = {}
|
|
84
|
+
elementConfigs[0]['___wrapper'] = true
|
|
83
85
|
|
|
84
86
|
elms[0] = this.element(
|
|
85
87
|
{ parent: parent || 'root' },
|
|
@@ -90,7 +92,9 @@ export default () =>
|
|
|
90
92
|
elementConfigs[0]['h'] = parent.node.h * (100 / 100)
|
|
91
93
|
elementConfigs[0]['texture'] = component.texture
|
|
92
94
|
elementConfigs[0]['color'] = component.color
|
|
93
|
-
elementConfigs[0]['
|
|
95
|
+
elementConfigs[0]['rounded'] = component.rounded
|
|
96
|
+
elementConfigs[0]['border'] = component.border
|
|
97
|
+
elementConfigs[0]['shadow'] = component.shadow
|
|
94
98
|
elms[0].populate(elementConfigs[0])
|
|
95
99
|
|
|
96
100
|
if (inSlot === true) {
|
|
@@ -123,6 +127,15 @@ export default () =>
|
|
|
123
127
|
function anonymous(component, elms, context, components, rootComponent, skips, effect) {
|
|
124
128
|
elms[0].set('color', component.color)
|
|
125
129
|
},
|
|
130
|
+
function anonymous(component, elms, context, components, rootComponent, skips, effect) {
|
|
131
|
+
elms[0].set('rounded', component.rounded)
|
|
132
|
+
},
|
|
133
|
+
function anonymous(component, elms, context, components, rootComponent, skips, effect) {
|
|
134
|
+
elms[0].set('border', component.border)
|
|
135
|
+
},
|
|
136
|
+
function anonymous(component, elms, context, components, rootComponent, skips, effect) {
|
|
137
|
+
elms[0].set('shadow', component.shadow)
|
|
138
|
+
},
|
|
126
139
|
],
|
|
127
140
|
context: {},
|
|
128
141
|
},
|
|
@@ -131,6 +144,9 @@ export default () =>
|
|
|
131
144
|
map: undefined,
|
|
132
145
|
frame: undefined,
|
|
133
146
|
color: undefined,
|
|
147
|
+
rounded: undefined,
|
|
148
|
+
border: undefined,
|
|
149
|
+
shadow: undefined,
|
|
134
150
|
},
|
|
135
151
|
state() {
|
|
136
152
|
return {
|
|
@@ -167,15 +183,20 @@ export default () =>
|
|
|
167
183
|
// Resolve frame data from sprite map
|
|
168
184
|
let options = null
|
|
169
185
|
if (
|
|
170
|
-
this.map !== undefined &&
|
|
171
186
|
this.map !== null &&
|
|
172
|
-
this.
|
|
173
|
-
this.frame !== null
|
|
187
|
+
this.map !== undefined &&
|
|
188
|
+
this.frame !== null &&
|
|
189
|
+
this.frame !== undefined
|
|
174
190
|
) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
191
|
+
if (
|
|
192
|
+
this.map.frames !== null &&
|
|
193
|
+
this.map.frames !== undefined &&
|
|
194
|
+
this.frame in this.map.frames
|
|
195
|
+
) {
|
|
196
|
+
options = Object.assign({}, this.map.defaults || {}, this.map.frames[this.frame])
|
|
197
|
+
} else if (this.frame in this.map) {
|
|
198
|
+
options = this.map[this.frame]
|
|
199
|
+
}
|
|
179
200
|
}
|
|
180
201
|
|
|
181
202
|
// If no map but frame is object (manual subtexture)
|
package/src/components/index.js
CHANGED
|
@@ -18,11 +18,9 @@
|
|
|
18
18
|
import Circle from './Circle.js'
|
|
19
19
|
import RouterView from './RouterView.js'
|
|
20
20
|
import Sprite from './Sprite.js'
|
|
21
|
-
import FPScounter from './FPScounter.js'
|
|
22
21
|
|
|
23
22
|
export default () => ({
|
|
24
23
|
Circle: Circle(),
|
|
25
24
|
RouterView: RouterView(),
|
|
26
25
|
Sprite: Sprite(),
|
|
27
|
-
FPScounter: FPScounter(),
|
|
28
26
|
})
|
|
@@ -24,6 +24,8 @@ import symbols from '../../lib/symbols.js'
|
|
|
24
24
|
import Settings from '../../settings.js'
|
|
25
25
|
import shaders from '../../lib/shaders/shaders.js'
|
|
26
26
|
|
|
27
|
+
const holderComponentMap = new WeakMap()
|
|
28
|
+
|
|
27
29
|
/**
|
|
28
30
|
* Creates a padding object from a value and direction.
|
|
29
31
|
* @param {number|object|string|undefined} padding - The padding value.
|
|
@@ -210,15 +212,29 @@ const propsTransformer = {
|
|
|
210
212
|
this.props['rotation'] = v * (Math.PI / 180)
|
|
211
213
|
},
|
|
212
214
|
set w(v) {
|
|
213
|
-
|
|
214
|
-
this.props['w'] =
|
|
215
|
+
const parsed = parsePercentage.call(this, v, 'w')
|
|
216
|
+
this.props['w'] = parsed
|
|
217
|
+
if (
|
|
218
|
+
this.___wrapper === true &&
|
|
219
|
+
this.element.component.eol !== true &&
|
|
220
|
+
this.element.component[symbols.holder] !== undefined
|
|
221
|
+
) {
|
|
222
|
+
this.element.component[symbols.holder].set('w', parsed)
|
|
223
|
+
}
|
|
215
224
|
},
|
|
216
225
|
set width(v) {
|
|
217
226
|
this.w = v
|
|
218
227
|
},
|
|
219
228
|
set h(v) {
|
|
220
|
-
|
|
221
|
-
this.props['h'] =
|
|
229
|
+
const parsed = parsePercentage.call(this, v, 'h')
|
|
230
|
+
this.props['h'] = parsed
|
|
231
|
+
if (
|
|
232
|
+
this.___wrapper === true &&
|
|
233
|
+
this.element.component.eol !== true &&
|
|
234
|
+
this.element.component[symbols.holder] !== undefined
|
|
235
|
+
) {
|
|
236
|
+
this.element.component[symbols.holder].set('h', parsed)
|
|
237
|
+
}
|
|
222
238
|
},
|
|
223
239
|
set height(v) {
|
|
224
240
|
this.h = v
|
|
@@ -509,6 +525,9 @@ const propsTransformer = {
|
|
|
509
525
|
this.props['data'] = v
|
|
510
526
|
}
|
|
511
527
|
},
|
|
528
|
+
set holder(v) {
|
|
529
|
+
this.props['interactive'] = v
|
|
530
|
+
},
|
|
512
531
|
}
|
|
513
532
|
|
|
514
533
|
export const elementAttributes = Object.keys(propsTransformer)
|
|
@@ -564,6 +583,10 @@ const Element = {
|
|
|
564
583
|
? renderer.createTextNode({ ...textDefaults, ...this.props.props })
|
|
565
584
|
: renderer.createNode(this.props.props)
|
|
566
585
|
|
|
586
|
+
if (this.props['holder'] === true) {
|
|
587
|
+
holderComponentMap.set(this.node, this.component)
|
|
588
|
+
}
|
|
589
|
+
|
|
567
590
|
if (props['@loaded'] !== undefined && typeof props['@loaded'] === 'function') {
|
|
568
591
|
this.node.on('loaded', (el, { type, dimensions }) => {
|
|
569
592
|
props['@loaded']({ w: dimensions.w, h: dimensions.h, type }, this)
|
|
@@ -587,6 +610,39 @@ const Element = {
|
|
|
587
610
|
})
|
|
588
611
|
}
|
|
589
612
|
},
|
|
613
|
+
/**
|
|
614
|
+
* Sets framework-provided inspector metadata
|
|
615
|
+
* Only sets if inspector is enabled and in dev mode
|
|
616
|
+
* @param {Object} data - Framework inspector metadata to merge
|
|
617
|
+
*/
|
|
618
|
+
setInspectorMetadata(data) {
|
|
619
|
+
// Early return if inspector not enabled (performance optimization)
|
|
620
|
+
if (inspectorEnabled !== true) {
|
|
621
|
+
return
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// Early return if element is destroyed (props.props is null)
|
|
625
|
+
if (this.props.props === undefined || this.props.props === null) {
|
|
626
|
+
return
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Initialize data object if it doesn't exist
|
|
630
|
+
if (this.props['data'] === undefined) {
|
|
631
|
+
this.props['data'] = {}
|
|
632
|
+
}
|
|
633
|
+
if (this.props.props['data'] === undefined) {
|
|
634
|
+
this.props.props['data'] = {}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// Merge framework data (blits-* keys data attributes)
|
|
638
|
+
Object.assign(this.props['data'], data)
|
|
639
|
+
Object.assign(this.props.props['data'], data)
|
|
640
|
+
|
|
641
|
+
// Sync to renderer node so inspector can see it
|
|
642
|
+
if (this.node !== undefined && this.node !== null) {
|
|
643
|
+
this.node.data = { ...this.props.props['data'] }
|
|
644
|
+
}
|
|
645
|
+
},
|
|
590
646
|
/**
|
|
591
647
|
* Set an individual property on the node
|
|
592
648
|
*
|
|
@@ -632,13 +688,31 @@ const Element = {
|
|
|
632
688
|
}
|
|
633
689
|
},
|
|
634
690
|
animate(prop, value, transition) {
|
|
691
|
+
// Clear any existing debounce timeout for this property
|
|
692
|
+
if (this.debounceTimeouts[prop] !== undefined) {
|
|
693
|
+
clearTimeout(this.debounceTimeouts[prop])
|
|
694
|
+
Log.debug(`Cleared debounce timeout for property "${prop}"`)
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// Debounce the animation execution
|
|
698
|
+
this.debounceTimeouts[prop] = setTimeout(() => {
|
|
699
|
+
delete this.debounceTimeouts[prop]
|
|
700
|
+
this._executeAnimation(prop, value, transition)
|
|
701
|
+
}, 0)
|
|
702
|
+
},
|
|
703
|
+
_executeAnimation(prop, value, transition) {
|
|
635
704
|
// check if a transition is already scheduled to run on the same prop
|
|
636
705
|
// and cancels it if it does
|
|
706
|
+
const stateOfAnimation =
|
|
707
|
+
this.scheduledTransitions[prop] !== undefined
|
|
708
|
+
? this.scheduledTransitions[prop].f.state
|
|
709
|
+
: undefined
|
|
710
|
+
|
|
637
711
|
if (
|
|
638
|
-
|
|
639
|
-
|
|
712
|
+
stateOfAnimation !== undefined &&
|
|
713
|
+
(stateOfAnimation === 'scheduled' || stateOfAnimation === 'running')
|
|
640
714
|
) {
|
|
641
|
-
this.scheduledTransitions[prop].f.stop()
|
|
715
|
+
this.scheduledTransitions[prop].f.stop(stateOfAnimation === 'running' ? false : true)
|
|
642
716
|
}
|
|
643
717
|
|
|
644
718
|
// if current value is the same as the value to animate to, instantly resolve
|
|
@@ -674,6 +748,11 @@ const Element = {
|
|
|
674
748
|
f,
|
|
675
749
|
}
|
|
676
750
|
|
|
751
|
+
// Update inspector metadata when transition starts
|
|
752
|
+
if (inspectorEnabled === true) {
|
|
753
|
+
this.setInspectorMetadata({ 'blits-isTransitioning': true })
|
|
754
|
+
}
|
|
755
|
+
|
|
677
756
|
if (transition.start !== undefined && typeof transition.start === 'function') {
|
|
678
757
|
// fire transition start callback when animation really starts (depending on specified delay)
|
|
679
758
|
f.once('animating', () => {
|
|
@@ -708,6 +787,12 @@ const Element = {
|
|
|
708
787
|
}
|
|
709
788
|
// remove the prop from scheduled transitions
|
|
710
789
|
delete this.scheduledTransitions[prop]
|
|
790
|
+
// Update inspector metadata when transition ends
|
|
791
|
+
if (inspectorEnabled === true) {
|
|
792
|
+
this.setInspectorMetadata({
|
|
793
|
+
'blits-isTransitioning': Object.keys(this.scheduledTransitions).length > 0,
|
|
794
|
+
})
|
|
795
|
+
}
|
|
711
796
|
})
|
|
712
797
|
|
|
713
798
|
// start animation
|
|
@@ -717,6 +802,14 @@ const Element = {
|
|
|
717
802
|
if (this.node === null) return
|
|
718
803
|
|
|
719
804
|
Log.debug('Deleting Node', this.nodeId)
|
|
805
|
+
|
|
806
|
+
// Clear all pending debounce timeouts
|
|
807
|
+
const debounceProps = Object.keys(this.debounceTimeouts)
|
|
808
|
+
for (let i = 0; i < debounceProps.length; i++) {
|
|
809
|
+
clearTimeout(this.debounceTimeouts[debounceProps[i]])
|
|
810
|
+
}
|
|
811
|
+
this.debounceTimeouts = null
|
|
812
|
+
|
|
720
813
|
// Clearing transition end callback functions
|
|
721
814
|
const transitionProps = Object.keys(this.scheduledTransitions)
|
|
722
815
|
for (let i = 0; i < transitionProps.length; i++) {
|
|
@@ -799,6 +892,7 @@ export default (config, component) => {
|
|
|
799
892
|
return Object.assign(Object.create(Element), {
|
|
800
893
|
props: Object.assign(Object.create(propsTransformer), { props: {} }),
|
|
801
894
|
scheduledTransitions: {},
|
|
895
|
+
debounceTimeouts: {},
|
|
802
896
|
config,
|
|
803
897
|
component,
|
|
804
898
|
})
|
package/src/engines/L3/launch.js
CHANGED
|
@@ -100,6 +100,7 @@ export default (App, target, settings = {}) => {
|
|
|
100
100
|
textureMemory: textureMemorySettings(settings),
|
|
101
101
|
createImageBitmapSupport: 'auto',
|
|
102
102
|
targetFPS: 'maxFPS' in settings ? settings.maxFPS : 0,
|
|
103
|
+
platform: 'platform' in settings ? settings.platform : null,
|
|
103
104
|
},
|
|
104
105
|
...(settings.advanced || {}),
|
|
105
106
|
},
|
|
@@ -118,7 +119,9 @@ export default (App, target, settings = {}) => {
|
|
|
118
119
|
|
|
119
120
|
shaderLoader()
|
|
120
121
|
fontLoader()
|
|
121
|
-
|
|
122
|
+
// Defer app initialization until after the current call stack is cleared,
|
|
123
|
+
// allowing the renderer to finish setting up before the app starts creating components
|
|
124
|
+
Promise.resolve().then(initApp)
|
|
122
125
|
|
|
123
126
|
return renderer
|
|
124
127
|
}
|
|
@@ -15,11 +15,12 @@
|
|
|
15
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import symbols from '
|
|
19
|
-
import { state } from '
|
|
20
|
-
import Settings from '
|
|
21
|
-
import { DEFAULT_HOLD_TIMEOUT_MS } from '
|
|
22
|
-
import { Log } from '
|
|
18
|
+
import symbols from '../lib/symbols.js'
|
|
19
|
+
import { state } from '../router/router.js'
|
|
20
|
+
import Settings from '../settings.js'
|
|
21
|
+
import { DEFAULT_HOLD_TIMEOUT_MS } from '../constants.js'
|
|
22
|
+
import { Log } from '../lib/log.js'
|
|
23
|
+
import { getAncestors } from './helpers.js'
|
|
23
24
|
|
|
24
25
|
let focusedComponent = null
|
|
25
26
|
let focusChain = []
|
|
@@ -99,19 +100,6 @@ export default {
|
|
|
99
100
|
},
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
/**
|
|
103
|
-
* Recursive function that retrieves the ancestors of a component
|
|
104
|
-
* @param {Array} components
|
|
105
|
-
* @returns array components
|
|
106
|
-
*/
|
|
107
|
-
const getAncestors = (components) => {
|
|
108
|
-
if (components[0][symbols.parent] !== undefined) {
|
|
109
|
-
components.unshift(components[0][symbols.parent])
|
|
110
|
-
return getAncestors(components)
|
|
111
|
-
}
|
|
112
|
-
return components
|
|
113
|
-
}
|
|
114
|
-
|
|
115
103
|
/**
|
|
116
104
|
* Get the component in the ancestors chain that has a handler for a certain key code
|
|
117
105
|
* @param {Object} component
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 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 symbols from '../lib/symbols.js'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Recursive function that retrieves the ancestors of a component
|
|
22
|
+
* @param {Array} components
|
|
23
|
+
* @returns array components
|
|
24
|
+
*/
|
|
25
|
+
export const getAncestors = (components) => {
|
|
26
|
+
if (components[0][symbols.parent] !== undefined) {
|
|
27
|
+
components.unshift(components[0][symbols.parent])
|
|
28
|
+
return getAncestors(components)
|
|
29
|
+
}
|
|
30
|
+
return components
|
|
31
|
+
}
|