| {% from "macros.tmpl" import wrap_with_condition -%} |
| |
| {# |
| 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, condition) |
| -#} |
| |
| #include "config.h" |
| #include "StyleBuilderFunctions.h" |
| |
| #include "CSSValueKeywords.h" |
| #include "core/css/CSSPrimitiveValueMappings.h" |
| #include "core/css/resolver/StyleResolver.h" |
| |
| {%- macro apply_initial(property_id) -%} |
| void StyleBuilderFunctions::applyInitial{{property_id}}(StyleResolver* styleResolver) |
| {%- endmacro %} |
| |
| {%- macro apply_inherit(property_id) -%} |
| void StyleBuilderFunctions::applyInherit{{property_id}}(StyleResolver* styleResolver) |
| {%- endmacro %} |
| |
| {%- macro apply_value(property_id) -%} |
| void StyleBuilderFunctions::applyValue{{property_id}}(StyleResolver* styleResolver, CSSValue* value) |
| {%- endmacro %} |
| |
| {%- macro set_value(property) -%} |
| styleResolver->style()->{{property.setter}} |
| {%- endmacro %} |
| |
| namespace WebCore { |
| |
| {%- macro apply_auto(property_id, auto_getter=none, auto_setter=none, auto_identity="CSSValueAuto", compute_length=false) %} |
| {%- set property = properties[property_id] %} |
| {%- set auto_getter = auto_getter or "hasAuto" + property.camel_case_name %} |
| {%- set auto_setter = auto_setter or "setHasAuto" + property.camel_case_name %} |
| {{ apply_initial(property_id) }} |
| { |
| styleResolver->style()->{{auto_setter}}(); |
| } |
| |
| {{ apply_inherit(property_id) }} |
| { |
| if (styleResolver->parentStyle()->{{auto_getter}}()) |
| styleResolver->style()->{{auto_setter}}(); |
| else |
| {{ set_value(property) }}(styleResolver->parentStyle()->{{property.getter}}()); |
| } |
| |
| {{ apply_value(property_id) }} |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (primitiveValue->getValueID() == {{auto_identity}}) |
| styleResolver->style()->{{auto_setter}}(); |
| else |
| {%- if compute_length %} |
| {{ set_value(property) }}(primitiveValue->computeLength<{{property.type_name}}>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom())); |
| {%- else %} |
| {{ set_value(property) }}(*primitiveValue); |
| {%- endif %} |
| } |
| {%- endmacro %} |
| |
| {{ apply_auto("CSSPropertyOrphans") }} |
| {{ apply_auto("CSSPropertyWebkitColumnCount") }} |
| {{ apply_auto("CSSPropertyWebkitColumnGap", auto_getter="hasNormalColumnGap", auto_setter="setHasNormalColumnGap", auto_identity="CSSValueNormal", compute_length=true) }} |
| {{ apply_auto("CSSPropertyWebkitColumnWidth", compute_length=true) }} |
| {{ apply_auto("CSSPropertyWidows") }} |
| {{ apply_auto("CSSPropertyZIndex") }} |
| |
| {%- macro apply_value_border_image(property_id) %} |
| {{ apply_value(property_id) }} |
| { |
| {%- set property = properties[property_id] %} |
| NinePieceImage image; |
| {%- if property_id == "CSSPropertyWebkitMaskBoxImage" %} |
| image.setMaskDefaults(); |
| {%- endif %} |
| styleResolver->styleMap()->mapNinePieceImage({{property_id}}, value, image); |
| {{ set_value(property) }}(image); |
| } |
| {%- endmacro %} |
| |
| {{ apply_value_border_image("CSSPropertyWebkitBorderImage") }} |
| {{ apply_value_border_image("CSSPropertyWebkitMaskBoxImage") }} |
| |
| {%- macro apply_color(property_id, default_getter="color", initial_color=none, inherit_color=false) %} |
| {%- set property = properties[property_id] %} |
| {%- call wrap_with_condition(property.condition) %} |
| {%- set visited_link_setter = "setVisitedLink" + property.camel_case_name %} |
| {{ apply_initial(property_id) }} |
| { |
| Color color = {{ initial_color or "Color" -}}(); |
| if (styleResolver->applyPropertyToRegularStyle()) |
| {{ set_value(property) }}(color); |
| if (styleResolver->applyPropertyToVisitedLinkStyle()) |
| styleResolver->style()->{{visited_link_setter}}(color); |
| } |
| |
| {{ apply_inherit(property_id) }} |
| { |
| // Visited link style can never explicitly inherit from parent visited link style so no separate getters are needed. |
| Color color = styleResolver->parentStyle()->{{property.getter}}(); |
| if (!color.isValid()) |
| color = styleResolver->parentStyle()->{{default_getter}}(); |
| if (styleResolver->applyPropertyToRegularStyle()) |
| {{ set_value(property) }}(color); |
| if (styleResolver->applyPropertyToVisitedLinkStyle()) |
| styleResolver->style()->{{visited_link_setter}}(color); |
| } |
| |
| {{ apply_value(property_id) }} |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| |
| {%- if inherit_color %} |
| if (primitiveValue->getValueID() == CSSValueCurrentcolor) { |
| applyInherit{{property_id}}(styleResolver); |
| return; |
| } |
| {%- endif %} |
| |
| if (styleResolver->applyPropertyToRegularStyle()) |
| {{ set_value(property) }}(styleResolver->colorFromPrimitiveValue(primitiveValue)); |
| if (styleResolver->applyPropertyToVisitedLinkStyle()) |
| styleResolver->style()->{{visited_link_setter}}(styleResolver->colorFromPrimitiveValue(primitiveValue, /* forVisitedLink */ true)); |
| } |
| {%- endcall %} |
| {%- endmacro %} |
| |
| {{ apply_color("CSSPropertyBackgroundColor", default_getter="invalidColor") }} |
| {{ apply_color("CSSPropertyBorderBottomColor") }} |
| {{ apply_color("CSSPropertyBorderLeftColor") }} |
| {{ apply_color("CSSPropertyBorderRightColor") }} |
| {{ apply_color("CSSPropertyBorderTopColor") }} |
| {{ apply_color("CSSPropertyColor", inherit_color=true, default_getter="invalidColor", initial_color="RenderStyle::initialColor") }} |
| {{ apply_color("CSSPropertyOutlineColor") }} |
| {{ apply_color("CSSPropertyTextDecorationColor") }} |
| {{ apply_color("CSSPropertyWebkitColumnRuleColor") }} |
| {{ apply_color("CSSPropertyWebkitTextEmphasisColor") }} |
| {{ apply_color("CSSPropertyWebkitTextFillColor") }} |
| {{ apply_color("CSSPropertyWebkitTextStrokeColor") }} |
| |
| {%- macro apply_fill_layer(property_id, fill_type) %} |
| {%- set layer_type = "Background" if "Background" in property_id else "Mask" %} |
| {%- set fill_layer_type = layer_type + "FillLayer" %} |
| {%- set access_layers = "access" + layer_type + "Layers" %} |
| {%- set map_fill = "mapFill" + fill_type %} |
| {{ apply_initial(property_id) }} |
| { |
| FillLayer* currChild = styleResolver->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}}(); |
| } |
| |
| {{ apply_inherit(property_id) }} |
| { |
| FillLayer* currChild = styleResolver->style()->{{access_layers}}(); |
| FillLayer* prevChild = 0; |
| const FillLayer* currParent = styleResolver->parentStyle()->{{layer_type|lower}}Layers(); |
| while (currParent && currParent->is{{fill_type}}Set()) { |
| if (!currChild) { |
| /* Need to make a new layer.*/ |
| currChild = new FillLayer({{fill_layer_type}}); |
| prevChild->setNext(currChild); |
| } |
| currChild->set{{fill_type}}(currParent->{{(fill_type[0]|lower) + fill_type[1:]}}()); |
| 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(); |
| } |
| } |
| |
| {{ apply_value(property_id) }} |
| { |
| FillLayer* currChild = styleResolver->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. */ |
| CSSValueList* valueList = toCSSValueList(value); |
| for (unsigned int i = 0; i < valueList->length(); i++) { |
| if (!currChild) { |
| /* Need to make a new layer to hold this value */ |
| currChild = new FillLayer({{fill_layer_type}}); |
| prevChild->setNext(currChild); |
| } |
| styleResolver->styleMap()->{{map_fill}}({{property_id}}, currChild, valueList->itemWithoutBoundsCheck(i)); |
| prevChild = currChild; |
| currChild = currChild->next(); |
| } |
| } else { |
| styleResolver->styleMap()->{{map_fill}}({{property_id}}, 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") }} |
| {{ 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") }} |
| {{ apply_fill_layer("CSSPropertyWebkitBackgroundComposite", "Composite") }} |
| {{ apply_fill_layer("CSSPropertyWebkitMaskClip", "Clip") }} |
| {{ apply_fill_layer("CSSPropertyWebkitMaskComposite", "Composite") }} |
| {{ apply_fill_layer("CSSPropertyWebkitMaskImage", "Image") }} |
| {{ 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") }} |
| |
| {%- macro apply_value_number(property_id, id_for_minus_one) %} |
| {{ apply_value(property_id) }} |
| { |
| {%- set property = properties[property_id] %} |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (primitiveValue->getValueID() == {{id_for_minus_one}}) |
| {{ set_value(property) }}(-1); |
| else |
| {{ set_value(property) }}(primitiveValue->getValue<{{property.type_name}}>(CSSPrimitiveValue::CSS_NUMBER)); |
| } |
| {%- endmacro %} |
| |
| {{ apply_value_number("CSSPropertyWebkitHyphenateLimitAfter", "CSSValueAuto") }} |
| {{ apply_value_number("CSSPropertyWebkitHyphenateLimitBefore", "CSSValueAuto") }} |
| {{ apply_value_number("CSSPropertyWebkitHyphenateLimitLines", "CSSValueNoLimit") }} |
| {{ apply_value_number("CSSPropertyWebkitMarqueeRepetition", "CSSValueInfinite") }} |
| |
| {%- macro apply_value_string(property_id, id_for_none) %} |
| {{ apply_value(property_id) }} |
| { |
| {%- set property = properties[property_id] %} |
| if (!value->isPrimitiveValue()) |
| return; |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (primitiveValue->getValueID() == {{id_for_none}}) |
| {{ set_value(property) }}(nullAtom); |
| else |
| {{ set_value(property) }}(primitiveValue->getStringValue()); |
| } |
| {%- endmacro %} |
| |
| {{ apply_value_string("CSSPropertyWebkitHighlight", "CSSValueNone") }} |
| {{ apply_value_string("CSSPropertyWebkitHyphenateCharacter", "CSSValueAuto") }} |
| {{ apply_value_string("CSSPropertyWebkitLineGrid", "CSSValueNone") }} |
| {{ apply_value_string("CSSPropertyWebkitFlowFrom", "CSSValueNone") }} |
| {{ apply_value_string("CSSPropertyWebkitFlowInto", "CSSValueNone") }} |
| |
| {{ apply_value("CSSPropertyWebkitMarqueeIncrement") }} |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (primitiveValue->getValueID()) { |
| switch (primitiveValue->getValueID()) { |
| case CSSValueSmall: |
| styleResolver->style()->setMarqueeIncrement(Length(1, Fixed)); // 1px. |
| break; |
| case CSSValueNormal: |
| styleResolver->style()->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default. |
| break; |
| case CSSValueLarge: |
| styleResolver->style()->setMarqueeIncrement(Length(36, Fixed)); // 36px. |
| break; |
| default: |
| break; |
| } |
| } else { |
| Length marqueeLength = styleResolver->convertToIntLength(primitiveValue, styleResolver->style(), styleResolver->rootElementStyle()); |
| if (!marqueeLength.isUndefined()) |
| styleResolver->style()->setMarqueeIncrement(marqueeLength); |
| } |
| } |
| |
| } // namespace WebCore |