diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/build/scripts/core/style/templates')
3 files changed, 308 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.cc.tmpl new file mode 100644 index 00000000000..5697ad5a947 --- /dev/null +++ b/chromium/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.cc.tmpl @@ -0,0 +1,81 @@ +{% from 'templates/macros.tmpl' import license, print_if, source_files_for_generated_file %} +{% from 'templates/fields/field.tmpl' import encode, getter_expression, setter_expression, fieldwise_copy, fieldwise_diff %} +{% from 'templates/fields/group.tmpl' import define_field_group_class %} +{{license()}} + +{{source_files_for_generated_file(template_file, input_files)}} + +#include "third_party/blink/renderer/core/style/computed_style.h" +#include "third_party/blink/renderer/core/style/computed_style_base.h" +#include "third_party/blink/renderer/platform/wtf/size_assertions.h" + +namespace blink { + +struct SameSizeAsComputedStyleBase { + {% if computed_style.subgroups is defined %} + void* dataRefs[{{computed_style.subgroups|length}}]; + {% endif %} + {% for field in computed_style.fields|rejectattr("is_bit_field") %} + {{field.type_name}} {{field.name}}; + {% endfor %} + unsigned m_bit_fields[{{computed_style.num_32_bit_words_for_bit_fields}}]; +}; + +// If this fails, the packing algorithm in make_computed_style_base.py has +// failed to produce the optimal packed size. To fix, update the algorithm to +// ensure that the buckets are placed so that each takes up at most 1 word. +ASSERT_SIZE(ComputedStyleBase, SameSizeAsComputedStyleBase); + +// Constructor and destructor are protected so that only the parent class ComputedStyle +// can instantiate this class. +ComputedStyleBase::ComputedStyleBase() : +{% set comma = joiner(", ") %} +{% for field in computed_style.fields %} + {{comma()}}{{field.name}}({{encode(field, field.default_value)}}) +{% endfor %} +{ + {% for subgroup in computed_style.subgroups %} + {{subgroup.member_name}}.Init(); + {% endfor %} +} + +void ComputedStyleBase::InheritFrom(const ComputedStyleBase& other, + IsAtShadowBoundary isAtShadowBoundary) { + {{fieldwise_copy(computed_style, computed_style.all_fields + |selectattr("is_property") + |selectattr("is_inherited") + |list + )|indent(2)}} +} + +void ComputedStyleBase::CopyNonInheritedFromCached( + const ComputedStyleBase& other) { + {{fieldwise_copy(computed_style, computed_style.all_fields + |rejectattr("has_custom_compare_and_copy") + |rejectattr("is_inherited") + |list + )|indent(2)}} +} + +void ComputedStyleBase::PropagateIndependentInheritedProperties( + const ComputedStyleBase& parentStyle) { + {% for field in computed_style.all_fields if field.is_property and field.is_independent %} + if ({{field.is_inherited_method_name}}()) + {{setter_expression(field)}} = parentStyle.{{getter_expression(field)}}; + {% endfor %} +} + +{% for name, groups_to_diff in diff_functions_map.items() %} +bool ComputedStyleBase::{{name}}(const ComputedStyle& a, const ComputedStyle& b) { + {{fieldwise_diff(groups_to_diff)|indent(4)}} + return false; +} + +{% endfor %} + +{% for group in computed_style.subgroups %} +{{define_field_group_class(group)}} + +{% endfor %} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl new file mode 100644 index 00000000000..eeaaa0586e5 --- /dev/null +++ b/chromium/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl @@ -0,0 +1,188 @@ +{% from 'templates/macros.tmpl' import license, print_if, source_files_for_generated_file %} +{% from 'templates/fields/field.tmpl' import encode, getter_expression, setter_expression, declare_storage, fieldwise_compare, fieldwise_copy, fieldwise_diff, fieldwise_pointer_compare_inherited %} +{% from 'templates/fields/group.tmpl' import declare_field_group_class %} +{{license()}} + +{{source_files_for_generated_file(template_file, input_files)}} + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/layout/layout_theme.h" +#include "third_party/blink/renderer/core/style/computed_style_constants.h" +#include "third_party/blink/renderer/core/style/data_ref.h" +#include "third_party/blink/renderer/core/style/member_copy.h" +#include "third_party/blink/renderer/core/style/computed_style_initial_values.h" +{% for path in include_paths %} +#include "{{path}}" +{% endfor %} + +{# Each field template has macros that we can call to generate specific + aspects of the field (e.g. getters, setters). +#} +{% import 'templates/fields/keyword.tmpl' as keyword %} +{% import 'templates/fields/multi_keyword.tmpl' as multi_keyword %} +{% import 'templates/fields/primitive.tmpl' as primitive %} +{% import 'templates/fields/monotonic_flag.tmpl' as monotonic_flag %} +{% import 'templates/fields/external.tmpl' as external %} +{% import 'templates/fields/pointer.tmpl' as pointer %} +{% from 'templates/fields/field.tmpl' import encode %} +{% set field_templates = { + 'keyword': keyword, + 'multi_keyword': multi_keyword, + 'primitive': primitive, + 'monotonic_flag': monotonic_flag, + 'external': external, + 'pointer': pointer + } %} + +namespace blink { + +// Forward declaration for diff functions. +class ComputedStyle; + +// The generated portion of ComputedStyle. For more info, see the header comment +// in ComputedStyle.h. +// +// ComputedStyleBase is a generated class that stores data members or 'fields' +// used in ComputedStyle. These fields can represent CSS properties or internal +// style information. +// +// STORAGE: +// +// Fields are organised in a tree structure, where a node (called a 'group') +// stores a set of fields and a set of pointers to child nodes (called +// 'subgroups'). We can visualise the tree structure with ComputedStyleBase as +// the root node: +// +// ComputedStyleBase (fields: display, vertical-align, ...) +// |- StyleSurroundData (fields: padding, border, ...) +// |- StyleBoxData (fields: width, height, ...) +// |- ... +// |- StyleRareNonInheritedData (fields: box-shadow, text-overflow, ...) +// |- StyleFlexibleBoxData (fields: flex-direction, flex-wrap, ...) +// |- ... +// +// This design saves memory by allowing multiple ComputedStyleBases to share the +// same instance of a subgroup. For example, if a page never uses flex box +// properties, then every ComputedStyleBase can share the same instance of +// StyleFlexibleBoxData. Without this sharing, we would need to allocate a copy +// of all the flex box fields for every ComputedStyleBase. Similarly, when an +// element inherits from its parent, its ComputedStyleBase can simply share all +// of its subgroups with the parent's. +// +// INTERFACE: +// +// The functions generated for a field is determined by its 'template'. For +// example, a field with the 'keyword' template has only one setter, whereas an +// 'external' field has an extra setter that takes an rvalue reference. A list +// of the available templates can be found in css_properties.json5. +class ComputedStyleBase { + public: + inline bool IndependentInheritedEqual(const ComputedStyleBase& o) const { + return ( + {{fieldwise_compare(computed_style, computed_style.all_fields + |selectattr("is_property") + |selectattr("is_inherited") + |selectattr("is_independent") + |list + )|indent(8)}} + ); + } + + inline bool NonIndependentInheritedEqual(const ComputedStyleBase& o) const { + return ( + {{fieldwise_compare(computed_style, computed_style.all_fields + |selectattr("is_property") + |selectattr("is_inherited") + |rejectattr("is_independent") + |list + )|indent(8)}} + ); + } + + inline bool InheritedEqual(const ComputedStyleBase& o) const { + return IndependentInheritedEqual(o) && NonIndependentInheritedEqual(o); + } + + inline bool NonInheritedEqual(const ComputedStyleBase& o) const { + return ( + {{fieldwise_compare(computed_style, computed_style.all_fields + |selectattr("is_property") + |rejectattr("is_inherited") + |list + )|indent(8)}} + ); + } + + inline bool InheritedDataShared(const ComputedStyleBase& o) const { + return ( + {{fieldwise_pointer_compare_inherited(computed_style)|indent(8)}} + ); + } + + enum IsAtShadowBoundary { + kAtShadowBoundary, + kNotAtShadowBoundary, + }; + + void InheritFrom(const ComputedStyleBase& other, + IsAtShadowBoundary isAtShadowBoundary); + + void CopyNonInheritedFromCached( + const ComputedStyleBase& other); + + // Copies the values of any independent inherited properties from the parent + // style that are marked as inherited by this style. + void PropagateIndependentInheritedProperties( + const ComputedStyleBase& parentStyle); + + {% for name, groups_to_diff in diff_functions_map.items() %} + static bool {{name}}(const ComputedStyle& a, const ComputedStyle& b); + {% endfor %} + + // Fields. + // TODO(sashab): Remove initialFoo() static methods and update callers to + // use resetFoo(), which can be more efficient. + + {% for field in computed_style.all_fields|sort(attribute='name') %} + // {{field.property_name}} + {{field_templates[field.field_template].decl_public_methods(field)|indent(2)}} + + {% endfor %} + private: + {% for subgroup in computed_style.subgroups %} + {{declare_field_group_class(subgroup)|indent(2)}} + + {% endfor %} + + protected: + // Constructor and destructor are protected so that only the parent class ComputedStyle + // can instantiate this class. + ComputedStyleBase(); + + {% for field in computed_style.all_fields|sort(attribute='name') %} + {% if field.field_template not in ('pointer',) %} + // {{field.property_name}} + {{field_templates[field.field_template].decl_protected_methods(field)|indent(2)}} + + {% endif %} + {% endfor %} + + ~ComputedStyleBase() = default; + + private: + // Storage. + {% for subgroup in computed_style.subgroups %} + DataRef<{{subgroup.type_name}}> {{subgroup.member_name}}; + {% endfor %} + + {% for field in computed_style.fields %} + {{declare_storage(field)}} + {% endfor %} +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_H_ diff --git a/chromium/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base_constants.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base_constants.h.tmpl new file mode 100644 index 00000000000..aee3668af2f --- /dev/null +++ b/chromium/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base_constants.h.tmpl @@ -0,0 +1,39 @@ +{% from 'templates/macros.tmpl' import license, print_if, source_files_for_generated_file %} +{{license()}} + +{{source_files_for_generated_file(template_file, input_files)}} + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_CONSTANTS_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_CONSTANTS_H_ + +namespace blink { + +// TODO(sashab): Move these enums to their own namespace, or add a CSS prefix, +// for consistency and to prevent name conflicts. + +{% for enum in enums %} +enum class {{enum.type_name}} : unsigned { + {% for value in enum.values %} + {{value}}{{print_if(enum.is_set, " = " ~ (0 if loop.first else 2**loop.index0))}}, + {% endfor %} +}; + +{% if enum.is_set %} +static const int k{{enum.type_name}}Bits = {{enum.values|length - 1}}; + +{% for op in ('|', '^') %} +inline {{enum.type_name}} operator{{op}}({{enum.type_name}} a, {{enum.type_name}} b) { + return static_cast<{{enum.type_name}}>( + static_cast<unsigned>(a) {{op}} static_cast<unsigned>(b) + ); +} +inline {{enum.type_name}}& operator{{op}}=({{enum.type_name}}& a, {{enum.type_name}} b) { + return a = a {{op}} b; +} + +{% endfor %} +{% endif %} +{% endfor %} +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_CONSTANTS_H_ |