1{% from 'macros.tmpl' import license %} 2{# 3 This file is for property handlers which use the templating engine to 4 reduce (handwritten) code duplication. 5 6 The `properties' dict can be used to access a property's parameters in 7 jinja2 templates (i.e. setter, getter, initial, type_name) 8#} 9#include "config.h" 10#include "StyleBuilderFunctions.h" 11 12#include "CSSValueKeywords.h" 13#include "core/css/BasicShapeFunctions.h" 14#include "core/css/CSSPrimitiveValueMappings.h" 15#include "core/css/Pair.h" 16#include "core/css/resolver/StyleResolverState.h" 17 18{% macro declare_initial_function(property_id) %} 19void StyleBuilderFunctions::applyInitial{{property_id}}(StyleResolverState& state) 20{%- endmacro %} 21{% macro declare_inherit_function(property_id) %} 22void StyleBuilderFunctions::applyInherit{{property_id}}(StyleResolverState& state) 23{%- endmacro %} 24{% macro declare_value_function(property_id) %} 25void StyleBuilderFunctions::applyValue{{property_id}}(StyleResolverState& state, CSSValue* value) 26{%- endmacro %} 27{% macro set_value(property) %} 28{% if property.svg %} 29state.style()->accessSVGStyle().{{property.setter}} 30{%- elif property.font %} 31state.fontBuilder().{{property.setter}} 32{%- else %} 33state.style()->{{property.setter}} 34{%- endif %} 35{% endmacro %} 36{% macro convert_and_set_value(property) %} 37{% if property.converter %} 38{{set_value(property)}}(StyleBuilderConverter::{{property.converter}}(state, value)); 39{%- else %} 40{{set_value(property)}}(static_cast<{{property.type_name}}>(*toCSSPrimitiveValue(value))); 41{%- endif %} 42{% endmacro %} 43 44namespace blink { 45 46{% for property_id, property in properties.items() if property.should_declare_functions %} 47{% set apply_type = property.apply_type %} 48{% if not property.custom_initial %} 49{{declare_initial_function(property_id)}} 50{ 51 {% if property.svg %} 52 {{set_value(property)}}(SVGRenderStyle::{{property.initial}}()); 53 {% elif property.font %} 54 {{set_value(property)}}(FontBuilder::{{property.initial}}()); 55 {% else %} 56 {{set_value(property)}}(RenderStyle::{{property.initial}}()); 57 {% endif %} 58} 59 60{% endif %} 61{% if not property.custom_inherit %} 62{{declare_inherit_function(property_id)}} 63{ 64 {% if property.svg %} 65 {{set_value(property)}}(state.parentStyle()->svgStyle().{{property.getter}}()); 66 {% elif property.font %} 67 {{set_value(property)}}(state.parentFontDescription().{{property.getter}}()); 68 {% else %} 69 {{set_value(property)}}(state.parentStyle()->{{property.getter}}()); 70 {% endif %} 71} 72 73{% endif %} 74{% if not property.custom_value %} 75{{declare_value_function(property_id)}} 76{ 77 {{convert_and_set_value(property)}} 78} 79 80{% endif %} 81{% endfor %} 82 83{% macro apply_animation(property_id, attribute, animation) %} 84{% set vector = attribute|lower_first + "List()" %} 85{{declare_initial_function(property_id)}} 86{ 87 CSS{{animation}}Data& data = state.style()->access{{animation}}s(); 88 data.{{vector}}.clear(); 89 data.{{vector}}.append(CSS{{animation}}Data::initial{{attribute}}()); 90} 91 92{{declare_inherit_function(property_id)}} 93{ 94 const CSS{{animation}}Data* parentData = state.parentStyle()->{{animation|lower}}s(); 95 if (!parentData) 96 applyInitial{{property_id}}(state); 97 else 98 state.style()->access{{animation}}s().{{vector}} = parentData->{{vector}}; 99} 100 101{{declare_value_function(property_id)}} 102{ 103 CSS{{animation}}Data& data = state.style()->access{{animation}}s(); 104 data.{{vector}}.clear(); 105 for (CSSValueListIterator i = value; i.hasMore(); i.advance()) 106 data.{{vector}}.append(state.styleMap().mapAnimation{{attribute}}(i.value())); 107} 108{% endmacro %} 109{{apply_animation('CSSPropertyWebkitAnimationDelay', 'Delay', 'Animation')}} 110{{apply_animation('CSSPropertyWebkitAnimationDirection', 'Direction', 'Animation')}} 111{{apply_animation('CSSPropertyWebkitAnimationDuration', 'Duration', 'Animation')}} 112{{apply_animation('CSSPropertyWebkitAnimationFillMode', 'FillMode', 'Animation')}} 113{{apply_animation('CSSPropertyWebkitAnimationIterationCount', 'IterationCount', 'Animation')}} 114{{apply_animation('CSSPropertyWebkitAnimationName', 'Name', 'Animation')}} 115{{apply_animation('CSSPropertyWebkitAnimationPlayState', 'PlayState', 'Animation')}} 116{{apply_animation('CSSPropertyWebkitAnimationTimingFunction', 'TimingFunction', 'Animation')}} 117{{apply_animation('CSSPropertyWebkitTransitionDelay', 'Delay', 'Transition')}} 118{{apply_animation('CSSPropertyWebkitTransitionDuration', 'Duration', 'Transition')}} 119{{apply_animation('CSSPropertyWebkitTransitionProperty', 'Property', 'Transition')}} 120{{apply_animation('CSSPropertyWebkitTransitionTimingFunction', 'TimingFunction', 'Transition')}} 121 122{% macro apply_auto(property_id, auto_getter=none, auto_setter=none, auto_identity='CSSValueAuto') %} 123{% set property = properties[property_id] %} 124{% set auto_getter = auto_getter or 'hasAuto' + property.name_for_methods %} 125{% set auto_setter = auto_setter or 'setHasAuto' + property.name_for_methods %} 126{{declare_initial_function(property_id)}} 127{ 128 state.style()->{{auto_setter}}(); 129} 130 131{{declare_inherit_function(property_id)}} 132{ 133 if (state.parentStyle()->{{auto_getter}}()) 134 state.style()->{{auto_setter}}(); 135 else 136 {{set_value(property)}}(state.parentStyle()->{{property.getter}}()); 137} 138 139{{declare_value_function(property_id)}} 140{ 141 if (!value->isPrimitiveValue()) 142 return; 143 144 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); 145 if (primitiveValue->getValueID() == {{auto_identity}}) 146 state.style()->{{auto_setter}}(); 147 else 148 {{convert_and_set_value(property)}} 149} 150{% endmacro %} 151{{apply_auto('CSSPropertyClip')}} 152{{apply_auto('CSSPropertyOrphans')}} 153{{apply_auto('CSSPropertyWebkitColumnCount')}} 154{{apply_auto('CSSPropertyWebkitColumnGap', auto_getter='hasNormalColumnGap', auto_setter='setHasNormalColumnGap', auto_identity='CSSValueNormal')}} 155{{apply_auto('CSSPropertyWebkitColumnWidth')}} 156{{apply_auto('CSSPropertyWidows')}} 157{{apply_auto('CSSPropertyZIndex')}} 158 159static bool lengthTypeAndValueMatch(const Length& length, LengthType type, float value) 160{ 161 return length.type() == type && length.value() == value; 162} 163 164static bool lengthTypeAndValueMatch(const LengthBox& lengthBox, LengthType type, float value) 165{ 166 return (lengthTypeAndValueMatch(lengthBox.left(), type, value) 167 && lengthTypeAndValueMatch(lengthBox.right(), type, value) 168 && lengthTypeAndValueMatch(lengthBox.top(), type, value) 169 && lengthTypeAndValueMatch(lengthBox.bottom(), type, value)); 170} 171 172static bool lengthTypeAndValueMatch(const BorderImageLength& borderImageLength, LengthType type, float value) 173{ 174 return borderImageLength.isLength() && lengthTypeAndValueMatch(borderImageLength.length(), type, value); 175} 176 177static bool lengthTypeAndValueMatch(const BorderImageLengthBox& borderImageLengthBox, LengthType type, float value) 178{ 179 return (lengthTypeAndValueMatch(borderImageLengthBox.left(), type, value) 180 && lengthTypeAndValueMatch(borderImageLengthBox.right(), type, value) 181 && lengthTypeAndValueMatch(borderImageLengthBox.top(), type, value) 182 && lengthTypeAndValueMatch(borderImageLengthBox.bottom(), type, value)); 183} 184 185{% macro apply_border_image_modifier(property_id, modifier_type) %} 186{% set is_mask_box = 'MaskBox' in property_id %} 187{% set getter = 'maskBoxImage' if is_mask_box else 'borderImage' %} 188{% set setter = 'setMaskBoxImage' if is_mask_box else 'setBorderImage' %} 189{{ declare_initial_function(property_id) }} 190{ 191 const NinePieceImage& currentImage = state.style()->{{getter}}(); 192 {# Check for equality in case we can bail out before creating a new NinePieceImage. #} 193 {% if modifier_type == 'Outset' %} 194 if (lengthTypeAndValueMatch(currentImage.outset(), Fixed, 0)) 195 return; 196 {% elif modifier_type == 'Repeat' %} 197 if (currentImage.horizontalRule() == StretchImageRule && currentImage.verticalRule() == StretchImageRule) 198 return; 199 {% elif modifier_type == 'Slice' and is_mask_box %} 200 // Masks have a different initial value for slices. Preserve the value of 0 for backwards compatibility. 201 if (currentImage.fill() == true && lengthTypeAndValueMatch(currentImage.imageSlices(), Fixed, 0)) 202 return; 203 {% elif modifier_type == 'Slice' and not is_mask_box %} 204 if (currentImage.fill() == false && lengthTypeAndValueMatch(currentImage.imageSlices(), Percent, 100)) 205 return; 206 {% elif modifier_type == 'Width' and is_mask_box %} 207 // Masks have a different initial value for widths. Preserve the value of 'auto' for backwards compatibility. 208 if (lengthTypeAndValueMatch(currentImage.borderSlices(), Auto, 0)) 209 return; 210 {% elif modifier_type == 'Width' and not is_mask_box %} 211 if (lengthTypeAndValueMatch(currentImage.borderSlices(), Fixed, 1)) 212 return; 213 {% endif %} 214 215 NinePieceImage image(currentImage); 216 {% if modifier_type == 'Outset' %} 217 image.setOutset(Length(0, Fixed)); 218 {% elif modifier_type == 'Repeat' %} 219 image.setHorizontalRule(StretchImageRule); 220 image.setVerticalRule(StretchImageRule); 221 {% elif modifier_type == 'Slice' and is_mask_box %} 222 image.setImageSlices(LengthBox({{ (['Length(0, Fixed)']*4) | join(', ') }})); 223 image.setFill(true); 224 {% elif modifier_type == 'Slice' and not is_mask_box %} 225 image.setImageSlices(LengthBox({{ (['Length(100, Percent)']*4) | join(', ') }})); 226 image.setFill(false); 227 {% elif modifier_type == 'Width' %} 228 image.setBorderSlices({{ 'Length(Auto)' if is_mask_box else '1.0' }}); 229 {% endif %} 230 state.style()->{{setter}}(image); 231} 232 233{{declare_inherit_function(property_id)}} 234{ 235 NinePieceImage image(state.style()->{{getter}}()); 236 {% if modifier_type == 'Outset' %} 237 image.copyOutsetFrom(state.parentStyle()->{{getter}}()); 238 {% elif modifier_type == 'Repeat' %} 239 image.copyRepeatFrom(state.parentStyle()->{{getter}}()); 240 {% elif modifier_type == 'Slice' %} 241 image.copyImageSlicesFrom(state.parentStyle()->{{getter}}()); 242 {% elif modifier_type == 'Width' %} 243 image.copyBorderSlicesFrom(state.parentStyle()->{{getter}}()); 244 {% endif %} 245 state.style()->{{setter}}(image); 246} 247 248{{declare_value_function(property_id)}} 249{ 250 NinePieceImage image(state.style()->{{getter}}()); 251 {% if modifier_type == 'Outset' %} 252 image.setOutset(state.styleMap().mapNinePieceImageQuad(value)); 253 {% elif modifier_type == 'Repeat' %} 254 state.styleMap().mapNinePieceImageRepeat(value, image); 255 {% elif modifier_type == 'Slice' %} 256 state.styleMap().mapNinePieceImageSlice(value, image); 257 {% elif modifier_type == 'Width' %} 258 image.setBorderSlices(state.styleMap().mapNinePieceImageQuad(value)); 259 {% endif %} 260 state.style()->{{setter}}(image); 261} 262{% endmacro %} 263{{apply_border_image_modifier('CSSPropertyBorderImageOutset', 'Outset')}} 264{{apply_border_image_modifier('CSSPropertyBorderImageRepeat', 'Repeat')}} 265{{apply_border_image_modifier('CSSPropertyBorderImageSlice', 'Slice')}} 266{{apply_border_image_modifier('CSSPropertyBorderImageWidth', 'Width')}} 267{{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageOutset', 'Outset')}} 268{{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageRepeat', 'Repeat')}} 269{{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageSlice', 'Slice')}} 270{{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageWidth', 'Width')}} 271 272{% macro apply_value_border_image_source(property_id) %} 273{{declare_value_function(property_id)}} 274{ 275 {% set property = properties[property_id] %} 276 {{set_value(property)}}(state.styleImage({{property_id}}, value)); 277} 278{% endmacro %} 279{{apply_value_border_image_source('CSSPropertyBorderImageSource')}} 280{{apply_value_border_image_source('CSSPropertyWebkitMaskBoxImageSource')}} 281 282{% macro apply_color(property_id, initial_color='StyleColor::currentColor') %} 283{% set property = properties[property_id] %} 284{% set visited_link_setter = 'setVisitedLink' + property.name_for_methods %} 285{{declare_initial_function(property_id)}} 286{ 287 StyleColor color = {{initial_color}}(); 288 if (state.applyPropertyToRegularStyle()) 289 {{set_value(property)}}(color); 290 if (state.applyPropertyToVisitedLinkStyle()) 291 state.style()->{{visited_link_setter}}(color); 292} 293 294{{declare_inherit_function(property_id)}} 295{ 296 // Visited link style can never explicitly inherit from parent visited link style so no separate getters are needed. 297 StyleColor color = state.parentStyle()->{{property.getter}}(); 298 Color resolvedColor = color.resolve(state.parentStyle()->color()); 299 if (state.applyPropertyToRegularStyle()) 300 {{set_value(property)}}(resolvedColor); 301 if (state.applyPropertyToVisitedLinkStyle()) 302 state.style()->{{visited_link_setter}}(resolvedColor); 303} 304 305{{declare_value_function(property_id)}} 306{ 307 if (state.applyPropertyToRegularStyle()) 308 {{set_value(property)}}(StyleBuilderConverter::convertStyleColor(state, value)); 309 if (state.applyPropertyToVisitedLinkStyle()) 310 state.style()->{{visited_link_setter}}(StyleBuilderConverter::convertStyleColor(state, value, true)); 311} 312{% endmacro %} 313{{apply_color('CSSPropertyBackgroundColor', initial_color='RenderStyle::initialBackgroundColor') }} 314{{apply_color('CSSPropertyBorderBottomColor')}} 315{{apply_color('CSSPropertyBorderLeftColor')}} 316{{apply_color('CSSPropertyBorderRightColor')}} 317{{apply_color('CSSPropertyBorderTopColor')}} 318{{apply_color('CSSPropertyOutlineColor')}} 319{{apply_color('CSSPropertyTextDecorationColor')}} 320{{apply_color('CSSPropertyWebkitColumnRuleColor')}} 321{{apply_color('CSSPropertyWebkitTextEmphasisColor')}} 322{{apply_color('CSSPropertyWebkitTextFillColor')}} 323{{apply_color('CSSPropertyWebkitTextStrokeColor')}} 324 325{% macro apply_counter(property_id, action) %} 326{% set property = properties[property_id] %} 327{{declare_initial_function(property_id)}} { } 328 329{{declare_inherit_function(property_id)}} 330{ 331 CounterDirectiveMap& map = state.style()->accessCounterDirectives(); 332 CounterDirectiveMap& parentMap = state.parentStyle()->accessCounterDirectives(); 333 334 typedef CounterDirectiveMap::iterator Iterator; 335 Iterator end = parentMap.end(); 336 for (Iterator it = parentMap.begin(); it != end; ++it) { 337 CounterDirectives& directives = map.add(it->key, CounterDirectives()).storedValue->value; 338 directives.inherit{{action}}(it->value); 339 } 340} 341 342{{declare_value_function(property_id)}} 343{ 344 CounterDirectiveMap& map = state.style()->accessCounterDirectives(); 345 typedef CounterDirectiveMap::iterator Iterator; 346 347 Iterator end = map.end(); 348 for (Iterator it = map.begin(); it != end; ++it) 349 it->value.clear{{action}}(); 350 351 if (!value->isValueList()) { 352 ASSERT(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNone); 353 return; 354 } 355 356 CSSValueList* list = toCSSValueList(value); 357 358 int length = list ? list->length() : 0; 359 for (int i = 0; i < length; ++i) { 360 CSSValue* currValue = list->item(i); 361 if (!currValue->isPrimitiveValue()) 362 continue; 363 364 Pair* pair = toCSSPrimitiveValue(currValue)->getPairValue(); 365 if (!pair || !pair->first() || !pair->second()) 366 continue; 367 368 AtomicString identifier(pair->first()->getStringValue()); 369 int value = pair->second()->getIntValue(); 370 CounterDirectives& directives = map.add(identifier, CounterDirectives()).storedValue->value; 371 {% if action == 'Reset' %} 372 directives.setResetValue(value); 373 {% else %} 374 directives.addIncrementValue(value); 375 {% endif %} 376 } 377} 378{% endmacro %} 379{{apply_counter('CSSPropertyCounterIncrement', 'Increment')}} 380{{apply_counter('CSSPropertyCounterReset', 'Reset')}} 381 382{% macro apply_fill_layer(property_id, fill_type) %} 383{% set layer_type = 'Background' if 'Background' in property_id else 'Mask' %} 384{% set fill_layer_type = layer_type + 'FillLayer' %} 385{% set access_layers = 'access' + layer_type + 'Layers' %} 386{% set map_fill = 'mapFill' + fill_type %} 387{{declare_initial_function(property_id)}} 388{ 389 FillLayer* currChild = &state.style()->{{access_layers}}(); 390 currChild->set{{fill_type}}(FillLayer::initialFill{{fill_type}}({{fill_layer_type}})); 391 for (currChild = currChild->next(); currChild; currChild = currChild->next()) 392 currChild->clear{{fill_type}}(); 393} 394 395{{declare_inherit_function(property_id)}} 396{ 397 FillLayer* currChild = &state.style()->{{access_layers}}(); 398 FillLayer* prevChild = 0; 399 const FillLayer* currParent = &state.parentStyle()->{{layer_type|lower}}Layers(); 400 while (currParent && currParent->is{{fill_type}}Set()) { 401 if (!currChild) 402 currChild = prevChild->ensureNext(); 403 currChild->set{{fill_type}}(currParent->{{fill_type|lower_first}}()); 404 prevChild = currChild; 405 currChild = prevChild->next(); 406 currParent = currParent->next(); 407 } 408 409 while (currChild) { 410 /* Reset any remaining layers to not have the property set. */ 411 currChild->clear{{fill_type}}(); 412 currChild = currChild->next(); 413 } 414} 415 416{{declare_value_function(property_id)}} 417{ 418 FillLayer* currChild = &state.style()->{{access_layers}}(); 419 FillLayer* prevChild = 0; 420 if (value->isValueList() && !value->isImageSetValue()) { 421 /* Walk each value and put it into a layer, creating new layers as needed. */ 422 CSSValueList* valueList = toCSSValueList(value); 423 for (unsigned int i = 0; i < valueList->length(); i++) { 424 if (!currChild) 425 currChild = prevChild->ensureNext(); 426 state.styleMap().{{map_fill}}(currChild, valueList->item(i)); 427 prevChild = currChild; 428 currChild = currChild->next(); 429 } 430 } else { 431 state.styleMap().{{map_fill}}(currChild, value); 432 currChild = currChild->next(); 433 } 434 while (currChild) { 435 /* Reset all remaining layers to not have the property set. */ 436 currChild->clear{{fill_type}}(); 437 currChild = currChild->next(); 438 } 439} 440{% endmacro %} 441{{apply_fill_layer('CSSPropertyBackgroundAttachment', 'Attachment')}} 442{{apply_fill_layer('CSSPropertyBackgroundBlendMode', 'BlendMode')}} 443{{apply_fill_layer('CSSPropertyBackgroundClip', 'Clip')}} 444{{apply_fill_layer('CSSPropertyBackgroundImage', 'Image')}} 445{{apply_fill_layer('CSSPropertyBackgroundOrigin', 'Origin')}} 446{{apply_fill_layer('CSSPropertyBackgroundPositionX', 'XPosition')}} 447{{apply_fill_layer('CSSPropertyBackgroundPositionY', 'YPosition')}} 448{{apply_fill_layer('CSSPropertyBackgroundRepeatX', 'RepeatX')}} 449{{apply_fill_layer('CSSPropertyBackgroundRepeatY', 'RepeatY')}} 450{{apply_fill_layer('CSSPropertyBackgroundSize', 'Size')}} 451{{apply_fill_layer('CSSPropertyMaskSourceType', 'MaskSourceType')}} 452{{apply_fill_layer('CSSPropertyWebkitBackgroundComposite', 'Composite')}} 453{{apply_fill_layer('CSSPropertyWebkitMaskClip', 'Clip')}} 454{{apply_fill_layer('CSSPropertyWebkitMaskComposite', 'Composite')}} 455{{apply_fill_layer('CSSPropertyWebkitMaskImage', 'Image')}} 456{{apply_fill_layer('CSSPropertyWebkitMaskOrigin', 'Origin')}} 457{{apply_fill_layer('CSSPropertyWebkitMaskPositionX', 'XPosition')}} 458{{apply_fill_layer('CSSPropertyWebkitMaskPositionY', 'YPosition')}} 459{{apply_fill_layer('CSSPropertyWebkitMaskRepeatX', 'RepeatX')}} 460{{apply_fill_layer('CSSPropertyWebkitMaskRepeatY', 'RepeatY')}} 461{{apply_fill_layer('CSSPropertyWebkitMaskSize', 'Size')}} 462 463{% macro apply_grid_template(property_id, type) %} 464{{declare_initial_function(property_id)}} 465{ 466 state.style()->setGridTemplate{{type}}s(RenderStyle::initialGridTemplate{{type}}s()); 467 state.style()->setNamedGrid{{type}}Lines(RenderStyle::initialNamedGrid{{type}}Lines()); 468 state.style()->setOrderedNamedGrid{{type}}Lines(RenderStyle::initialOrderedNamedGrid{{type}}Lines()); 469} 470 471{{declare_inherit_function(property_id)}} 472{ 473 state.style()->setGridTemplate{{type}}s(state.parentStyle()->gridTemplate{{type}}s()); 474 state.style()->setNamedGrid{{type}}Lines(state.parentStyle()->namedGrid{{type}}Lines()); 475 state.style()->setOrderedNamedGrid{{type}}Lines(state.parentStyle()->orderedNamedGrid{{type}}Lines()); 476} 477 478{{declare_value_function(property_id)}} 479{ 480 Vector<GridTrackSize> trackSizes; 481 NamedGridLinesMap namedGridLines; 482 OrderedNamedGridLines orderedNamedGridLines; 483 if (!StyleBuilderConverter::convertGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, state)) 484 return; 485 const NamedGridAreaMap& namedGridAreas = state.style()->namedGridArea(); 486 if (!namedGridAreas.isEmpty()) 487 StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(namedGridAreas, namedGridLines, For{{type}}s); 488 state.style()->setGridTemplate{{type}}s(trackSizes); 489 state.style()->setNamedGrid{{type}}Lines(namedGridLines); 490 state.style()->setOrderedNamedGrid{{type}}Lines(orderedNamedGridLines); 491} 492{% endmacro %} 493{{apply_grid_template('CSSPropertyGridTemplateColumns', 'Column')}} 494{{apply_grid_template('CSSPropertyGridTemplateRows', 'Row')}} 495 496{% macro apply_value_number(property_id, id_for_minus_one) %} 497{{declare_value_function(property_id)}} 498{ 499 {% set property = properties[property_id] %} 500 if (!value->isPrimitiveValue()) 501 return; 502 503 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); 504 if (primitiveValue->getValueID() == {{id_for_minus_one}}) 505 {{set_value(property)}}(-1); 506 else 507 {{set_value(property)}}(primitiveValue->getValue<{{property.type_name}}>(CSSPrimitiveValue::CSS_NUMBER)); 508} 509{% endmacro %} 510{{apply_value_number('CSSPropertyInternalMarqueeRepetition', 'CSSValueInfinite')}} 511 512{% macro apply_value_shape(property_id) %} 513{{declare_value_function(property_id)}} 514{ 515 {% set property = properties[property_id] %} 516 if (value->isPrimitiveValue()) { 517 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); 518 if (primitiveValue->getValueID() == CSSValueNone) 519 {{set_value(property)}}(nullptr); 520 } else if (value->isImageValue() || value->isImageGeneratorValue() || value->isImageSetValue()) { 521 {{set_value(property)}}(ShapeValue::createImageValue(state.styleImage({{property_id}}, value))); 522 } else if (value->isValueList()) { 523 RefPtr<BasicShape> shape; 524 CSSBoxType cssBox = BoxMissing; 525 CSSValueList* valueList = toCSSValueList(value); 526 for (unsigned i = 0; i < valueList->length(); ++i) { 527 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(valueList->item(i)); 528 if (primitiveValue->isShape()) 529 shape = basicShapeForValue(state, primitiveValue->getShapeValue()); 530 else if (primitiveValue->getValueID() == CSSValueContentBox 531 || primitiveValue->getValueID() == CSSValueBorderBox 532 || primitiveValue->getValueID() == CSSValuePaddingBox 533 || primitiveValue->getValueID() == CSSValueMarginBox) 534 cssBox = CSSBoxType(*primitiveValue); 535 else 536 return; 537 } 538 539 if (shape) 540 {{set_value(property)}}(ShapeValue::createShapeValue(shape.release(), cssBox)); 541 else if (cssBox != BoxMissing) 542 {{set_value(property)}}(ShapeValue::createBoxShapeValue(cssBox)); 543 } 544} 545{% endmacro %} 546{{apply_value_shape('CSSPropertyShapeOutside')}} 547 548{% macro apply_alignment(property_id, alignment_type) %} 549{% set property = properties[property_id] %} 550{{declare_initial_function(property_id)}} 551{ 552 state.style()->set{{alignment_type}}(RenderStyle::initial{{alignment_type}}()); 553 state.style()->set{{alignment_type}}OverflowAlignment(RenderStyle::initial{{alignment_type}}OverflowAlignment()); 554} 555 556{{declare_inherit_function(property_id)}} 557{ 558 state.style()->set{{alignment_type}}(state.parentStyle()->{{property.getter}}()); 559 state.style()->set{{alignment_type}}OverflowAlignment(state.parentStyle()->{{property.getter}}OverflowAlignment()); 560} 561 562{{declare_value_function(property_id)}} 563{ 564 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); 565 if (Pair* pairValue = primitiveValue->getPairValue()) { 566 state.style()->set{{alignment_type}}(*pairValue->first()); 567 state.style()->set{{alignment_type}}OverflowAlignment(*pairValue->second()); 568 } else { 569 state.style()->set{{alignment_type}}(*primitiveValue); 570 } 571} 572{% endmacro %} 573{{apply_alignment('CSSPropertyJustifySelf', 'JustifySelf')}} 574{{apply_alignment('CSSPropertyAlignItems', 'AlignItems')}} 575{{apply_alignment('CSSPropertyAlignSelf', 'AlignSelf')}} 576 577{% macro apply_svg_paint(property_id, paint_type) %} 578{% set property = properties[property_id] %} 579{{declare_initial_function(property_id)}} 580{ 581 {{set_value(property)}}( 582 SVGRenderStyle::initial{{paint_type}}Type(), 583 SVGRenderStyle::initial{{paint_type}}Color(), 584 SVGRenderStyle::initial{{paint_type}}Uri(), 585 state.applyPropertyToRegularStyle(), 586 state.applyPropertyToVisitedLinkStyle()); 587} 588 589{{declare_inherit_function(property_id)}} 590{ 591 const SVGRenderStyle& svgParentStyle = state.parentStyle()->svgStyle(); 592 {{set_value(property)}}( 593 svgParentStyle.{{paint_type|lower_first}}Type(), 594 svgParentStyle.{{paint_type|lower_first}}Color(), 595 svgParentStyle.{{paint_type|lower_first}}Uri(), 596 state.applyPropertyToRegularStyle(), 597 state.applyPropertyToVisitedLinkStyle()); 598} 599 600{{declare_value_function(property_id)}} 601{ 602 String url; 603 if (value->isValueList()) { 604 CSSValueList* list = toCSSValueList(value); 605 ASSERT(list->length() > 1); 606 607 if (!list->item(0)->isPrimitiveValue()) 608 return; 609 610 CSSPrimitiveValue* pValue = toCSSPrimitiveValue(list->item(0)); 611 if (!pValue->isURI()) 612 return; 613 614 url = pValue->getStringValue(); 615 value = list->item(1); 616 } 617 if (value->isPrimitiveValue()) { 618 CSSPrimitiveValue* pValue = toCSSPrimitiveValue(value); 619 Color c; 620 SVGPaintType ptype = SVG_PAINTTYPE_RGBCOLOR; 621 if (pValue->isRGBColor()) { 622 c = pValue->getRGBA32Value(); 623 ptype = url.isEmpty() ? SVG_PAINTTYPE_RGBCOLOR : SVG_PAINTTYPE_URI_RGBCOLOR; 624 } else if (pValue->getValueID() == CSSValueCurrentcolor) { 625 c = state.style()->color(); 626 ptype = url.isEmpty() ? SVG_PAINTTYPE_CURRENTCOLOR : SVG_PAINTTYPE_URI_CURRENTCOLOR; 627 } else if (pValue->getValueID() == CSSValueNone) { 628 ptype = url.isEmpty() ? SVG_PAINTTYPE_NONE : SVG_PAINTTYPE_URI_NONE; 629 } else if (pValue->isURI()) { 630 ptype = SVG_PAINTTYPE_URI; 631 url = pValue->getStringValue(); 632 } else { 633 return; 634 } 635 {{set_value(property)}}(ptype, c, url, 636 state.applyPropertyToRegularStyle(), 637 state.applyPropertyToVisitedLinkStyle()); 638 } 639} 640{% endmacro %} 641{{apply_svg_paint('CSSPropertyFill', 'FillPaint')}} 642{{apply_svg_paint('CSSPropertyStroke', 'StrokePaint')}} 643} // namespace blink 644