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:
ALL = [LIGHT, DARK]
class VariableType:
COLOR = 'color'
OPACITY = 'opacity'
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):
self.colors = collections.OrderedDict()
def __init__(self, default_mode):
self.variables = collections.OrderedDict()
self._default_mode = default_mode
def AddColor(self, name, value_str):
if name in self.colors:
raise ValueError('%s defined more than once' % name)
def Add(self, mode, name, value):
if name not in self.variables:
self.variables[name] = {}
self.variables[name][mode] = value
try:
self.colors[name] = Color(value_str)
except Exception as err:
raise ValueError('Error parsing "%s": %s' % (value_str, err))
def keys(self):
return self.variables.keys()
def items(self):
return self.variables.items()
def __getitem__(self, key):
return self.variables[key]
class BaseGenerator:
......@@ -55,22 +67,32 @@ class BaseGenerator:
def __init__(self):
self.out_file_path = None
self.in_files = []
self._mode_variables = dict()
# 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
# not specified in the default mode.
self._default_mode = Modes.LIGHT
for mode in Modes.ALL:
self._mode_variables[mode] = ModeVariables()
# A dictionary of |VariableType| to dictionaries of variable names to
# 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):
try:
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):
for mode in Modes.ALL:
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):
self.in_files.append(path)
......@@ -91,7 +113,7 @@ class BaseGenerator:
% name)
self.AddColor(name, value)
except Exception as err:
except ValueError as err:
raise ValueError('\n%s:\n %s' % (path, err))
def ApplyTemplate(self, style_generator, path_to_template, params):
......@@ -106,15 +128,18 @@ class BaseGenerator:
return template.render(params)
def Validate(self):
colors = self.model[VariableType.COLOR]
def CheckColorInDefaultMode(name):
if name not in self._mode_variables[self._default_mode].colors:
raise ValueError(
"%s not defined in '%s' mode" % (name, self._default_mode))
if (name not in colors.variables
or self._default_mode not in colors.variables[name]):
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.
for m in self._mode_variables.values():
for name, value in m.colors.items():
for name, mode_values in colors.variables.items():
for mode, value in mode_values.items():
CheckColorInDefaultMode(name)
if value.var:
CheckColorInDefaultMode(value.var)
......
......@@ -2,7 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# 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):
......@@ -14,9 +15,16 @@ class CSSStyleGenerator(BaseGenerator):
self.GetParameters())
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 {
'light_variables': self._mode_variables[Modes.LIGHT],
'dark_variables': self._mode_variables[Modes.DARK],
'light_colors': BuildColorsForMode(Modes.LIGHT),
'dark_colors': BuildColorsForMode(Modes.DARK),
}
def GetFilters(self):
......
......@@ -15,13 +15,13 @@ TODO(https://crbug.com/1062154): Remove once deprecated colors are removed from
Chrome OS pages.
-#}
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}}: {{css_color_from_rgb_var(var_name, color.a)}};
{% endfor %}
}
{% if dark_variables.colors -%}
{% if dark_colors -%}
@media (prefers-color-scheme: dark) {
{#-
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
Chrome OS pages.
#}
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}}: {{css_color_from_rgb_var(var_name, color.a)}};
{% endfor %}
......
......@@ -3,7 +3,7 @@
# found in the LICENSE file.
import os
from base_generator import Color, Modes, BaseGenerator
from base_generator import Color, Modes, BaseGenerator, VariableType
class ViewsStyleGenerator(BaseGenerator):
......@@ -40,14 +40,8 @@ class ViewsStyleGenerator(BaseGenerator):
def _CreateColorList(self):
color_list = []
for color_name in (
self._mode_variables[self._default_mode].colors.keys()):
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)
for name, mode_values in self.model[VariableType.COLOR].items():
color_list.append({'name': name, 'mode_values': mode_values})
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