refactor style setter to separate theme generation from theme application

This commit is contained in:
Henry Jameson 2024-04-03 22:42:34 +03:00
parent 2382810823
commit dd4867d8de

View File

@ -6,7 +6,13 @@ import { getCssRules } from '../theme_data/css_utils.js'
import { defaultState } from '../../modules/config.js' import { defaultState } from '../../modules/config.js'
import { chunk } from 'lodash' import { chunk } from 'lodash'
export const applyTheme = async (input) => { export const generateTheme = async (input, callbacks) => {
const {
onNewRule = (rule) => {},
onLazyFinished = () => {},
onEagerFinished = () => {}
} = callbacks
let extraRules let extraRules
if (input.themeFileVersion === 1) { if (input.themeFileVersion === 1) {
extraRules = convertTheme2To3(input) extraRules = convertTheme2To3(input)
@ -17,11 +23,6 @@ export const applyTheme = async (input) => {
// Assuming that "worst case scenario background" is panel background since it's the most likely one // Assuming that "worst case scenario background" is panel background since it's the most likely one
const themes3 = init(extraRules, extraRules[0].directives['--bg'].split('|')[1].trim()) const themes3 = init(extraRules, extraRules[0].directives['--bg'].split('|')[1].trim())
const body = document.body
const styleSheet = new CSSStyleSheet()
document.adoptedStyleSheets = [styleSheet]
body.classList.add('hidden')
getCssRules(themes3.eager, themes3.staticVars).forEach(rule => { getCssRules(themes3.eager, themes3.staticVars).forEach(rule => {
// Hacks to support multiple selectors on same component // Hacks to support multiple selectors on same component
@ -37,13 +38,12 @@ export const applyTheme = async (input) => {
parts[1], parts[1],
'}' '}'
].join('') ].join('')
styleSheet.insertRule(newRule, 'index-max') onNewRule(newRule)
} else { } else {
styleSheet.insertRule(rule, 'index-max') onNewRule(rule)
} }
}) })
onEagerFinished()
body.classList.remove('hidden')
// Optimization - instead of processing all lazy rules in one go, process them in small chunks // Optimization - instead of processing all lazy rules in one go, process them in small chunks
// so that UI can do other things and be somewhat responsive while less important rules are being // so that UI can do other things and be somewhat responsive while less important rules are being
@ -67,9 +67,9 @@ export const applyTheme = async (input) => {
parts[1], parts[1],
'}' '}'
].join('') ].join('')
styleSheet.insertRule(newRule, 'index-max') onNewRule(newRule)
} else { } else {
styleSheet.insertRule(rule, 'index-max') onNewRule(rule)
} }
}) })
// const t1 = performance.now() // const t1 = performance.now()
@ -78,10 +78,34 @@ export const applyTheme = async (input) => {
counter += 1 counter += 1
if (counter < chunks.length) { if (counter < chunks.length) {
setTimeout(processChunk, 0) setTimeout(processChunk, 0)
} else {
onLazyFinished()
} }
}) })
} }
setTimeout(processChunk, 0)
return { lazyProcessFunc: processChunk }
}
export const applyTheme = async (input) => {
const body = document.body
body.classList.add('hidden')
const styleSheet = new CSSStyleSheet()
document.adoptedStyleSheets = [styleSheet]
const { lazyProcessFunc } = await generateTheme(
input,
{
onNewRule (rule) {
styleSheet.insertRule(rule, 'index-max')
}
}
)
body.classList.remove('hidden')
setTimeout(lazyProcessFunc, 0)
return Promise.resolve() return Promise.resolve()
} }