| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2016 The Chromium Authors. All rights reserved. | 2 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import math | 6 import math |
| 7 import sys | 7 import sys |
| 8 | 8 |
| 9 import json5_generator | 9 import json5_generator |
| 10 import template_expander | 10 import template_expander |
| 11 import make_style_builder | 11 import make_style_builder |
| 12 | 12 |
| 13 from name_utilities import camel_case, lower_first, upper_first_letter, enum_for
_css_keyword | 13 from name_utilities import camel_case, lower_first, upper_first_letter, enum_for
_css_keyword |
| 14 | 14 |
| 15 | 15 |
| 16 # Temporary hard-coded list of fields that are not CSS properties. | 16 # Temporary hard-coded list of fields that are not CSS properties. |
| 17 # Ideally these would be specified in a .in or .json5 file. | 17 # Ideally these would be specified in a .json5 file. |
| 18 NONPROPERTY_FIELDS = set([ | 18 NONPROPERTY_FIELDS = [ |
| 19 'isLink', | 19 {'name': 'isLink', 'field_template': 'monotonic_flag'}, |
| 20 # Style can not be shared. | 20 # Style can not be shared. |
| 21 'unique', | 21 {'name': 'unique', 'field_template': 'monotonic_flag'}, |
| 22 # Whether this style is affected by these pseudo-classes. | 22 # Whether this style is affected by these pseudo-classes. |
| 23 'affectedByFocus', | 23 {'name': 'affectedByFocus', 'field_template': 'monotonic_flag'}, |
| 24 'affectedByHover', | 24 {'name': 'affectedByHover', 'field_template': 'monotonic_flag'}, |
| 25 'affectedByActive', | 25 {'name': 'affectedByActive', 'field_template': 'monotonic_flag'}, |
| 26 'affectedByDrag', | 26 {'name': 'affectedByDrag', 'field_template': 'monotonic_flag'}, |
| 27 # A non-inherited property references a variable or @apply is used | 27 # A non-inherited property references a variable or @apply is used |
| 28 'hasVariableReferenceFromNonInheritedProperty', | 28 {'name': 'hasVariableReferenceFromNonInheritedProperty', 'field_template': '
monotonic_flag'}, |
| 29 # Explicitly inherits a non-inherited property | 29 # Explicitly inherits a non-inherited property |
| 30 'hasExplicitlyInheritedProperties', | 30 {'name': 'hasExplicitlyInheritedProperties', 'field_template': 'monotonic_fl
ag'} |
| 31 ]) | 31 ] |
| 32 | 32 |
| 33 | 33 |
| 34 class Field(object): | 34 class Field(object): |
| 35 """ | 35 """ |
| 36 The generated ComputedStyle object is made up of a series of Fields. | 36 The generated ComputedStyle object is made up of a series of Fields. |
| 37 Each Field has a name, size, type, etc, and a bunch of attributes to | 37 Each Field has a name, size, type, etc, and a bunch of attributes to |
| 38 determine which methods it will be used in. | 38 determine which methods it will be used in. |
| 39 | 39 |
| 40 A Field also has enough information to use any storage type in C++, such as | 40 A Field also has enough information to use any storage type in C++, such as |
| 41 regular member variables, or more complex storage like vectors or hashmaps. | 41 regular member variables, or more complex storage like vectors or hashmaps. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 field_template='flag', | 194 field_template='flag', |
| 195 size=1, | 195 size=1, |
| 196 default_value='true', | 196 default_value='true', |
| 197 getter_method_name=field_name_suffix_lower, | 197 getter_method_name=field_name_suffix_lower, |
| 198 setter_method_name='set' + field_name_suffix_upper, | 198 setter_method_name='set' + field_name_suffix_upper, |
| 199 initial_method_name='initial' + field_name_suffix_upper, | 199 initial_method_name='initial' + field_name_suffix_upper, |
| 200 resetter_method_name='reset' + field_name_suffix_upper, | 200 resetter_method_name='reset' + field_name_suffix_upper, |
| 201 ) | 201 ) |
| 202 | 202 |
| 203 | 203 |
| 204 def _create_nonproperty_field(field_name): | 204 def _create_nonproperty_field(property_): |
| 205 """ | 205 """ |
| 206 Create a nonproperty field from its name and return the Field object. | 206 Create a nonproperty field from an entry in NONPROPERTY_FIELDS and return th
e Field object. |
| 207 """ | 207 """ |
| 208 member_name = 'm_' + field_name | 208 # TODO(shend): Make this work for nonflags |
| 209 field_name_upper = upper_first_letter(field_name) | 209 assert property_['field_template'] in ('flag', 'monotonic_flag'), \ |
| 210 "Nonproperties with arbitrary templates are not yet supported" |
| 211 member_name = 'm_' + property_['name'] |
| 212 field_name_upper = upper_first_letter(property_['name']) |
| 210 | 213 |
| 211 return Field( | 214 return Field( |
| 212 'nonproperty', | 215 'nonproperty', |
| 213 name=member_name, | 216 name=member_name, |
| 214 property_name=field_name, | 217 property_name=property_['name'], |
| 215 type_name='bool', | 218 type_name='bool', |
| 216 field_template='monotonic_flag', | 219 field_template=property_['field_template'], |
| 217 size=1, | 220 size=1, |
| 218 default_value='false', | 221 default_value='false', |
| 219 getter_method_name=field_name, | 222 getter_method_name=property_['name'], |
| 220 setter_method_name='set' + field_name_upper, | 223 setter_method_name='set' + field_name_upper, |
| 221 initial_method_name='initial' + field_name_upper, | 224 initial_method_name='initial' + field_name_upper, |
| 222 resetter_method_name='reset' + field_name_upper, | 225 resetter_method_name='reset' + field_name_upper, |
| 223 ) | 226 ) |
| 224 | 227 |
| 225 | 228 |
| 226 def _create_fields(properties): | 229 def _create_fields(properties): |
| 227 """ | 230 """ |
| 228 Create ComputedStyle fields from CSS properties and return a list of Field o
bjects. | 231 Create ComputedStyle fields from CSS properties and return a list of Field o
bjects. |
| 229 """ | 232 """ |
| 230 fields = [] | 233 fields = [] |
| 231 for property_ in properties: | 234 for property_ in properties: |
| 232 # Only generate properties that have a field template | 235 # Only generate properties that have a field template |
| 233 if property_['field_template'] is not None: | 236 if property_['field_template'] is not None: |
| 234 # If the property is independent, add the single-bit sized isInherit
ed flag | 237 # If the property is independent, add the single-bit sized isInherit
ed flag |
| 235 # to the list of Fields as well. | 238 # to the list of Fields as well. |
| 236 if property_['independent']: | 239 if property_['independent']: |
| 237 fields.append(_create_inherited_flag_field(property_)) | 240 fields.append(_create_inherited_flag_field(property_)) |
| 238 | 241 |
| 239 fields.append(_create_property_field(property_)) | 242 fields.append(_create_property_field(property_)) |
| 240 | 243 |
| 241 for field_name in NONPROPERTY_FIELDS: | 244 # TODO(shend): Merge NONPROPERTY_FIELDS with property_values so that propert
ies and |
| 242 fields.append(_create_nonproperty_field(field_name)) | 245 # nonproperties can be treated uniformly. |
| 246 for property_ in NONPROPERTY_FIELDS: |
| 247 fields.append(_create_nonproperty_field(property_)) |
| 243 | 248 |
| 244 return fields | 249 return fields |
| 245 | 250 |
| 246 | 251 |
| 247 def _pack_fields(fields): | 252 def _pack_fields(fields): |
| 248 """ | 253 """ |
| 249 Group a list of fields into buckets to minimise padding. | 254 Group a list of fields into buckets to minimise padding. |
| 250 Returns a list of buckets, where each bucket is a list of Field objects. | 255 Returns a list of buckets, where each bucket is a list of Field objects. |
| 251 """ | 256 """ |
| 252 # Since fields cannot cross word boundaries, in order to minimize | 257 # Since fields cannot cross word boundaries, in order to minimize |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 'mapping': [('k' + camel_case(k), enum_for_css_keyword(k)) f
or k in property_['keywords']], | 376 'mapping': [('k' + camel_case(k), enum_for_css_keyword(k)) f
or k in property_['keywords']], |
| 372 } | 377 } |
| 373 | 378 |
| 374 return { | 379 return { |
| 375 'include_paths': self._include_paths, | 380 'include_paths': self._include_paths, |
| 376 'mappings': mappings, | 381 'mappings': mappings, |
| 377 } | 382 } |
| 378 | 383 |
| 379 if __name__ == '__main__': | 384 if __name__ == '__main__': |
| 380 json5_generator.Maker(ComputedStyleBaseWriter).main() | 385 json5_generator.Maker(ComputedStyleBaseWriter).main() |
| OLD | NEW |