| {% from 'macros.tmpl' import license %} |
| {% from 'fields/field.tmpl' import encode, getter_expression, setter_expression, declare_storage, fieldwise_compare, fieldwise_copy, fieldwise_diff, fieldwise_pointer_compare_inherited %} |
| {% from 'fields/group.tmpl' import declare_field_group_class %} |
| {{license()}} |
| |
| #ifndef ComputedStyleBase_h |
| #define ComputedStyleBase_h |
| |
| #include "core/CoreExport.h" |
| #include "core/layout/LayoutTheme.h" |
| #include "core/style/ComputedStyleConstants.h" |
| #include "core/style/DataRef.h" |
| #include "core/style/MemberCopy.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 'fields/keyword.tmpl' as keyword %} |
| {% import 'fields/multi_keyword.tmpl' as multi_keyword %} |
| {% import 'fields/primitive.tmpl' as primitive %} |
| {% import 'fields/monotonic_flag.tmpl' as monotonic_flag %} |
| {% import 'fields/storage_only.tmpl' as storage_only %} |
| {% import 'fields/external.tmpl' as external %} |
| {% import 'fields/pointer.tmpl' as pointer %} |
| {% from 'fields/field.tmpl' import encode %} |
| {% set field_templates = { |
| 'keyword': keyword, |
| 'multi_keyword': multi_keyword, |
| 'primitive': primitive, |
| 'monotonic_flag': monotonic_flag, |
| 'storage_only': storage_only, |
| '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 CSSProperties.json5. |
| class CORE_EXPORT 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 in ('storage_only', 'monotonic_flag', 'external') %} |
| // {{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 // ComputedStyleBase_h |