@lightningjs/blits 0.5.6 → 0.5.8
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 +14 -0
- package/boilerplate/package.json +1 -1
- package/package.json +1 -1
- package/src/component.js +3 -2
- package/src/components/RouterView.js +5 -0
- package/src/element.js +218 -179
- package/src/launch.d.ts +6 -1
- package/src/lib/reactivity/reactive.js +19 -11
- package/src/lib/setup/base.js +8 -12
- package/src/router/router.js +14 -1
- package/src/router.js +0 -72
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
# v0.5.8
|
|
4
|
+
|
|
5
|
+
_15 dec 2023_
|
|
6
|
+
|
|
7
|
+
- Internal refactor of the `Element`
|
|
8
|
+
|
|
9
|
+
# v0.5.7
|
|
10
|
+
|
|
11
|
+
_13 dec 2023_
|
|
12
|
+
|
|
13
|
+
- Added history and backhandling to the router
|
|
14
|
+
- Linked effects directly to the available shaders exposed by the L3 renderer (starting 0.6.0)
|
|
15
|
+
- Added setting `reactivityMode` to control whether `Proxy` (default) or `defineProperty` is used to trigger reactive side effects
|
|
16
|
+
|
|
3
17
|
# v0.5.6
|
|
4
18
|
|
|
5
19
|
_11 dec 2023_
|
package/boilerplate/package.json
CHANGED
package/package.json
CHANGED
package/src/component.js
CHANGED
|
@@ -35,6 +35,7 @@ import setupWatch from './lib/setup/watch.js'
|
|
|
35
35
|
import { effect } from './lib/reactivity/effect.js'
|
|
36
36
|
import { Log } from './lib/log.js'
|
|
37
37
|
|
|
38
|
+
import Settings from './settings.js'
|
|
38
39
|
import symbols from './lib/symbols.js'
|
|
39
40
|
|
|
40
41
|
const stage = {
|
|
@@ -142,7 +143,7 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
142
143
|
configurable: false,
|
|
143
144
|
},
|
|
144
145
|
[symbols.props]: {
|
|
145
|
-
value: reactive(opts.props || {}),
|
|
146
|
+
value: reactive(opts.props || {}, Settings.get('reactivityMode')),
|
|
146
147
|
writable: false,
|
|
147
148
|
enumerable: false,
|
|
148
149
|
configurable: false,
|
|
@@ -157,7 +158,7 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
157
158
|
})
|
|
158
159
|
|
|
159
160
|
Object.defineProperty(this, symbols.state, {
|
|
160
|
-
value: reactive(this[symbols.originalState]),
|
|
161
|
+
value: reactive(this[symbols.originalState], Settings.get('reactivityMode')),
|
|
161
162
|
writable: false,
|
|
162
163
|
enumerable: false,
|
|
163
164
|
configurable: false,
|
package/src/element.js
CHANGED
|
@@ -33,172 +33,212 @@ const parseToObject = (str) => {
|
|
|
33
33
|
return JSON.parse(str.replace(/'/g, '"').replace(/([\w-_]+)\s*:/g, '"$1":'))
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
const parsePercentage = function (v, base) {
|
|
37
|
+
if (typeof v === 'string' && v.endsWith('%')) {
|
|
38
|
+
return this.element.node._parent[base] * (parseFloat(v) / 100)
|
|
39
|
+
}
|
|
40
|
+
return v
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const unpackTransition = (obj) => {
|
|
44
|
+
if (typeof obj === 'object' && obj.constructor === Object) {
|
|
45
|
+
if ('value' in obj) {
|
|
46
|
+
return obj.value
|
|
47
|
+
} else if ('transition' in obj) {
|
|
48
|
+
return unpackTransition(obj.transition)
|
|
48
49
|
}
|
|
50
|
+
}
|
|
51
|
+
return obj
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const Props = {
|
|
55
|
+
set parent(v) {
|
|
56
|
+
this._props.parent = v === 'root' ? renderer.root : v.node
|
|
57
|
+
this._set.add('parent')
|
|
49
58
|
},
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (props.parent === 'root') {
|
|
62
|
-
props.parent = renderer.root
|
|
63
|
-
} else {
|
|
64
|
-
props.parent = props.parent.node
|
|
65
|
-
}
|
|
59
|
+
set rotation(v) {
|
|
60
|
+
this._props.rotation = v * (Math.PI / 180)
|
|
61
|
+
this._set.add('rotation')
|
|
62
|
+
},
|
|
63
|
+
set w(v) {
|
|
64
|
+
this._props.width = parsePercentage.call(this, v, 'width')
|
|
65
|
+
this._set.add('width')
|
|
66
|
+
},
|
|
67
|
+
set width(v) {
|
|
68
|
+
this._props.width = parsePercentage.call(this, v, 'width')
|
|
69
|
+
this._set.add('width')
|
|
66
70
|
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
set h(v) {
|
|
72
|
+
this._props.height = parsePercentage.call(this, v, 'height')
|
|
73
|
+
this._set.add('height')
|
|
74
|
+
},
|
|
75
|
+
set height(v) {
|
|
76
|
+
this._props.height = parsePercentage.call(this, v, 'height')
|
|
77
|
+
this._set.add('height')
|
|
78
|
+
},
|
|
79
|
+
set x(v) {
|
|
80
|
+
this._props.x = parsePercentage.call(this, v, 'width')
|
|
81
|
+
this._set.add('x')
|
|
82
|
+
},
|
|
83
|
+
set y(v) {
|
|
84
|
+
this._props.y = parsePercentage.call(this, v, 'height')
|
|
85
|
+
this._set.add('y')
|
|
86
|
+
},
|
|
87
|
+
set z(v) {
|
|
88
|
+
this._props.zIndex = v
|
|
89
|
+
this._set.add('zIndex')
|
|
90
|
+
},
|
|
91
|
+
set zIndex(v) {
|
|
92
|
+
this._props.zIndex = v
|
|
93
|
+
this._set.add('zIndex')
|
|
94
|
+
},
|
|
95
|
+
set color(v) {
|
|
96
|
+
if (typeof v === 'object' || (isObjectString(v) && (v = parseToObject(v)))) {
|
|
72
97
|
const map = {
|
|
73
98
|
top: 'colorTop',
|
|
74
99
|
bottom: 'colorBottom',
|
|
75
100
|
left: 'colorLeft',
|
|
76
101
|
right: 'colorRight',
|
|
77
102
|
}
|
|
78
|
-
|
|
79
|
-
|
|
103
|
+
this._props.color = 0
|
|
104
|
+
Object.entries(v).forEach((color) => {
|
|
105
|
+
this._props[map[color[0]]] = colors.normalize(color[1])
|
|
106
|
+
this._set.add(map[color[0]])
|
|
80
107
|
})
|
|
81
|
-
delete props.color
|
|
82
108
|
} else {
|
|
83
|
-
|
|
109
|
+
this._props.color = colors.normalize(v)
|
|
84
110
|
}
|
|
111
|
+
this._set.add('color')
|
|
85
112
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
x: 'width',
|
|
91
|
-
h: 'height',
|
|
92
|
-
height: 'height',
|
|
93
|
-
y: 'height',
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const base = map[prop]
|
|
97
|
-
if (base) {
|
|
98
|
-
props[prop] = this.node._parent[base] * (parseFloat(props[prop]) / 100)
|
|
113
|
+
set src(v) {
|
|
114
|
+
this._props.src = v
|
|
115
|
+
if (!this._set.has('color')) {
|
|
116
|
+
this._props.color = 0xffffffff
|
|
99
117
|
}
|
|
118
|
+
this._set.add('src')
|
|
100
119
|
},
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
120
|
+
set texture(v) {
|
|
121
|
+
this._props.texture = v
|
|
122
|
+
this._set.add('texture')
|
|
123
|
+
},
|
|
124
|
+
set mount(v) {
|
|
125
|
+
if (typeof v === 'object' || (isObjectString(v) && (v = parseToObject(v)))) {
|
|
126
|
+
if (v.x) {
|
|
127
|
+
this._props.mountX = v.x
|
|
128
|
+
this._set.add('mountX')
|
|
109
129
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
130
|
+
if (v.y) {
|
|
131
|
+
this._props.mountY = v.y
|
|
132
|
+
this._set.add('mountY')
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
this._props.mountX = this._props.mountY = v
|
|
136
|
+
this._set.add('mountX')
|
|
137
|
+
this._set.add('mountY')
|
|
114
138
|
}
|
|
115
139
|
},
|
|
116
|
-
pivot(
|
|
117
|
-
if (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const map = {
|
|
122
|
-
x: 'pivotX',
|
|
123
|
-
y: 'pivotY',
|
|
140
|
+
set pivot(v) {
|
|
141
|
+
if (typeof v === 'object' || (isObjectString(v) && (v = parseToObject(v)))) {
|
|
142
|
+
if (v.x) {
|
|
143
|
+
this._set.add('pivotX')
|
|
144
|
+
this._props.pivotX = v.x
|
|
124
145
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
146
|
+
if (v.y) {
|
|
147
|
+
this._set.add('pivotY')
|
|
148
|
+
this._props.pivotY = v.y
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
this._props.pivotX = this._props.pivotY = v
|
|
152
|
+
this._set.add('pivotX')
|
|
153
|
+
this._set.add('pivotY')
|
|
129
154
|
}
|
|
130
155
|
},
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
156
|
+
set scale(v) {
|
|
157
|
+
if (typeof v === 'object' || (isObjectString(v) && (v = parseToObject(v)))) {
|
|
158
|
+
if (v.x) this._props.scaleX = v.x
|
|
159
|
+
if (v.y) this._props.scaleY = v.y
|
|
160
|
+
} else {
|
|
161
|
+
this._props.scale = v
|
|
162
|
+
}
|
|
163
|
+
this._set.add('scale')
|
|
134
164
|
},
|
|
135
|
-
|
|
136
|
-
|
|
165
|
+
set show(v) {
|
|
166
|
+
this.alpha = v ? 1 : 0
|
|
137
167
|
},
|
|
138
|
-
|
|
139
|
-
|
|
168
|
+
set alpha(v) {
|
|
169
|
+
this._props.alpha = v
|
|
170
|
+
this._set.add('alpha')
|
|
140
171
|
},
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
props.color = 'src' in props || 'texture' in props ? '0xffffffff' : '0x00000000'
|
|
144
|
-
}
|
|
172
|
+
set text(v) {
|
|
173
|
+
this._props.text = v !== undefined ? v.toString() : ''
|
|
145
174
|
},
|
|
146
|
-
effects(
|
|
147
|
-
|
|
148
|
-
effects:
|
|
175
|
+
set effects(v) {
|
|
176
|
+
this._props.shader = renderer.createShader('DynamicShader', {
|
|
177
|
+
effects: v.map((eff) => {
|
|
149
178
|
if (eff.props && eff.props.color) {
|
|
150
179
|
eff.props.color = colors.normalize(eff.props.color)
|
|
151
180
|
}
|
|
152
181
|
return eff
|
|
153
182
|
}),
|
|
154
183
|
})
|
|
155
|
-
|
|
156
|
-
delete props.effects
|
|
184
|
+
this._set.add('effects')
|
|
157
185
|
},
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
props.color = 0xffffffff
|
|
161
|
-
}
|
|
186
|
+
set fontFamily(v) {
|
|
187
|
+
this._props.fontFamily = v
|
|
162
188
|
},
|
|
163
|
-
|
|
164
|
-
this.
|
|
189
|
+
set fontSize(v) {
|
|
190
|
+
this._props.fontSize = v
|
|
165
191
|
},
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
192
|
+
set wordWrap(v) {
|
|
193
|
+
this._props.width = v
|
|
194
|
+
},
|
|
195
|
+
set contain(v) {
|
|
196
|
+
this._props.contain = v
|
|
197
|
+
},
|
|
198
|
+
set maxLines(v) {
|
|
199
|
+
this.height = v * this.element.node.fontSize
|
|
200
|
+
},
|
|
201
|
+
set letterSpacing(v) {
|
|
202
|
+
this._props.letterSpacing = v
|
|
203
|
+
},
|
|
204
|
+
set textAlign(v) {
|
|
205
|
+
this._props.textAlign = v
|
|
171
206
|
},
|
|
172
207
|
}
|
|
173
208
|
|
|
174
209
|
const Element = {
|
|
175
|
-
defaults: {
|
|
176
|
-
rotation: 0,
|
|
177
|
-
},
|
|
210
|
+
defaults: {},
|
|
178
211
|
populate(data) {
|
|
179
212
|
const props = {
|
|
180
213
|
...this.defaults,
|
|
181
214
|
...this.config,
|
|
182
215
|
...data,
|
|
183
216
|
}
|
|
217
|
+
|
|
184
218
|
this.initData = data
|
|
185
219
|
|
|
186
220
|
if (props[symbols.isSlot]) {
|
|
187
221
|
this[symbols.isSlot] = true
|
|
188
222
|
}
|
|
189
223
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
224
|
+
this.props.element = this
|
|
225
|
+
|
|
226
|
+
for (const [prop, value] of Object.entries(props)) {
|
|
227
|
+
const descriptor = Object.getOwnPropertyDescriptor(Props, prop)
|
|
228
|
+
if (descriptor && descriptor.set) {
|
|
229
|
+
this.props[prop] = unpackTransition(value)
|
|
195
230
|
}
|
|
196
|
-
|
|
197
|
-
})
|
|
231
|
+
}
|
|
198
232
|
|
|
199
|
-
|
|
233
|
+
// correct for default white nodes
|
|
234
|
+
if (!this.props._set.has('color')) {
|
|
235
|
+
this.props._props.color =
|
|
236
|
+
this.props._set.has('src') || this.props._set.has('texture') ? 0xffffffff : 0
|
|
237
|
+
}
|
|
200
238
|
|
|
201
|
-
this.node = props.__textnode
|
|
239
|
+
this.node = props.__textnode
|
|
240
|
+
? renderer.createTextNode(this.props._props)
|
|
241
|
+
: renderer.createNode(this.props._props)
|
|
202
242
|
|
|
203
243
|
if (props['@loaded']) {
|
|
204
244
|
this.node.on('loaded', (el, { type, dimensions }) => {
|
|
@@ -213,43 +253,24 @@ const Element = {
|
|
|
213
253
|
}
|
|
214
254
|
},
|
|
215
255
|
set(prop, value) {
|
|
216
|
-
|
|
217
|
-
this.animate(prop, value.transition)
|
|
218
|
-
} else {
|
|
219
|
-
const props = {}
|
|
220
|
-
if (prop !== 'texture') {
|
|
221
|
-
props[prop] = transformations.unpackTransition(value)
|
|
222
|
-
} else {
|
|
223
|
-
props[prop] = value
|
|
224
|
-
}
|
|
256
|
+
const propsSet = new Set(this.props._set)
|
|
225
257
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
transformations[prop](props, this.setProperties, this)
|
|
229
|
-
}
|
|
258
|
+
this.props._props = {}
|
|
259
|
+
this.props[prop] = unpackTransition(value)
|
|
230
260
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
this.node[
|
|
236
|
-
}
|
|
261
|
+
for (const [p, v] of Object.entries(this.props._props)) {
|
|
262
|
+
if (isTransition(value) && propsSet.has(p)) {
|
|
263
|
+
return this.animate(p, v, value.transition)
|
|
264
|
+
} else {
|
|
265
|
+
this.node[p] = v
|
|
266
|
+
}
|
|
237
267
|
}
|
|
238
|
-
this.setProperties.indexOf(prop) === -1 && this.setProperties.push(prop)
|
|
239
268
|
},
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
},
|
|
244
|
-
get nodeId() {
|
|
245
|
-
return this.node && this.node.id
|
|
246
|
-
},
|
|
247
|
-
get ref() {
|
|
248
|
-
return this.initData.ref || null
|
|
249
|
-
},
|
|
250
|
-
animate(prop, value) {
|
|
269
|
+
animate(prop, value, transition) {
|
|
270
|
+
if (this.node[prop] === value) return Promise.resolve()
|
|
271
|
+
// check if a transition is already schedule or running on the same prop
|
|
251
272
|
if (this.scheduledTransitions[prop]) {
|
|
252
|
-
clearTimeout(this.scheduledTransitions[prop].timeout)
|
|
273
|
+
// clearTimeout(this.scheduledTransitions[prop].timeout)
|
|
253
274
|
if (this.scheduledTransitions[prop].f.state === 'running') {
|
|
254
275
|
this.scheduledTransitions[prop].f.pause()
|
|
255
276
|
// fastforward to final value
|
|
@@ -258,55 +279,73 @@ const Element = {
|
|
|
258
279
|
}
|
|
259
280
|
|
|
260
281
|
const props = {}
|
|
261
|
-
props[prop] =
|
|
262
|
-
|
|
263
|
-
transformations.remap(props)
|
|
282
|
+
props[prop] = value
|
|
264
283
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
284
|
+
// construct animate function
|
|
285
|
+
const f = this.node.animate(props, {
|
|
286
|
+
duration:
|
|
287
|
+
typeof transition === 'object'
|
|
288
|
+
? 'duration' in transition
|
|
289
|
+
? transition.duration
|
|
290
|
+
: 300
|
|
291
|
+
: 300,
|
|
292
|
+
easing:
|
|
293
|
+
typeof transition === 'object'
|
|
294
|
+
? 'function' in transition
|
|
295
|
+
? transition.function
|
|
296
|
+
: 'ease'
|
|
297
|
+
: 'ease',
|
|
298
|
+
})
|
|
268
299
|
|
|
269
|
-
//
|
|
270
|
-
|
|
300
|
+
// schedule transition
|
|
301
|
+
return new Promise((resolve) => {
|
|
302
|
+
this.scheduledTransitions[prop] = {
|
|
303
|
+
v: props[prop],
|
|
304
|
+
f,
|
|
305
|
+
timeout: setTimeout(() => {
|
|
306
|
+
// fire transition start callback if specified
|
|
307
|
+
transition.start &&
|
|
308
|
+
typeof transition.start === 'function' &&
|
|
309
|
+
transition.start.call(this.component, this, prop, props[prop])
|
|
271
310
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
if (this.node[prop] !== props[prop]) {
|
|
277
|
-
const f = this.node.animate(props, {
|
|
278
|
-
duration: typeof value === 'object' ? ('duration' in value ? value.duration : 300) : 300,
|
|
279
|
-
easing:
|
|
280
|
-
typeof value === 'object' ? ('function' in value ? value.function : 'ease') : 'ease',
|
|
281
|
-
})
|
|
282
|
-
return new Promise((resolve) => {
|
|
283
|
-
this.scheduledTransitions[prop] = {
|
|
284
|
-
v: props[prop],
|
|
285
|
-
f,
|
|
286
|
-
timeout: setTimeout(() => {
|
|
287
|
-
value.start &&
|
|
288
|
-
typeof value.start === 'function' &&
|
|
289
|
-
value.start.call(this.component, this, prop, props[prop])
|
|
311
|
+
// start the animation
|
|
312
|
+
try {
|
|
290
313
|
f.start()
|
|
291
314
|
.waitUntilStopped()
|
|
292
315
|
.then(() => delete this.scheduledTransitions[prop])
|
|
293
316
|
.then(() => {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
317
|
+
// fire transition end callback if specified
|
|
318
|
+
transition.end &&
|
|
319
|
+
typeof transition.end === 'function' &&
|
|
320
|
+
transition.end.call(this.component, this, prop, props[prop])
|
|
297
321
|
})
|
|
298
322
|
.then(resolve)
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
323
|
+
} catch (e) {
|
|
324
|
+
Log.error(e)
|
|
325
|
+
}
|
|
326
|
+
}, transition.delay || 0),
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
},
|
|
330
|
+
delete() {
|
|
331
|
+
Log.debug('Deleting Node', this.nodeId)
|
|
332
|
+
Object.values(this.scheduledTransitions).forEach((scheduledTransition) => {
|
|
333
|
+
clearTimeout(scheduledTransition.timeout)
|
|
334
|
+
})
|
|
335
|
+
this.node.parent = null
|
|
336
|
+
},
|
|
337
|
+
get nodeId() {
|
|
338
|
+
return this.node && this.node.id
|
|
339
|
+
},
|
|
340
|
+
get ref() {
|
|
341
|
+
return this.initData.ref || null
|
|
303
342
|
},
|
|
304
343
|
}
|
|
305
344
|
|
|
306
345
|
export default (config, component) =>
|
|
307
346
|
Object.assign(Object.create(Element), {
|
|
347
|
+
props: Object.assign(Object.create(Props), { _props: {}, _set: new Set() }),
|
|
308
348
|
node: null,
|
|
309
|
-
setProperties: [],
|
|
310
349
|
scheduledTransitions: {},
|
|
311
350
|
initData: {},
|
|
312
351
|
config,
|
package/src/launch.d.ts
CHANGED
|
@@ -55,6 +55,7 @@ type Font = WebFont | SdfFont
|
|
|
55
55
|
|
|
56
56
|
export type DebugLevel = 0 | 1 | 2
|
|
57
57
|
export type LogTypes = 'info' | 'warn' | 'error' | 'debug'
|
|
58
|
+
export type ReactivityModes = 'Proxy' | 'defineProperty'
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
61
|
* Settings
|
|
@@ -90,7 +91,11 @@ export interface Settings {
|
|
|
90
91
|
/**
|
|
91
92
|
* Custom keymapping
|
|
92
93
|
*/
|
|
93
|
-
keymap?: object
|
|
94
|
+
keymap?: object,
|
|
95
|
+
/**
|
|
96
|
+
* Mode of reactivity (`Proxy` or `defineProperty`)
|
|
97
|
+
*/
|
|
98
|
+
reactivityMode?: ReactivityModes
|
|
94
99
|
}
|
|
95
100
|
|
|
96
101
|
/**
|
|
@@ -27,8 +27,12 @@ const arrayMethods = [
|
|
|
27
27
|
'shift',
|
|
28
28
|
'splice',
|
|
29
29
|
'unshift',
|
|
30
|
+
'sort',
|
|
31
|
+
'reverse',
|
|
30
32
|
]
|
|
31
33
|
|
|
34
|
+
const arrayPatchMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']
|
|
35
|
+
|
|
32
36
|
const proxyMap = new WeakMap()
|
|
33
37
|
|
|
34
38
|
const reactiveProxy = (target) => {
|
|
@@ -79,17 +83,22 @@ const reactiveDefineProperty = (target) => {
|
|
|
79
83
|
Object.keys(target).forEach((key) => {
|
|
80
84
|
let internalValue = target[key]
|
|
81
85
|
|
|
82
|
-
if (
|
|
83
|
-
target[key]
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
if (target[key] !== null && typeof target[key] === 'object') {
|
|
87
|
+
if (Object.getPrototypeOf(target[key]) === Object.prototype) {
|
|
88
|
+
return reactiveDefineProperty(target[key])
|
|
89
|
+
} else if (Array.isArray(target[key])) {
|
|
90
|
+
for (let i = 0; i < arrayPatchMethods.length - 1; i++) {
|
|
91
|
+
target[key][arrayPatchMethods[i]] = function (v) {
|
|
92
|
+
Array.prototype[arrayPatchMethods[i]].call(this, v)
|
|
93
|
+
trigger(target, key)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
Object.defineProperty(target, key, {
|
|
91
|
-
enumerable: true,
|
|
92
|
-
configurable: true,
|
|
100
|
+
enumerable: true,
|
|
101
|
+
configurable: true,
|
|
93
102
|
get() {
|
|
94
103
|
track(target, key)
|
|
95
104
|
return internalValue
|
|
@@ -107,9 +116,8 @@ const reactiveDefineProperty = (target) => {
|
|
|
107
116
|
return target
|
|
108
117
|
}
|
|
109
118
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return type === 'proxy' ? reactiveProxy(target) : reactiveDefineProperty(target)
|
|
119
|
+
export const reactive = (target, mode = 'Proxy') => {
|
|
120
|
+
return mode === 'defineProperty' ? reactiveDefineProperty(target) : reactiveProxy(target)
|
|
113
121
|
}
|
|
114
122
|
|
|
115
123
|
export const memo = (raw) => {
|
package/src/lib/setup/base.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { renderer } from '../../launch.js'
|
|
19
19
|
import Focus from '../../focus.js'
|
|
20
|
-
import { to, currentRoute, navigating } from '../../router/router.js'
|
|
20
|
+
import { to, currentRoute, navigating, back } from '../../router/router.js'
|
|
21
21
|
import Image from '../../components/Image.js'
|
|
22
22
|
import Circle from '../../components/Circle.js'
|
|
23
23
|
import RouterView from '../../components/RouterView.js'
|
|
@@ -29,16 +29,8 @@ import symbols from '../symbols.js'
|
|
|
29
29
|
|
|
30
30
|
import { trigger } from '../reactivity/effect.js'
|
|
31
31
|
|
|
32
|
-
const
|
|
33
|
-
radius: 'radius',
|
|
32
|
+
const shaderAlias = {
|
|
34
33
|
rounded: 'radius',
|
|
35
|
-
border: 'border',
|
|
36
|
-
borderTop: 'borderTop',
|
|
37
|
-
borderBottom: 'borderBottom',
|
|
38
|
-
borderLeft: 'borderLeft',
|
|
39
|
-
borderRight: 'borderRight',
|
|
40
|
-
grayScale: 'grayscale',
|
|
41
|
-
glitch: 'glitch',
|
|
42
34
|
}
|
|
43
35
|
|
|
44
36
|
export default (component) => {
|
|
@@ -101,9 +93,12 @@ export default (component) => {
|
|
|
101
93
|
},
|
|
102
94
|
shader: {
|
|
103
95
|
value: function (type, args) {
|
|
104
|
-
|
|
96
|
+
const target = shaderAlias[type] || type
|
|
97
|
+
const shaders = renderer.driver.stage.shManager.getRegisteredEffects()
|
|
98
|
+
|
|
99
|
+
if (target in shaders) {
|
|
105
100
|
return {
|
|
106
|
-
type:
|
|
101
|
+
type: target,
|
|
107
102
|
props: args,
|
|
108
103
|
}
|
|
109
104
|
} else {
|
|
@@ -117,6 +112,7 @@ export default (component) => {
|
|
|
117
112
|
$router: {
|
|
118
113
|
value: {
|
|
119
114
|
to,
|
|
115
|
+
back,
|
|
120
116
|
get currentRoute() {
|
|
121
117
|
return currentRoute
|
|
122
118
|
},
|
package/src/router/router.js
CHANGED
|
@@ -26,6 +26,7 @@ export let currentRoute
|
|
|
26
26
|
export let navigating = false
|
|
27
27
|
|
|
28
28
|
const cacheMap = new WeakMap()
|
|
29
|
+
const history = []
|
|
29
30
|
|
|
30
31
|
export const getHash = () => {
|
|
31
32
|
return (document.location.hash || '/').replace(/^#/, '')
|
|
@@ -49,6 +50,7 @@ export const navigate = async function () {
|
|
|
49
50
|
const route = matchHash(hash, this.parent[symbols.routes])
|
|
50
51
|
|
|
51
52
|
if (route) {
|
|
53
|
+
if (history[history.length - 1] !== hash) history.push(hash)
|
|
52
54
|
// apply default transition if none specified
|
|
53
55
|
if (!('transition' in route)) {
|
|
54
56
|
route.transition = fadeInFadeOutTransition
|
|
@@ -163,7 +165,7 @@ const removeView = async (route, view, transition) => {
|
|
|
163
165
|
|
|
164
166
|
const setOrAnimate = (node, transition, shouldAnimate = true) => {
|
|
165
167
|
return shouldAnimate
|
|
166
|
-
? node.animate(transition.prop, transition)
|
|
168
|
+
? node.animate(transition.prop, transition.value, transition)
|
|
167
169
|
: node.set(transition.prop, transition.value)
|
|
168
170
|
}
|
|
169
171
|
|
|
@@ -171,7 +173,18 @@ export const to = (location) => {
|
|
|
171
173
|
window.location.hash = `#${location}`
|
|
172
174
|
}
|
|
173
175
|
|
|
176
|
+
export const back = () => {
|
|
177
|
+
if (history.length > 1) {
|
|
178
|
+
to(history[history.length - 2])
|
|
179
|
+
history.splice(-2, 2)
|
|
180
|
+
return true
|
|
181
|
+
} else {
|
|
182
|
+
return false
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
174
186
|
export default {
|
|
175
187
|
navigate,
|
|
176
188
|
to,
|
|
189
|
+
back,
|
|
177
190
|
}
|
package/src/router.js
DELETED
|
@@ -1,72 +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 { Log } from './lib/log.js'
|
|
19
|
-
|
|
20
|
-
import symbols from './lib/symbols.js'
|
|
21
|
-
|
|
22
|
-
export const getHash = () => {
|
|
23
|
-
return (document.location.hash || '/').replace(/^#/, '')
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const matchHash = (path, routes = []) => {
|
|
27
|
-
const route = routes
|
|
28
|
-
.filter((r) => {
|
|
29
|
-
return r.path === path
|
|
30
|
-
})
|
|
31
|
-
.pop()
|
|
32
|
-
return route
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const navigate = function () {
|
|
36
|
-
if (this.parent[symbols.routes]) {
|
|
37
|
-
const hash = getHash()
|
|
38
|
-
const route = matchHash(hash, this.parent[symbols.routes])
|
|
39
|
-
if (route) {
|
|
40
|
-
if (this[symbols.currentView]) {
|
|
41
|
-
for (let i = 0; i < this[symbols.currentView][symbols.children].length - 1; i++) {
|
|
42
|
-
if (
|
|
43
|
-
this[symbols.currentView][symbols.children][i] &&
|
|
44
|
-
this[symbols.currentView][symbols.children][i].destroy
|
|
45
|
-
) {
|
|
46
|
-
this[symbols.currentView][symbols.children][i].destroy()
|
|
47
|
-
this[symbols.currentView][symbols.children][i] = null
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
this[symbols.currentView].destroy()
|
|
51
|
-
this[symbols.currentView] = null
|
|
52
|
-
}
|
|
53
|
-
this[symbols.children][1] = this[symbols.currentView] = route.component(
|
|
54
|
-
this[symbols.props],
|
|
55
|
-
this[symbols.children][0],
|
|
56
|
-
this
|
|
57
|
-
)
|
|
58
|
-
this[symbols.currentView].focus()
|
|
59
|
-
} else {
|
|
60
|
-
Log.error(`Route ${hash} not found`)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export const to = (location) => {
|
|
66
|
-
window.location.hash = `#${location}`
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export default {
|
|
70
|
-
navigate,
|
|
71
|
-
to,
|
|
72
|
-
}
|