Commit 3ca5df0c authored by Christopher Lam's avatar Christopher Lam Committed by Commit Bot

[style_var_gen] Refactor model.

This CL refactors the model to more closely match the data. In particular,
the model used to be colors[mode][name] and is now colors[name][mode],
which matches the data. This is in preparation for implementing
opacities, a 'generate-dark-mode-only' mode, and dark-mode-agnostic
properties.

Other minor changes:
- BaseGenerator.colors is now BaseGenerator.model[VariableType.COLOR]
- ModeVariables now has methods that let it be used more like a dict()

Bug: 1018654
Change-Id: I5422178053434b49ac64a6290983092cbbbf0ab0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2245968
Commit-Queue: calamity <calamity@chromium.org>
Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#780201}
parent 42b5e4aa
...@@ -28,21 +28,33 @@ class Modes: ...@@ -28,21 +28,33 @@ class Modes:
ALL = [LIGHT, DARK] ALL = [LIGHT, DARK]
class VariableType:
COLOR = 'color'
OPACITY = 'opacity'
class ModeVariables: class ModeVariables:
'''A representation of variables to generate for a single Mode. '''A dictionary of variable names to their values in each mode.
e.g mode_variables['blue'][Modes.LIGHT] = Color(...)
''' '''
def __init__(self): def __init__(self, default_mode):
self.colors = collections.OrderedDict() self.variables = collections.OrderedDict()
self._default_mode = default_mode
def AddColor(self, name, value_str): def Add(self, mode, name, value):
if name in self.colors: if name not in self.variables:
raise ValueError('%s defined more than once' % name) self.variables[name] = {}
self.variables[name][mode] = value
try: def keys(self):
self.colors[name] = Color(value_str) return self.variables.keys()
except Exception as err:
raise ValueError('Error parsing "%s": %s' % (value_str, err)) def items(self):
return self.variables.items()
def __getitem__(self, key):
return self.variables[key]
class BaseGenerator: class BaseGenerator:
...@@ -55,22 +67,32 @@ class BaseGenerator: ...@@ -55,22 +67,32 @@ class BaseGenerator:
def __init__(self): def __init__(self):
self.out_file_path = None self.out_file_path = None
self.in_files = [] self.in_files = []
self._mode_variables = dict()
# The mode that colors will fallback to when not specified in a # The mode that colors will fallback to when not specified in a
# non-default mode. An error will be raised if a color in any mode is # non-default mode. An error will be raised if a color in any mode is
# not specified in the default mode. # not specified in the default mode.
self._default_mode = Modes.LIGHT self._default_mode = Modes.LIGHT
for mode in Modes.ALL: # A dictionary of |VariableType| to dictionaries of variable names to
self._mode_variables[mode] = ModeVariables() # values. May point to a ModeVariables instance which further adds a
# layer making the structure name -> mode -> value.
self.model = {
VariableType.COLOR: ModeVariables(self._default_mode),
VariableType.OPACITY: ModeVariables(self._default_mode),
}
def AddColor(self, name, value_obj): def AddColor(self, name, value_obj):
try:
if isinstance(value_obj, unicode): if isinstance(value_obj, unicode):
self._mode_variables[self._default_mode].AddColor(name, value_obj) self.model[VariableType.COLOR].Add(self._default_mode, name,
Color(value_obj))
elif isinstance(value_obj, dict): elif isinstance(value_obj, dict):
for mode in Modes.ALL: for mode in Modes.ALL:
if mode in value_obj: if mode in value_obj:
self._mode_variables[mode].AddColor(name, value_obj[mode]) self.model[VariableType.COLOR].Add(
mode, name, Color(value_obj[mode]))
except ValueError as err:
raise ValueError('Error parsing color "%s": %s' % (value_obj, err))
def AddJSONFileToModel(self, path): def AddJSONFileToModel(self, path):
self.in_files.append(path) self.in_files.append(path)
...@@ -91,7 +113,7 @@ class BaseGenerator: ...@@ -91,7 +113,7 @@ class BaseGenerator:
% name) % name)
self.AddColor(name, value) self.AddColor(name, value)
except Exception as err: except ValueError as err:
raise ValueError('\n%s:\n %s' % (path, err)) raise ValueError('\n%s:\n %s' % (path, err))
def ApplyTemplate(self, style_generator, path_to_template, params): def ApplyTemplate(self, style_generator, path_to_template, params):
...@@ -106,15 +128,18 @@ class BaseGenerator: ...@@ -106,15 +128,18 @@ class BaseGenerator:
return template.render(params) return template.render(params)
def Validate(self): def Validate(self):
colors = self.model[VariableType.COLOR]
def CheckColorInDefaultMode(name): def CheckColorInDefaultMode(name):
if name not in self._mode_variables[self._default_mode].colors: if (name not in colors.variables
raise ValueError( or self._default_mode not in colors.variables[name]):
"%s not defined in '%s' mode" % (name, self._default_mode)) raise ValueError("%s not defined in default mode '%s'" %
(name, self._default_mode))
# Check all colors in all models refer to colors that exist in the # Check all colors in all modes refer to colors that exist in the
# default mode. # default mode.
for m in self._mode_variables.values(): for name, mode_values in colors.variables.items():
for name, value in m.colors.items(): for mode, value in mode_values.items():
CheckColorInDefaultMode(name) CheckColorInDefaultMode(name)
if value.var: if value.var:
CheckColorInDefaultMode(value.var) CheckColorInDefaultMode(value.var)
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
from base_generator import Color, Modes, BaseGenerator from base_generator import Color, Modes, BaseGenerator, VariableType
import collections
class CSSStyleGenerator(BaseGenerator): class CSSStyleGenerator(BaseGenerator):
...@@ -14,9 +15,16 @@ class CSSStyleGenerator(BaseGenerator): ...@@ -14,9 +15,16 @@ class CSSStyleGenerator(BaseGenerator):
self.GetParameters()) self.GetParameters())
def GetParameters(self): def GetParameters(self):
def BuildColorsForMode(mode):
colors = collections.OrderedDict()
for name, mode_values in self.model[VariableType.COLOR].items():
if mode in mode_values:
colors[name] = mode_values[mode]
return colors
return { return {
'light_variables': self._mode_variables[Modes.LIGHT], 'light_colors': BuildColorsForMode(Modes.LIGHT),
'dark_variables': self._mode_variables[Modes.DARK], 'dark_colors': BuildColorsForMode(Modes.DARK),
} }
def GetFilters(self): def GetFilters(self):
......
...@@ -15,13 +15,13 @@ TODO(https://crbug.com/1062154): Remove once deprecated colors are removed from ...@@ -15,13 +15,13 @@ TODO(https://crbug.com/1062154): Remove once deprecated colors are removed from
Chrome OS pages. Chrome OS pages.
-#} -#}
html:not(body) { html:not(body) {
{%- for var_name, color in light_variables.colors.items() %} {%- for var_name, color in light_colors.items() %}
{{var_name | to_var_name}}-rgb: {{color | css_color_rgb}}; {{var_name | to_var_name}}-rgb: {{color | css_color_rgb}};
{{var_name | to_var_name}}: {{css_color_from_rgb_var(var_name, color.a)}}; {{var_name | to_var_name}}: {{css_color_from_rgb_var(var_name, color.a)}};
{% endfor %} {% endfor %}
} }
{% if dark_variables.colors -%} {% if dark_colors -%}
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
{#- {#-
The :not(body) adds extra selector specificity so that these colors 'win' The :not(body) adds extra selector specificity so that these colors 'win'
...@@ -30,7 +30,7 @@ TODO(https://crbug.com/1062154): Remove once deprecated colors are removed from ...@@ -30,7 +30,7 @@ TODO(https://crbug.com/1062154): Remove once deprecated colors are removed from
Chrome OS pages. Chrome OS pages.
#} #}
html:not(body) { html:not(body) {
{%- for var_name, color in dark_variables.colors.items() %} {%- for var_name, color in dark_colors.items() %}
{{var_name | to_var_name}}-rgb: {{color | css_color_rgb}}; {{var_name | to_var_name}}-rgb: {{color | css_color_rgb}};
{{var_name | to_var_name}}: {{css_color_from_rgb_var(var_name, color.a)}}; {{var_name | to_var_name}}: {{css_color_from_rgb_var(var_name, color.a)}};
{% endfor %} {% endfor %}
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# found in the LICENSE file. # found in the LICENSE file.
import os import os
from base_generator import Color, Modes, BaseGenerator from base_generator import Color, Modes, BaseGenerator, VariableType
class ViewsStyleGenerator(BaseGenerator): class ViewsStyleGenerator(BaseGenerator):
...@@ -40,14 +40,8 @@ class ViewsStyleGenerator(BaseGenerator): ...@@ -40,14 +40,8 @@ class ViewsStyleGenerator(BaseGenerator):
def _CreateColorList(self): def _CreateColorList(self):
color_list = [] color_list = []
for color_name in ( for name, mode_values in self.model[VariableType.COLOR].items():
self._mode_variables[self._default_mode].colors.keys()): color_list.append({'name': name, 'mode_values': mode_values})
color_obj = {'name': color_name, 'mode_values': {}}
for m in Modes.ALL:
mode_colors = self._mode_variables[m].colors
if color_name in mode_colors:
color_obj['mode_values'][m] = mode_colors[color_name]
color_list.append(color_obj)
return color_list return color_list
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment