summaryrefslogtreecommitdiff
path: root/chromium/tools/style_variable_generator
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/tools/style_variable_generator')
-rw-r--r--chromium/tools/style_variable_generator/base_generator.py116
-rw-r--r--chromium/tools/style_variable_generator/base_generator_test.py60
-rw-r--r--chromium/tools/style_variable_generator/colors_test_dark_only_expected.css19
-rw-r--r--chromium/tools/style_variable_generator/colors_test_expected.css8
-rw-r--r--chromium/tools/style_variable_generator/colors_test_expected.h3
-rw-r--r--chromium/tools/style_variable_generator/css_generator.py29
-rw-r--r--chromium/tools/style_variable_generator/css_generator.tmpl16
-rw-r--r--chromium/tools/style_variable_generator/css_generator_test.py7
-rw-r--r--chromium/tools/style_variable_generator/path_overrides.py16
-rw-r--r--chromium/tools/style_variable_generator/style_variable_generator.gni1
-rw-r--r--chromium/tools/style_variable_generator/style_variable_generator.py5
-rw-r--r--chromium/tools/style_variable_generator/views_generator.py13
-rw-r--r--chromium/tools/style_variable_generator/views_generator_h.tmpl5
13 files changed, 246 insertions, 52 deletions
diff --git a/chromium/tools/style_variable_generator/base_generator.py b/chromium/tools/style_variable_generator/base_generator.py
index 596b222c578..4663c4e23b9 100644
--- a/chromium/tools/style_variable_generator/base_generator.py
+++ b/chromium/tools/style_variable_generator/base_generator.py
@@ -7,6 +7,7 @@ import sys
import collections
import re
import textwrap
+import path_overrides
from color import Color
_FILE_PATH = os.path.dirname(os.path.realpath(__file__))
@@ -27,21 +28,42 @@ 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))
+ # Returns the value that |name| will have in |mode|. Resolves to the default
+ # mode's value if the a value for |mode| isn't specified. Always returns a
+ # value.
+ def Resolve(self, name, mode):
+ if mode in self.variables[name]:
+ return self.variables[name][mode]
+
+ return self.variables[name][self._default_mode]
+
+ def keys(self):
+ return self.variables.keys()
+
+ def items(self):
+ return self.variables.items()
+
+ def __getitem__(self, key):
+ return self.variables[key]
class BaseGenerator:
@@ -53,29 +75,46 @@ class BaseGenerator:
def __init__(self):
self.out_file_path = None
- self._mode_variables = dict()
+ self.in_files = []
+ self.generate_single_mode = None
+
# 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):
- if isinstance(value_obj, unicode):
- self._mode_variables[self._default_mode].AddColor(name, 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])
+ try:
+ if isinstance(value_obj, unicode):
+ 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.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)
with open(path, 'r') as f:
- # TODO(calamity): Add allow_duplicate_keys=False once pyjson5 is
- # rolled.
- data = json5.loads(
- f.read(), object_pairs_hook=collections.OrderedDict)
+ self.AddJSONToModel(f.read())
+
+ def AddJSONToModel(self, json_string):
+ # TODO(calamity): Add allow_duplicate_keys=False once pyjson5 is
+ # rolled.
+ data = json5.loads(json_string,
+ object_pairs_hook=collections.OrderedDict)
try:
for name, value in data['colors'].items():
@@ -85,33 +124,38 @@ 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):
- current_dir = os.path.dirname(os.path.realpath(__file__))
+ loader_root_dir = path_overrides.GetFileSystemLoaderRootDirectory()
jinja_env = jinja2.Environment(
- loader=jinja2.FileSystemLoader(current_dir),
+ loader=jinja2.FileSystemLoader(loader_root_dir),
keep_trailing_newline=True)
jinja_env.globals.update(style_generator.GetGlobals())
jinja_env.filters.update(style_generator.GetFilters())
- template = jinja_env.get_template(path_to_template)
+ template = jinja_env.get_template(
+ path_overrides.GetPathToTemplate(path_to_template))
return template.render(params)
def Validate(self):
- def CheckIsInDefaultModel(name):
- if name not in self._mode_variables[self._default_mode].colors:
- raise ValueError(
- "%s not defined in '%s' mode" % (name, self._default_mode))
+ colors = self.model[VariableType.COLOR]
+
+ def CheckColorInDefaultMode(name):
+ 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:
- CheckIsInDefaultModel(value.var)
+ CheckColorInDefaultMode(value.var)
if value.rgb_var:
- CheckIsInDefaultModel(value.rgb_var[:-4])
+ CheckColorInDefaultMode(value.rgb_var[:-4])
# TODO(calamity): Check for circular references.
diff --git a/chromium/tools/style_variable_generator/base_generator_test.py b/chromium/tools/style_variable_generator/base_generator_test.py
new file mode 100644
index 00000000000..a7fdd13664c
--- /dev/null
+++ b/chromium/tools/style_variable_generator/base_generator_test.py
@@ -0,0 +1,60 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from base_generator import BaseGenerator
+import unittest
+
+
+class BaseGeneratorTest(unittest.TestCase):
+ def setUp(self):
+ self.generator = BaseGenerator()
+
+ def testMissingColor(self):
+ # google_grey_900 is missing.
+ self.generator.AddJSONToModel('''
+{
+ colors: {
+ cros_default_text_color: {
+ light: "$google_grey_900",
+ dark: "rgb(255, 255, 255)",
+ },
+ },
+}
+ ''')
+ self.assertRaises(ValueError, self.generator.Validate)
+
+ # Add google_grey_900.
+ self.generator.AddJSONToModel('''
+{
+ colors: {
+ google_grey_900: "rgb(255, 255, 255)",
+ }
+}
+ ''')
+ self.generator.Validate()
+
+ def testMissingDefaultModeColor(self):
+ # google_grey_900 is missing in the default mode (light).
+ self.generator.AddJSONToModel('''
+{
+ colors: {
+ google_grey_900: { dark: "rgb(255, 255, 255)", },
+ }
+}
+ ''')
+ self.assertRaises(ValueError, self.generator.Validate)
+
+ # Add google_grey_900 to light mode.
+ self.generator.AddJSONToModel('''
+{
+ colors: {
+ google_grey_900: { light: "rgb(255, 255, 255)", }
+ }
+}
+ ''')
+ self.generator.Validate()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/chromium/tools/style_variable_generator/colors_test_dark_only_expected.css b/chromium/tools/style_variable_generator/colors_test_dark_only_expected.css
new file mode 100644
index 00000000000..f387b995960
--- /dev/null
+++ b/chromium/tools/style_variable_generator/colors_test_dark_only_expected.css
@@ -0,0 +1,19 @@
+/* Copyright 2020 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+/* This file is generated from:
+ * colors_test.json5
+ */
+
+html:not(body) {
+ --google-grey-900-rgb: 32, 33, 36;
+ --google-grey-900: rgb(var(--google-grey-900-rgb));
+
+ --cros-default-text-color-rgb: 255, 255, 255;
+ --cros-default-text-color: rgb(var(--cros-default-text-color-rgb));
+
+ --cros-toggle-color-rgb: var(--cros-default-text-color-rgb);
+ --cros-toggle-color: rgba(var(--cros-toggle-color-rgb), 0.1);
+
+}
diff --git a/chromium/tools/style_variable_generator/colors_test_expected.css b/chromium/tools/style_variable_generator/colors_test_expected.css
index 277b79cce2f..ccbe7b6e275 100644
--- a/chromium/tools/style_variable_generator/colors_test_expected.css
+++ b/chromium/tools/style_variable_generator/colors_test_expected.css
@@ -1,3 +1,11 @@
+/* Copyright 2020 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+/* This file is generated from:
+ * colors_test.json5
+ */
+
html:not(body) {
--google-grey-900-rgb: 32, 33, 36;
--google-grey-900: rgb(var(--google-grey-900-rgb));
diff --git a/chromium/tools/style_variable_generator/colors_test_expected.h b/chromium/tools/style_variable_generator/colors_test_expected.h
index 56b0d852445..7fff1ebfab0 100644
--- a/chromium/tools/style_variable_generator/colors_test_expected.h
+++ b/chromium/tools/style_variable_generator/colors_test_expected.h
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file is generated from:
+// colors_test.json5
+
#ifndef TOOLS_STYLE_VARIABLE_GENERATOR_COLORS_TEST_EXPECTED_H_
#define TOOLS_STYLE_VARIABLE_GENERATOR_COLORS_TEST_EXPECTED_H_
diff --git a/chromium/tools/style_variable_generator/css_generator.py b/chromium/tools/style_variable_generator/css_generator.py
index b18f5a21999..22f7209fdb1 100644
--- a/chromium/tools/style_variable_generator/css_generator.py
+++ b/chromium/tools/style_variable_generator/css_generator.py
@@ -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,30 @@ class CSSStyleGenerator(BaseGenerator):
self.GetParameters())
def GetParameters(self):
+ def BuildColorsForMode(mode, resolve_missing=False):
+ '''Builds a name to Color dictionary for |mode|.
+ If |resolve_missing| is true, colors that aren't specified in |mode|
+ will be resolved to their default mode value.'''
+ colors = collections.OrderedDict()
+ for name, mode_values in self.model[VariableType.COLOR].items():
+ if resolve_missing:
+ colors[name] = self.model[VariableType.COLOR].Resolve(
+ name, mode)
+ else:
+ if mode in mode_values:
+ colors[name] = mode_values[mode]
+ return colors
+
+ if self.generate_single_mode:
+ return {
+ 'light_colors':
+ BuildColorsForMode(self.generate_single_mode,
+ resolve_missing=True)
+ }
+
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):
@@ -29,6 +51,7 @@ class CSSStyleGenerator(BaseGenerator):
def GetGlobals(self):
return {
'css_color_from_rgb_var': self._CssColorFromRGBVar,
+ 'in_files': self.in_files,
}
def _ToVarName(self, var_name):
diff --git a/chromium/tools/style_variable_generator/css_generator.tmpl b/chromium/tools/style_variable_generator/css_generator.tmpl
index e896834d8c6..b33a22cc77c 100644
--- a/chromium/tools/style_variable_generator/css_generator.tmpl
+++ b/chromium/tools/style_variable_generator/css_generator.tmpl
@@ -1,3 +1,13 @@
+/* Copyright 2020 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+/* This file is generated from:
+{%- for path in in_files %}
+ * {{path}}
+{%- endfor %}
+ */
+
{#
The :not(body) adds extra selector specificity so that these colors 'win'
against paper-styles/color.html.
@@ -5,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_colors %}
-{% if dark_variables.colors -%}
@media (prefers-color-scheme: dark) {
{#-
The :not(body) adds extra selector specificity so that these colors 'win'
@@ -20,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 %}
diff --git a/chromium/tools/style_variable_generator/css_generator_test.py b/chromium/tools/style_variable_generator/css_generator_test.py
index 75d139e5787..50eac224bd7 100644
--- a/chromium/tools/style_variable_generator/css_generator_test.py
+++ b/chromium/tools/style_variable_generator/css_generator_test.py
@@ -3,6 +3,7 @@
# found in the LICENSE file.
from css_generator import CSSStyleGenerator
+from base_generator import Modes
import unittest
@@ -23,6 +24,12 @@ class CSSStyleGeneratorTest(unittest.TestCase):
self.assertEqualToFile(self.generator.Render(),
'colors_test_expected.css')
+ def testColorTestJSONDarkOnly(self):
+ self.generator.AddJSONFileToModel('colors_test.json5')
+ self.generator.generate_single_mode = Modes.DARK
+ self.assertEqualToFile(self.generator.Render(),
+ 'colors_test_dark_only_expected.css')
+
if __name__ == '__main__':
unittest.main()
diff --git a/chromium/tools/style_variable_generator/path_overrides.py b/chromium/tools/style_variable_generator/path_overrides.py
new file mode 100644
index 00000000000..4cd408366a7
--- /dev/null
+++ b/chromium/tools/style_variable_generator/path_overrides.py
@@ -0,0 +1,16 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+
+
+# Returns the FileSystemLoader root directory. Overridden in google3.
+def GetFileSystemLoaderRootDirectory():
+ return os.path.dirname(os.path.realpath(__file__))
+
+
+# Returns the path to the template relative to FileSystemLoader root.
+# Overridden in google3.
+def GetPathToTemplate(path_to_template):
+ return path_to_template
diff --git a/chromium/tools/style_variable_generator/style_variable_generator.gni b/chromium/tools/style_variable_generator/style_variable_generator.gni
index c1beb86294b..2b443e91c83 100644
--- a/chromium/tools/style_variable_generator/style_variable_generator.gni
+++ b/chromium/tools/style_variable_generator/style_variable_generator.gni
@@ -60,7 +60,6 @@ template("style_variable_generator") {
]
out_file = "$target_gen_dir/${original_target_name}.h"
outputs = [ out_file ]
-
args = [
"--generator=Views",
"--out-file",
diff --git a/chromium/tools/style_variable_generator/style_variable_generator.py b/chromium/tools/style_variable_generator/style_variable_generator.py
index b2b11cde780..e7b20fd8371 100644
--- a/chromium/tools/style_variable_generator/style_variable_generator.py
+++ b/chromium/tools/style_variable_generator/style_variable_generator.py
@@ -6,6 +6,7 @@ import argparse
import sys
from css_generator import CSSStyleGenerator
from views_generator import ViewsStyleGenerator
+from base_generator import Modes
def main():
@@ -17,6 +18,9 @@ def main():
choices=['CSS', 'Views'],
required=True,
help='type of file to generate')
+ parser.add_argument('--generate-single-mode',
+ choices=Modes.ALL,
+ help='generates output for a single mode')
parser.add_argument('--out-file', help='file to write output to')
parser.add_argument('targets', nargs='+', help='source json5 color files')
@@ -31,6 +35,7 @@ def main():
for t in args.targets:
style_generator.AddJSONFileToModel(t)
+ style_generator.generate_single_mode = args.generate_single_mode
style_generator.out_file_path = args.out_file
if args.out_file:
diff --git a/chromium/tools/style_variable_generator/views_generator.py b/chromium/tools/style_variable_generator/views_generator.py
index 2fb4b4f0336..9f2587d4336 100644
--- a/chromium/tools/style_variable_generator/views_generator.py
+++ b/chromium/tools/style_variable_generator/views_generator.py
@@ -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):
@@ -30,6 +30,7 @@ class ViewsStyleGenerator(BaseGenerator):
'Modes': Modes,
'out_file_path': None,
'namespace_name': None,
+ 'in_files': self.in_files,
}
if self.out_file_path:
globals['out_file_path'] = self.out_file_path
@@ -39,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
diff --git a/chromium/tools/style_variable_generator/views_generator_h.tmpl b/chromium/tools/style_variable_generator/views_generator_h.tmpl
index 33ea309ba4f..e9250f29a6b 100644
--- a/chromium/tools/style_variable_generator/views_generator_h.tmpl
+++ b/chromium/tools/style_variable_generator/views_generator_h.tmpl
@@ -6,6 +6,11 @@
out_file_path|upper|replace("/","_")|replace(".","_")|
replace("-", "_")) %}
+// This file is generated from:
+{%- for path in in_files %}
+// {{path}}
+{%- endfor %}
+
#ifndef {{header_guard}}
#define {{header_guard}}