@lightningjs/blits 2.0.0-beta.1 → 2.0.0-beta.10
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 +83 -0
- package/README.md +2 -0
- package/element-test-full.txt +0 -0
- package/index.d.ts +114 -14
- package/package.json +28 -8
- package/scripts/lint.js +17 -0
- package/scripts/prepublishOnly.js +15 -6
- package/scripts/prepush.js +25 -7
- package/src/announcer/announcer.js +54 -6
- package/src/announcer/speechSynthesis.js +156 -37
- package/src/application.js +98 -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 +65 -8
- package/src/components/index.js +0 -2
- package/src/constants.js +17 -0
- package/src/engine.js +17 -0
- package/src/engines/L3/element.js +101 -7
- package/src/engines/L3/fontLoader.js +17 -0
- package/src/engines/L3/index.js +17 -0
- package/src/engines/L3/launch.js +4 -1
- package/src/engines/L3/shaderLoader.js +17 -0
- package/src/engines/index.js +17 -0
- 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/helpers/fetchJson.js +4 -6
- package/src/launch.js +1 -0
- package/src/lib/codegenerator/generator.js +55 -9
- 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 +113 -28
- package/src/lib/shaders/shaders.js +2 -1
- package/src/lib/symbols.js +19 -0
- package/src/lib/utils.js +17 -0
- package/src/plugin.js +17 -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/localCookie.js +4 -6
- 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/inject-dev-config.js +17 -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,11 @@ export default () =>
|
|
|
131
144
|
map: undefined,
|
|
132
145
|
frame: undefined,
|
|
133
146
|
color: undefined,
|
|
147
|
+
rounded: undefined,
|
|
148
|
+
border: undefined,
|
|
149
|
+
shadow: undefined,
|
|
150
|
+
'@loaded': undefined,
|
|
151
|
+
'@error': undefined,
|
|
134
152
|
},
|
|
135
153
|
state() {
|
|
136
154
|
return {
|
|
@@ -139,6 +157,33 @@ export default () =>
|
|
|
139
157
|
}
|
|
140
158
|
},
|
|
141
159
|
|
|
160
|
+
hooks: {
|
|
161
|
+
ready() {
|
|
162
|
+
const loaded = this['@loaded']
|
|
163
|
+
if (loaded && typeof loaded === 'function') {
|
|
164
|
+
const cb = (payload) => loaded({ w: payload?.w, h: payload?.h }, this[symbols.wrapper])
|
|
165
|
+
this._loadedCb = cb
|
|
166
|
+
if (this.spriteTexture !== undefined && this.spriteTexture !== null) {
|
|
167
|
+
this.spriteTexture.on('loaded', cb)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const error = this['@error']
|
|
171
|
+
if (error && typeof error === 'function') {
|
|
172
|
+
const cb = (payload) => error(payload, this[symbols.wrapper])
|
|
173
|
+
this._failedCb = cb
|
|
174
|
+
if (this.spriteTexture !== undefined && this.spriteTexture !== null) {
|
|
175
|
+
this.spriteTexture.on('failed', cb)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
destroy() {
|
|
180
|
+
if (this.spriteTexture !== undefined && this.spriteTexture !== null) {
|
|
181
|
+
if (this._loadedCb) this.spriteTexture.off('loaded', this._loadedCb)
|
|
182
|
+
if (this._failedCb) this.spriteTexture.off('failed', this._failedCb)
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
|
|
142
187
|
computed: {
|
|
143
188
|
texture() {
|
|
144
189
|
// If no image - nothing to render
|
|
@@ -158,24 +203,36 @@ export default () =>
|
|
|
158
203
|
this.spriteTexture === null ||
|
|
159
204
|
this.currentSrc !== this.image
|
|
160
205
|
) {
|
|
206
|
+
const prevTexture = this.spriteTexture
|
|
207
|
+
if (prevTexture !== undefined && prevTexture !== null) {
|
|
208
|
+
if (this._loadedCb) prevTexture.off('loaded', this._loadedCb)
|
|
209
|
+
if (this._failedCb) prevTexture.off('failed', this._failedCb)
|
|
210
|
+
}
|
|
161
211
|
this.spriteTexture = renderer.createTexture('ImageTexture', {
|
|
162
212
|
src: this.image,
|
|
163
213
|
})
|
|
164
214
|
this.currentSrc = this.image
|
|
215
|
+
if (this._loadedCb) this.spriteTexture.on('loaded', this._loadedCb)
|
|
216
|
+
if (this._failedCb) this.spriteTexture.on('failed', this._failedCb)
|
|
165
217
|
}
|
|
166
218
|
|
|
167
219
|
// Resolve frame data from sprite map
|
|
168
220
|
let options = null
|
|
169
221
|
if (
|
|
170
|
-
this.map !== undefined &&
|
|
171
222
|
this.map !== null &&
|
|
172
|
-
this.
|
|
173
|
-
this.frame !== null
|
|
223
|
+
this.map !== undefined &&
|
|
224
|
+
this.frame !== null &&
|
|
225
|
+
this.frame !== undefined
|
|
174
226
|
) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
227
|
+
if (
|
|
228
|
+
this.map.frames !== null &&
|
|
229
|
+
this.map.frames !== undefined &&
|
|
230
|
+
this.frame in this.map.frames
|
|
231
|
+
) {
|
|
232
|
+
options = Object.assign({}, this.map.defaults || {}, this.map.frames[this.frame])
|
|
233
|
+
} else if (this.frame in this.map) {
|
|
234
|
+
options = this.map[this.frame]
|
|
235
|
+
}
|
|
179
236
|
}
|
|
180
237
|
|
|
181
238
|
// 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
|
})
|
package/src/constants.js
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
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
|
+
|
|
1
18
|
export const DEFAULT_HOLD_TIMEOUT_MS = 50
|
|
2
19
|
|
|
3
20
|
export const DEFAULT_KEYMAP = {
|
package/src/engine.js
CHANGED
|
@@ -1 +1,18 @@
|
|
|
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
|
+
|
|
1
18
|
export { L3 as default } from './engines/index.js'
|
|
@@ -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
|
})
|
|
@@ -1,3 +1,20 @@
|
|
|
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
|
+
|
|
1
18
|
import Settings from '../../settings.js'
|
|
2
19
|
import { renderer } from './launch.js'
|
|
3
20
|
|