@lightningjs/blits 1.9.1 → 1.10.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 +19 -0
- package/docs/built-in/layout.md +8 -0
- package/package.json +4 -3
- package/src/component.js +2 -1
- package/src/components/RouterView.js +5 -2
- package/src/components/RouterView.orig.js +5 -2
- package/src/engines/L3/element.js +35 -11
- package/src/engines/L3/element.test.js +8 -8
- package/src/focus.js +1 -0
- package/src/lib/blitsfileconverter/blitsfileconverter.js +52 -0
- package/vite/blitsFileConverter.js +38 -0
- package/vite/index.js +3 -1
- package/vite/msdfGenerator.js +17 -0
- package/vite/preCompiler.js +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.10.0
|
|
4
|
+
|
|
5
|
+
_8 nov 2024_
|
|
6
|
+
|
|
7
|
+
- Fixed issue with back button not bubbling to App component after last page in router history is popped
|
|
8
|
+
- Added `align-items` attribute to Layout component
|
|
9
|
+
- Fixed issue with watching nested state variables and global state
|
|
10
|
+
- Upgraded to renderer 2.6.2
|
|
11
|
+
- Fixed issue with white background for Elements with falsy src attribute
|
|
12
|
+
- Fixed issue with calling focus on component that already is focussed
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## v1.9.2
|
|
16
|
+
|
|
17
|
+
_5 nov 2024_
|
|
18
|
+
|
|
19
|
+
- Fixed Element related tests
|
|
20
|
+
- Bumped renderer to version 2.6.0
|
|
21
|
+
|
|
3
22
|
## v1.9.1
|
|
4
23
|
|
|
5
24
|
_4 nov 2024_
|
package/docs/built-in/layout.md
CHANGED
|
@@ -37,6 +37,14 @@ In order to align vertically use `<Layout direction="vertical"></Layout>`. And u
|
|
|
37
37
|
|
|
38
38
|
By default the Layout-component places each Element directly besides (or below) the previous one. By adding the `gap`-attribute you can control how much space will be added between each Element or Component. The `gap`-attribute accepts a number in pixels.
|
|
39
39
|
|
|
40
|
+
### Aligning items
|
|
41
|
+
|
|
42
|
+
The layout component positions its children based on the provided direction (`horizontal` or `vertical`). With the `align-items`-attribute you can specify how to align the children on the opposite axis:
|
|
43
|
+
|
|
44
|
+
- `start` (the default value) - aligns the children in the _top_ for horizontal layouts, and on the _left_ for vertical layouts
|
|
45
|
+
- `center` - align the children in the center
|
|
46
|
+
- `end` - aligns the children in the _bottom_ for horizontal layouts, and on the _right_ for vertical layouts
|
|
47
|
+
|
|
40
48
|
### Dynamic dimensions
|
|
41
49
|
|
|
42
50
|
For the Layout component to work properly, the direct children all need to have dimensions (i.e `w` and `h` attributes). The exception here being Text elements.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightningjs/blits",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Blits: The Lightning 3 App Development Framework",
|
|
5
5
|
"bin": "bin/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"./transitions": "./src/router/transitions/index.js",
|
|
10
10
|
"./precompiler": "./src/lib/precompiler/precompiler.js",
|
|
11
11
|
"./plugins": "./src/plugins/index.js",
|
|
12
|
-
"./symbols": "./src/lib/symbols.js"
|
|
12
|
+
"./symbols": "./src/lib/symbols.js",
|
|
13
|
+
"./blitsFileConverter": "./src/lib/blitsfileconverter/blitsfileconverter.js"
|
|
13
14
|
},
|
|
14
15
|
"scripts": {
|
|
15
16
|
"test": "c8 npm run test:run",
|
|
@@ -49,7 +50,7 @@
|
|
|
49
50
|
},
|
|
50
51
|
"dependencies": {
|
|
51
52
|
"@lightningjs/msdf-generator": "^1.1.0",
|
|
52
|
-
"@lightningjs/renderer": "^2.
|
|
53
|
+
"@lightningjs/renderer": "^2.6.2"
|
|
53
54
|
},
|
|
54
55
|
"repository": {
|
|
55
56
|
"type": "git",
|
package/src/component.js
CHANGED
|
@@ -176,6 +176,7 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
176
176
|
for (let i = 0; i < watcherkeysLength; i++) {
|
|
177
177
|
let target = this
|
|
178
178
|
let key = watcherkeys[i]
|
|
179
|
+
const watchKey = key
|
|
179
180
|
// when dot notation used, find the nested target
|
|
180
181
|
if (key.indexOf('.') > -1) {
|
|
181
182
|
const keys = key.split('.')
|
|
@@ -190,7 +191,7 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
190
191
|
effect((force = false) => {
|
|
191
192
|
const newValue = target[key]
|
|
192
193
|
if (old !== newValue || force === true) {
|
|
193
|
-
this[symbols.watchers][
|
|
194
|
+
this[symbols.watchers][watchKey].apply(this, [newValue, old])
|
|
194
195
|
old = newValue
|
|
195
196
|
}
|
|
196
197
|
})
|
|
@@ -24,9 +24,11 @@ import Settings from '../../settings.js'
|
|
|
24
24
|
|
|
25
25
|
const layoutFn = function (config) {
|
|
26
26
|
let offset = 0
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
27
|
+
const position = config.direction === 'vertical' ? 'y' : 'x'
|
|
28
|
+
const oppositePosition = config.direction === 'vertical' ? 'x' : 'y'
|
|
29
|
+
const oppositeMount = config.direction === 'vertical' ? 'mountX' : 'mountY'
|
|
30
|
+
const dimension = config.direction === 'vertical' ? 'height' : 'width'
|
|
31
|
+
const oppositeDimension = config.direction === 'vertical' ? 'width' : 'height'
|
|
30
32
|
|
|
31
33
|
const children = this.children
|
|
32
34
|
const childrenLength = children.length
|
|
@@ -34,11 +36,11 @@ const layoutFn = function (config) {
|
|
|
34
36
|
const gap = config.gap || 0
|
|
35
37
|
for (let i = 0; i < childrenLength; i++) {
|
|
36
38
|
const node = children[i]
|
|
37
|
-
node[
|
|
39
|
+
node[position] = offset
|
|
38
40
|
// todo: temporary text check, due to 1px width of empty text node
|
|
39
|
-
if (
|
|
41
|
+
if (dimension === 'width') {
|
|
40
42
|
offset += node.width + (node.width !== ('text' in node ? 1 : 0) ? gap : 0)
|
|
41
|
-
} else if (
|
|
43
|
+
} else if (dimension === 'height') {
|
|
42
44
|
offset +=
|
|
43
45
|
'text' in node
|
|
44
46
|
? node.width > 1
|
|
@@ -48,11 +50,25 @@ const layoutFn = function (config) {
|
|
|
48
50
|
? node.height + gap
|
|
49
51
|
: 0
|
|
50
52
|
}
|
|
51
|
-
otherDimension = Math.max(otherDimension, node[
|
|
53
|
+
otherDimension = Math.max(otherDimension, node[oppositeDimension])
|
|
52
54
|
}
|
|
53
55
|
// adjust the size of the layout container
|
|
54
|
-
this[
|
|
55
|
-
this[
|
|
56
|
+
this[dimension] = offset - gap
|
|
57
|
+
this[oppositeDimension] = otherDimension
|
|
58
|
+
|
|
59
|
+
const align = {
|
|
60
|
+
start: 0,
|
|
61
|
+
end: 1,
|
|
62
|
+
center: 0.5,
|
|
63
|
+
}[config['align-items'] || 'start']
|
|
64
|
+
|
|
65
|
+
if (align !== 0) {
|
|
66
|
+
for (let i = 0; i < childrenLength; i++) {
|
|
67
|
+
const node = children[i]
|
|
68
|
+
node[oppositePosition] = otherDimension
|
|
69
|
+
node[oppositeMount] = align
|
|
70
|
+
}
|
|
71
|
+
}
|
|
56
72
|
}
|
|
57
73
|
|
|
58
74
|
const isTransition = (value) => {
|
|
@@ -146,7 +162,7 @@ const propsTransformer = {
|
|
|
146
162
|
set src(v) {
|
|
147
163
|
this.props['src'] = v
|
|
148
164
|
if (this.raw['color'] === undefined) {
|
|
149
|
-
this.props['color'] = 0xffffffff
|
|
165
|
+
this.props['color'] = this.props['src'] ? 0xffffffff : 0x00000000
|
|
150
166
|
}
|
|
151
167
|
},
|
|
152
168
|
set texture(v) {
|
|
@@ -225,7 +241,15 @@ const propsTransformer = {
|
|
|
225
241
|
}
|
|
226
242
|
},
|
|
227
243
|
set show(v) {
|
|
228
|
-
|
|
244
|
+
if (v) {
|
|
245
|
+
this.props['alpha'] = 1
|
|
246
|
+
this.props['width'] = this.raw['w'] || this.raw['width']
|
|
247
|
+
this.props['height'] = this.raw['h'] || this.raw['height']
|
|
248
|
+
} else {
|
|
249
|
+
this.props['alpha'] = 0
|
|
250
|
+
this.props['width'] = 0
|
|
251
|
+
this.props['height'] = 0
|
|
252
|
+
}
|
|
229
253
|
},
|
|
230
254
|
set alpha(v) {
|
|
231
255
|
this.props['alpha'] = v
|
|
@@ -101,7 +101,7 @@ test('Element - Set `w` property', (assert) => {
|
|
|
101
101
|
|
|
102
102
|
assert.equal(el.node['width'], 100, 'Node width parameter should be set')
|
|
103
103
|
assert.equal(el.props.props['width'], 100, 'Props width parameter should be set')
|
|
104
|
-
assert.equal(el.props.raw
|
|
104
|
+
assert.equal(el.props.raw['w'], 100, "Props' raw map entry should be added")
|
|
105
105
|
assert.end()
|
|
106
106
|
})
|
|
107
107
|
|
|
@@ -116,7 +116,7 @@ test('Element - Set `mount` property', (assert) => {
|
|
|
116
116
|
assert.equal(el.node['mountY'], 20, 'Node mountY parameter should be set')
|
|
117
117
|
assert.equal(el.props.props['mountX'], 10, 'Props mountX parameter should be set')
|
|
118
118
|
assert.equal(el.props.props['mountY'], 20, 'Props mountY parameter should be set')
|
|
119
|
-
assert.equal(el.props.raw
|
|
119
|
+
assert.equal(el.props.raw['mount'], value, "Props' raw map entry should be added")
|
|
120
120
|
assert.end()
|
|
121
121
|
})
|
|
122
122
|
|
|
@@ -128,7 +128,7 @@ test('Element - Set `color` property', (assert) => {
|
|
|
128
128
|
|
|
129
129
|
assert.equal(el.node['color'], '0xf0ffffff', 'Node color parameter should be set')
|
|
130
130
|
assert.equal(el.props.props['color'], '0xf0ffffff', 'Props color parameter should be set')
|
|
131
|
-
assert.equal(el.props.raw
|
|
131
|
+
assert.equal(el.props.raw['color'], 'azure', "Props' raw map entry should be added")
|
|
132
132
|
assert.end()
|
|
133
133
|
})
|
|
134
134
|
|
|
@@ -141,7 +141,7 @@ test('Element - Set `src` property', (assert) => {
|
|
|
141
141
|
|
|
142
142
|
assert.equal(el.node['src'], value, 'Node src parameter should be set')
|
|
143
143
|
assert.equal(el.props.props['src'], value, 'Props src parameter should be set')
|
|
144
|
-
assert.equal(el.props.raw
|
|
144
|
+
assert.equal(el.props.raw['src'], value, "Props' raw map entry should be added")
|
|
145
145
|
assert.equal(el.props.props['color'], 0xffffffff, 'Props default color parameter should be set')
|
|
146
146
|
assert.end()
|
|
147
147
|
})
|
|
@@ -154,7 +154,7 @@ test('Element - Set `texture` property', (assert) => {
|
|
|
154
154
|
|
|
155
155
|
assert.equal(el.node['texture'], 'foo', 'Node texture parameter should be set')
|
|
156
156
|
assert.equal(el.props.props['texture'], 'foo', 'Props texture parameter should be set')
|
|
157
|
-
assert.equal(el.props.raw
|
|
157
|
+
assert.equal(el.props.raw['texture'], 'foo', "Props' raw map entry should be added")
|
|
158
158
|
assert.equal(el.props.props['color'], 0xffffffff, 'Props default color parameter should be set')
|
|
159
159
|
assert.end()
|
|
160
160
|
})
|
|
@@ -181,7 +181,7 @@ test('Element - Set `fit` property with a string type value', (assert) => {
|
|
|
181
181
|
fitVal,
|
|
182
182
|
'Props textureOptions parameter should be set'
|
|
183
183
|
)
|
|
184
|
-
assert.equal(el.props.raw
|
|
184
|
+
assert.equal(el.props.raw['fit'], fitVal, "Props' raw map entry should be added")
|
|
185
185
|
assert.end()
|
|
186
186
|
})
|
|
187
187
|
|
|
@@ -212,7 +212,7 @@ test('Element - Set `fit` property with an object type value', (assert) => {
|
|
|
212
212
|
1,
|
|
213
213
|
'Node resizeMode "clipY" parameter should be set to correct value'
|
|
214
214
|
)
|
|
215
|
-
assert.equal(el.props.raw
|
|
215
|
+
assert.equal(el.props.raw['fit'], fitVal, "Props' raw map entry should be added")
|
|
216
216
|
assert.end()
|
|
217
217
|
})
|
|
218
218
|
|
|
@@ -243,7 +243,7 @@ test('Element - Set `fit` property with position key as a string type value', (a
|
|
|
243
243
|
1,
|
|
244
244
|
'Node resizeMode "clipY" parameter should be set to correct value'
|
|
245
245
|
)
|
|
246
|
-
assert.equal(el.props.raw
|
|
246
|
+
assert.equal(el.props.raw['fit'], fitVal, "Props' raw map entry should be added")
|
|
247
247
|
assert.end()
|
|
248
248
|
})
|
|
249
249
|
|
package/src/focus.js
CHANGED
|
@@ -38,6 +38,7 @@ export default {
|
|
|
38
38
|
return focusedComponent
|
|
39
39
|
},
|
|
40
40
|
set(component, event) {
|
|
41
|
+
if (component === focusedComponent) return
|
|
41
42
|
clearTimeout(setFocusTimeout)
|
|
42
43
|
focusedComponent && focusedComponent !== component.parent && focusedComponent.unfocus()
|
|
43
44
|
focusChain.reverse().forEach((cmp) => cmp.unfocus())
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
export default (source) => {
|
|
19
|
+
const { template, script } = parseBlitsFile(source)
|
|
20
|
+
return injectTemplate(script, template)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const parseBlitsFile = (source) => {
|
|
24
|
+
const templateMatch = source.match(/<template>([\s\S]*?)<\/template>/)
|
|
25
|
+
const scriptMatch = source.match(/<script(?:\s+lang=["'](?:js|ts)["'])?\s*>([\s\S]*?)<\/script>/)
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
template: templateMatch ? templateMatch[1].trim() : '',
|
|
29
|
+
script: scriptMatch ? scriptMatch[1].trim() : '',
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const injectTemplate = (script, template) => {
|
|
34
|
+
const componentRegex =
|
|
35
|
+
/(Blits\.Component|Component)\s*\(\s*(['"`])(?:(?=(\\?))\3.)*?\2\s*,\s*\{|Blits\.Application\s*\(\s*\{/
|
|
36
|
+
|
|
37
|
+
const match = script.match(componentRegex)
|
|
38
|
+
|
|
39
|
+
if (!match) {
|
|
40
|
+
// we might consider initializing a component if it's not found automatically
|
|
41
|
+
throw new Error(
|
|
42
|
+
'Could not find Blits.Component, Component, or Blits.Application initialization in the script'
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// The insertion point is right after the opening curly brace
|
|
47
|
+
const insertIndex = match.index + match[0].length
|
|
48
|
+
|
|
49
|
+
// Using template literals to preserve multiline strings and escape characters
|
|
50
|
+
const injection = `\n template: \`${template.replace(/`/g, '\\`')}\`,\n`
|
|
51
|
+
return script.slice(0, insertIndex) + injection + script.slice(insertIndex)
|
|
52
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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 blitsfileconverter from '../src/lib/blitsfileconverter/blitsfileconverter.js'
|
|
19
|
+
|
|
20
|
+
export default function blitsFileType() {
|
|
21
|
+
return {
|
|
22
|
+
name: 'vite-plugin-blits-file-type',
|
|
23
|
+
enforce: 'pre',
|
|
24
|
+
transform(src, id) {
|
|
25
|
+
if (id.endsWith('.blits')) {
|
|
26
|
+
try {
|
|
27
|
+
const transformedCode = blitsfileconverter(src)
|
|
28
|
+
return {
|
|
29
|
+
code: transformedCode,
|
|
30
|
+
map: null, // no source map
|
|
31
|
+
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
this.error(error)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
}
|
package/vite/index.js
CHANGED
|
@@ -17,8 +17,10 @@
|
|
|
17
17
|
|
|
18
18
|
import preCompiler from './preCompiler.js'
|
|
19
19
|
import msdfGenerator from './msdfGenerator.js'
|
|
20
|
+
import blitsFileConverter from './blitsFileConverter.js'
|
|
20
21
|
|
|
21
22
|
export { default as preCompiler } from './preCompiler.js'
|
|
22
23
|
export { default as msdfGenerator } from './msdfGenerator.js'
|
|
24
|
+
export { default as blitsFileConverter } from './blitsFileConverter.js'
|
|
23
25
|
|
|
24
|
-
export default [preCompiler(), msdfGenerator()]
|
|
26
|
+
export default [blitsFileConverter(), preCompiler(), msdfGenerator()]
|
package/vite/msdfGenerator.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
|
import path from 'path'
|
|
2
19
|
import * as fs from 'fs'
|
|
3
20
|
import { createHash } from 'crypto'
|
package/vite/preCompiler.js
CHANGED
|
@@ -27,6 +27,13 @@ export default function () {
|
|
|
27
27
|
},
|
|
28
28
|
transform(source, filePath) {
|
|
29
29
|
if (config.blits && config.blits.precompile === false) return source
|
|
30
|
+
|
|
31
|
+
const fileExtension = path.extname(filePath)
|
|
32
|
+
|
|
33
|
+
// we should only precompile .js and .ts files
|
|
34
|
+
if (fileExtension === '.js' || fileExtension === '.ts') {
|
|
35
|
+
return compiler(source, filePath)
|
|
36
|
+
}
|
|
30
37
|
const relativePath = path.relative(process.cwd(), filePath)
|
|
31
38
|
return compiler(source, relativePath)
|
|
32
39
|
},
|