From 38c34b8b51136e3d73506cf5347aa57541b36653 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Feb 2020 00:34:30 +0200
Subject: [PATCH] fixed eslint, made `mod` work properly depending on context
 including in shadows

---
 src/components/style_switcher/preview.vue     |  2 +-
 src/services/style_setter/style_setter.js     | 22 +++++--
 src/services/theme_data/theme_data.service.js | 59 ++++++++++---------
 3 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/src/components/style_switcher/preview.vue b/src/components/style_switcher/preview.vue
index 5b8c3839f..8afbb1238 100644
--- a/src/components/style_switcher/preview.vue
+++ b/src/components/style_switcher/preview.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="preview-container">
-    <div class="underlay underlay-preview"/>
+    <div class="underlay underlay-preview" />
     <div class="panel dummy">
       <div class="panel-heading">
         <div class="title">
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index b9a23ad73..321021529 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -1,6 +1,6 @@
 import { times } from 'lodash'
 import { convert } from 'chromatism'
-import { rgb2hex, hex2rgb, rgba2css, getCssColor } from '../color_convert/color_convert.js'
+import { rgb2hex, hex2rgb, rgba2css, getCssColor, relativeLuminance } from '../color_convert/color_convert.js'
 import { getColors, computeDynamicColor } from '../theme_data/theme_data.service.js'
 
 // While this is not used anymore right now, I left it in if we want to do custom
@@ -133,8 +133,7 @@ export const generateColors = (themeData) => {
     theme: {
       colors: htmlColors.solid,
       opacity
-    },
-    mod
+    }
   }
 }
 
@@ -281,7 +280,18 @@ export const DEFAULT_SHADOWS = {
     alpha: 1
   }]
 }
-export const generateShadows = (input, colors, mod) => {
+export const generateShadows = (input, colors) => {
+  // TODO this is a small hack for `mod` to work with shadows
+  // this is used to get the "context" of shadow, i.e. for `mod` properly depend on background color of element
+  const hackContextDict = {
+    button: 'btn',
+    panel: 'bg',
+    top: 'topBar',
+    popup: 'popover',
+    avatar: 'bg',
+    panelHeader: 'panel',
+    input: 'input'
+  }
   const inputShadows = input.shadows && !input.themeEngineVersion
     ? shadows2to3(input.shadows)
     : input.shadows || {}
@@ -289,6 +299,10 @@ export const generateShadows = (input, colors, mod) => {
     ...DEFAULT_SHADOWS,
     ...inputShadows
   }).reduce((shadowsAcc, [slotName, shadowDefs]) => {
+    const slotFirstWord = slotName.replace(/[A-Z].*$/, '')
+    const colorSlotName = hackContextDict[slotFirstWord]
+    const isLightOnDark = relativeLuminance(convert(colors[colorSlotName]).rgb) < 0.5
+    const mod = isLightOnDark ? 1 : -1
     const newShadow = shadowDefs.reduce((shadowAcc, def) => [
       ...shadowAcc,
       {
diff --git a/src/services/theme_data/theme_data.service.js b/src/services/theme_data/theme_data.service.js
index e9ed3781f..7479a55ee 100644
--- a/src/services/theme_data/theme_data.service.js
+++ b/src/services/theme_data/theme_data.service.js
@@ -259,13 +259,34 @@ export const computeDynamicColor = (sourceColor, getColor, mod) => {
  * value and uses inheritance data to figure out color needed for the slot.
  */
 export const getColors = (sourceColors, sourceOpacity) => SLOT_ORDERED.reduce(({ colors, opacity }, key) => {
-  const value = SLOT_INHERITANCE[key]
-  const isObject = typeof value === 'object'
-  const isString = typeof value === 'string'
   const sourceColor = sourceColors[key]
-  const variant = value.variant || value.layer || 'bg'
-  const isLightOnDark = relativeLuminance(colors[variant] || sourceColors[variant]) < 0.5
+  const value = expandSlotValue(SLOT_INHERITANCE[key])
+  const deps = getDependencies(key, SLOT_INHERITANCE)
+  const isTextColor = !!value.textColor
+  const variant = value.variant || value.layer
+
+  let backgroundColor = null
+
+  if (isTextColor) {
+    backgroundColor = alphaBlendLayers(
+      { ...(colors[deps[0]] || convert(sourceColors[key] || '#FF00FF').rgb) },
+      getLayers(
+        getLayerSlot(key) || 'bg',
+        variant || 'bg',
+        getOpacitySlot(variant),
+        colors,
+        opacity
+      )
+    )
+  } else if (variant && variant !== key) {
+    backgroundColor = colors[variant] || convert(sourceColors[variant]).rgb
+  } else {
+    backgroundColor = colors.bg || convert(sourceColors.bg)
+  }
+
+  const isLightOnDark = relativeLuminance(backgroundColor) < 0.5
   const mod = isLightOnDark ? 1 : -1
+
   let outputColor = null
   if (sourceColor) {
     // Color is defined in source color
@@ -280,7 +301,6 @@ export const getColors = (sourceColors, sourceOpacity) => SLOT_ORDERED.reduce(({
         opacity
       ).slice(0, -1)
       targetColor = {
-        // TODO: try to use alpha-blended background here
         ...alphaBlendLayers(
           convert('#FF00FF').rgb,
           layers
@@ -297,43 +317,24 @@ export const getColors = (sourceColors, sourceOpacity) => SLOT_ORDERED.reduce(({
       targetColor = convert(targetColor).rgb
     }
     outputColor = { ...targetColor }
-  } else if (isString && value.startsWith('#')) {
-    // slot: '#000000' shorthand
-    outputColor = convert(value).rgb
-  } else if (isObject && value.default) {
+  } else if (value.default) {
     // same as above except in object form
     outputColor = convert(value.default).rgb
   } else {
     // calculate color
     const defaultColorFunc = (mod, dep) => ({ ...dep })
-    const deps = getDependencies(key, SLOT_INHERITANCE)
-    const colorFunc = (isObject && value.color) || defaultColorFunc
+    const colorFunc = value.color || defaultColorFunc
 
     if (value.textColor) {
-      // textColor case
-      const bg = alphaBlendLayers(
-        { ...colors[deps[0]] },
-        getLayers(
-          value.layer,
-          value.variant || value.layer,
-          getOpacitySlot(value.variant || value.layer),
-          colors,
-          opacity
-        )
-      )
-      const isLightOnDark = relativeLuminance(bg) > 0.5
-      const mod = isLightOnDark ? 1 : -1
-
       if (value.textColor === 'bw') {
-        outputColor = contrastRatio(bg).rgb
+        outputColor = contrastRatio(backgroundColor).rgb
       } else {
         let color = { ...colors[deps[0]] }
         if (value.color) {
           color = colorFunc(mod, ...deps.map((dep) => ({ ...colors[dep] })))
         }
-
         outputColor = getTextColor(
-          bg,
+          backgroundColor,
           { ...color },
           value.textColor === 'preserve'
         )
-- 
GitLab