Merge branch 'appearance-tab' into shigusegubu-themes3
This commit is contained in:
commit
a4ab8e065a
17 changed files with 614 additions and 279 deletions
|
|
@ -159,3 +159,15 @@ export const getCssRules = (rules, debug) => rules.map(rule => {
|
|||
footer
|
||||
].join('\n')
|
||||
}).filter(x => x)
|
||||
|
||||
export const getScopedVersion = (rules, newScope) => {
|
||||
return rules.map(x => {
|
||||
if (x.startsWith('html')) {
|
||||
return x.replace('html', newScope)
|
||||
} else if (x.startsWith('#content')) {
|
||||
return x.replace('#content', newScope)
|
||||
} else {
|
||||
return newScope + ' > ' + x
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,23 @@ export const getAllPossibleCombinations = (array) => {
|
|||
return combos.reduce((acc, x) => [...acc, ...x], [])
|
||||
}
|
||||
|
||||
// Converts rule, parents and their criteria into a CSS (or path if ignoreOutOfTreeSelector == true) selector
|
||||
/**
|
||||
* Converts rule, parents and their criteria into a CSS (or path if ignoreOutOfTreeSelector == true)
|
||||
* selector.
|
||||
*
|
||||
* "path" here refers to "fake" selector that cannot be actually used in UI but is used for internal
|
||||
* purposes
|
||||
*
|
||||
* @param {Object} components - object containing all components definitions
|
||||
*
|
||||
* @returns {Function}
|
||||
* @param {Object} rule - rule in question to convert to CSS selector
|
||||
* @param {boolean} ignoreOutOfTreeSelector - wthether to ignore aformentioned field in
|
||||
* component definition and use selector
|
||||
* @param {boolean} isParent - (mostly) internal argument used when recursing
|
||||
*
|
||||
* @returns {String} CSS selector (or path)
|
||||
*/
|
||||
export const genericRuleToSelector = components => (rule, ignoreOutOfTreeSelector, isParent) => {
|
||||
if (!rule && !isParent) return null
|
||||
const component = components[rule.component]
|
||||
|
|
@ -79,6 +95,17 @@ export const genericRuleToSelector = components => (rule, ignoreOutOfTreeSelecto
|
|||
return selectors.trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if combination matches
|
||||
*
|
||||
* @param {Object} criteria - criteria to match against
|
||||
* @param {Object} subject - rule/combination to check match
|
||||
* @param {boolean} strict - strict checking:
|
||||
* By default every variant and state inherits from "normal" state/variant
|
||||
* so when checking if combination matches, it WILL match against "normal"
|
||||
* state/variant. In strict mode inheritance is ignored an "normal" does
|
||||
* not match
|
||||
*/
|
||||
export const combinationsMatch = (criteria, subject, strict) => {
|
||||
if (criteria.component !== subject.component) return false
|
||||
|
||||
|
|
@ -101,6 +128,15 @@ export const combinationsMatch = (criteria, subject, strict) => {
|
|||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for rule that matches `criteria` in set of rules
|
||||
* meant to be used in a ruleset.filter() function
|
||||
*
|
||||
* @param {Object} criteria - criteria to search for
|
||||
* @param {boolean} strict - whether search strictly or not (see combinationsMatch)
|
||||
*
|
||||
* @return function that returns true/false if subject matches
|
||||
*/
|
||||
export const findRules = (criteria, strict) => subject => {
|
||||
// If we searching for "general" rules - ignore "specific" ones
|
||||
if (criteria.parent === null && !!subject.parent) return false
|
||||
|
|
@ -125,6 +161,7 @@ export const findRules = (criteria, strict) => subject => {
|
|||
return true
|
||||
}
|
||||
|
||||
// Pre-fills 'normal' state/variant if missing
|
||||
export const normalizeCombination = rule => {
|
||||
rule.variant = rule.variant ?? 'normal'
|
||||
rule.state = [...new Set(['normal', ...(rule.state || [])])]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ export const basePaletteKeys = new Set([
|
|||
'cBlue',
|
||||
'cRed',
|
||||
'cGreen',
|
||||
'cOrange'
|
||||
'cOrange',
|
||||
|
||||
'wallpaper'
|
||||
])
|
||||
|
||||
export const fontsKeys = new Set([
|
||||
|
|
|
|||
|
|
@ -149,11 +149,30 @@ const ruleToSelector = genericRuleToSelector(components)
|
|||
|
||||
export const getEngineChecksum = () => engineChecksum
|
||||
|
||||
/**
|
||||
* Initializes and compiles the theme according to the ruleset
|
||||
*
|
||||
* @param {Object[]} inputRuleset - set of rules to compile theme against. Acts as an override to
|
||||
* component default rulesets
|
||||
* @param {string} ultimateBackgroundColor - Color that will be the "final" background for
|
||||
* calculating contrast ratios and making text automatically accessible. Really used for cases when
|
||||
* stuff is transparent.
|
||||
* @param {boolean} debug - print out debug information in console, mostly just performance stuff
|
||||
* @param {boolean} liteMode - use validInnerComponentsLite instead of validInnerComponents, meant to
|
||||
* generatate theme previews and such that need to be compiled faster and don't require a lot of other
|
||||
* components present in "normal" mode
|
||||
* @param {boolean} onlyNormalState - only use components 'normal' states, meant for generating theme
|
||||
* previews since states are the biggest factor for compilation time and are completely unnecessary
|
||||
* when previewing multiple themes at same time
|
||||
* @param {string} rootComponentName - [UNTESTED] which component to start from, meant for previewing a
|
||||
* part of the theme (i.e. just the button) for themes 3 editor.
|
||||
*/
|
||||
export const init = ({
|
||||
inputRuleset,
|
||||
ultimateBackgroundColor,
|
||||
debug = false,
|
||||
liteMode = false,
|
||||
onlyNormalState = false,
|
||||
rootComponentName = 'Root'
|
||||
}) => {
|
||||
if (!inputRuleset) throw new Error('Ruleset is null or undefined!')
|
||||
|
|
@ -402,11 +421,16 @@ export const init = ({
|
|||
const processInnerComponent = (component, parent) => {
|
||||
const combinations = []
|
||||
const {
|
||||
validInnerComponents = [],
|
||||
states: originalStates = {},
|
||||
variants: originalVariants = {}
|
||||
} = component
|
||||
|
||||
const validInnerComponents = (
|
||||
liteMode
|
||||
? (component.validInnerComponentsLite || component.validInnerComponents)
|
||||
: component.validInnerComponents
|
||||
) || []
|
||||
|
||||
// Normalizing states and variants to always include "normal"
|
||||
const states = { normal: '', ...originalStates }
|
||||
const variants = { normal: '', ...originalVariants }
|
||||
|
|
@ -418,22 +442,26 @@ export const init = ({
|
|||
|
||||
// Optimization: we only really need combinations without "normal" because all states implicitly have it
|
||||
const permutationStateKeys = Object.keys(states).filter(s => s !== 'normal')
|
||||
const stateCombinations = [
|
||||
['normal'],
|
||||
...getAllPossibleCombinations(permutationStateKeys)
|
||||
.map(combination => ['normal', ...combination])
|
||||
.filter(combo => {
|
||||
// Optimization: filter out some hard-coded combinations that don't make sense
|
||||
if (combo.indexOf('disabled') >= 0) {
|
||||
return !(
|
||||
combo.indexOf('hover') >= 0 ||
|
||||
combo.indexOf('focused') >= 0 ||
|
||||
combo.indexOf('pressed') >= 0
|
||||
)
|
||||
}
|
||||
return true
|
||||
})
|
||||
]
|
||||
const stateCombinations = onlyNormalState
|
||||
? [
|
||||
['normal']
|
||||
]
|
||||
: [
|
||||
['normal'],
|
||||
...getAllPossibleCombinations(permutationStateKeys)
|
||||
.map(combination => ['normal', ...combination])
|
||||
.filter(combo => {
|
||||
// Optimization: filter out some hard-coded combinations that don't make sense
|
||||
if (combo.indexOf('disabled') >= 0) {
|
||||
return !(
|
||||
combo.indexOf('hover') >= 0 ||
|
||||
combo.indexOf('focused') >= 0 ||
|
||||
combo.indexOf('pressed') >= 0
|
||||
)
|
||||
}
|
||||
return true
|
||||
})
|
||||
]
|
||||
|
||||
const stateVariantCombination = Object.keys(variants).map(variant => {
|
||||
return stateCombinations.map(state => ({ variant, state }))
|
||||
|
|
@ -460,7 +488,9 @@ export const init = ({
|
|||
const t0 = performance.now()
|
||||
const combinations = processInnerComponent(components[rootComponentName] ?? components.Root)
|
||||
const t1 = performance.now()
|
||||
console.debug('Tree traveral took ' + (t1 - t0) + ' ms')
|
||||
if (debug) {
|
||||
console.debug('Tree traveral took ' + (t1 - t0) + ' ms')
|
||||
}
|
||||
|
||||
const result = combinations.map((combination) => {
|
||||
if (combination.lazy) {
|
||||
|
|
@ -470,7 +500,9 @@ export const init = ({
|
|||
}
|
||||
}).filter(x => x)
|
||||
const t2 = performance.now()
|
||||
console.debug('Eager processing took ' + (t2 - t1) + ' ms')
|
||||
if (debug) {
|
||||
console.debug('Eager processing took ' + (t2 - t1) + ' ms')
|
||||
}
|
||||
|
||||
return {
|
||||
lazy: result.filter(x => typeof x === 'function'),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue