blob: f90a511579caeead18c56c1ed94228ef4010de39 [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 counter_value = ToCSSPrimitiveValue(pair.Second()).GetIntValue();
CounterDirectives& directives =
map.insert(identifier, CounterDirectives()).stored_value->value;
{% if action == 'Reset' %}
directives.SetResetValue(counter_value);
{% else %}
directives.AddIncrementValue(counter_value);
{% endif %}
}
DCHECK(!map.IsEmpty());
}
{% endmacro %}
{{apply_counter('CSSPropertyCounterIncrement', 'Increment')}}
{{apply_counter('CSSPropertyCounterReset', 'Reset')}}
{% 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