| {% 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 |