logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git

css_utils.js (5060B)


  1. import { convert } from 'chromatism'
  2. import { hex2rgb, rgba2css } from '../color_convert/color_convert.js'
  3. // This changes what backgrounds are used to "stacked" solid colors so you can see
  4. // what theme engine "thinks" is actual background color is for purposes of text color
  5. // generation and for when --stacked variable is used
  6. const DEBUG = false
  7. export const parseCssShadow = (text) => {
  8. const dimensions = /(\d[a-z]*\s?){2,4}/.exec(text)?.[0]
  9. const inset = /inset/.exec(text)?.[0]
  10. const color = text.replace(dimensions, '').replace(inset, '')
  11. const [x, y, blur = 0, spread = 0] = dimensions.split(/ /).filter(x => x).map(x => x.trim())
  12. const isInset = inset?.trim() === 'inset'
  13. const colorString = color.split(/ /).filter(x => x).map(x => x.trim())[0]
  14. return {
  15. x,
  16. y,
  17. blur,
  18. spread,
  19. inset: isInset,
  20. color: colorString
  21. }
  22. }
  23. export const getCssColorString = (color, alpha = 1) => rgba2css({ ...convert(color).rgb, a: alpha })
  24. export const getCssShadow = (input, usesDropShadow) => {
  25. if (input.length === 0) {
  26. return 'none'
  27. }
  28. return input
  29. .filter(_ => usesDropShadow ? _.inset : _)
  30. .map((shad) => [
  31. shad.x,
  32. shad.y,
  33. shad.blur,
  34. shad.spread
  35. ].map(_ => _ + 'px ').concat([
  36. getCssColorString(shad.color, shad.alpha),
  37. shad.inset ? 'inset' : ''
  38. ]).join(' ')).join(', ')
  39. }
  40. export const getCssShadowFilter = (input) => {
  41. if (input.length === 0) {
  42. return 'none'
  43. }
  44. return input
  45. // drop-shadow doesn't support inset or spread
  46. .filter((shad) => !shad.inset && Number(shad.spread) === 0)
  47. .map((shad) => [
  48. shad.x,
  49. shad.y,
  50. // drop-shadow's blur is twice as strong compared to box-shadow
  51. shad.blur / 2
  52. ].map(_ => _ + 'px').concat([
  53. getCssColorString(shad.color, shad.alpha)
  54. ]).join(' '))
  55. .map(_ => `drop-shadow(${_})`)
  56. .join(' ')
  57. }
  58. export const getCssRules = (rules) => rules.map(rule => {
  59. let selector = rule.selector
  60. if (!selector) {
  61. selector = 'html'
  62. }
  63. const header = selector + ' {'
  64. const footer = '}'
  65. const virtualDirectives = Object.entries(rule.virtualDirectives || {}).map(([k, v]) => {
  66. return ' ' + k + ': ' + v
  67. }).join(';\n')
  68. const directives = Object.entries(rule.directives).map(([k, v]) => {
  69. switch (k) {
  70. case 'roundness': {
  71. return ' ' + [
  72. '--roundness: ' + v + 'px'
  73. ].join(';\n ')
  74. }
  75. case 'shadow': {
  76. return ' ' + [
  77. '--shadow: ' + getCssShadow(rule.dynamicVars.shadow),
  78. '--shadowFilter: ' + getCssShadowFilter(rule.dynamicVars.shadow),
  79. '--shadowInset: ' + getCssShadow(rule.dynamicVars.shadow, true)
  80. ].join(';\n ')
  81. }
  82. case 'background': {
  83. if (DEBUG) {
  84. return `
  85. --background: ${getCssColorString(rule.dynamicVars.stacked)};
  86. background-color: ${getCssColorString(rule.dynamicVars.stacked)};
  87. `
  88. }
  89. if (v === 'transparent') {
  90. if (rule.component === 'Root') return []
  91. return [
  92. rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + v) : '',
  93. ' --background: ' + v
  94. ].filter(x => x).join(';\n')
  95. }
  96. const color = getCssColorString(rule.dynamicVars.background, rule.directives.opacity)
  97. const cssDirectives = ['--background: ' + color]
  98. if (rule.directives.backgroundNoCssColor !== 'yes') {
  99. cssDirectives.push('background-color: ' + color)
  100. }
  101. return cssDirectives.filter(x => x).join(';\n')
  102. }
  103. case 'blur': {
  104. const cssDirectives = []
  105. if (rule.directives.opacity < 1) {
  106. cssDirectives.push(`--backdrop-filter: blur(${v}) `)
  107. if (rule.directives.backgroundNoCssColor !== 'yes') {
  108. cssDirectives.push(`backdrop-filter: blur(${v}) `)
  109. }
  110. }
  111. return cssDirectives.join(';\n')
  112. }
  113. case 'font': {
  114. return 'font-family: ' + v
  115. }
  116. case 'textColor': {
  117. if (rule.directives.textNoCssColor === 'yes') { return '' }
  118. return 'color: ' + v
  119. }
  120. default:
  121. if (k.startsWith('--')) {
  122. const [type, value] = v.split('|').map(x => x.trim()) // woah, Extreme!
  123. switch (type) {
  124. case 'color': {
  125. const color = rule.dynamicVars[k]
  126. if (typeof color === 'string') {
  127. return k + ': ' + rgba2css(hex2rgb(color))
  128. } else {
  129. return k + ': ' + rgba2css(color)
  130. }
  131. }
  132. case 'generic':
  133. return k + ': ' + value
  134. default:
  135. return ''
  136. }
  137. }
  138. return ''
  139. }
  140. }).filter(x => x).map(x => ' ' + x).join(';\n')
  141. return [
  142. header,
  143. directives + ';',
  144. (rule.component === 'Text' && rule.state.indexOf('faint') < 0 && rule.directives.textNoCssColor !== 'yes') ? ' color: var(--text);' : '',
  145. '',
  146. virtualDirectives,
  147. footer
  148. ].join('\n')
  149. }).filter(x => x)