Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85712891
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/services/theme_data/pleromafe.t3.js b/src/services/theme_data/pleromafe.t3.js
index b7b125731f..8d8e19cd3e 100644
--- a/src/services/theme_data/pleromafe.t3.js
+++ b/src/services/theme_data/pleromafe.t3.js
@@ -1,32 +1,40 @@
export const sampleRules = [
{
component: 'Underlay',
// variant: 'normal',
// state: 'normal'
directives: {
background: '#000000',
opacity: 0.2
}
},
{
component: 'Panel',
directives: {
background: '#FFFFFF',
opacity: 0.9
}
},
{
component: 'PanelHeader',
directives: {
background: '#000000',
opacity: 0.9
}
},
{
component: 'Button',
directives: {
- background: '#808080',
- opacity: 0.5
+ background: '#000000',
+ opacity: 0.8
+ }
+ },
+ {
+ component: 'Button',
+ state: ['hover'],
+ directives: {
+ background: '#FF00FF',
+ opacity: 0.9
}
}
]
diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js
index d65d535274..2ef5e17fd2 100644
--- a/src/services/theme_data/theme_data_3.service.js
+++ b/src/services/theme_data/theme_data_3.service.js
@@ -1,198 +1,202 @@
import { convert } from 'chromatism'
import { alphaBlend, getTextColor, rgba2css } from '../color_convert/color_convert.js'
import Underlay from 'src/components/underlay.style.js'
import Panel from 'src/components/panel.style.js'
import PanelHeader from 'src/components/panel_header.style.js'
import Button from 'src/components/button.style.js'
import Text from 'src/components/text.style.js'
import Icon from 'src/components/icon.style.js'
const root = Underlay
const components = {
Underlay,
Panel,
PanelHeader,
Button,
Text,
Icon
}
// This gives you an array of arrays of all possible unique (i.e. order-insensitive) combinations
export const getAllPossibleCombinations = (array) => {
const combos = [array.map(x => [x])]
for (let comboSize = 2; comboSize <= array.length; comboSize++) {
const previous = combos[combos.length - 1]
const selfSet = new Set()
const newCombos = previous.map(self => {
self.forEach(x => selfSet.add(x))
const nonSelf = array.filter(x => !selfSet.has(x))
return nonSelf.map(x => [...self, x])
})
const flatCombos = newCombos.reduce((acc, x) => [...acc, ...x], [])
combos.push(flatCombos)
}
return combos.reduce((acc, x) => [...acc, ...x], [])
}
export const ruleToSelector = (rule) => {
const component = components[rule.component]
const { states, variants, selector } = component
const applicableStates = ((rule.state || []).filter(x => x !== 'normal')).map(state => states[state])
const applicableVariantName = (rule.variant || 'normal')
let applicableVariant = ''
if (applicableVariantName !== 'normal') {
applicableVariant = variants[applicableVariantName]
}
const selectors = [selector, applicableVariant, ...applicableStates]
.toSorted((a, b) => {
if (a.startsWith(':')) return 1
else return -1
})
.join('')
if (rule.parent) {
return ruleToSelector(rule.parent) + ' ' + selectors
}
return selectors
}
export const init = (ruleset) => {
const rootName = root.name
const rules = []
const rulesByComponent = {}
const addRule = (rule) => {
rules.push(rule)
rulesByComponent[rule.component] = rulesByComponent[rule.component] || []
rulesByComponent[rule.component].push(rule)
}
const findRules = (combination) => rule => {
if (combination.component !== rule.component) return false
if (Object.prototype.hasOwnProperty.call(rule, 'variant')) {
if (combination.variant !== rule.variant) return false
} else {
if (combination.variant !== 'normal') return false
}
if (Object.prototype.hasOwnProperty.call(rule, 'state')) {
const ruleStatesSet = new Set(['normal', ...(rule.state || [])])
- return combination.state.every(state => ruleStatesSet.has(state))
+ const combinationSet = new Set(['normal', ...combination.state])
+ const setsAreEqual = combination.state.every(state => ruleStatesSet.has(state)) &&
+ [...ruleStatesSet].every(state => combinationSet.has(state))
+ return setsAreEqual
} else {
if (combination.state.length !== 1 || combination.state[0] !== 'normal') return false
return true
}
}
const findLowerLevelRule = (parent, filter = () => true) => {
let lowerLevelComponent = null
let currentParent = parent
while (currentParent) {
const rulesParent = ruleset.filter(findRules(currentParent, true))
+ rulesParent > 1 && console.log('OOPS')
lowerLevelComponent = rulesParent[rulesParent.length - 1]
currentParent = currentParent.parent
if (lowerLevelComponent && filter(lowerLevelComponent)) currentParent = null
}
return filter(lowerLevelComponent) ? lowerLevelComponent : null
}
const processInnerComponent = (component, parent) => {
const {
validInnerComponents = [],
states: originalStates = {},
variants: originalVariants = {},
name
} = component
const states = { normal: '', ...originalStates }
const variants = { normal: '', ...originalVariants }
const innerComponents = validInnerComponents.map(name => components[name])
const stateCombinations = getAllPossibleCombinations(Object.keys(states))
const stateVariantCombination = Object.keys(variants).map(variant => {
return stateCombinations.map(state => ({ variant, state }))
}).reduce((acc, x) => [...acc, ...x], [])
const VIRTUAL_COMPONENTS = new Set(['Text', 'Link', 'Icon'])
stateVariantCombination.forEach(combination => {
const existingRules = ruleset.filter(findRules({ component: component.name, ...combination }))
const lastRule = existingRules[existingRules.length - 1]
if (existingRules.length !== 0) {
const { directives } = lastRule
const rgb = convert(directives.background).rgb
// TODO: DEFAULT TEXT COLOR
const bg = findLowerLevelRule(parent)?.cache.background || convert('#FFFFFF').rgb
if (!lastRule.cache?.background) {
const blend = directives.opacity < 1 ? alphaBlend(rgb, directives.opacity, bg) : rgb
lastRule.cache = lastRule.cache || {}
lastRule.cache.background = blend
addRule(lastRule)
}
} else {
if (VIRTUAL_COMPONENTS.has(component.name)) {
const selector = component.name + ruleToSelector({ component: component.name, ...combination })
const lowerLevel = findLowerLevelRule(parent, (r) => {
if (components[r.component].validInnerComponents.indexOf(component.name) < 0) return false
if (r.cache?.background === undefined) return false
if (r.cache.textDefined) {
return !r.cache.textDefined[selector]
}
return true
})
if (!lowerLevel) return
lowerLevel.cache.textDefined = lowerLevel.cache.textDefined || {}
lowerLevel.cache.textDefined[selector] = true
addRule({
parent,
component: component.name,
...combination,
directives: {
// TODO: DEFAULT TEXT COLOR
textColor: getTextColor(convert(lowerLevel.cache.background).rgb, convert('#FFFFFF').rgb, component.name === 'Link'),
// Debug: lets you see what it think background color should be
background: convert(lowerLevel.cache.background).hex
}
})
}
}
innerComponents.forEach(innerComponent => processInnerComponent(innerComponent, { parent, component: name, ...combination }))
})
}
processInnerComponent(components[rootName])
// console.info(rules.map(x => [
// (parent?.component || 'root') + ' -> ' + x.component,
// // 'Cached background:' + convert(bg).hex,
// // 'Color: ' + convert(x.directives.background).hex + ' A:' + x.directives.opacity,
// JSON.stringify(x.directives)
// // '=> Blend: ' + convert(x.cache.background).hex
// ].join(' ')))
return {
raw: rules,
css: rules.map(rule => {
const header = ruleToSelector(rule) + ' {'
const footer = '}'
const directives = Object.entries(rule.directives).map(([k, v]) => {
switch (k) {
case 'background': return 'background-color: ' + rgba2css({ ...convert(v).rgb, a: rule.directives.opacity ?? 1 })
case 'textColor': return 'color: ' + rgba2css({ ...convert(v).rgb, a: rule.directives.opacity ?? 1 })
default: return ''
}
}).filter(x => x).map(x => ' ' + x).join(';\n')
return [header, directives, footer].join('\n')
})
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Sep 19, 1:23 PM (21 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1764947
Default Alt Text
(8 KB)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline
Log In to Comment