blob: d44ecbba575459bed9abbe281424c4eef74b4f45 [file] [log] [blame]
{% from 'templates/macros.tmpl' import license, source_files_for_generated_file %}
{% from 'core/css/properties/templates/style_builder_functions.tmpl' import set_value, convert_and_set_value %}
{#
This file is for property handlers which use the templating engine to
reduce (handwritten) code duplication.
The `properties' dict can be used to access a property's parameters in
jinja2 templates (i.e. setter, getter, initial, type_name)
TODO(meade): Delete this file once all StyleBuilderFunction generation
is moved to the CSSProperty.
#}
{{source_files_for_generated_file(template_file, input_files)}}
#include "StyleBuilderFunctions.h"
#include "CSSValueKeywords.h"
#include "core/animation/css/CSSAnimationData.h"
#include "core/css/BasicShapeFunctions.h"
#include "core/css/CSSContentDistributionValue.h"
#include "core/css/CSSCustomIdentValue.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/CSSURIValue.h"
#include "core/css/CSSValuePair.h"
#include "core/css/resolver/StyleResolverState.h"
#include "core/style/ComputedStyle.h"
{% macro declare_initial_function(property_id) %}
void StyleBuilderFunctions::applyInitial{{property_id}}(StyleResolverState& state)
{%- endmacro %}
{% macro declare_inherit_function(property_id) %}
void StyleBuilderFunctions::applyInherit{{property_id}}(StyleResolverState& state)
{%- endmacro %}
{% macro declare_value_function(property_id) %}
void StyleBuilderFunctions::applyValue{{property_id}}(StyleResolverState& state, const CSSValue& value)
{%- endmacro %}
{% macro set_is_inherited(property) %}
state.Style()->{{property.is_inherited_setter}}
{%- endmacro %}
namespace blink {
{% for property in properties if property.should_declare_functions
and not property.use_property_class_in_stylebuilder %}
{% if not property.custom_apply_functions_initial %}
{{declare_initial_function(property.property_id)}} {
{% if property.svg %}
{{set_value(property)}}(SVGComputedStyle::{{property.initial}}());
{% elif property.font %}
{{set_value(property)}}(FontBuilder::{{property.initial}}());
{% else %}
{{set_value(property)}}(ComputedStyleInitialValues::{{property.initial}}());
{% endif %}
{% if property.independent %}
{{set_is_inherited(property)}}(false);
{% endif %}
}
{% endif %}
{% if not property.custom_apply_functions_inherit %}
{{declare_inherit_function(property.property_id)}} {
{% if property.svg %}
{{set_value(property)}}(state.ParentStyle()->SvgStyle().{{property.getter}}());
{% elif property.font %}
{{set_value(property)}}(state.ParentFontDescription().{{property.getter}}());
{% else %}
{{set_value(property)}}(state.ParentStyle()->{{property.getter}}());
{% endif %}
{% if property.independent %}
{{set_is_inherited(property)}}(true);
{% endif %}
}
{% endif %}
{% if not property.custom_apply_functions_value %}
{{declare_value_function(property.property_id)}} {
{{convert_and_set_value(property)}}
{% if property.independent %}
{{set_is_inherited(property)}}(false);
{% endif %}
}
{% endif %}
{% endfor %}
{% macro apply_animation(property_id, attribute, animation) %}
{% set vector = attribute + "List()" %}
{{declare_initial_function(property_id)}} {
CSS{{animation}}Data& data = state.Style()->Access{{animation}}s();
data.{{vector}}.clear();
data.{{vector}}.push_back(CSS{{animation}}Data::Initial{{attribute}}());
}
{{declare_inherit_function(property_id)}} {
const CSS{{animation}}Data* parentData = state.ParentStyle()->{{animation}}s();
if (!parentData)
applyInitial{{property_id}}(state);
else
state.Style()->Access{{animation}}s().{{vector}} = parentData->{{vector}};
}
{{declare_value_function(property_id)}} {
CSS{{animation}}Data& data = state.Style()->Access{{animation}}s();
data.{{vector}}.clear();
for (auto& listValue : ToCSSValueList(value))
data.{{vector}}.push_back(CSSToStyleMap::MapAnimation{{attribute}}(*listValue));
}
{% endmacro %}
{{apply_animation('CSSPropertyAnimationDelay', 'Delay', 'Animation')}}
{{apply_animation('CSSPropertyAnimationDirection', 'Direction', 'Animation')}}
{{apply_animation('CSSPropertyAnimationDuration', 'Duration', 'Animation')}}
{{apply_animation('CSSPropertyAnimationFillMode', 'FillMode', 'Animation')}}
{{apply_animation('CSSPropertyAnimationIterationCount', 'IterationCount', 'Animation')}}
{{apply_animation('CSSPropertyAnimationName', 'Name', 'Animation')}}
{{apply_animation('CSSPropertyAnimationPlayState', 'PlayState', 'Animation')}}
{{apply_animation('CSSPropertyAnimationTimingFunction', 'TimingFunction', 'Animation')}}
{{apply_animation('CSSPropertyTransitionDelay', 'Delay', 'Transition')}}
{{apply_animation('CSSPropertyTransitionDuration', 'Duration', 'Transition')}}
{{apply_animation('CSSPropertyTransitionProperty', 'Property', 'Transition')}}
{{apply_animation('CSSPropertyTransitionTimingFunction', 'TimingFunction', 'Transition')}}
{% macro apply_color(property_id, initial_color='StyleColor::CurrentColor') %}
{% set property = properties_by_id[property_id] %}
{% set visited_link_setter = 'SetVisitedLink' + property.name_for_methods %}
{{declare_initial_function(property_id)}} {
StyleColor color = {{initial_color}}();
if (state.ApplyPropertyToRegularStyle())
{{set_value(property)}}(color);
if (state.ApplyPropertyToVisitedLinkStyle())
state.Style()->{{visited_link_setter}}(color);
}
{{declare_inherit_function(property_id)}} {
// Visited link style can never explicitly inherit from parent visited link
// style so no separate getters are needed.
StyleColor color = state.ParentStyle()->{{property.getter}}();
if (state.ApplyPropertyToRegularStyle())
{{set_value(property)}}(color);
if (state.ApplyPropertyToVisitedLinkStyle())
state.Style()->{{visited_link_setter}}(color);
}
{{declare_value_function(property_id)}}
{
if (state.ApplyPropertyToRegularStyle())
{{set_value(property)}}(StyleBuilderConverter::ConvertStyleColor(state, value));
if (state.ApplyPropertyToVisitedLinkStyle()) {
state.Style()->{{visited_link_setter}}(
StyleBuilderConverter::ConvertStyleColor(state, value, true));
}
}
{% endmacro %}
{{apply_color('CSSPropertyBackgroundColor', initial_color='ComputedStyleInitialValues::InitialBackgroundColor') }}
{{apply_color('CSSPropertyBorderBottomColor')}}
{{apply_color('CSSPropertyBorderLeftColor')}}
{{apply_color('CSSPropertyBorderRightColor')}}
{{apply_color('CSSPropertyBorderTopColor')}}
{{apply_color('CSSPropertyOutlineColor')}}
{{apply_color('CSSPropertyTextDecorationColor')}}
{{apply_color('CSSPropertyColumnRuleColor')}}
{{apply_color('CSSPropertyWebkitTextEmphasisColor')}}
{{apply_color('CSSPropertyWebkitTextFillColor')}}
{{apply_color('CSSPropertyWebkitTextStrokeColor')}}
{% macro apply_counter(property_id, action) %}
{% set property = properties_by_id[property_id] %}
{{declare_initial_function(property_id)}} {
state.Style()->Clear{{action}}Directives();
}
{{declare_inherit_function(property_id)}} {
const CounterDirectiveMap* parentMap = state.ParentStyle()->GetCounterDirectives();
if (!parentMap)
return;
CounterDirectiveMap& map = state.Style()->AccessCounterDirectives();
DCHECK(!parentMap->IsEmpty());
typedef CounterDirectiveMap::const_iterator Iterator;
Iterator end = parentMap->end();
for (Iterator it = parentMap->begin(); it != end; ++it) {
CounterDirectives& directives = map.insert(it->key, CounterDirectives()).stored_value->value;
directives.Inherit{{action}}(it->value);
}
}
{{declare_value_function(property_id)}} {
state.Style()->Clear{{action}}Directives();
if (!value.IsValueList()) {
DCHECK(value.IsIdentifierValue());
DCHECK_EQ(ToCSSIdentifierValue(value).GetValueID(), CSSValueNone);
return;
}
CounterDirectiveMap& map = state.Style()->AccessCounterDirectives();
const CSSValueList& list = ToCSSValueList(value);
for (size_t i = 0; i < list.length(); ++i) {
const CSSValuePair& pair = ToCSSValuePair(list.Item(i));
AtomicString identifier(ToCSSCustomIdentValue(pair.First()).Value());
int value = ToCSSPrimitiveValue(pair.Second()).GetIntValue();
CounterDirectives& directives =
map.insert(identifier, CounterDirectives()).stored_value->value;
{% if action == 'Reset' %}
directives.SetResetValue(value);
{% else %}
directives.AddIncrementValue(value);
{% endif %}
}
DCHECK(!map.IsEmpty());
}
{% endmacro %}
{{apply_counter('CSSPropertyCounterIncrement', 'Increment')}}
{{apply_counter('CSSPropertyCounterReset', 'Reset')}}
{% macro apply_fill_layer(property_id, fill_type, fill_type_getter = None) %}
{% set layer_type = 'Background' if 'Background' in property_id else 'Mask' %}
{% set fill_layer_type = 'EFillLayerType::k' + layer_type %}
{% set access_layers = 'Access' + layer_type + 'Layers' %}
{% set map_fill = 'MapFill' + fill_type %}
{% set fill_type_getter = fill_type_getter or fill_type %}
{{declare_initial_function(property_id)}} {
FillLayer* currChild = &state.Style()->{{access_layers}}();
currChild->Set{{fill_type}}(FillLayer::InitialFill{{fill_type}}({{fill_layer_type}}));
for (currChild = currChild->Next(); currChild; currChild = currChild->Next())
currChild->Clear{{fill_type}}();
}
{{declare_inherit_function(property_id)}} {
FillLayer* currChild = &state.Style()->{{access_layers}}();
FillLayer* prevChild = 0;
const FillLayer* currParent = &state.ParentStyle()->{{layer_type}}Layers();
while (currParent && currParent->Is{{fill_type}}Set()) {
if (!currChild)
currChild = prevChild->EnsureNext();
currChild->Set{{fill_type}}(currParent->{{fill_type_getter}}());
prevChild = currChild;
currChild = prevChild->Next();
currParent = currParent->Next();
}
while (currChild) {
// Reset any remaining layers to not have the property set.
currChild->Clear{{fill_type}}();
currChild = currChild->Next();
}
}
{{declare_value_function(property_id)}} {
FillLayer* currChild = &state.Style()->{{access_layers}}();
FillLayer* prevChild = 0;
if (value.IsValueList() && !value.IsImageSetValue()) {
// Walk each value and put it into a layer, creating new layers as needed.
const CSSValueList& valueList = ToCSSValueList(value);
for (unsigned int i = 0; i < valueList.length(); i++) {
if (!currChild)
currChild = prevChild->EnsureNext();
CSSToStyleMap::{{map_fill}}(state, currChild, valueList.Item(i));
prevChild = currChild;
currChild = currChild->Next();
}
} else {
CSSToStyleMap::{{map_fill}}(state, currChild, value);
currChild = currChild->Next();
}
while (currChild) {
// Reset all remaining layers to not have the property set.
currChild->Clear{{fill_type}}();
currChild = currChild->Next();
}
}
{% endmacro %}
{{apply_fill_layer('CSSPropertyBackgroundAttachment', 'Attachment')}}
{{apply_fill_layer('CSSPropertyBackgroundBlendMode', 'BlendMode')}}
{{apply_fill_layer('CSSPropertyBackgroundClip', 'Clip')}}
{{apply_fill_layer('CSSPropertyBackgroundImage', 'Image', 'GetImage')}}
{{apply_fill_layer('CSSPropertyBackgroundOrigin', 'Origin')}}
{{apply_fill_layer('CSSPropertyBackgroundPositionX', 'XPosition')}}
{{apply_fill_layer('CSSPropertyBackgroundPositionY', 'YPosition')}}
{{apply_fill_layer('CSSPropertyBackgroundRepeatX', 'RepeatX')}}
{{apply_fill_layer('CSSPropertyBackgroundRepeatY', 'RepeatY')}}
{{apply_fill_layer('CSSPropertyBackgroundSize', 'Size', 'Size')}}
{{apply_fill_layer('CSSPropertyMaskSourceType', 'MaskSourceType')}}
{{apply_fill_layer('CSSPropertyWebkitMaskClip', 'Clip')}}
{{apply_fill_layer('CSSPropertyWebkitMaskComposite', 'Composite')}}
{{apply_fill_layer('CSSPropertyWebkitMaskImage', 'Image', 'GetImage')}}
{{apply_fill_layer('CSSPropertyWebkitMaskOrigin', 'Origin')}}
{{apply_fill_layer('CSSPropertyWebkitMaskPositionX', 'XPosition')}}
{{apply_fill_layer('CSSPropertyWebkitMaskPositionY', 'YPosition')}}
{{apply_fill_layer('CSSPropertyWebkitMaskRepeatX', 'RepeatX')}}
{{apply_fill_layer('CSSPropertyWebkitMaskRepeatY', 'RepeatY')}}
{{apply_fill_layer('CSSPropertyWebkitMaskSize', 'Size', 'Size')}}
{% macro apply_grid_template(property_id, type) %}
{{declare_initial_function(property_id)}} {
state.Style()->SetGridTemplate{{type}}s(ComputedStyleInitialValues::InitialGridTemplate{{type}}s());
state.Style()->SetNamedGrid{{type}}Lines(ComputedStyleInitialValues::InitialNamedGrid{{type}}Lines());
state.Style()->SetOrderedNamedGrid{{type}}Lines(ComputedStyleInitialValues::InitialOrderedNamedGrid{{type}}Lines());
state.Style()->SetGridAutoRepeat{{type}}s(ComputedStyleInitialValues::InitialGridAutoRepeat{{type}}s());
state.Style()->SetGridAutoRepeat{{type}}sInsertionPoint(ComputedStyleInitialValues::InitialGridAutoRepeat{{type}}sInsertionPoint());
state.Style()->SetAutoRepeatNamedGrid{{type}}Lines(ComputedStyleInitialValues::InitialNamedGrid{{type}}Lines());
state.Style()->SetAutoRepeatOrderedNamedGrid{{type}}Lines(ComputedStyleInitialValues::InitialOrderedNamedGrid{{type}}Lines());
state.Style()->SetGridAutoRepeat{{type}}sType(ComputedStyleInitialValues::InitialGridAutoRepeat{{type}}sType());
}
{{declare_inherit_function(property_id)}} {
state.Style()->SetGridTemplate{{type}}s(state.ParentStyle()->GridTemplate{{type}}s());
state.Style()->SetNamedGrid{{type}}Lines(state.ParentStyle()->NamedGrid{{type}}Lines());
state.Style()->SetOrderedNamedGrid{{type}}Lines(state.ParentStyle()->OrderedNamedGrid{{type}}Lines());
state.Style()->SetGridAutoRepeat{{type}}s(state.ParentStyle()->GridAutoRepeat{{type}}s());
state.Style()->SetGridAutoRepeat{{type}}sInsertionPoint(state.ParentStyle()->GridAutoRepeat{{type}}sInsertionPoint());
state.Style()->SetAutoRepeatNamedGrid{{type}}Lines(state.ParentStyle()->AutoRepeatNamedGrid{{type}}Lines());
state.Style()->SetAutoRepeatOrderedNamedGrid{{type}}Lines(state.ParentStyle()->AutoRepeatOrderedNamedGrid{{type}}Lines());
state.Style()->SetGridAutoRepeat{{type}}sType(state.ParentStyle()->GridAutoRepeat{{type}}sType());
}
{{declare_value_function(property_id)}} {
Vector<GridTrackSize> trackSizes;
Vector<GridTrackSize> autoRepeatTrackSizes;
NamedGridLinesMap namedGridLines;
OrderedNamedGridLines orderedNamedGridLines;
NamedGridLinesMap autoRepeatNamedGridLines;
OrderedNamedGridLines autoRepeatOrderedNamedGridLines;
AutoRepeatType autoRepeatType = ComputedStyleInitialValues::InitialGridAutoRepeatType();
size_t autoRepeatInsertionPoint =
ComputedStyleInitialValues::InitialGridAutoRepeatInsertionPoint();
StyleBuilderConverter::ConvertGridTrackList(
value, trackSizes, namedGridLines, orderedNamedGridLines,
autoRepeatTrackSizes, autoRepeatNamedGridLines,
autoRepeatOrderedNamedGridLines, autoRepeatInsertionPoint,
autoRepeatType, state);
const NamedGridAreaMap& namedGridAreas = state.Style()->NamedGridArea();
if (!namedGridAreas.IsEmpty()) {
StyleBuilderConverter::CreateImplicitNamedGridLinesFromGridArea(
namedGridAreas, namedGridLines, kFor{{type}}s);
}
state.Style()->SetGridTemplate{{type}}s(trackSizes);
state.Style()->SetNamedGrid{{type}}Lines(namedGridLines);
state.Style()->SetOrderedNamedGrid{{type}}Lines(orderedNamedGridLines);
state.Style()->SetGridAutoRepeat{{type}}s(autoRepeatTrackSizes);
state.Style()->SetGridAutoRepeat{{type}}sInsertionPoint(
autoRepeatInsertionPoint);
state.Style()->SetAutoRepeatNamedGrid{{type}}Lines(autoRepeatNamedGridLines);
state.Style()->SetAutoRepeatOrderedNamedGrid{{type}}Lines(
autoRepeatOrderedNamedGridLines);
state.Style()->SetGridAutoRepeat{{type}}sType(autoRepeatType);
}
{% endmacro %}
{{apply_grid_template('CSSPropertyGridTemplateColumns', 'Column')}}
{{apply_grid_template('CSSPropertyGridTemplateRows', 'Row')}}
{% macro apply_svg_paint(property_id, paint_type) %}
{% set property = properties_by_id[property_id] %}
{{declare_initial_function(property_id)}} {
{{set_value(property)}}(
SVGComputedStyle::Initial{{paint_type}}Type(),
SVGComputedStyle::Initial{{paint_type}}Color(),
SVGComputedStyle::Initial{{paint_type}}Uri(),
state.ApplyPropertyToRegularStyle(),
state.ApplyPropertyToVisitedLinkStyle());
}
{{declare_inherit_function(property_id)}} {
const SVGComputedStyle& svgParentStyle = state.ParentStyle()->SvgStyle();
{{set_value(property)}}(
svgParentStyle.{{paint_type}}Type(),
svgParentStyle.{{paint_type}}Color(),
svgParentStyle.{{paint_type}}Uri(),
state.ApplyPropertyToRegularStyle(),
state.ApplyPropertyToVisitedLinkStyle());
}
{{declare_value_function(property_id)}} {
const CSSValue* localValue = &value;
String url;
if (value.IsValueList()) {
const CSSValueList& list = ToCSSValueList(value);
DCHECK_EQ(list.length(), 2U);
url = ToCSSURIValue(list.Item(0)).Value();
localValue = &list.Item(1);
}
Color color;
SVGPaintType paintType = SVG_PAINTTYPE_RGBCOLOR;
if (localValue->IsURIValue()) {
paintType = SVG_PAINTTYPE_URI;
url = ToCSSURIValue(localValue)->Value();
} else if (localValue->IsIdentifierValue() &&
ToCSSIdentifierValue(localValue)->GetValueID() == CSSValueNone) {
paintType = url.IsEmpty() ? SVG_PAINTTYPE_NONE : SVG_PAINTTYPE_URI_NONE;
} else if (localValue->IsIdentifierValue() &&
ToCSSIdentifierValue(localValue)->GetValueID() == CSSValueCurrentcolor) {
color = state.Style()->GetColor();
paintType = url.IsEmpty() ? SVG_PAINTTYPE_CURRENTCOLOR
: SVG_PAINTTYPE_URI_CURRENTCOLOR;
} else {
color = StyleBuilderConverter::ConvertColor(state, *localValue);
paintType = url.IsEmpty() ? SVG_PAINTTYPE_RGBCOLOR
: SVG_PAINTTYPE_URI_RGBCOLOR;
}
{{set_value(property)}}(paintType, color, url,
state.ApplyPropertyToRegularStyle(),
state.ApplyPropertyToVisitedLinkStyle());
}
{% endmacro %}
{{apply_svg_paint('CSSPropertyFill', 'FillPaint')}}
{{apply_svg_paint('CSSPropertyStroke', 'StrokePaint')}}
} // namespace blink