@lightningjs/blits 2.0.0-beta.1 → 2.0.0-beta.11
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 +169 -41
- 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
|
@@ -35,10 +35,12 @@ const findMatchingBrace = (text, startPos) => {
|
|
|
35
35
|
// Skip comments when not in strings
|
|
36
36
|
else if (!inString && char === '/' && text[position + 1] === '/') {
|
|
37
37
|
// Skip line comment
|
|
38
|
-
|
|
38
|
+
const nextNewline = text.indexOf('\n', position + 2)
|
|
39
|
+
position = nextNewline === -1 ? text.length - 1 : nextNewline
|
|
39
40
|
} else if (!inString && char === '/' && text[position + 1] === '*') {
|
|
40
41
|
// Skip block comment
|
|
41
|
-
|
|
42
|
+
const end = text.indexOf('*/', position + 2)
|
|
43
|
+
position = end === -1 ? text.length - 1 : end + 1
|
|
42
44
|
}
|
|
43
45
|
// Count braces only outside strings and comments
|
|
44
46
|
else if (!inString) {
|
|
@@ -60,6 +62,44 @@ const findComputedFunctionEnd = (computedObj, openingBracePos) => {
|
|
|
60
62
|
return findMatchingBrace(computedObj, openingBracePos)
|
|
61
63
|
}
|
|
62
64
|
|
|
65
|
+
// Skip whitespace + commas + comments (line and block) starting from `pos`, return next code position.
|
|
66
|
+
const skipNonCode = (text, pos) => {
|
|
67
|
+
let p = pos
|
|
68
|
+
while (p < text.length) {
|
|
69
|
+
const c = text[p]
|
|
70
|
+
|
|
71
|
+
// whitespace
|
|
72
|
+
if (c === ' ' || c === '\t' || c === '\n' || c === '\r') {
|
|
73
|
+
p++
|
|
74
|
+
continue
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// separators between object members
|
|
78
|
+
if (c === ',') {
|
|
79
|
+
p++
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// line comment
|
|
84
|
+
if (c === '/' && text[p + 1] === '/') {
|
|
85
|
+
const nextNewline = text.indexOf('\n', p + 2)
|
|
86
|
+
p = nextNewline === -1 ? text.length : nextNewline + 1
|
|
87
|
+
continue
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// block comment
|
|
91
|
+
if (c === '/' && text[p + 1] === '*') {
|
|
92
|
+
const end = text.indexOf('*/', p + 2)
|
|
93
|
+
p = end === -1 ? text.length : end + 2
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return p
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return p
|
|
101
|
+
}
|
|
102
|
+
|
|
63
103
|
export default (code) => {
|
|
64
104
|
// Find component declarations
|
|
65
105
|
const componentRegex =
|
|
@@ -83,6 +123,8 @@ export default (code) => {
|
|
|
83
123
|
|
|
84
124
|
if (computedEnd !== -1) {
|
|
85
125
|
const computedObj = configObject.substring(computedStart, computedEnd)
|
|
126
|
+
const computedBlockStart = computedKeywordMatch.index
|
|
127
|
+
const computedBlockEnd = computedEnd
|
|
86
128
|
|
|
87
129
|
// Process each computed property
|
|
88
130
|
const computedProps = []
|
|
@@ -93,15 +135,20 @@ export default (code) => {
|
|
|
93
135
|
// using cursor-based parsing gives better accuracy
|
|
94
136
|
while (currentPos < computedObj.length - 1) {
|
|
95
137
|
// -1 to exclude the closing brace
|
|
96
|
-
//
|
|
97
|
-
|
|
138
|
+
// Skip whitespace/comments so we don't match commented-out computed functions
|
|
139
|
+
currentPos = skipNonCode(computedObj, currentPos)
|
|
140
|
+
if (currentPos >= computedObj.length - 1) break
|
|
141
|
+
|
|
142
|
+
// Find the next function name (computed properties are `name() { ... }`)
|
|
143
|
+
const functionNameMatch = /^(\w+)\s*\(\)\s*/.exec(computedObj.substring(currentPos))
|
|
98
144
|
if (!functionNameMatch) break
|
|
99
145
|
|
|
100
146
|
const funcName = functionNameMatch[1]
|
|
101
|
-
const funcNamePos = currentPos
|
|
147
|
+
const funcNamePos = currentPos
|
|
102
148
|
|
|
103
149
|
// Find opening brace for this function
|
|
104
|
-
const
|
|
150
|
+
const afterSignaturePos = funcNamePos + functionNameMatch[0].length
|
|
151
|
+
const openingBracePos = computedObj.indexOf('{', afterSignaturePos)
|
|
105
152
|
if (openingBracePos === -1) break
|
|
106
153
|
|
|
107
154
|
// Find closing brace for individual computed function
|
|
@@ -133,21 +180,22 @@ export default (code) => {
|
|
|
133
180
|
}
|
|
134
181
|
|
|
135
182
|
// Store the original computed object for later replacement
|
|
136
|
-
const originalComputedObj = configObject.substring(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
)
|
|
183
|
+
const originalComputedObj = configObject.substring(computedBlockStart, computedBlockEnd)
|
|
184
|
+
const computedObjOffsetInOriginal = computedStart - computedBlockStart
|
|
185
|
+
const computedObjEndInOriginal = computedObjOffsetInOriginal + computedObj.length
|
|
140
186
|
|
|
141
187
|
let modifiedComputedObj = originalComputedObj
|
|
142
188
|
let hasChanges = false
|
|
143
189
|
|
|
190
|
+
const replacements = []
|
|
191
|
+
|
|
144
192
|
for (const prop of computedProps) {
|
|
145
193
|
const thisRefs = extractThisReferences(prop.body)
|
|
146
194
|
|
|
147
195
|
if (thisRefs.size > 0) {
|
|
148
196
|
// Skip if already modified
|
|
149
197
|
if (
|
|
150
|
-
prop.body.includes(commentText) ||
|
|
198
|
+
prop.body.includes(commentText.trim()) ||
|
|
151
199
|
Array.from(thisRefs).some((ref) => prop.body.startsWith(ref))
|
|
152
200
|
) {
|
|
153
201
|
continue
|
|
@@ -181,13 +229,31 @@ export default (code) => {
|
|
|
181
229
|
prop.fullText.substring(0, openBraceIndex).match(/^(\s*)/)[0] +
|
|
182
230
|
'}'
|
|
183
231
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
232
|
+
replacements.push({
|
|
233
|
+
start: prop.startPos,
|
|
234
|
+
end: prop.endPos,
|
|
235
|
+
text: modifiedPropText,
|
|
236
|
+
})
|
|
187
237
|
}
|
|
188
238
|
}
|
|
189
239
|
}
|
|
190
240
|
|
|
241
|
+
if (replacements.length > 0) {
|
|
242
|
+
let modifiedComputedInner = computedObj
|
|
243
|
+
|
|
244
|
+
replacements.sort((a, b) => b.start - a.start)
|
|
245
|
+
for (const r of replacements) {
|
|
246
|
+
modifiedComputedInner =
|
|
247
|
+
modifiedComputedInner.slice(0, r.start) + r.text + modifiedComputedInner.slice(r.end)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
modifiedComputedObj =
|
|
251
|
+
originalComputedObj.slice(0, computedObjOffsetInOriginal) +
|
|
252
|
+
modifiedComputedInner +
|
|
253
|
+
originalComputedObj.slice(computedObjEndInOriginal)
|
|
254
|
+
hasChanges = true
|
|
255
|
+
}
|
|
256
|
+
|
|
191
257
|
if (hasChanges) {
|
|
192
258
|
// Store the modification of the entire computed object
|
|
193
259
|
modifications.push({
|
|
@@ -213,7 +279,12 @@ export default (code) => {
|
|
|
213
279
|
modifiedCode = modifiedCode.replace(mod.original, mod.replacement)
|
|
214
280
|
}
|
|
215
281
|
|
|
216
|
-
|
|
282
|
+
// Returning code without a source map
|
|
283
|
+
// Vite will automatically chain this with the next plugin's source map (preCompiler)
|
|
284
|
+
return {
|
|
285
|
+
code: modifiedCode,
|
|
286
|
+
map: { mappings: '' },
|
|
287
|
+
}
|
|
217
288
|
}
|
|
218
289
|
|
|
219
290
|
return null
|
|
@@ -222,24 +293,38 @@ export default (code) => {
|
|
|
222
293
|
const extractThisReferences = (funcBody) => {
|
|
223
294
|
const thisRefs = new Set()
|
|
224
295
|
|
|
225
|
-
//
|
|
226
|
-
const refRegex = /this
|
|
296
|
+
// Match full property chains, including optional chaining
|
|
297
|
+
const refRegex = /this(?:\.[$\w]+|\?\.[$\w]+)+/g
|
|
227
298
|
let refMatch
|
|
228
299
|
|
|
229
300
|
while ((refMatch = refRegex.exec(funcBody)) !== null) {
|
|
230
301
|
const fullRef = refMatch[0]
|
|
231
302
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
303
|
+
const segmentRegex = /(\??\.)([$\w]+)/g
|
|
304
|
+
let segMatch
|
|
305
|
+
let lastValidRef = 'this'
|
|
306
|
+
|
|
307
|
+
while ((segMatch = segmentRegex.exec(fullRef.substring(4))) !== null) {
|
|
308
|
+
const candidate = 'this' + fullRef.substring(4, 4 + segMatch.index + segMatch[0].length)
|
|
309
|
+
const afterCandidate = funcBody.substring(refMatch.index + candidate.length)
|
|
310
|
+
if (afterCandidate.match(/^\s*\(/)) {
|
|
311
|
+
break
|
|
312
|
+
}
|
|
313
|
+
lastValidRef = candidate
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (lastValidRef !== 'this') {
|
|
317
|
+
thisRefs.add(lastValidRef)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Remove shorter prefixes when a longer chain already covers them
|
|
322
|
+
for (const ref of [...thisRefs]) {
|
|
323
|
+
for (const other of thisRefs) {
|
|
324
|
+
if (other !== ref && other.startsWith(ref + '.')) {
|
|
325
|
+
thisRefs.delete(ref)
|
|
326
|
+
break
|
|
327
|
+
}
|
|
243
328
|
}
|
|
244
329
|
}
|
|
245
330
|
|
|
@@ -139,11 +139,12 @@ export default {
|
|
|
139
139
|
return v
|
|
140
140
|
}
|
|
141
141
|
if (typeof v === 'string') {
|
|
142
|
-
return colors.normalize(v)
|
|
142
|
+
return colors.normalize(v, v)
|
|
143
143
|
}
|
|
144
144
|
if (Array.isArray(v) === true) {
|
|
145
145
|
return v.map((i) => this.parseProp(i))
|
|
146
146
|
}
|
|
147
|
+
return v
|
|
147
148
|
},
|
|
148
149
|
parseProps(v) {
|
|
149
150
|
if (typeof v === 'string') {
|
package/src/lib/symbols.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
|
/**
|
|
2
19
|
* Symbol registry for internal framework properties and generated code.
|
|
3
20
|
*
|
|
@@ -17,6 +34,7 @@
|
|
|
17
34
|
* @property {symbol} inputEvents
|
|
18
35
|
* @property {symbol} internalEvent
|
|
19
36
|
* @property {symbol} intervals
|
|
37
|
+
* @property {symbol} debounces
|
|
20
38
|
* @property {symbol} isProxy
|
|
21
39
|
* @property {symbol} launched
|
|
22
40
|
* @property {symbol} level
|
|
@@ -73,6 +91,7 @@ export default {
|
|
|
73
91
|
inputEvents: Symbol('inputEvents'),
|
|
74
92
|
internalEvent: Symbol('internalEvent'),
|
|
75
93
|
intervals: Symbol('intervals'),
|
|
94
|
+
debounces: Symbol('debounces'),
|
|
76
95
|
isProxy: Symbol('isProxy'),
|
|
77
96
|
launched: Symbol('launched'),
|
|
78
97
|
level: Symbol('level'),
|
package/src/lib/utils.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
|
/**
|
|
2
19
|
* A mapping of common screen resolution names to their scale factors relative to 1080p (Full HD).
|
|
3
20
|
*
|
package/src/plugin.js
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 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 log from './plugins/log.js'
|
|
2
19
|
|
|
3
20
|
export const plugins = {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 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 type AppStatePlugin<TState extends Record<string, unknown> = Record<string, unknown>> = TState
|
|
19
|
+
|
|
20
|
+
declare const appState: {
|
|
21
|
+
readonly name: 'appState'
|
|
22
|
+
plugin: <TState extends Record<string, unknown>>(state?: TState) => AppStatePlugin<TState>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default appState
|
|
26
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 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 as language } from './language.js'
|
|
19
|
+
export { default as theme } from './theme.js'
|
|
20
|
+
export { default as appState } from './appstate.js'
|
|
21
|
+
export { default as storage } from './storage/storage.js'
|
|
22
|
+
|
|
23
|
+
// Re-export plugin interfaces for convenience
|
|
24
|
+
export type { LanguagePlugin, LanguagePluginOptions } from './language.js'
|
|
25
|
+
export type { ThemePlugin, ThemePluginConfig } from './theme.js'
|
|
26
|
+
export type { StoragePlugin } from './storage/storage.js'
|
|
27
|
+
export type { AppStatePlugin } from './appstate.js'
|
|
28
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 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 interface LanguagePlugin {
|
|
19
|
+
translate(key: string, ...replacements: any[]): string
|
|
20
|
+
readonly language: string
|
|
21
|
+
set(language: string): void
|
|
22
|
+
translations(translationsObject: Record<string, unknown>): void
|
|
23
|
+
load(file: string): Promise<void>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface LanguagePluginOptions {
|
|
27
|
+
file?: string
|
|
28
|
+
language?: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare const language: {
|
|
32
|
+
readonly name: 'language'
|
|
33
|
+
plugin: (options?: LanguagePluginOptions) => LanguagePlugin
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default language
|
|
37
|
+
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Copyright 2019 Metrological
|
|
6
|
-
*
|
|
7
|
-
* Licensed under the Apache License, Version 2.0 (the License);
|
|
2
|
+
* Copyright 2025 Comcast Cable Communications Management, LLC
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
4
|
* you may not use this file except in compliance with the License.
|
|
9
5
|
* You may obtain a copy of the License at
|
|
10
6
|
*
|
|
@@ -15,6 +11,8 @@
|
|
|
15
11
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
12
|
* See the License for the specific language governing permissions and
|
|
17
13
|
* limitations under the License.
|
|
14
|
+
*
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
18
16
|
*/
|
|
19
17
|
|
|
20
18
|
// LocalStorage and Cookie storage library
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 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 interface StoragePlugin {
|
|
19
|
+
get<T = unknown>(key: string): T | null
|
|
20
|
+
set(key: string, value: unknown): boolean
|
|
21
|
+
remove(key: string): void
|
|
22
|
+
clear(): void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare const storage: {
|
|
26
|
+
readonly name: 'storage'
|
|
27
|
+
plugin: () => StoragePlugin
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default storage
|
|
31
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 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 interface ThemePlugin {
|
|
19
|
+
get<T = unknown>(key: string): T | undefined
|
|
20
|
+
get<T>(key: string, fallback: T): T
|
|
21
|
+
/**
|
|
22
|
+
* @deprecated
|
|
23
|
+
* Deprecated: use `$theme.current()` instead
|
|
24
|
+
*/
|
|
25
|
+
set(theme: string): void
|
|
26
|
+
current(theme: string): void
|
|
27
|
+
variant(theme: string): void
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ThemePluginConfig {
|
|
31
|
+
themes?: Record<string, Record<string, unknown>>
|
|
32
|
+
current?: string
|
|
33
|
+
base?: string
|
|
34
|
+
variant?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare const theme: {
|
|
38
|
+
readonly name: 'theme'
|
|
39
|
+
plugin: (config?: ThemePluginConfig | Record<string, unknown>) => ThemePlugin
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default theme
|
|
43
|
+
|
package/src/plugins/theme.js
CHANGED
|
@@ -20,13 +20,17 @@ import { reactive } from '../lib/reactivity/reactive.js'
|
|
|
20
20
|
|
|
21
21
|
import Settings from '../settings.js'
|
|
22
22
|
|
|
23
|
-
const getValueByDotNotation = (obj, base, path) => {
|
|
23
|
+
const getValueByDotNotation = (obj, base, variant, path) => {
|
|
24
24
|
const keys = path.split('.')
|
|
25
25
|
|
|
26
26
|
for (let i = 0; i < keys.length; i++) {
|
|
27
27
|
const key = keys[i]
|
|
28
28
|
|
|
29
|
-
if (
|
|
29
|
+
if (variant !== null && key in variant === true) {
|
|
30
|
+
obj = variant[key]
|
|
31
|
+
variant = variant !== null && key in variant === true ? variant[key] : null
|
|
32
|
+
base = base !== null && key in base === true ? base[key] : null
|
|
33
|
+
} else if (obj !== null && key in obj === true) {
|
|
30
34
|
obj = obj[key]
|
|
31
35
|
base = base !== null && key in base === true ? base[key] : null
|
|
32
36
|
}
|
|
@@ -51,6 +55,7 @@ export default {
|
|
|
51
55
|
const state = reactive(
|
|
52
56
|
{
|
|
53
57
|
current: 'default',
|
|
58
|
+
variant: null,
|
|
54
59
|
},
|
|
55
60
|
Settings.get('reactivityMode'),
|
|
56
61
|
true
|
|
@@ -62,6 +67,7 @@ export default {
|
|
|
62
67
|
themes = config.themes
|
|
63
68
|
state.current = config.current || 'default'
|
|
64
69
|
base = config.base || 'default'
|
|
70
|
+
state.variant = config.variant || null
|
|
65
71
|
} else {
|
|
66
72
|
themes = { default: config }
|
|
67
73
|
}
|
|
@@ -71,8 +77,14 @@ export default {
|
|
|
71
77
|
// reference state.current, to trigger reactive effects for
|
|
72
78
|
// theme get function when current theme is modified
|
|
73
79
|
state.current
|
|
80
|
+
state.variant
|
|
74
81
|
if (themeMap[key] !== undefined) return themeMap[key]
|
|
75
|
-
const value = getValueByDotNotation(
|
|
82
|
+
const value = getValueByDotNotation(
|
|
83
|
+
themes[state.current],
|
|
84
|
+
themes[base] || null,
|
|
85
|
+
themes[state.variant] || null,
|
|
86
|
+
key
|
|
87
|
+
)
|
|
76
88
|
if (value !== undefined) {
|
|
77
89
|
// store the value for next time
|
|
78
90
|
themeMap[key] = value
|
|
@@ -82,6 +94,11 @@ export default {
|
|
|
82
94
|
},
|
|
83
95
|
|
|
84
96
|
set(theme) {
|
|
97
|
+
Log.warn('$theme.set() is deprecated, use $theme.current() instead')
|
|
98
|
+
this.current(theme)
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
current(theme) {
|
|
85
102
|
if (theme in themes) {
|
|
86
103
|
themeMap = {}
|
|
87
104
|
state.current = theme
|
|
@@ -89,6 +106,16 @@ export default {
|
|
|
89
106
|
Log.warn(`Theme ${theme} not found`)
|
|
90
107
|
}
|
|
91
108
|
},
|
|
109
|
+
|
|
110
|
+
variant(theme) {
|
|
111
|
+
if (theme in themes) {
|
|
112
|
+
themeMap = {}
|
|
113
|
+
state.variant = theme
|
|
114
|
+
console.log('change variant', theme)
|
|
115
|
+
} else {
|
|
116
|
+
Log.warn(`Variant ${theme} not found`)
|
|
117
|
+
}
|
|
118
|
+
},
|
|
92
119
|
}
|
|
93
120
|
},
|
|
94
121
|
}
|