1{% from 'templates/macros.tmpl' import license, print_if, source_files_for_generated_file %} 2{% from 'templates/fields/field.tmpl' import encode, getter_expression, setter_expression, declare_storage, fieldwise_compare, fieldwise_copy, fieldwise_diff, fieldwise_pointer_compare_inherited %} 3{% from 'templates/fields/group.tmpl' import declare_field_group_class %} 4{{license()}} 5 6{{source_files_for_generated_file(template_file, input_files)}} 7 8#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_H_ 9#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_H_ 10 11#include "third_party/blink/renderer/core/core_export.h" 12#include "third_party/blink/renderer/core/layout/layout_theme.h" 13#include "third_party/blink/renderer/core/style/computed_style_constants.h" 14#include "third_party/blink/renderer/core/style/data_ref.h" 15#include "third_party/blink/renderer/core/style/member_copy.h" 16#include "third_party/blink/renderer/core/style/computed_style_initial_values.h" 17{% for path in include_paths %} 18#include "{{path}}" 19{% endfor %} 20 21{# Each field template has macros that we can call to generate specific 22 aspects of the field (e.g. getters, setters). 23#} 24{% import 'templates/fields/keyword.tmpl' as keyword %} 25{% import 'templates/fields/multi_keyword.tmpl' as multi_keyword %} 26{% import 'templates/fields/primitive.tmpl' as primitive %} 27{% import 'templates/fields/monotonic_flag.tmpl' as monotonic_flag %} 28{% import 'templates/fields/external.tmpl' as external %} 29{% import 'templates/fields/pointer.tmpl' as pointer %} 30{% from 'templates/fields/field.tmpl' import encode %} 31{% set field_templates = { 32 'keyword': keyword, 33 'multi_keyword': multi_keyword, 34 'primitive': primitive, 35 'monotonic_flag': monotonic_flag, 36 'external': external, 37 'pointer': pointer 38 } %} 39 40namespace blink { 41 42// Forward declaration for diff functions. 43class ComputedStyle; 44 45// The generated portion of ComputedStyle. For more info, see the header comment 46// in ComputedStyle.h. 47// 48// ComputedStyleBase is a generated class that stores data members or 'fields' 49// used in ComputedStyle. These fields can represent CSS properties or internal 50// style information. 51// 52// STORAGE: 53// 54// Fields are organised in a tree structure, where a node (called a 'group') 55// stores a set of fields and a set of pointers to child nodes (called 56// 'subgroups'). We can visualise the tree structure with ComputedStyleBase as 57// the root node: 58// 59// ComputedStyleBase (fields: display, vertical-align, ...) 60// |- StyleSurroundData (fields: padding, border, ...) 61// |- StyleBoxData (fields: width, height, ...) 62// |- ... 63// |- StyleRareNonInheritedData (fields: box-shadow, text-overflow, ...) 64// |- StyleFlexibleBoxData (fields: flex-direction, flex-wrap, ...) 65// |- ... 66// 67// This design saves memory by allowing multiple ComputedStyleBases to share the 68// same instance of a subgroup. For example, if a page never uses flex box 69// properties, then every ComputedStyleBase can share the same instance of 70// StyleFlexibleBoxData. Without this sharing, we would need to allocate a copy 71// of all the flex box fields for every ComputedStyleBase. Similarly, when an 72// element inherits from its parent, its ComputedStyleBase can simply share all 73// of its subgroups with the parent's. 74// 75// INTERFACE: 76// 77// The functions generated for a field is determined by its 'template'. For 78// example, a field with the 'keyword' template has only one setter, whereas an 79// 'external' field has an extra setter that takes an rvalue reference. A list 80// of the available templates can be found in css_properties.json5. 81class ComputedStyleBase { 82 public: 83 inline bool IndependentInheritedEqual(const ComputedStyleBase& o) const { 84 return ( 85 {{fieldwise_compare(computed_style, computed_style.all_fields 86 |selectattr("is_property") 87 |selectattr("is_inherited") 88 |selectattr("is_independent") 89 |list 90 )|indent(8)}} 91 ); 92 } 93 94 inline bool NonIndependentInheritedEqual(const ComputedStyleBase& o) const { 95 return ( 96 {{fieldwise_compare(computed_style, computed_style.all_fields 97 |selectattr("is_property") 98 |selectattr("is_inherited") 99 |rejectattr("is_independent") 100 |list 101 )|indent(8)}} 102 ); 103 } 104 105 inline bool InheritedEqual(const ComputedStyleBase& o) const { 106 return IndependentInheritedEqual(o) && NonIndependentInheritedEqual(o); 107 } 108 109 inline bool NonInheritedEqual(const ComputedStyleBase& o) const { 110 return ( 111 {{fieldwise_compare(computed_style, computed_style.all_fields 112 |selectattr("is_property") 113 |rejectattr("is_inherited") 114 |list 115 )|indent(8)}} 116 ); 117 } 118 119 inline bool InheritedDataShared(const ComputedStyleBase& o) const { 120 return ( 121 {{fieldwise_pointer_compare_inherited(computed_style)|indent(8)}} 122 ); 123 } 124 125 enum IsAtShadowBoundary { 126 kAtShadowBoundary, 127 kNotAtShadowBoundary, 128 }; 129 130 void InheritFrom(const ComputedStyleBase& other, 131 IsAtShadowBoundary isAtShadowBoundary); 132 133 void CopyNonInheritedFromCached( 134 const ComputedStyleBase& other); 135 136 // Copies the values of any independent inherited properties from the parent 137 // style that are marked as inherited by this style. 138 void PropagateIndependentInheritedProperties( 139 const ComputedStyleBase& parentStyle); 140 141 {% for name, groups_to_diff in diff_functions_map.items() %} 142 static bool {{name}}(const ComputedStyle& a, const ComputedStyle& b); 143 {% endfor %} 144 145 // Fields. 146 // TODO(sashab): Remove initialFoo() static methods and update callers to 147 // use resetFoo(), which can be more efficient. 148 149 {% for field in computed_style.all_fields|sort(attribute='name') %} 150 // {{field.property_name}} 151 {{field_templates[field.field_template].decl_public_methods(field)|indent(2)}} 152 153 {% endfor %} 154 private: 155 {% for subgroup in computed_style.subgroups %} 156 {{declare_field_group_class(subgroup)|indent(2)}} 157 158 {% endfor %} 159 160 protected: 161 // Constructor and destructor are protected so that only the parent class ComputedStyle 162 // can instantiate this class. 163 ComputedStyleBase(); 164 165 {% for field in computed_style.all_fields|sort(attribute='name') %} 166 {% if field.field_template not in ('pointer',) %} 167 // {{field.property_name}} 168 {{field_templates[field.field_template].decl_protected_methods(field)|indent(2)}} 169 170 {% endif %} 171 {% endfor %} 172 173 ~ComputedStyleBase() = default; 174 175 private: 176 // Storage. 177 {% for subgroup in computed_style.subgroups %} 178 DataRef<{{subgroup.type_name}}> {{subgroup.member_name}}; 179 {% endfor %} 180 181 {% for field in computed_style.fields %} 182 {{declare_storage(field)}} 183 {% endfor %} 184}; 185 186} // namespace blink 187 188#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_H_ 189