Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / build / scripts / templates / StyleBuilderFunctions.cpp.tmpl
bloba45c65b2685e32602ef8224cabe672edfa5d5ba1
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.
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"
12 #include "CSSValueKeywords.h"
13 #include "core/css/BasicShapeFunctions.h"
14 #include "core/css/CSSContentDistributionValue.h"
15 #include "core/css/CSSPrimitiveValueMappings.h"
16 #include "core/css/CSSValuePair.h"
17 #include "core/css/resolver/StyleResolverState.h"
19 {% macro declare_initial_function(property_id) %}
20 void StyleBuilderFunctions::applyInitial{{property_id}}(StyleResolverState& state)
21 {%- endmacro %}
22 {% macro declare_inherit_function(property_id) %}
23 void StyleBuilderFunctions::applyInherit{{property_id}}(StyleResolverState& state)
24 {%- endmacro %}
25 {% macro declare_value_function(property_id) %}
26 void StyleBuilderFunctions::applyValue{{property_id}}(StyleResolverState& state, CSSValue* value)
27 {%- endmacro %}
28 {% macro set_value(property) %}
29 {% if property.svg %}
30 state.style()->accessSVGStyle().{{property.setter}}
31 {%- elif property.font %}
32 state.fontBuilder().{{property.setter}}
33 {%- else %}
34 state.style()->{{property.setter}}
35 {%- endif %}
36 {% endmacro %}
37 {% macro convert_and_set_value(property) %}
38 {% if property.converter %}
39 {{set_value(property)}}(StyleBuilderConverter::{{property.converter}}(state, value));
40 {%- else %}
41 {{set_value(property)}}(static_cast<{{property.type_name}}>(*toCSSPrimitiveValue(value)));
42 {%- endif %}
43 {% endmacro %}
45 namespace blink {
47 {% for property_id, property in properties.items() if property.should_declare_functions %}
48 {% set apply_type = property.apply_type %}
49 {% if not property.custom_initial %}
50 {{declare_initial_function(property_id)}}
52     {% if property.svg %}
53     {{set_value(property)}}(SVGComputedStyle::{{property.initial}}());
54     {% elif property.font %}
55     {{set_value(property)}}(FontBuilder::{{property.initial}}());
56     {% else %}
57     {{set_value(property)}}(ComputedStyle::{{property.initial}}());
58     {% endif %}
61 {% endif %}
62 {% if not property.custom_inherit %}
63 {{declare_inherit_function(property_id)}}
65     {% if property.svg %}
66     {{set_value(property)}}(state.parentStyle()->svgStyle().{{property.getter}}());
67     {% elif property.font %}
68     {{set_value(property)}}(state.parentFontDescription().{{property.getter}}());
69     {% else %}
70     {{set_value(property)}}(state.parentStyle()->{{property.getter}}());
71     {% endif %}
74 {% endif %}
75 {% if not property.custom_value %}
76 {{declare_value_function(property_id)}}
78     {{convert_and_set_value(property)}}
81 {% endif %}
82 {% endfor %}
84 {% macro apply_animation(property_id, attribute, animation) %}
85 {% set vector = attribute|lower_first + "List()" %}
86 {{declare_initial_function(property_id)}}
88     CSS{{animation}}Data& data = state.style()->access{{animation}}s();
89     data.{{vector}}.clear();
90     data.{{vector}}.append(CSS{{animation}}Data::initial{{attribute}}());
93 {{declare_inherit_function(property_id)}}
95     const CSS{{animation}}Data* parentData = state.parentStyle()->{{animation|lower}}s();
96     if (!parentData)
97         applyInitial{{property_id}}(state);
98     else
99         state.style()->access{{animation}}s().{{vector}} = parentData->{{vector}};
102 {{declare_value_function(property_id)}}
104     CSS{{animation}}Data& data = state.style()->access{{animation}}s();
105     data.{{vector}}.clear();
106     for (auto& listValue : toCSSValueList(*value))
107         data.{{vector}}.append(CSSToStyleMap::mapAnimation{{attribute}}(listValue.get()));
109 {% endmacro %}
110 {{apply_animation('CSSPropertyAnimationDelay', 'Delay', 'Animation')}}
111 {{apply_animation('CSSPropertyAnimationDirection', 'Direction', 'Animation')}}
112 {{apply_animation('CSSPropertyAnimationDuration', 'Duration', 'Animation')}}
113 {{apply_animation('CSSPropertyAnimationFillMode', 'FillMode', 'Animation')}}
114 {{apply_animation('CSSPropertyAnimationIterationCount', 'IterationCount', 'Animation')}}
115 {{apply_animation('CSSPropertyAnimationName', 'Name', 'Animation')}}
116 {{apply_animation('CSSPropertyAnimationPlayState', 'PlayState', 'Animation')}}
117 {{apply_animation('CSSPropertyAnimationTimingFunction', 'TimingFunction', 'Animation')}}
118 {{apply_animation('CSSPropertyTransitionDelay', 'Delay', 'Transition')}}
119 {{apply_animation('CSSPropertyTransitionDuration', 'Duration', 'Transition')}}
120 {{apply_animation('CSSPropertyTransitionProperty', 'Property', 'Transition')}}
121 {{apply_animation('CSSPropertyTransitionTimingFunction', 'TimingFunction', 'Transition')}}
123 {% macro apply_auto(property_id, auto_getter=none, auto_setter=none, auto_identity='CSSValueAuto') %}
124 {% set property = properties[property_id] %}
125 {% set auto_getter = auto_getter or 'hasAuto' + property.name_for_methods %}
126 {% set auto_setter = auto_setter or 'setHasAuto' + property.name_for_methods %}
127 {{declare_initial_function(property_id)}}
129     state.style()->{{auto_setter}}();
132 {{declare_inherit_function(property_id)}}
134     if (state.parentStyle()->{{auto_getter}}())
135         state.style()->{{auto_setter}}();
136     else
137         {{set_value(property)}}(state.parentStyle()->{{property.getter}}());
140 {{declare_value_function(property_id)}}
142     if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == {{auto_identity}})
143         state.style()->{{auto_setter}}();
144     else
145         {{convert_and_set_value(property)}}
147 {% endmacro %}
148 {{apply_auto('CSSPropertyClip')}}
149 {{apply_auto('CSSPropertyOrphans')}}
150 {{apply_auto('CSSPropertyWebkitColumnCount')}}
151 {{apply_auto('CSSPropertyWebkitColumnGap', auto_getter='hasNormalColumnGap', auto_setter='setHasNormalColumnGap', auto_identity='CSSValueNormal')}}
152 {{apply_auto('CSSPropertyWebkitColumnWidth')}}
153 {{apply_auto('CSSPropertyWidows')}}
154 {{apply_auto('CSSPropertyZIndex')}}
156 static bool lengthMatchesAllSides(const LengthBox& lengthBox, const Length& length)
158     return (lengthBox.left() == length
159         && lengthBox.right() == length
160         && lengthBox.top() == length
161         && lengthBox.bottom() == length);
164 static bool borderImageLengthMatchesAllSides(const BorderImageLengthBox& borderImageLengthBox, const BorderImageLength& borderImageLength)
166     return (borderImageLengthBox.left() == borderImageLength
167         && borderImageLengthBox.right() == borderImageLength
168         && borderImageLengthBox.top() == borderImageLength
169         && borderImageLengthBox.bottom() == borderImageLength);
172 {% macro apply_border_image_modifier(property_id, modifier_type) %}
173 {% set is_mask_box = 'MaskBox' in property_id %}
174 {% set getter = 'maskBoxImage' if is_mask_box else 'borderImage' %}
175 {% set setter = 'setMaskBoxImage' if is_mask_box else 'setBorderImage' %}
176 {{ declare_initial_function(property_id) }}
178     const NinePieceImage& currentImage = state.style()->{{getter}}();
179     {# Check for equality in case we can bail out before creating a new NinePieceImage. #}
180     {% if modifier_type == 'Outset' %}
181     if (borderImageLengthMatchesAllSides(currentImage.outset(), BorderImageLength(Length(0, Fixed))))
182         return;
183     {% elif modifier_type == 'Repeat' %}
184     if (currentImage.horizontalRule() == StretchImageRule && currentImage.verticalRule() == StretchImageRule)
185         return;
186     {% elif modifier_type == 'Slice' and is_mask_box %}
187     // Masks have a different initial value for slices. Preserve the value of 0 for backwards compatibility.
188     if (currentImage.fill() == true && lengthMatchesAllSides(currentImage.imageSlices(), Length(0, Fixed)))
189         return;
190     {% elif modifier_type == 'Slice' and not is_mask_box %}
191     if (currentImage.fill() == false && lengthMatchesAllSides(currentImage.imageSlices(), Length(100, Percent)))
192         return;
193     {% elif modifier_type == 'Width' and is_mask_box %}
194     // Masks have a different initial value for widths. Preserve the value of 'auto' for backwards compatibility.
195     if (borderImageLengthMatchesAllSides(currentImage.borderSlices(), BorderImageLength(Length(Auto))))
196         return;
197     {% elif modifier_type == 'Width' and not is_mask_box %}
198     if (borderImageLengthMatchesAllSides(currentImage.borderSlices(), BorderImageLength(1.0)))
199         return;
200     {% endif %}
202     NinePieceImage image(currentImage);
203     {% if modifier_type == 'Outset' %}
204     image.setOutset(Length(0, Fixed));
205     {% elif modifier_type == 'Repeat' %}
206     image.setHorizontalRule(StretchImageRule);
207     image.setVerticalRule(StretchImageRule);
208     {% elif modifier_type == 'Slice' and is_mask_box %}
209     image.setImageSlices(LengthBox({{ (['Length(0, Fixed)']*4) | join(', ') }}));
210     image.setFill(true);
211     {% elif modifier_type == 'Slice' and not is_mask_box %}
212     image.setImageSlices(LengthBox({{ (['Length(100, Percent)']*4) | join(', ') }}));
213     image.setFill(false);
214     {% elif modifier_type == 'Width' %}
215     image.setBorderSlices({{ 'Length(Auto)' if is_mask_box else '1.0' }});
216     {% endif %}
217     state.style()->{{setter}}(image);
220 {{declare_inherit_function(property_id)}}
222     NinePieceImage image(state.style()->{{getter}}());
223     {% if modifier_type == 'Outset' %}
224     image.copyOutsetFrom(state.parentStyle()->{{getter}}());
225     {% elif modifier_type == 'Repeat' %}
226     image.copyRepeatFrom(state.parentStyle()->{{getter}}());
227     {% elif modifier_type == 'Slice' %}
228     image.copyImageSlicesFrom(state.parentStyle()->{{getter}}());
229     {% elif modifier_type == 'Width' %}
230     image.copyBorderSlicesFrom(state.parentStyle()->{{getter}}());
231     {% endif %}
232     state.style()->{{setter}}(image);
235 {{declare_value_function(property_id)}}
237     NinePieceImage image(state.style()->{{getter}}());
238     {% if modifier_type == 'Outset' %}
239     image.setOutset(CSSToStyleMap::mapNinePieceImageQuad(state, value));
240     {% elif modifier_type == 'Repeat' %}
241     CSSToStyleMap::mapNinePieceImageRepeat(state, value, image);
242     {% elif modifier_type == 'Slice' %}
243     CSSToStyleMap::mapNinePieceImageSlice(state, value, image);
244     {% elif modifier_type == 'Width' %}
245     image.setBorderSlices(CSSToStyleMap::mapNinePieceImageQuad(state, value));
246     {% endif %}
247     state.style()->{{setter}}(image);
249 {% endmacro %}
250 {{apply_border_image_modifier('CSSPropertyBorderImageOutset', 'Outset')}}
251 {{apply_border_image_modifier('CSSPropertyBorderImageRepeat', 'Repeat')}}
252 {{apply_border_image_modifier('CSSPropertyBorderImageSlice', 'Slice')}}
253 {{apply_border_image_modifier('CSSPropertyBorderImageWidth', 'Width')}}
254 {{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageOutset', 'Outset')}}
255 {{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageRepeat', 'Repeat')}}
256 {{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageSlice', 'Slice')}}
257 {{apply_border_image_modifier('CSSPropertyWebkitMaskBoxImageWidth', 'Width')}}
259 {% macro apply_value_border_image_source(property_id) %}
260 {{declare_value_function(property_id)}}
262     {% set property = properties[property_id] %}
263     {{set_value(property)}}(state.styleImage({{property_id}}, value));
265 {% endmacro %}
266 {{apply_value_border_image_source('CSSPropertyBorderImageSource')}}
267 {{apply_value_border_image_source('CSSPropertyWebkitMaskBoxImageSource')}}
269 {% macro apply_color(property_id, initial_color='StyleColor::currentColor') %}
270 {% set property = properties[property_id] %}
271 {% set visited_link_setter = 'setVisitedLink' + property.name_for_methods %}
272 {{declare_initial_function(property_id)}}
274     StyleColor color = {{initial_color}}();
275     if (state.applyPropertyToRegularStyle())
276         {{set_value(property)}}(color);
277     if (state.applyPropertyToVisitedLinkStyle())
278         state.style()->{{visited_link_setter}}(color);
281 {{declare_inherit_function(property_id)}}
283     // Visited link style can never explicitly inherit from parent visited link style so no separate getters are needed.
284     StyleColor color = state.parentStyle()->{{property.getter}}();
285     if (state.applyPropertyToRegularStyle())
286         {{set_value(property)}}(color);
287     if (state.applyPropertyToVisitedLinkStyle())
288         state.style()->{{visited_link_setter}}(color);
291 {{declare_value_function(property_id)}}
293     if (state.applyPropertyToRegularStyle())
294         {{set_value(property)}}(StyleBuilderConverter::convertStyleColor(state, value));
295     if (state.applyPropertyToVisitedLinkStyle())
296         state.style()->{{visited_link_setter}}(StyleBuilderConverter::convertStyleColor(state, value, true));
298 {% endmacro %}
299 {{apply_color('CSSPropertyBackgroundColor', initial_color='ComputedStyle::initialBackgroundColor') }}
300 {{apply_color('CSSPropertyBorderBottomColor')}}
301 {{apply_color('CSSPropertyBorderLeftColor')}}
302 {{apply_color('CSSPropertyBorderRightColor')}}
303 {{apply_color('CSSPropertyBorderTopColor')}}
304 {{apply_color('CSSPropertyOutlineColor')}}
305 {{apply_color('CSSPropertyTextDecorationColor')}}
306 {{apply_color('CSSPropertyWebkitColumnRuleColor')}}
307 {{apply_color('CSSPropertyWebkitTextEmphasisColor')}}
308 {{apply_color('CSSPropertyWebkitTextFillColor')}}
309 {{apply_color('CSSPropertyWebkitTextStrokeColor')}}
311 {% macro apply_counter(property_id, action) %}
312 {% set property = properties[property_id] %}
313 {{declare_initial_function(property_id)}} {
314     state.style()->clear{{action}}Directives();
317 {{declare_inherit_function(property_id)}}
319     const CounterDirectiveMap* parentMap = state.parentStyle()->counterDirectives();
320     if (!parentMap)
321         return;
323     CounterDirectiveMap& map = state.style()->accessCounterDirectives();
324     ASSERT(!parentMap->isEmpty());
326     typedef CounterDirectiveMap::const_iterator Iterator;
327     Iterator end = parentMap->end();
328     for (Iterator it = parentMap->begin(); it != end; ++it) {
329         CounterDirectives& directives = map.add(it->key, CounterDirectives()).storedValue->value;
330         directives.inherit{{action}}(it->value);
331     }
334 {{declare_value_function(property_id)}}
336     state.style()->clear{{action}}Directives();
338     if (!value->isValueList()) {
339         ASSERT(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
340         return;
341     }
343     CounterDirectiveMap& map = state.style()->accessCounterDirectives();
345     CSSValueList* list = toCSSValueList(value);
347     int length = list ? list->length() : 0;
348     for (int i = 0; i < length; ++i) {
349         const CSSValuePair* pair = toCSSValuePair(list->item(i));
350         AtomicString identifier(toCSSPrimitiveValue(pair->first()).getStringValue());
351         int value = toCSSPrimitiveValue(pair->second()).getIntValue();
352         CounterDirectives& directives = map.add(identifier, CounterDirectives()).storedValue->value;
353         {% if action == 'Reset' %}
354         directives.setResetValue(value);
355         {% else %}
356         directives.addIncrementValue(value);
357         {% endif %}
358     }
359     ASSERT(!map.isEmpty());
361 {% endmacro %}
362 {{apply_counter('CSSPropertyCounterIncrement', 'Increment')}}
363 {{apply_counter('CSSPropertyCounterReset', 'Reset')}}
365 {% macro apply_fill_layer(property_id, fill_type) %}
366 {% set layer_type = 'Background' if 'Background' in property_id else 'Mask' %}
367 {% set fill_layer_type = layer_type + 'FillLayer' %}
368 {% set access_layers = 'access' + layer_type + 'Layers' %}
369 {% set map_fill = 'mapFill' + fill_type %}
370 {{declare_initial_function(property_id)}}
372     FillLayer* currChild = &state.style()->{{access_layers}}();
373     currChild->set{{fill_type}}(FillLayer::initialFill{{fill_type}}({{fill_layer_type}}));
374     for (currChild = currChild->next(); currChild; currChild = currChild->next())
375         currChild->clear{{fill_type}}();
378 {{declare_inherit_function(property_id)}}
380     FillLayer* currChild = &state.style()->{{access_layers}}();
381     FillLayer* prevChild = 0;
382     const FillLayer* currParent = &state.parentStyle()->{{layer_type|lower}}Layers();
383     while (currParent && currParent->is{{fill_type}}Set()) {
384         if (!currChild)
385             currChild = prevChild->ensureNext();
386         currChild->set{{fill_type}}(currParent->{{fill_type|lower_first}}());
387         prevChild = currChild;
388         currChild = prevChild->next();
389         currParent = currParent->next();
390     }
392     while (currChild) {
393         /* Reset any remaining layers to not have the property set. */
394         currChild->clear{{fill_type}}();
395         currChild = currChild->next();
396     }
399 {{declare_value_function(property_id)}}
401     FillLayer* currChild = &state.style()->{{access_layers}}();
402     FillLayer* prevChild = 0;
403     if (value->isValueList() && !value->isImageSetValue()) {
404         /* Walk each value and put it into a layer, creating new layers as needed. */
405         CSSValueList* valueList = toCSSValueList(value);
406         for (unsigned int i = 0; i < valueList->length(); i++) {
407             if (!currChild)
408                 currChild = prevChild->ensureNext();
409             CSSToStyleMap::{{map_fill}}(state, currChild, valueList->item(i));
410             prevChild = currChild;
411             currChild = currChild->next();
412         }
413     } else {
414         CSSToStyleMap::{{map_fill}}(state, currChild, value);
415         currChild = currChild->next();
416     }
417     while (currChild) {
418         /* Reset all remaining layers to not have the property set. */
419         currChild->clear{{fill_type}}();
420         currChild = currChild->next();
421     }
423 {% endmacro %}
424 {{apply_fill_layer('CSSPropertyBackgroundAttachment', 'Attachment')}}
425 {{apply_fill_layer('CSSPropertyBackgroundBlendMode', 'BlendMode')}}
426 {{apply_fill_layer('CSSPropertyBackgroundClip', 'Clip')}}
427 {{apply_fill_layer('CSSPropertyBackgroundImage', 'Image')}}
428 {{apply_fill_layer('CSSPropertyBackgroundOrigin', 'Origin')}}
429 {{apply_fill_layer('CSSPropertyBackgroundPositionX', 'XPosition')}}
430 {{apply_fill_layer('CSSPropertyBackgroundPositionY', 'YPosition')}}
431 {{apply_fill_layer('CSSPropertyBackgroundRepeatX', 'RepeatX')}}
432 {{apply_fill_layer('CSSPropertyBackgroundRepeatY', 'RepeatY')}}
433 {{apply_fill_layer('CSSPropertyBackgroundSize', 'Size')}}
434 {{apply_fill_layer('CSSPropertyMaskSourceType', 'MaskSourceType')}}
435 {{apply_fill_layer('CSSPropertyWebkitBackgroundComposite', 'Composite')}}
436 {{apply_fill_layer('CSSPropertyWebkitMaskClip', 'Clip')}}
437 {{apply_fill_layer('CSSPropertyWebkitMaskComposite', 'Composite')}}
438 {{apply_fill_layer('CSSPropertyWebkitMaskImage', 'Image')}}
439 {{apply_fill_layer('CSSPropertyWebkitMaskOrigin', 'Origin')}}
440 {{apply_fill_layer('CSSPropertyWebkitMaskPositionX', 'XPosition')}}
441 {{apply_fill_layer('CSSPropertyWebkitMaskPositionY', 'YPosition')}}
442 {{apply_fill_layer('CSSPropertyWebkitMaskRepeatX', 'RepeatX')}}
443 {{apply_fill_layer('CSSPropertyWebkitMaskRepeatY', 'RepeatY')}}
444 {{apply_fill_layer('CSSPropertyWebkitMaskSize', 'Size')}}
446 {% macro apply_grid_template(property_id, type) %}
447 {{declare_initial_function(property_id)}}
449     state.style()->setGridTemplate{{type}}s(ComputedStyle::initialGridTemplate{{type}}s());
450     state.style()->setNamedGrid{{type}}Lines(ComputedStyle::initialNamedGrid{{type}}Lines());
451     state.style()->setOrderedNamedGrid{{type}}Lines(ComputedStyle::initialOrderedNamedGrid{{type}}Lines());
454 {{declare_inherit_function(property_id)}}
456     state.style()->setGridTemplate{{type}}s(state.parentStyle()->gridTemplate{{type}}s());
457     state.style()->setNamedGrid{{type}}Lines(state.parentStyle()->namedGrid{{type}}Lines());
458     state.style()->setOrderedNamedGrid{{type}}Lines(state.parentStyle()->orderedNamedGrid{{type}}Lines());
461 {{declare_value_function(property_id)}}
463     Vector<GridTrackSize> trackSizes;
464     NamedGridLinesMap namedGridLines;
465     OrderedNamedGridLines orderedNamedGridLines;
466     StyleBuilderConverter::convertGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, state);
467     const NamedGridAreaMap& namedGridAreas = state.style()->namedGridArea();
468     if (!namedGridAreas.isEmpty())
469         StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(namedGridAreas, namedGridLines, For{{type}}s);
470     state.style()->setGridTemplate{{type}}s(trackSizes);
471     state.style()->setNamedGrid{{type}}Lines(namedGridLines);
472     state.style()->setOrderedNamedGrid{{type}}Lines(orderedNamedGridLines);
474 {% endmacro %}
475 {{apply_grid_template('CSSPropertyGridTemplateColumns', 'Column')}}
476 {{apply_grid_template('CSSPropertyGridTemplateRows', 'Row')}}
478 {% macro apply_svg_paint(property_id, paint_type) %}
479 {% set property = properties[property_id] %}
480 {{declare_initial_function(property_id)}}
482     {{set_value(property)}}(
483         SVGComputedStyle::initial{{paint_type}}Type(),
484         SVGComputedStyle::initial{{paint_type}}Color(),
485         SVGComputedStyle::initial{{paint_type}}Uri(),
486         state.applyPropertyToRegularStyle(),
487         state.applyPropertyToVisitedLinkStyle());
490 {{declare_inherit_function(property_id)}}
492     const SVGComputedStyle& svgParentStyle = state.parentStyle()->svgStyle();
493     {{set_value(property)}}(
494         svgParentStyle.{{paint_type|lower_first}}Type(),
495         svgParentStyle.{{paint_type|lower_first}}Color(),
496         svgParentStyle.{{paint_type|lower_first}}Uri(),
497         state.applyPropertyToRegularStyle(),
498         state.applyPropertyToVisitedLinkStyle());
501 {{declare_value_function(property_id)}}
503     String url;
504     if (value->isValueList()) {
505         CSSValueList* list = toCSSValueList(value);
506         ASSERT(list->length() == 2);
507         url = toCSSPrimitiveValue(list->item(0))->getStringValue();
508         value = list->item(1);
509     }
511     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
512     Color color;
513     SVGPaintType paintType = SVG_PAINTTYPE_RGBCOLOR;
514     if (primitiveValue->getValueID() == CSSValueNone) {
515         paintType = url.isEmpty() ? SVG_PAINTTYPE_NONE : SVG_PAINTTYPE_URI_NONE;
516     } else if (primitiveValue->isURI()) {
517         paintType = SVG_PAINTTYPE_URI;
518         url = primitiveValue->getStringValue();
519     } else if (primitiveValue->getValueID() == CSSValueCurrentcolor) {
520         color = state.style()->color();
521         paintType = url.isEmpty() ? SVG_PAINTTYPE_CURRENTCOLOR : SVG_PAINTTYPE_URI_CURRENTCOLOR;
522     } else {
523         color = StyleBuilderConverter::convertColor(state, primitiveValue);
524         paintType = url.isEmpty() ? SVG_PAINTTYPE_RGBCOLOR : SVG_PAINTTYPE_URI_RGBCOLOR;
525     }
526     {{set_value(property)}}(paintType, color, url,
527         state.applyPropertyToRegularStyle(),
528         state.applyPropertyToVisitedLinkStyle());
530 {% endmacro %}
531 {{apply_svg_paint('CSSPropertyFill', 'FillPaint')}}
532 {{apply_svg_paint('CSSPropertyStroke', 'StrokePaint')}}
533 } // namespace blink