f6c6fb717c75cf732184fdbd09e5b2afd9a5e15b
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / resolver / StyleBuilderCustom.cpp
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
4  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
5  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
6  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
7  * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
8  * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
9  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
10  * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
11  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are
14  * met:
15  *
16  *     * Redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer.
18  *     * Redistributions in binary form must reproduce the above
19  * copyright notice, this list of conditions and the following disclaimer
20  * in the documentation and/or other materials provided with the
21  * distribution.
22  *     * Neither the name of Google Inc. nor the names of its
23  * contributors may be used to endorse or promote products derived from
24  * this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */
38
39 #include "config.h"
40 #include "StyleBuilderFunctions.h"
41
42 #include "CSSPropertyNames.h"
43 #include "CSSValueKeywords.h"
44 #include "StylePropertyShorthand.h"
45 #include "core/css/BasicShapeFunctions.h"
46 #include "core/css/CSSAspectRatioValue.h"
47 #include "core/css/CSSCursorImageValue.h"
48 #include "core/css/CSSFontValue.h"
49 #include "core/css/CSSFunctionValue.h"
50 #include "core/css/CSSGradientValue.h"
51 #include "core/css/CSSGridLineNamesValue.h"
52 #include "core/css/CSSGridTemplateValue.h"
53 #include "core/css/CSSHelper.h"
54 #include "core/css/CSSImageSetValue.h"
55 #include "core/css/CSSLineBoxContainValue.h"
56 #include "core/css/parser/BisonCSSParser.h"
57 #include "core/css/CSSPrimitiveValueMappings.h"
58 #include "core/css/CSSProperty.h"
59 #include "core/css/CSSReflectValue.h"
60 #include "core/css/CSSVariableValue.h"
61 #include "core/css/Counter.h"
62 #include "core/css/Pair.h"
63 #include "core/css/Rect.h"
64 #include "core/css/StylePropertySet.h"
65 #include "core/css/StyleRule.h"
66 #include "core/css/resolver/ElementStyleResources.h"
67 #include "core/css/resolver/FilterOperationResolver.h"
68 #include "core/css/resolver/FontBuilder.h"
69 #include "core/css/resolver/StyleBuilder.h"
70 #include "core/css/resolver/TransformBuilder.h"
71 #include "core/frame/Frame.h"
72 #include "core/frame/Settings.h"
73 #include "core/rendering/style/CounterContent.h"
74 #include "core/rendering/style/CursorList.h"
75 #include "core/rendering/style/QuotesData.h"
76 #include "core/rendering/style/RenderStyle.h"
77 #include "core/rendering/style/RenderStyleConstants.h"
78 #include "core/rendering/style/SVGRenderStyle.h"
79 #include "core/rendering/style/SVGRenderStyleDefs.h"
80 #include "core/rendering/style/StyleGeneratedImage.h"
81 #include "core/svg/SVGColor.h"
82 #include "core/svg/SVGPaint.h"
83 #include "platform/fonts/FontDescription.h"
84 #include "wtf/MathExtras.h"
85 #include "wtf/StdLibExtras.h"
86 #include "wtf/Vector.h"
87
88 namespace WebCore {
89
90 static Length clipConvertToLength(StyleResolverState& state, CSSPrimitiveValue* value)
91 {
92     return value->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
93 }
94
95 void StyleBuilderFunctions::applyInitialCSSPropertyClip(StyleResolverState& state)
96 {
97     state.style()->setClip(Length(), Length(), Length(), Length());
98     state.style()->setHasClip(false);
99 }
100
101 void StyleBuilderFunctions::applyInheritCSSPropertyClip(StyleResolverState& state)
102 {
103     RenderStyle* parentStyle = state.parentStyle();
104     if (!parentStyle->hasClip())
105         return applyInitialCSSPropertyClip(state);
106     state.style()->setClip(parentStyle->clipTop(), parentStyle->clipRight(), parentStyle->clipBottom(), parentStyle->clipLeft());
107     state.style()->setHasClip(true);
108 }
109
110 void StyleBuilderFunctions::applyValueCSSPropertyClip(StyleResolverState& state, CSSValue* value)
111 {
112     if (!value->isPrimitiveValue())
113         return;
114
115     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
116
117     if (Rect* rect = primitiveValue->getRectValue()) {
118         Length top = clipConvertToLength(state, rect->top());
119         Length right = clipConvertToLength(state, rect->right());
120         Length bottom = clipConvertToLength(state, rect->bottom());
121         Length left = clipConvertToLength(state, rect->left());
122         state.style()->setClip(top, right, bottom, left);
123         state.style()->setHasClip(true);
124     } else if (primitiveValue->getValueID() == CSSValueAuto) {
125         state.style()->setClip(Length(), Length(), Length(), Length());
126         state.style()->setHasClip(false);
127     }
128 }
129
130 void StyleBuilderFunctions::applyInitialCSSPropertyColor(StyleResolverState& state)
131 {
132     Color color = RenderStyle::initialColor();
133     if (state.applyPropertyToRegularStyle())
134         state.style()->setColor(color);
135     if (state.applyPropertyToVisitedLinkStyle())
136         state.style()->setVisitedLinkColor(color);
137 }
138
139 void StyleBuilderFunctions::applyInheritCSSPropertyColor(StyleResolverState& state)
140 {
141     Color color = state.parentStyle()->color();
142     if (state.applyPropertyToRegularStyle())
143         state.style()->setColor(color);
144     if (state.applyPropertyToVisitedLinkStyle())
145         state.style()->setVisitedLinkColor(color);
146 }
147
148 void StyleBuilderFunctions::applyValueCSSPropertyColor(StyleResolverState& state, CSSValue* value)
149 {
150     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
151     // As per the spec, 'color: currentColor' is treated as 'color: inherit'
152     if (primitiveValue->getValueID() == CSSValueCurrentcolor) {
153         applyInheritCSSPropertyColor(state);
154         return;
155     }
156
157     if (state.applyPropertyToRegularStyle())
158         state.style()->setColor(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color()));
159     if (state.applyPropertyToVisitedLinkStyle())
160         state.style()->setVisitedLinkColor(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color(), state.element()->isLink() /* forVisitedLink */));
161 }
162
163 void StyleBuilderFunctions::applyInitialCSSPropertyCursor(StyleResolverState& state)
164 {
165     state.style()->clearCursorList();
166     state.style()->setCursor(RenderStyle::initialCursor());
167 }
168
169 void StyleBuilderFunctions::applyInheritCSSPropertyCursor(StyleResolverState& state)
170 {
171     state.style()->setCursor(state.parentStyle()->cursor());
172     state.style()->setCursorList(state.parentStyle()->cursors());
173 }
174
175 void StyleBuilderFunctions::applyValueCSSPropertyCursor(StyleResolverState& state, CSSValue* value)
176 {
177     state.style()->clearCursorList();
178     if (value->isValueList()) {
179         CSSValueList* list = toCSSValueList(value);
180         int len = list->length();
181         state.style()->setCursor(CURSOR_AUTO);
182         for (int i = 0; i < len; i++) {
183             CSSValue* item = list->itemWithoutBoundsCheck(i);
184             if (item->isCursorImageValue()) {
185                 CSSCursorImageValue* image = toCSSCursorImageValue(item);
186                 if (image->updateIfSVGCursorIsUsed(state.element())) // Elements with SVG cursors are not allowed to share style.
187                     state.style()->setUnique();
188                 state.style()->addCursor(state.styleImage(CSSPropertyCursor, image), image->hotSpot());
189             } else if (item->isPrimitiveValue()) {
190                 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item);
191                 if (primitiveValue->isValueID())
192                     state.style()->setCursor(*primitiveValue);
193             }
194         }
195     } else if (value->isPrimitiveValue()) {
196         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
197         if (primitiveValue->isValueID() && state.style()->cursor() != ECursor(*primitiveValue))
198             state.style()->setCursor(*primitiveValue);
199     }
200 }
201
202 void StyleBuilderFunctions::applyValueCSSPropertyDirection(StyleResolverState& state, CSSValue* value)
203 {
204     state.style()->setDirection(*toCSSPrimitiveValue(value));
205     Element* element = state.element();
206     if (element && element == element->document().documentElement())
207         element->document().setDirectionSetOnDocumentElement(true);
208 }
209
210 static inline bool isValidDisplayValue(StyleResolverState& state, EDisplay displayPropertyValue)
211 {
212     if (state.element() && state.element()->isSVGElement() && state.style()->styleType() == NOPSEUDO)
213         return (displayPropertyValue == INLINE || displayPropertyValue == BLOCK || displayPropertyValue == NONE);
214     return true;
215 }
216
217 void StyleBuilderFunctions::applyInheritCSSPropertyDisplay(StyleResolverState& state)
218 {
219     EDisplay display = state.parentStyle()->display();
220     if (!isValidDisplayValue(state, display))
221         return;
222     state.style()->setDisplay(display);
223 }
224
225 void StyleBuilderFunctions::applyValueCSSPropertyDisplay(StyleResolverState& state, CSSValue* value)
226 {
227     if (!value->isPrimitiveValue())
228         return;
229
230     EDisplay display = *toCSSPrimitiveValue(value);
231
232     if (!isValidDisplayValue(state, display))
233         return;
234
235     state.style()->setDisplay(display);
236 }
237
238 void StyleBuilderFunctions::applyInitialCSSPropertyFontFamily(StyleResolverState& state)
239 {
240     state.fontBuilder().setFontFamilyInitial(state.style()->effectiveZoom());
241 }
242
243 void StyleBuilderFunctions::applyInheritCSSPropertyFontFamily(StyleResolverState& state)
244 {
245     state.fontBuilder().setFontFamilyInherit(state.parentFontDescription());
246 }
247
248 void StyleBuilderFunctions::applyValueCSSPropertyFontFamily(StyleResolverState& state, CSSValue* value)
249 {
250     state.fontBuilder().setFontFamilyValue(value, state.style()->effectiveZoom());
251 }
252
253 void StyleBuilderFunctions::applyInitialCSSPropertyFontSize(StyleResolverState& state)
254 {
255     state.fontBuilder().setFontSizeInitial(state.style()->effectiveZoom());
256 }
257
258 void StyleBuilderFunctions::applyInheritCSSPropertyFontSize(StyleResolverState& state)
259 {
260     state.fontBuilder().setFontSizeInherit(state.parentFontDescription(), state.style()->effectiveZoom());
261 }
262
263 void StyleBuilderFunctions::applyValueCSSPropertyFontSize(StyleResolverState& state, CSSValue* value)
264 {
265     state.fontBuilder().setFontSizeValue(value, state.parentStyle(), state.rootElementStyle(), state.style()->effectiveZoom());
266 }
267
268 void StyleBuilderFunctions::applyInitialCSSPropertyFontWeight(StyleResolverState& state)
269 {
270     state.fontBuilder().setWeight(FontWeightNormal);
271 }
272
273 void StyleBuilderFunctions::applyInheritCSSPropertyFontWeight(StyleResolverState& state)
274 {
275     state.fontBuilder().setWeight(state.parentFontDescription().weight());
276 }
277
278 void StyleBuilderFunctions::applyValueCSSPropertyFontWeight(StyleResolverState& state, CSSValue* value)
279 {
280     if (!value->isPrimitiveValue())
281         return;
282     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
283     switch (primitiveValue->getValueID()) {
284     case CSSValueInvalid:
285         ASSERT_NOT_REACHED();
286         break;
287     case CSSValueBolder:
288         state.fontBuilder().setWeightBolder();
289         break;
290     case CSSValueLighter:
291         state.fontBuilder().setWeightLighter();
292         break;
293     default:
294         state.fontBuilder().setWeight(*primitiveValue);
295     }
296 }
297
298 void StyleBuilderFunctions::applyValueCSSPropertyLineHeight(StyleResolverState& state, CSSValue* value)
299 {
300     if (!value->isPrimitiveValue())
301         return;
302
303     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
304     Length lineHeight;
305
306     if (primitiveValue->getValueID() == CSSValueNormal) {
307         lineHeight = RenderStyle::initialLineHeight();
308     } else if (primitiveValue->isLength()) {
309         float multiplier = state.style()->effectiveZoom();
310         if (Frame* frame = state.document().frame())
311             multiplier *= frame->textZoomFactor();
312         lineHeight = primitiveValue->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier));
313     } else if (primitiveValue->isPercentage()) {
314         lineHeight = Length((state.style()->computedFontSize() * primitiveValue->getIntValue()) / 100.0, Fixed);
315     } else if (primitiveValue->isNumber()) {
316         lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
317     } else if (primitiveValue->isCalculated()) {
318         double multiplier = state.style()->effectiveZoom();
319         if (Frame* frame = state.document().frame())
320             multiplier *= frame->textZoomFactor();
321         Length zoomedLength = Length(primitiveValue->cssCalcValue()->toCalcValue(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier)));
322         lineHeight = Length(valueForLength(zoomedLength, state.style()->fontSize()), Fixed);
323     } else {
324         return;
325     }
326     state.style()->setLineHeight(lineHeight);
327 }
328
329 void StyleBuilderFunctions::applyValueCSSPropertyListStyleImage(StyleResolverState& state, CSSValue* value)
330 {
331     state.style()->setListStyleImage(state.styleImage(CSSPropertyListStyleImage, value));
332 }
333
334 void StyleBuilderFunctions::applyInitialCSSPropertyOutlineStyle(StyleResolverState& state)
335 {
336     state.style()->setOutlineStyleIsAuto(RenderStyle::initialOutlineStyleIsAuto());
337     state.style()->setOutlineStyle(RenderStyle::initialBorderStyle());
338 }
339
340 void StyleBuilderFunctions::applyInheritCSSPropertyOutlineStyle(StyleResolverState& state)
341 {
342     state.style()->setOutlineStyleIsAuto(state.parentStyle()->outlineStyleIsAuto());
343     state.style()->setOutlineStyle(state.parentStyle()->outlineStyle());
344 }
345
346 void StyleBuilderFunctions::applyValueCSSPropertyOutlineStyle(StyleResolverState& state, CSSValue* value)
347 {
348     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
349     state.style()->setOutlineStyleIsAuto(*primitiveValue);
350     state.style()->setOutlineStyle(*primitiveValue);
351 }
352
353 void StyleBuilderFunctions::applyValueCSSPropertyResize(StyleResolverState& state, CSSValue* value)
354 {
355     if (!value->isPrimitiveValue())
356         return;
357
358     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
359
360     EResize r = RESIZE_NONE;
361     switch (primitiveValue->getValueID()) {
362     case 0:
363         return;
364     case CSSValueAuto:
365         if (Settings* settings = state.document().settings())
366             r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE;
367         break;
368     default:
369         r = *primitiveValue;
370     }
371     state.style()->setResize(r);
372 }
373
374 static Length mmLength(double mm) { return Length(mm * cssPixelsPerMillimeter, Fixed); }
375 static Length inchLength(double inch) { return Length(inch * cssPixelsPerInch, Fixed); }
376 static bool getPageSizeFromName(CSSPrimitiveValue* pageSizeName, CSSPrimitiveValue* pageOrientation, Length& width, Length& height)
377 {
378     DEFINE_STATIC_LOCAL(Length, a5Width, (mmLength(148)));
379     DEFINE_STATIC_LOCAL(Length, a5Height, (mmLength(210)));
380     DEFINE_STATIC_LOCAL(Length, a4Width, (mmLength(210)));
381     DEFINE_STATIC_LOCAL(Length, a4Height, (mmLength(297)));
382     DEFINE_STATIC_LOCAL(Length, a3Width, (mmLength(297)));
383     DEFINE_STATIC_LOCAL(Length, a3Height, (mmLength(420)));
384     DEFINE_STATIC_LOCAL(Length, b5Width, (mmLength(176)));
385     DEFINE_STATIC_LOCAL(Length, b5Height, (mmLength(250)));
386     DEFINE_STATIC_LOCAL(Length, b4Width, (mmLength(250)));
387     DEFINE_STATIC_LOCAL(Length, b4Height, (mmLength(353)));
388     DEFINE_STATIC_LOCAL(Length, letterWidth, (inchLength(8.5)));
389     DEFINE_STATIC_LOCAL(Length, letterHeight, (inchLength(11)));
390     DEFINE_STATIC_LOCAL(Length, legalWidth, (inchLength(8.5)));
391     DEFINE_STATIC_LOCAL(Length, legalHeight, (inchLength(14)));
392     DEFINE_STATIC_LOCAL(Length, ledgerWidth, (inchLength(11)));
393     DEFINE_STATIC_LOCAL(Length, ledgerHeight, (inchLength(17)));
394
395     if (!pageSizeName)
396         return false;
397
398     switch (pageSizeName->getValueID()) {
399     case CSSValueA5:
400         width = a5Width;
401         height = a5Height;
402         break;
403     case CSSValueA4:
404         width = a4Width;
405         height = a4Height;
406         break;
407     case CSSValueA3:
408         width = a3Width;
409         height = a3Height;
410         break;
411     case CSSValueB5:
412         width = b5Width;
413         height = b5Height;
414         break;
415     case CSSValueB4:
416         width = b4Width;
417         height = b4Height;
418         break;
419     case CSSValueLetter:
420         width = letterWidth;
421         height = letterHeight;
422         break;
423     case CSSValueLegal:
424         width = legalWidth;
425         height = legalHeight;
426         break;
427     case CSSValueLedger:
428         width = ledgerWidth;
429         height = ledgerHeight;
430         break;
431     default:
432         return false;
433     }
434
435     if (pageOrientation) {
436         switch (pageOrientation->getValueID()) {
437         case CSSValueLandscape:
438             std::swap(width, height);
439             break;
440         case CSSValuePortrait:
441             // Nothing to do.
442             break;
443         default:
444             return false;
445         }
446     }
447     return true;
448 }
449
450 void StyleBuilderFunctions::applyInitialCSSPropertySize(StyleResolverState&) { }
451 void StyleBuilderFunctions::applyInheritCSSPropertySize(StyleResolverState&) { }
452 void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value)
453 {
454     state.style()->resetPageSizeType();
455     Length width;
456     Length height;
457     PageSizeType pageSizeType = PAGE_SIZE_AUTO;
458     CSSValueListInspector inspector(value);
459     switch (inspector.length()) {
460     case 2: {
461         // <length>{2} | <page-size> <orientation>
462         if (!inspector.first()->isPrimitiveValue() || !inspector.second()->isPrimitiveValue())
463             return;
464         CSSPrimitiveValue* first = toCSSPrimitiveValue(inspector.first());
465         CSSPrimitiveValue* second = toCSSPrimitiveValue(inspector.second());
466         if (first->isLength()) {
467             // <length>{2}
468             if (!second->isLength())
469                 return;
470             width = first->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
471             height = second->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
472         } else {
473             // <page-size> <orientation>
474             // The value order is guaranteed. See BisonCSSParser::parseSizeParameter.
475             if (!getPageSizeFromName(first, second, width, height))
476                 return;
477         }
478         pageSizeType = PAGE_SIZE_RESOLVED;
479         break;
480     }
481     case 1: {
482         // <length> | auto | <page-size> | [ portrait | landscape]
483         if (!inspector.first()->isPrimitiveValue())
484             return;
485         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(inspector.first());
486         if (primitiveValue->isLength()) {
487             // <length>
488             pageSizeType = PAGE_SIZE_RESOLVED;
489             width = height = primitiveValue->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
490         } else {
491             switch (primitiveValue->getValueID()) {
492             case 0:
493                 return;
494             case CSSValueAuto:
495                 pageSizeType = PAGE_SIZE_AUTO;
496                 break;
497             case CSSValuePortrait:
498                 pageSizeType = PAGE_SIZE_AUTO_PORTRAIT;
499                 break;
500             case CSSValueLandscape:
501                 pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE;
502                 break;
503             default:
504                 // <page-size>
505                 pageSizeType = PAGE_SIZE_RESOLVED;
506                 if (!getPageSizeFromName(primitiveValue, 0, width, height))
507                     return;
508             }
509         }
510         break;
511     }
512     default:
513         return;
514     }
515     state.style()->setPageSizeType(pageSizeType);
516     state.style()->setPageSize(LengthSize(width, height));
517 }
518
519 void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value)
520 {
521     if (!value->isPrimitiveValue())
522         return;
523
524     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
525     // FIXME : Per http://www.w3.org/TR/css3-text/#text-align0 can now take <string> but this is not implemented in the
526     // rendering code.
527     if (primitiveValue->isString())
528         return;
529
530     if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent)
531         state.style()->setTextAlign(*primitiveValue);
532     else if (state.parentStyle()->textAlign() == TASTART)
533         state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT);
534     else if (state.parentStyle()->textAlign() == TAEND)
535         state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT);
536     else
537         state.style()->setTextAlign(state.parentStyle()->textAlign());
538 }
539
540 void StyleBuilderFunctions::applyValueCSSPropertyTextDecoration(StyleResolverState& state, CSSValue* value)
541 {
542     TextDecoration t = RenderStyle::initialTextDecoration();
543     for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
544         CSSValue* item = i.value();
545         t |= *toCSSPrimitiveValue(item);
546     }
547     state.style()->setTextDecoration(t);
548 }
549
550 void StyleBuilderFunctions::applyInheritCSSPropertyTextIndent(StyleResolverState& state)
551 {
552     state.style()->setTextIndent(state.parentStyle()->textIndent());
553     state.style()->setTextIndentLine(state.parentStyle()->textIndentLine());
554 }
555
556 void StyleBuilderFunctions::applyInitialCSSPropertyTextIndent(StyleResolverState& state)
557 {
558     state.style()->setTextIndent(RenderStyle::initialTextIndent());
559     state.style()->setTextIndentLine(RenderStyle::initialTextIndentLine());
560 }
561
562 void StyleBuilderFunctions::applyValueCSSPropertyTextIndent(StyleResolverState& state, CSSValue* value)
563 {
564     if (!value->isValueList())
565         return;
566
567     // [ <length> | <percentage> ] each-line
568     // The order is guaranteed. See BisonCSSParser::parseTextIndent.
569     // The second value, each-line is handled only when css3TextEnabled() returns true.
570
571     CSSValueList* valueList = toCSSValueList(value);
572     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(valueList->itemWithoutBoundsCheck(0));
573     Length lengthOrPercentageValue = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
574     state.style()->setTextIndent(lengthOrPercentageValue);
575
576     ASSERT(valueList->length() <= 2);
577     CSSPrimitiveValue* eachLineValue = toCSSPrimitiveValue(valueList->item(1));
578     if (eachLineValue) {
579         ASSERT(eachLineValue->getValueID() == CSSValueEachLine);
580         state.style()->setTextIndentLine(TextIndentEachLine);
581     } else
582         state.style()->setTextIndentLine(TextIndentFirstLine);
583 }
584
585 void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value)
586 {
587     if (!value->isPrimitiveValue())
588         return;
589
590     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
591
592     if (primitiveValue->getValueID())
593         return state.style()->setVerticalAlign(*primitiveValue);
594
595     state.style()->setVerticalAlignLength(primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()));
596 }
597
598 void StyleBuilderFunctions::applyValueCSSPropertyTouchAction(StyleResolverState& state, CSSValue* value)
599 {
600     TouchAction action = RenderStyle::initialTouchAction();
601     for (CSSValueListIterator i(value); i.hasMore(); i.advance())
602         action |= *toCSSPrimitiveValue(i.value());
603
604     state.style()->setTouchAction(action);
605 }
606
607 static void resetEffectiveZoom(StyleResolverState& state)
608 {
609     // Reset the zoom in effect. This allows the setZoom method to accurately compute a new zoom in effect.
610     state.setEffectiveZoom(state.parentStyle() ? state.parentStyle()->effectiveZoom() : RenderStyle::initialZoom());
611 }
612
613 void StyleBuilderFunctions::applyInitialCSSPropertyZoom(StyleResolverState& state)
614 {
615     resetEffectiveZoom(state);
616     state.setZoom(RenderStyle::initialZoom());
617 }
618
619 void StyleBuilderFunctions::applyInheritCSSPropertyZoom(StyleResolverState& state)
620 {
621     resetEffectiveZoom(state);
622     state.setZoom(state.parentStyle()->zoom());
623 }
624
625 void StyleBuilderFunctions::applyValueCSSPropertyZoom(StyleResolverState& state, CSSValue* value)
626 {
627     ASSERT_WITH_SECURITY_IMPLICATION(value->isPrimitiveValue());
628     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
629
630     if (primitiveValue->getValueID() == CSSValueNormal) {
631         resetEffectiveZoom(state);
632         state.setZoom(RenderStyle::initialZoom());
633     } else if (primitiveValue->getValueID() == CSSValueReset) {
634         state.setEffectiveZoom(RenderStyle::initialZoom());
635         state.setZoom(RenderStyle::initialZoom());
636     } else if (primitiveValue->getValueID() == CSSValueDocument) {
637         float docZoom = state.rootElementStyle() ? state.rootElementStyle()->zoom() : RenderStyle::initialZoom();
638         state.setEffectiveZoom(docZoom);
639         state.setZoom(docZoom);
640     } else if (primitiveValue->isPercentage()) {
641         resetEffectiveZoom(state);
642         if (float percent = primitiveValue->getFloatValue())
643             state.setZoom(percent / 100.0f);
644     } else if (primitiveValue->isNumber()) {
645         resetEffectiveZoom(state);
646         if (float number = primitiveValue->getFloatValue())
647             state.setZoom(number);
648     }
649 }
650
651 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitAspectRatio(StyleResolverState& state)
652 {
653     state.style()->setHasAspectRatio(RenderStyle::initialHasAspectRatio());
654     state.style()->setAspectRatioDenominator(RenderStyle::initialAspectRatioDenominator());
655     state.style()->setAspectRatioNumerator(RenderStyle::initialAspectRatioNumerator());
656 }
657
658 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitAspectRatio(StyleResolverState& state)
659 {
660     if (!state.parentStyle()->hasAspectRatio())
661         return;
662     state.style()->setHasAspectRatio(true);
663     state.style()->setAspectRatioDenominator(state.parentStyle()->aspectRatioDenominator());
664     state.style()->setAspectRatioNumerator(state.parentStyle()->aspectRatioNumerator());
665 }
666
667 void StyleBuilderFunctions::applyValueCSSPropertyWebkitAspectRatio(StyleResolverState& state, CSSValue* value)
668 {
669     if (!value->isAspectRatioValue()) {
670         state.style()->setHasAspectRatio(false);
671         return;
672     }
673     CSSAspectRatioValue* aspectRatioValue = toCSSAspectRatioValue(value);
674     state.style()->setHasAspectRatio(true);
675     state.style()->setAspectRatioDenominator(aspectRatioValue->denominatorValue());
676     state.style()->setAspectRatioNumerator(aspectRatioValue->numeratorValue());
677 }
678
679 void StyleBuilderFunctions::applyValueCSSPropertyWebkitBorderImage(StyleResolverState& state, CSSValue* value)
680 {
681     NinePieceImage image;
682     state.styleMap().mapNinePieceImage(state.style(), CSSPropertyWebkitBorderImage, value, image);
683     state.style()->setBorderImage(image);
684 }
685
686 void StyleBuilderFunctions::applyValueCSSPropertyWebkitClipPath(StyleResolverState& state, CSSValue* value)
687 {
688     if (value->isPrimitiveValue()) {
689         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
690         if (primitiveValue->getValueID() == CSSValueNone) {
691             state.style()->setClipPath(0);
692         } else if (primitiveValue->isShape()) {
693             state.style()->setClipPath(ShapeClipPathOperation::create(basicShapeForValue(state, primitiveValue->getShapeValue())));
694         } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_URI) {
695             String cssURLValue = primitiveValue->getStringValue();
696             KURL url = state.document().completeURL(cssURLValue);
697             // FIXME: It doesn't work with forward or external SVG references (see https://bugs.webkit.org/show_bug.cgi?id=90405)
698             state.style()->setClipPath(ReferenceClipPathOperation::create(cssURLValue, AtomicString(url.fragmentIdentifier())));
699         }
700     }
701 }
702
703 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state)
704 {
705     state.fontBuilder().setFontVariantLigaturesInitial();
706 }
707
708 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state)
709 {
710     state.fontBuilder().setFontVariantLigaturesInherit(state.parentFontDescription());
711 }
712
713 void StyleBuilderFunctions::applyValueCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state, CSSValue* value)
714 {
715     state.fontBuilder().setFontVariantLigaturesValue(value);
716 }
717
718 void StyleBuilderFunctions::applyValueCSSPropertyInternalMarqueeIncrement(StyleResolverState& state, CSSValue* value)
719 {
720     if (!value->isPrimitiveValue())
721         return;
722
723     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
724     if (primitiveValue->getValueID()) {
725         switch (primitiveValue->getValueID()) {
726         case CSSValueSmall:
727             state.style()->setMarqueeIncrement(Length(1, Fixed)); // 1px.
728             break;
729         case CSSValueNormal:
730             state.style()->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default.
731             break;
732         case CSSValueLarge:
733             state.style()->setMarqueeIncrement(Length(36, Fixed)); // 36px.
734             break;
735         default:
736             break;
737         }
738     } else {
739         Length marqueeLength = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
740         state.style()->setMarqueeIncrement(marqueeLength);
741     }
742 }
743
744 void StyleBuilderFunctions::applyValueCSSPropertyInternalMarqueeSpeed(StyleResolverState& state, CSSValue* value)
745 {
746     if (!value->isPrimitiveValue())
747         return;
748
749     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
750     if (CSSValueID valueID = primitiveValue->getValueID()) {
751         switch (valueID) {
752         case CSSValueSlow:
753             state.style()->setMarqueeSpeed(500); // 500 msec.
754             break;
755         case CSSValueNormal:
756             state.style()->setMarqueeSpeed(85); // 85msec. The WinIE default.
757             break;
758         case CSSValueFast:
759             state.style()->setMarqueeSpeed(10); // 10msec. Super fast.
760             break;
761         default:
762             break;
763         }
764     } else if (primitiveValue->isTime()) {
765         state.style()->setMarqueeSpeed(primitiveValue->computeTime<int, CSSPrimitiveValue::Milliseconds>());
766     } else if (primitiveValue->isNumber()) { // For scrollamount support.
767         state.style()->setMarqueeSpeed(primitiveValue->getIntValue());
768     }
769 }
770
771 // FIXME: We should use the same system for this as the rest of the pseudo-shorthands (e.g. background-position)
772 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitPerspectiveOrigin(StyleResolverState& state)
773 {
774     applyInitialCSSPropertyWebkitPerspectiveOriginX(state);
775     applyInitialCSSPropertyWebkitPerspectiveOriginY(state);
776 }
777
778 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitPerspectiveOrigin(StyleResolverState& state)
779 {
780     applyInheritCSSPropertyWebkitPerspectiveOriginX(state);
781     applyInheritCSSPropertyWebkitPerspectiveOriginY(state);
782 }
783
784 void StyleBuilderFunctions::applyValueCSSPropertyWebkitPerspectiveOrigin(StyleResolverState&, CSSValue* value)
785 {
786     // This is expanded in the parser
787     ASSERT_NOT_REACHED();
788 }
789
790 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state)
791 {
792     state.style()->setTextEmphasisFill(RenderStyle::initialTextEmphasisFill());
793     state.style()->setTextEmphasisMark(RenderStyle::initialTextEmphasisMark());
794     state.style()->setTextEmphasisCustomMark(RenderStyle::initialTextEmphasisCustomMark());
795 }
796
797 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state)
798 {
799     state.style()->setTextEmphasisFill(state.parentStyle()->textEmphasisFill());
800     state.style()->setTextEmphasisMark(state.parentStyle()->textEmphasisMark());
801     state.style()->setTextEmphasisCustomMark(state.parentStyle()->textEmphasisCustomMark());
802 }
803
804 void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state, CSSValue* value)
805 {
806     if (value->isValueList()) {
807         CSSValueList* list = toCSSValueList(value);
808         ASSERT(list->length() == 2);
809         if (list->length() != 2)
810             return;
811         for (unsigned i = 0; i < 2; ++i) {
812             CSSValue* item = list->itemWithoutBoundsCheck(i);
813             if (!item->isPrimitiveValue())
814                 continue;
815
816             CSSPrimitiveValue* value = toCSSPrimitiveValue(item);
817             if (value->getValueID() == CSSValueFilled || value->getValueID() == CSSValueOpen)
818                 state.style()->setTextEmphasisFill(*value);
819             else
820                 state.style()->setTextEmphasisMark(*value);
821         }
822         state.style()->setTextEmphasisCustomMark(nullAtom);
823         return;
824     }
825
826     if (!value->isPrimitiveValue())
827         return;
828     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
829
830     if (primitiveValue->isString()) {
831         state.style()->setTextEmphasisFill(TextEmphasisFillFilled);
832         state.style()->setTextEmphasisMark(TextEmphasisMarkCustom);
833         state.style()->setTextEmphasisCustomMark(AtomicString(primitiveValue->getStringValue()));
834         return;
835     }
836
837     state.style()->setTextEmphasisCustomMark(nullAtom);
838
839     if (primitiveValue->getValueID() == CSSValueFilled || primitiveValue->getValueID() == CSSValueOpen) {
840         state.style()->setTextEmphasisFill(*primitiveValue);
841         state.style()->setTextEmphasisMark(TextEmphasisMarkAuto);
842     } else {
843         state.style()->setTextEmphasisFill(TextEmphasisFillFilled);
844         state.style()->setTextEmphasisMark(*primitiveValue);
845     }
846 }
847
848 void StyleBuilderFunctions::applyValueCSSPropertyTextUnderlinePosition(StyleResolverState& state, CSSValue* value)
849 {
850     // This is true if value is 'auto' or 'alphabetic'.
851     if (value->isPrimitiveValue()) {
852         TextUnderlinePosition t = *toCSSPrimitiveValue(value);
853         state.style()->setTextUnderlinePosition(t);
854         return;
855     }
856
857     unsigned t = 0;
858     for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
859         CSSValue* item = i.value();
860         TextUnderlinePosition t2 = *toCSSPrimitiveValue(item);
861         t |= t2;
862     }
863     state.style()->setTextUnderlinePosition(static_cast<TextUnderlinePosition>(t));
864 }
865
866 // Everything below this line is from the old StyleResolver::applyProperty
867 // and eventually needs to move into new StyleBuilderFunctions calls intead.
868
869 #define HANDLE_INHERIT(prop, Prop) \
870 if (isInherit) { \
871     state.style()->set##Prop(state.parentStyle()->prop()); \
872     return; \
873 }
874
875 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
876 HANDLE_INHERIT(prop, Prop) \
877 if (isInitial) { \
878     state.style()->set##Prop(RenderStyle::initial##Prop()); \
879     return; \
880 }
881
882 #define HANDLE_SVG_INHERIT(prop, Prop) \
883 if (isInherit) { \
884     state.style()->accessSVGStyle()->set##Prop(state.parentStyle()->svgStyle()->prop()); \
885     return; \
886 }
887
888 #define HANDLE_SVG_INHERIT_AND_INITIAL(prop, Prop) \
889 HANDLE_SVG_INHERIT(prop, Prop) \
890 if (isInitial) { \
891     state.style()->accessSVGStyle()->set##Prop(SVGRenderStyle::initial##Prop()); \
892     return; \
893 }
894
895 static GridLength createGridTrackBreadth(CSSPrimitiveValue* primitiveValue, const StyleResolverState& state)
896 {
897     if (primitiveValue->getValueID() == CSSValueMinContent)
898         return Length(MinContent);
899
900     if (primitiveValue->getValueID() == CSSValueMaxContent)
901         return Length(MaxContent);
902
903     // Fractional unit.
904     if (primitiveValue->isFlex())
905         return GridLength(primitiveValue->getDoubleValue());
906
907     return primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
908 }
909
910 static GridTrackSize createGridTrackSize(CSSValue* value, const StyleResolverState& state)
911 {
912     if (value->isPrimitiveValue())
913         return GridTrackSize(createGridTrackBreadth(toCSSPrimitiveValue(value), state));
914
915     CSSFunctionValue* minmaxFunction = toCSSFunctionValue(value);
916     CSSValueList* arguments = minmaxFunction->arguments();
917     ASSERT_WITH_SECURITY_IMPLICATION(arguments->length() == 2);
918     GridLength minTrackBreadth(createGridTrackBreadth(toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(0)), state));
919     GridLength maxTrackBreadth(createGridTrackBreadth(toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(1)), state));
920     return GridTrackSize(minTrackBreadth, maxTrackBreadth);
921 }
922
923 static bool createGridTrackList(CSSValue* value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines, const StyleResolverState& state)
924 {
925     // Handle 'none'.
926     if (value->isPrimitiveValue()) {
927         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
928         return primitiveValue->getValueID() == CSSValueNone;
929     }
930
931     if (!value->isValueList())
932         return false;
933
934     size_t currentNamedGridLine = 0;
935     for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
936         CSSValue* currValue = i.value();
937         if (currValue->isGridLineNamesValue()) {
938             CSSGridLineNamesValue* lineNamesValue = toCSSGridLineNamesValue(currValue);
939             for (CSSValueListIterator j = lineNamesValue; j.hasMore(); j.advance()) {
940                 String namedGridLine = toCSSPrimitiveValue(j.value())->getStringValue();
941                 NamedGridLinesMap::AddResult result = namedGridLines.add(namedGridLine, Vector<size_t>());
942                 result.iterator->value.append(currentNamedGridLine);
943                 OrderedNamedGridLines::AddResult orderedInsertionResult = orderedNamedGridLines.add(currentNamedGridLine, Vector<String>());
944                 orderedInsertionResult.iterator->value.append(namedGridLine);
945             }
946             continue;
947         }
948
949         ++currentNamedGridLine;
950         trackSizes.append(createGridTrackSize(currValue, state));
951     }
952
953     // The parser should have rejected any <track-list> without any <track-size> as
954     // this is not conformant to the syntax.
955     ASSERT(!trackSizes.isEmpty());
956     return true;
957 }
958
959 static bool createGridPosition(CSSValue* value, GridPosition& position)
960 {
961     // We accept the specification's grammar:
962     // 'auto' | [ <integer> || <string> ] | [ span && [ <integer> || string ] ] | <ident>
963
964     if (value->isPrimitiveValue()) {
965         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
966         // We translate <ident> to <string> during parsing as it
967         // makes handling it more simple.
968         if (primitiveValue->isString()) {
969             position.setNamedGridArea(primitiveValue->getStringValue());
970             return true;
971         }
972
973         ASSERT(primitiveValue->getValueID() == CSSValueAuto);
974         return true;
975     }
976
977     CSSValueList* values = toCSSValueList(value);
978     ASSERT(values->length());
979
980     bool isSpanPosition = false;
981     // The specification makes the <integer> optional, in which case it default to '1'.
982     int gridLineNumber = 1;
983     String gridLineName;
984
985     CSSValueListIterator it = values;
986     CSSPrimitiveValue* currentValue = toCSSPrimitiveValue(it.value());
987     if (currentValue->getValueID() == CSSValueSpan) {
988         isSpanPosition = true;
989         it.advance();
990         currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
991     }
992
993     if (currentValue && currentValue->isNumber()) {
994         gridLineNumber = currentValue->getIntValue();
995         it.advance();
996         currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
997     }
998
999     if (currentValue && currentValue->isString()) {
1000         gridLineName = currentValue->getStringValue();
1001         it.advance();
1002     }
1003
1004     ASSERT(!it.hasMore());
1005     if (isSpanPosition)
1006         position.setSpanPosition(gridLineNumber, gridLineName);
1007     else
1008         position.setExplicitPosition(gridLineNumber, gridLineName);
1009
1010     return true;
1011 }
1012
1013 static bool degreeToGlyphOrientation(CSSPrimitiveValue* primitiveValue, EGlyphOrientation& orientation)
1014 {
1015     if (!primitiveValue)
1016         return false;
1017
1018     if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_DEG)
1019         return false;
1020
1021     float angle = fabsf(fmodf(primitiveValue->getFloatValue(), 360.0f));
1022
1023     if (angle <= 45.0f || angle > 315.0f) {
1024         orientation = GO_0DEG;
1025         return true;
1026     }
1027     if (angle > 45.0f && angle <= 135.0f) {
1028         orientation = GO_90DEG;
1029         return true;
1030     }
1031     if (angle > 135.0f && angle <= 225.0f) {
1032         orientation = GO_180DEG;
1033         return true;
1034     }
1035     orientation = GO_270DEG;
1036     return true;
1037 }
1038
1039 static Color colorFromSVGColorCSSValue(SVGColor* svgColor, const Color& fgColor)
1040 {
1041     Color color;
1042     if (svgColor->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
1043         color = fgColor;
1044     else
1045         color = svgColor->color();
1046     return color;
1047 }
1048
1049 static EPaintOrder paintOrderFlattened(CSSValue* cssPaintOrder)
1050 {
1051     if (cssPaintOrder->isValueList()) {
1052         int paintOrder = 0;
1053         CSSValueListInspector iter(cssPaintOrder);
1054         for (size_t i = 0; i < iter.length(); i++) {
1055             CSSPrimitiveValue* value = toCSSPrimitiveValue(iter.item(i));
1056
1057             EPaintOrderType paintOrderType = PT_NONE;
1058             switch (value->getValueID()) {
1059             case CSSValueFill:
1060                 paintOrderType = PT_FILL;
1061                 break;
1062             case CSSValueStroke:
1063                 paintOrderType = PT_STROKE;
1064                 break;
1065             case CSSValueMarkers:
1066                 paintOrderType = PT_MARKERS;
1067                 break;
1068             default:
1069                 ASSERT_NOT_REACHED();
1070                 break;
1071             }
1072
1073             paintOrder |= (paintOrderType << kPaintOrderBitwidth*i);
1074         }
1075         return (EPaintOrder)paintOrder;
1076     }
1077
1078     return PO_NORMAL;
1079 }
1080
1081 static inline bool isValidVisitedLinkProperty(CSSPropertyID id)
1082 {
1083     switch (id) {
1084     case CSSPropertyBackgroundColor:
1085     case CSSPropertyBorderLeftColor:
1086     case CSSPropertyBorderRightColor:
1087     case CSSPropertyBorderTopColor:
1088     case CSSPropertyBorderBottomColor:
1089     case CSSPropertyColor:
1090     case CSSPropertyFill:
1091     case CSSPropertyOutlineColor:
1092     case CSSPropertyStroke:
1093     case CSSPropertyTextDecorationColor:
1094     case CSSPropertyWebkitColumnRuleColor:
1095     case CSSPropertyWebkitTextEmphasisColor:
1096     case CSSPropertyWebkitTextFillColor:
1097     case CSSPropertyWebkitTextStrokeColor:
1098         return true;
1099     default:
1100         break;
1101     }
1102
1103     return false;
1104 }
1105
1106 static bool hasVariableReference(CSSValue* value)
1107 {
1108     if (value->isPrimitiveValue()) {
1109         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1110         return primitiveValue->hasVariableReference();
1111     }
1112
1113     if (value->isCalcValue())
1114         return toCSSCalcValue(value)->hasVariableReference();
1115
1116     if (value->isReflectValue()) {
1117         CSSReflectValue* reflectValue = toCSSReflectValue(value);
1118         CSSPrimitiveValue* direction = reflectValue->direction();
1119         CSSPrimitiveValue* offset = reflectValue->offset();
1120         CSSValue* mask = reflectValue->mask();
1121         return (direction && hasVariableReference(direction)) || (offset && hasVariableReference(offset)) || (mask && hasVariableReference(mask));
1122     }
1123
1124     for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
1125         if (hasVariableReference(i.value()))
1126             return true;
1127     }
1128
1129     return false;
1130 }
1131
1132 // FIXME: Resolving variables should be factored better. Maybe a resover-style class?
1133 static void resolveVariables(StyleResolverState& state, CSSPropertyID id, CSSValue* value, Vector<std::pair<CSSPropertyID, String> >& knownExpressions)
1134 {
1135     std::pair<CSSPropertyID, String> expression(id, value->serializeResolvingVariables(*state.style()->variables()));
1136
1137     if (knownExpressions.contains(expression))
1138         return; // cycle detected.
1139
1140     knownExpressions.append(expression);
1141
1142     // FIXME: It would be faster not to re-parse from strings, but for now CSS property validation lives inside the parser so we do it there.
1143     RefPtr<MutableStylePropertySet> resultSet = MutableStylePropertySet::create();
1144     if (!BisonCSSParser::parseValue(resultSet.get(), id, expression.second, false, state.document()))
1145         return; // expression failed to parse.
1146
1147     for (unsigned i = 0; i < resultSet->propertyCount(); i++) {
1148         StylePropertySet::PropertyReference property = resultSet->propertyAt(i);
1149         if (property.id() != CSSPropertyVariable && hasVariableReference(property.value())) {
1150             resolveVariables(state, property.id(), property.value(), knownExpressions);
1151         } else {
1152             StyleBuilder::applyProperty(property.id(), state, property.value());
1153             // All properties become dependent on their parent style when they use variables.
1154             state.style()->setHasExplicitlyInheritedProperties();
1155         }
1156     }
1157 }
1158
1159 void StyleBuilder::applyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value)
1160 {
1161     if (RuntimeEnabledFeatures::cssVariablesEnabled() && id != CSSPropertyVariable && hasVariableReference(value)) {
1162         Vector<std::pair<CSSPropertyID, String> > knownExpressions;
1163         resolveVariables(state, id, value, knownExpressions);
1164         return;
1165     }
1166
1167     // CSS variables don't resolve shorthands at parsing time, so this should be *after* handling variables.
1168     ASSERT_WITH_MESSAGE(!isExpandedShorthand(id), "Shorthand property id = %d wasn't expanded at parsing time", id);
1169
1170     bool isInherit = state.parentNode() && value->isInheritedValue();
1171     bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue());
1172
1173     ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
1174     ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle())
1175
1176     if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
1177         // Limit the properties that can be applied to only the ones honored by :visited.
1178         return;
1179     }
1180
1181     CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0;
1182     if (primitiveValue && primitiveValue->getValueID() == CSSValueCurrentcolor)
1183         state.style()->setHasCurrentColor();
1184
1185     if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(id))
1186         state.parentStyle()->setHasExplicitlyInheritedProperties();
1187
1188     if (id == CSSPropertyVariable) {
1189         ASSERT_WITH_SECURITY_IMPLICATION(value->isVariableValue());
1190         CSSVariableValue* variable = toCSSVariableValue(value);
1191         ASSERT(!variable->name().isEmpty());
1192         ASSERT(!variable->value().isEmpty());
1193         state.style()->setVariable(variable->name(), variable->value());
1194         return;
1195     }
1196
1197     if (StyleBuilder::applyProperty(id, state, value, isInitial, isInherit))
1198         return;
1199
1200     // Fall back to the old switch statement, which is now in StyleBuilderCustom.cpp
1201     StyleBuilder::oldApplyProperty(id, state, value, isInitial, isInherit);
1202 }
1203
1204
1205 void StyleBuilder::oldApplyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value, bool isInitial, bool isInherit)
1206 {
1207     CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0;
1208
1209     // What follows is a list that maps the CSS properties into their corresponding front-end
1210     // RenderStyle values.
1211     switch (id) {
1212     case CSSPropertyContent:
1213         // list of string, uri, counter, attr, i
1214         {
1215             // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This
1216             // note is a reminder that eventually "inherit" needs to be supported.
1217
1218             if (isInitial) {
1219                 state.style()->clearContent();
1220                 return;
1221             }
1222
1223             if (!value->isValueList())
1224                 return;
1225
1226             bool didSet = false;
1227             for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
1228                 CSSValue* item = i.value();
1229                 if (item->isImageGeneratorValue()) {
1230                     if (item->isGradientValue())
1231                         state.style()->setContent(StyleGeneratedImage::create(toCSSGradientValue(item)->gradientWithStylesResolved(state.document().textLinkColors(), state.style()->color()).get()), didSet);
1232                     else
1233                         state.style()->setContent(StyleGeneratedImage::create(toCSSImageGeneratorValue(item)), didSet);
1234                     didSet = true;
1235                 } else if (item->isImageSetValue()) {
1236                     state.style()->setContent(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item)), didSet);
1237                     didSet = true;
1238                 }
1239
1240                 if (item->isImageValue()) {
1241                     state.style()->setContent(state.elementStyleResources().cachedOrPendingFromValue(CSSPropertyContent, toCSSImageValue(item)), didSet);
1242                     didSet = true;
1243                     continue;
1244                 }
1245
1246                 if (!item->isPrimitiveValue())
1247                     continue;
1248
1249                 CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item);
1250
1251                 if (contentValue->isString()) {
1252                     state.style()->setContent(contentValue->getStringValue().impl(), didSet);
1253                     didSet = true;
1254                 } else if (contentValue->isAttr()) {
1255                     // FIXME: Can a namespace be specified for an attr(foo)?
1256                     if (state.style()->styleType() == NOPSEUDO)
1257                         state.style()->setUnique();
1258                     else
1259                         state.parentStyle()->setUnique();
1260                     QualifiedName attr(nullAtom, AtomicString(contentValue->getStringValue()), nullAtom);
1261                     const AtomicString& value = state.element()->getAttribute(attr);
1262                     state.style()->setContent(value.isNull() ? emptyString() : value.string(), didSet);
1263                     didSet = true;
1264                     // register the fact that the attribute value affects the style
1265                     state.contentAttrValues().append(attr.localName());
1266                 } else if (contentValue->isCounter()) {
1267                     Counter* counterValue = contentValue->getCounterValue();
1268                     EListStyleType listStyleType = NoneListStyle;
1269                     CSSValueID listStyleIdent = counterValue->listStyleIdent();
1270                     if (listStyleIdent != CSSValueNone)
1271                         listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
1272                     OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(AtomicString(counterValue->identifier()), listStyleType, AtomicString(counterValue->separator())));
1273                     state.style()->setContent(counter.release(), didSet);
1274                     didSet = true;
1275                 } else {
1276                     switch (contentValue->getValueID()) {
1277                     case CSSValueOpenQuote:
1278                         state.style()->setContent(OPEN_QUOTE, didSet);
1279                         didSet = true;
1280                         break;
1281                     case CSSValueCloseQuote:
1282                         state.style()->setContent(CLOSE_QUOTE, didSet);
1283                         didSet = true;
1284                         break;
1285                     case CSSValueNoOpenQuote:
1286                         state.style()->setContent(NO_OPEN_QUOTE, didSet);
1287                         didSet = true;
1288                         break;
1289                     case CSSValueNoCloseQuote:
1290                         state.style()->setContent(NO_CLOSE_QUOTE, didSet);
1291                         didSet = true;
1292                         break;
1293                     default:
1294                         // normal and none do not have any effect.
1295                         { }
1296                     }
1297                 }
1298             }
1299             if (!didSet)
1300                 state.style()->clearContent();
1301             return;
1302         }
1303     case CSSPropertyQuotes:
1304         HANDLE_INHERIT_AND_INITIAL(quotes, Quotes);
1305         if (value->isValueList()) {
1306             CSSValueList* list = toCSSValueList(value);
1307             RefPtr<QuotesData> quotes = QuotesData::create();
1308             for (size_t i = 0; i < list->length(); i += 2) {
1309                 CSSValue* first = list->itemWithoutBoundsCheck(i);
1310                 // item() returns null if out of bounds so this is safe.
1311                 CSSValue* second = list->item(i + 1);
1312                 if (!second)
1313                     continue;
1314                 String startQuote = toCSSPrimitiveValue(first)->getStringValue();
1315                 String endQuote = toCSSPrimitiveValue(second)->getStringValue();
1316                 quotes->addPair(std::make_pair(startQuote, endQuote));
1317             }
1318             state.style()->setQuotes(quotes);
1319             return;
1320         }
1321         if (primitiveValue) {
1322             if (primitiveValue->getValueID() == CSSValueNone)
1323                 state.style()->setQuotes(QuotesData::create());
1324         }
1325         return;
1326     // Shorthand properties.
1327     case CSSPropertyFont:
1328         // Only System Font identifiers should come through this method
1329         // all other values should have been handled when the shorthand
1330         // was expanded by the parser.
1331         // FIXME: System Font identifiers should not hijack this
1332         // short-hand CSSProperty like this.
1333         ASSERT(!isInitial);
1334         ASSERT(!isInherit);
1335         ASSERT(primitiveValue);
1336         state.style()->setLineHeight(RenderStyle::initialLineHeight());
1337         state.setLineHeightValue(0);
1338         state.fontBuilder().fromSystemFont(primitiveValue->getValueID(), state.style()->effectiveZoom());
1339         return;
1340     case CSSPropertyAnimation:
1341     case CSSPropertyBackground:
1342     case CSSPropertyBackgroundPosition:
1343     case CSSPropertyBackgroundRepeat:
1344     case CSSPropertyBorder:
1345     case CSSPropertyBorderBottom:
1346     case CSSPropertyBorderColor:
1347     case CSSPropertyBorderImage:
1348     case CSSPropertyBorderLeft:
1349     case CSSPropertyBorderRadius:
1350     case CSSPropertyBorderRight:
1351     case CSSPropertyBorderSpacing:
1352     case CSSPropertyBorderStyle:
1353     case CSSPropertyBorderTop:
1354     case CSSPropertyBorderWidth:
1355     case CSSPropertyListStyle:
1356     case CSSPropertyMargin:
1357     case CSSPropertyObjectPosition:
1358     case CSSPropertyOutline:
1359     case CSSPropertyOverflow:
1360     case CSSPropertyPadding:
1361     case CSSPropertyTransition:
1362     case CSSPropertyWebkitAnimation:
1363     case CSSPropertyWebkitBorderAfter:
1364     case CSSPropertyWebkitBorderBefore:
1365     case CSSPropertyWebkitBorderEnd:
1366     case CSSPropertyWebkitBorderStart:
1367     case CSSPropertyWebkitBorderRadius:
1368     case CSSPropertyWebkitColumns:
1369     case CSSPropertyWebkitColumnRule:
1370     case CSSPropertyFlex:
1371     case CSSPropertyFlexFlow:
1372     case CSSPropertyGridColumn:
1373     case CSSPropertyGridRow:
1374     case CSSPropertyGridArea:
1375     case CSSPropertyWebkitMarginCollapse:
1376     case CSSPropertyWebkitMask:
1377     case CSSPropertyWebkitMaskPosition:
1378     case CSSPropertyWebkitMaskRepeat:
1379     case CSSPropertyWebkitTextEmphasis:
1380     case CSSPropertyWebkitTextStroke:
1381     case CSSPropertyWebkitTransition:
1382     case CSSPropertyWebkitTransformOrigin:
1383         ASSERT(isExpandedShorthand(id));
1384         ASSERT_NOT_REACHED();
1385         break;
1386
1387     // CSS3 Properties
1388     case CSSPropertyWebkitBoxReflect: {
1389         HANDLE_INHERIT_AND_INITIAL(boxReflect, BoxReflect)
1390         if (primitiveValue) {
1391             state.style()->setBoxReflect(RenderStyle::initialBoxReflect());
1392             return;
1393         }
1394
1395         if (!value->isReflectValue())
1396             return;
1397
1398         CSSReflectValue* reflectValue = toCSSReflectValue(value);
1399         RefPtr<StyleReflection> reflection = StyleReflection::create();
1400         reflection->setDirection(*reflectValue->direction());
1401         if (reflectValue->offset())
1402             reflection->setOffset(reflectValue->offset()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()));
1403         NinePieceImage mask;
1404         mask.setMaskDefaults();
1405         state.styleMap().mapNinePieceImage(state.style(), id, reflectValue->mask(), mask);
1406         reflection->setMask(mask);
1407
1408         state.style()->setBoxReflect(reflection.release());
1409         return;
1410     }
1411     case CSSPropertySrc: // Only used in @font-face rules.
1412         return;
1413     case CSSPropertyUnicodeRange: // Only used in @font-face rules.
1414         return;
1415     case CSSPropertyWebkitLocale: {
1416         HANDLE_INHERIT_AND_INITIAL(locale, Locale);
1417         if (!primitiveValue)
1418             return;
1419         if (primitiveValue->getValueID() == CSSValueAuto)
1420             state.style()->setLocale(nullAtom);
1421         else
1422             state.style()->setLocale(AtomicString(primitiveValue->getStringValue()));
1423         state.fontBuilder().setScript(state.style()->locale());
1424         return;
1425     }
1426     case CSSPropertyWebkitAppRegion: {
1427         if (!primitiveValue || !primitiveValue->getValueID())
1428             return;
1429         state.style()->setDraggableRegionMode(primitiveValue->getValueID() == CSSValueDrag ? DraggableRegionDrag : DraggableRegionNoDrag);
1430         state.document().setHasAnnotatedRegions(true);
1431         return;
1432     }
1433     case CSSPropertyWebkitTextStrokeWidth: {
1434         HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth)
1435         float width = 0;
1436         switch (primitiveValue->getValueID()) {
1437         case CSSValueThin:
1438         case CSSValueMedium:
1439         case CSSValueThick: {
1440             double result = 1.0 / 48;
1441             if (primitiveValue->getValueID() == CSSValueMedium)
1442                 result *= 3;
1443             else if (primitiveValue->getValueID() == CSSValueThick)
1444                 result *= 5;
1445             width = CSSPrimitiveValue::create(result, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(state.cssToLengthConversionData());
1446             break;
1447         }
1448         default:
1449             width = primitiveValue->computeLength<float>(state.cssToLengthConversionData());
1450             break;
1451         }
1452         state.style()->setTextStrokeWidth(width);
1453         return;
1454     }
1455     case CSSPropertyWebkitTransform: {
1456         HANDLE_INHERIT_AND_INITIAL(transform, Transform);
1457         TransformOperations operations;
1458         TransformBuilder::createTransformOperations(value, state.cssToLengthConversionData(), operations);
1459         state.style()->setTransform(operations);
1460         return;
1461     }
1462     case CSSPropertyWebkitPerspective: {
1463         HANDLE_INHERIT_AND_INITIAL(perspective, Perspective)
1464
1465         if (!primitiveValue)
1466             return;
1467
1468         if (primitiveValue->getValueID() == CSSValueNone) {
1469             state.style()->setPerspective(0);
1470             return;
1471         }
1472
1473         float perspectiveValue;
1474         if (primitiveValue->isLength()) {
1475             perspectiveValue = primitiveValue->computeLength<float>(state.cssToLengthConversionData());
1476         } else if (primitiveValue->isNumber()) {
1477             // For backward compatibility, treat valueless numbers as px.
1478             perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(state.cssToLengthConversionData());
1479         } else {
1480             return;
1481         }
1482
1483         if (perspectiveValue >= 0.0f)
1484             state.style()->setPerspective(perspectiveValue);
1485         return;
1486     }
1487     case CSSPropertyWebkitTapHighlightColor: {
1488         HANDLE_INHERIT_AND_INITIAL(tapHighlightColor, TapHighlightColor);
1489         if (!primitiveValue)
1490             break;
1491
1492         Color col = state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color());
1493         state.style()->setTapHighlightColor(col);
1494         return;
1495     }
1496     case CSSPropertyInternalCallback: {
1497         if (isInherit || isInitial)
1498             return;
1499         if (primitiveValue && primitiveValue->getValueID() == CSSValueInternalPresence) {
1500             state.style()->addCallbackSelector(state.currentRule()->selectorList().selectorsText());
1501             return;
1502         }
1503         break;
1504     }
1505     case CSSPropertyInvalid:
1506         return;
1507     // Directional properties are resolved by resolveDirectionAwareProperty() before the switch.
1508     case CSSPropertyWebkitBorderEndColor:
1509     case CSSPropertyWebkitBorderEndStyle:
1510     case CSSPropertyWebkitBorderEndWidth:
1511     case CSSPropertyWebkitBorderStartColor:
1512     case CSSPropertyWebkitBorderStartStyle:
1513     case CSSPropertyWebkitBorderStartWidth:
1514     case CSSPropertyWebkitBorderBeforeColor:
1515     case CSSPropertyWebkitBorderBeforeStyle:
1516     case CSSPropertyWebkitBorderBeforeWidth:
1517     case CSSPropertyWebkitBorderAfterColor:
1518     case CSSPropertyWebkitBorderAfterStyle:
1519     case CSSPropertyWebkitBorderAfterWidth:
1520     case CSSPropertyWebkitMarginEnd:
1521     case CSSPropertyWebkitMarginStart:
1522     case CSSPropertyWebkitMarginBefore:
1523     case CSSPropertyWebkitMarginAfter:
1524     case CSSPropertyWebkitMarginBeforeCollapse:
1525     case CSSPropertyWebkitMarginTopCollapse:
1526     case CSSPropertyWebkitMarginAfterCollapse:
1527     case CSSPropertyWebkitMarginBottomCollapse:
1528     case CSSPropertyWebkitPaddingEnd:
1529     case CSSPropertyWebkitPaddingStart:
1530     case CSSPropertyWebkitPaddingBefore:
1531     case CSSPropertyWebkitPaddingAfter:
1532     case CSSPropertyWebkitLogicalWidth:
1533     case CSSPropertyWebkitLogicalHeight:
1534     case CSSPropertyWebkitMinLogicalWidth:
1535     case CSSPropertyWebkitMinLogicalHeight:
1536     case CSSPropertyWebkitMaxLogicalWidth:
1537     case CSSPropertyWebkitMaxLogicalHeight:
1538     {
1539         CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, state.style()->direction(), state.style()->writingMode());
1540         ASSERT(newId != id);
1541         return applyProperty(newId, state, value);
1542     }
1543     case CSSPropertyFontStretch:
1544     case CSSPropertyPage:
1545     case CSSPropertyTextLineThroughColor:
1546     case CSSPropertyTextLineThroughMode:
1547     case CSSPropertyTextLineThroughStyle:
1548     case CSSPropertyTextLineThroughWidth:
1549     case CSSPropertyTextOverlineColor:
1550     case CSSPropertyTextOverlineMode:
1551     case CSSPropertyTextOverlineStyle:
1552     case CSSPropertyTextOverlineWidth:
1553     case CSSPropertyTextUnderlineColor:
1554     case CSSPropertyTextUnderlineMode:
1555     case CSSPropertyTextUnderlineStyle:
1556     case CSSPropertyTextUnderlineWidth:
1557     case CSSPropertyWebkitFontSizeDelta:
1558     case CSSPropertyWebkitTextDecorationsInEffect:
1559         return;
1560
1561     // CSS Text Layout Module Level 3: Vertical writing support
1562     case CSSPropertyWebkitWritingMode: {
1563         HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode);
1564
1565         if (primitiveValue)
1566             state.setWritingMode(*primitiveValue);
1567
1568         // FIXME: It is not ok to modify document state while applying style.
1569         if (state.element() && state.element() == state.document().documentElement())
1570             state.document().setWritingModeSetOnDocumentElement(true);
1571         return;
1572     }
1573
1574     case CSSPropertyWebkitTextOrientation: {
1575         HANDLE_INHERIT_AND_INITIAL(textOrientation, TextOrientation);
1576
1577         if (primitiveValue)
1578             state.setTextOrientation(*primitiveValue);
1579
1580         return;
1581     }
1582
1583     case CSSPropertyWebkitLineBoxContain: {
1584         HANDLE_INHERIT_AND_INITIAL(lineBoxContain, LineBoxContain)
1585         if (primitiveValue && primitiveValue->getValueID() == CSSValueNone) {
1586             state.style()->setLineBoxContain(LineBoxContainNone);
1587             return;
1588         }
1589
1590         if (!value->isLineBoxContainValue())
1591             return;
1592
1593         state.style()->setLineBoxContain(toCSSLineBoxContainValue(value)->value());
1594         return;
1595     }
1596
1597     // CSS Fonts Module Level 3
1598     case CSSPropertyWebkitFontFeatureSettings: {
1599         if (primitiveValue && primitiveValue->getValueID() == CSSValueNormal) {
1600             state.fontBuilder().setFeatureSettingsNormal();
1601             return;
1602         }
1603
1604         if (!value->isValueList())
1605             return;
1606
1607         state.fontBuilder().setFeatureSettingsValue(value);
1608         return;
1609     }
1610
1611     case CSSPropertyWebkitFilter: {
1612         HANDLE_INHERIT_AND_INITIAL(filter, Filter);
1613         FilterOperations operations;
1614         if (FilterOperationResolver::createFilterOperations(value, state.cssToLengthConversionData(), operations, state))
1615             state.style()->setFilter(operations);
1616         return;
1617     }
1618     case CSSPropertyGridAutoColumns: {
1619         HANDLE_INHERIT_AND_INITIAL(gridAutoColumns, GridAutoColumns);
1620         state.style()->setGridAutoColumns(createGridTrackSize(value, state));
1621         return;
1622     }
1623     case CSSPropertyGridAutoRows: {
1624         HANDLE_INHERIT_AND_INITIAL(gridAutoRows, GridAutoRows);
1625         state.style()->setGridAutoRows(createGridTrackSize(value, state));
1626         return;
1627     }
1628     case CSSPropertyGridDefinitionColumns: {
1629         if (isInherit) {
1630             state.style()->setGridDefinitionColumns(state.parentStyle()->gridDefinitionColumns());
1631             state.style()->setNamedGridColumnLines(state.parentStyle()->namedGridColumnLines());
1632             state.style()->setOrderedNamedGridColumnLines(state.parentStyle()->orderedNamedGridColumnLines());
1633             return;
1634         }
1635         if (isInitial) {
1636             state.style()->setGridDefinitionColumns(RenderStyle::initialGridDefinitionColumns());
1637             state.style()->setNamedGridColumnLines(RenderStyle::initialNamedGridColumnLines());
1638             state.style()->setOrderedNamedGridColumnLines(RenderStyle::initialOrderedNamedGridColumnLines());
1639             return;
1640         }
1641
1642         Vector<GridTrackSize> trackSizes;
1643         NamedGridLinesMap namedGridLines;
1644         OrderedNamedGridLines orderedNamedGridLines;
1645         if (!createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, state))
1646             return;
1647         state.style()->setGridDefinitionColumns(trackSizes);
1648         state.style()->setNamedGridColumnLines(namedGridLines);
1649         state.style()->setOrderedNamedGridColumnLines(orderedNamedGridLines);
1650         return;
1651     }
1652     case CSSPropertyGridDefinitionRows: {
1653         if (isInherit) {
1654             state.style()->setGridDefinitionRows(state.parentStyle()->gridDefinitionRows());
1655             state.style()->setNamedGridRowLines(state.parentStyle()->namedGridRowLines());
1656             state.style()->setOrderedNamedGridRowLines(state.parentStyle()->orderedNamedGridRowLines());
1657             return;
1658         }
1659         if (isInitial) {
1660             state.style()->setGridDefinitionRows(RenderStyle::initialGridDefinitionRows());
1661             state.style()->setNamedGridRowLines(RenderStyle::initialNamedGridRowLines());
1662             state.style()->setOrderedNamedGridRowLines(RenderStyle::initialOrderedNamedGridRowLines());
1663             return;
1664         }
1665
1666         Vector<GridTrackSize> trackSizes;
1667         NamedGridLinesMap namedGridLines;
1668         OrderedNamedGridLines orderedNamedGridLines;
1669         if (!createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, state))
1670             return;
1671         state.style()->setGridDefinitionRows(trackSizes);
1672         state.style()->setNamedGridRowLines(namedGridLines);
1673         state.style()->setOrderedNamedGridRowLines(orderedNamedGridLines);
1674         return;
1675     }
1676
1677     case CSSPropertyGridColumnStart: {
1678         HANDLE_INHERIT_AND_INITIAL(gridColumnStart, GridColumnStart);
1679         GridPosition startPosition;
1680         if (!createGridPosition(value, startPosition))
1681             return;
1682         state.style()->setGridColumnStart(startPosition);
1683         return;
1684     }
1685     case CSSPropertyGridColumnEnd: {
1686         HANDLE_INHERIT_AND_INITIAL(gridColumnEnd, GridColumnEnd);
1687         GridPosition endPosition;
1688         if (!createGridPosition(value, endPosition))
1689             return;
1690         state.style()->setGridColumnEnd(endPosition);
1691         return;
1692     }
1693
1694     case CSSPropertyGridRowStart: {
1695         HANDLE_INHERIT_AND_INITIAL(gridRowStart, GridRowStart);
1696         GridPosition beforePosition;
1697         if (!createGridPosition(value, beforePosition))
1698             return;
1699         state.style()->setGridRowStart(beforePosition);
1700         return;
1701     }
1702     case CSSPropertyGridRowEnd: {
1703         HANDLE_INHERIT_AND_INITIAL(gridRowEnd, GridRowEnd);
1704         GridPosition afterPosition;
1705         if (!createGridPosition(value, afterPosition))
1706             return;
1707         state.style()->setGridRowEnd(afterPosition);
1708         return;
1709     }
1710
1711     case CSSPropertyGridTemplate: {
1712         if (isInherit) {
1713             state.style()->setNamedGridArea(state.parentStyle()->namedGridArea());
1714             state.style()->setNamedGridAreaRowCount(state.parentStyle()->namedGridAreaRowCount());
1715             state.style()->setNamedGridAreaColumnCount(state.parentStyle()->namedGridAreaColumnCount());
1716             return;
1717         }
1718         if (isInitial) {
1719             state.style()->setNamedGridArea(RenderStyle::initialNamedGridArea());
1720             state.style()->setNamedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount());
1721             state.style()->setNamedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount());
1722             return;
1723         }
1724
1725         if (value->isPrimitiveValue()) {
1726             ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
1727             return;
1728         }
1729
1730         CSSGridTemplateValue* gridTemplateValue = toCSSGridTemplateValue(value);
1731         state.style()->setNamedGridArea(gridTemplateValue->gridAreaMap());
1732         state.style()->setNamedGridAreaRowCount(gridTemplateValue->rowCount());
1733         state.style()->setNamedGridAreaColumnCount(gridTemplateValue->columnCount());
1734         return;
1735     }
1736
1737     case CSSPropertyJustifySelf: {
1738         HANDLE_INHERIT_AND_INITIAL(justifySelf, JustifySelf);
1739         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1740         if (Pair* pairValue = primitiveValue->getPairValue()) {
1741             state.style()->setJustifySelf(*pairValue->first());
1742             state.style()->setJustifySelfOverflowAlignment(*pairValue->second());
1743         } else {
1744             state.style()->setJustifySelf(*primitiveValue);
1745         }
1746         return;
1747     }
1748
1749     case CSSPropertyAlignSelf: {
1750         HANDLE_INHERIT_AND_INITIAL(alignSelf, AlignSelf);
1751         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1752         if (Pair* pairValue = primitiveValue->getPairValue()) {
1753             state.style()->setAlignSelf(*pairValue->first());
1754             state.style()->setAlignSelfOverflowAlignment(*pairValue->second());
1755         } else {
1756             state.style()->setAlignSelf(*primitiveValue);
1757         }
1758         return;
1759     }
1760
1761     case CSSPropertyAlignItems: {
1762         HANDLE_INHERIT_AND_INITIAL(alignItems, AlignItems);
1763         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1764         if (Pair* pairValue = primitiveValue->getPairValue()) {
1765             state.style()->setAlignItems(*pairValue->first());
1766             state.style()->setAlignItemsOverflowAlignment(*pairValue->second());
1767         } else {
1768             state.style()->setAlignItems(*primitiveValue);
1769         }
1770         return;
1771     }
1772
1773     // These properties are aliased and we already applied the property on the prefixed version.
1774     case CSSPropertyAnimationDelay:
1775     case CSSPropertyAnimationDirection:
1776     case CSSPropertyAnimationDuration:
1777     case CSSPropertyAnimationFillMode:
1778     case CSSPropertyAnimationIterationCount:
1779     case CSSPropertyAnimationName:
1780     case CSSPropertyAnimationPlayState:
1781     case CSSPropertyAnimationTimingFunction:
1782     case CSSPropertyTransitionDelay:
1783     case CSSPropertyTransitionDuration:
1784     case CSSPropertyTransitionProperty:
1785     case CSSPropertyTransitionTimingFunction:
1786         return;
1787     // These properties are implemented in StyleBuilder::applyProperty.
1788     case CSSPropertyBackgroundAttachment:
1789     case CSSPropertyBackgroundBlendMode:
1790     case CSSPropertyBackgroundClip:
1791     case CSSPropertyBackgroundColor:
1792     case CSSPropertyBackgroundImage:
1793     case CSSPropertyBackgroundOrigin:
1794     case CSSPropertyBackgroundPositionX:
1795     case CSSPropertyBackgroundPositionY:
1796     case CSSPropertyBackgroundRepeatX:
1797     case CSSPropertyBackgroundRepeatY:
1798     case CSSPropertyBackgroundSize:
1799     case CSSPropertyBorderBottomColor:
1800     case CSSPropertyBorderBottomLeftRadius:
1801     case CSSPropertyBorderBottomRightRadius:
1802     case CSSPropertyBorderBottomStyle:
1803     case CSSPropertyBorderBottomWidth:
1804     case CSSPropertyBorderCollapse:
1805     case CSSPropertyBorderImageOutset:
1806     case CSSPropertyBorderImageRepeat:
1807     case CSSPropertyBorderImageSlice:
1808     case CSSPropertyBorderImageSource:
1809     case CSSPropertyBorderImageWidth:
1810     case CSSPropertyBorderLeftColor:
1811     case CSSPropertyBorderLeftStyle:
1812     case CSSPropertyBorderLeftWidth:
1813     case CSSPropertyBorderRightColor:
1814     case CSSPropertyBorderRightStyle:
1815     case CSSPropertyBorderRightWidth:
1816     case CSSPropertyBorderTopColor:
1817     case CSSPropertyBorderTopLeftRadius:
1818     case CSSPropertyBorderTopRightRadius:
1819     case CSSPropertyBorderTopStyle:
1820     case CSSPropertyBorderTopWidth:
1821     case CSSPropertyBottom:
1822     case CSSPropertyBoxShadow:
1823     case CSSPropertyBoxSizing:
1824     case CSSPropertyCaptionSide:
1825     case CSSPropertyClear:
1826     case CSSPropertyClip:
1827     case CSSPropertyColor:
1828     case CSSPropertyCounterIncrement:
1829     case CSSPropertyCounterReset:
1830     case CSSPropertyCursor:
1831     case CSSPropertyDirection:
1832     case CSSPropertyDisplay:
1833     case CSSPropertyEmptyCells:
1834     case CSSPropertyFloat:
1835     case CSSPropertyFontKerning:
1836     case CSSPropertyFontSize:
1837     case CSSPropertyFontStyle:
1838     case CSSPropertyFontVariant:
1839     case CSSPropertyFontWeight:
1840     case CSSPropertyHeight:
1841     case CSSPropertyImageRendering:
1842     case CSSPropertyIsolation:
1843     case CSSPropertyLeft:
1844     case CSSPropertyLetterSpacing:
1845     case CSSPropertyLineHeight:
1846     case CSSPropertyListStyleImage:
1847     case CSSPropertyListStylePosition:
1848     case CSSPropertyListStyleType:
1849     case CSSPropertyMarginBottom:
1850     case CSSPropertyMarginLeft:
1851     case CSSPropertyMarginRight:
1852     case CSSPropertyMarginTop:
1853     case CSSPropertyMaxHeight:
1854     case CSSPropertyMaxWidth:
1855     case CSSPropertyMinHeight:
1856     case CSSPropertyMixBlendMode:
1857     case CSSPropertyMinWidth:
1858     case CSSPropertyObjectFit:
1859     case CSSPropertyOpacity:
1860     case CSSPropertyOrphans:
1861     case CSSPropertyOutlineColor:
1862     case CSSPropertyOutlineOffset:
1863     case CSSPropertyOutlineStyle:
1864     case CSSPropertyOutlineWidth:
1865     case CSSPropertyOverflowWrap:
1866     case CSSPropertyOverflowX:
1867     case CSSPropertyOverflowY:
1868     case CSSPropertyPaddingBottom:
1869     case CSSPropertyPaddingLeft:
1870     case CSSPropertyPaddingRight:
1871     case CSSPropertyPaddingTop:
1872     case CSSPropertyPageBreakAfter:
1873     case CSSPropertyPageBreakBefore:
1874     case CSSPropertyPageBreakInside:
1875     case CSSPropertyPointerEvents:
1876     case CSSPropertyPosition:
1877     case CSSPropertyResize:
1878     case CSSPropertyRight:
1879     case CSSPropertyScrollBehavior:
1880     case CSSPropertySize:
1881     case CSSPropertySpeak:
1882     case CSSPropertyTabSize:
1883     case CSSPropertyTableLayout:
1884     case CSSPropertyTextAlign:
1885     case CSSPropertyTextAlignLast:
1886     case CSSPropertyTextDecoration:
1887     case CSSPropertyTextDecorationLine:
1888     case CSSPropertyTextDecorationStyle:
1889     case CSSPropertyTextDecorationColor:
1890     case CSSPropertyTextIndent:
1891     case CSSPropertyTextJustify:
1892     case CSSPropertyTextOverflow:
1893     case CSSPropertyTextRendering:
1894     case CSSPropertyTextShadow:
1895     case CSSPropertyTextTransform:
1896     case CSSPropertyTop:
1897     case CSSPropertyTouchAction:
1898     case CSSPropertyTouchActionDelay:
1899     case CSSPropertyUnicodeBidi:
1900     case CSSPropertyVariable:
1901     case CSSPropertyVerticalAlign:
1902     case CSSPropertyVisibility:
1903     case CSSPropertyWebkitAnimationDelay:
1904     case CSSPropertyWebkitAnimationDirection:
1905     case CSSPropertyWebkitAnimationDuration:
1906     case CSSPropertyWebkitAnimationFillMode:
1907     case CSSPropertyWebkitAnimationIterationCount:
1908     case CSSPropertyWebkitAnimationName:
1909     case CSSPropertyWebkitAnimationPlayState:
1910     case CSSPropertyWebkitAnimationTimingFunction:
1911     case CSSPropertyWebkitAppearance:
1912     case CSSPropertyWebkitAspectRatio:
1913     case CSSPropertyWebkitBackfaceVisibility:
1914     case CSSPropertyWebkitBackgroundClip:
1915     case CSSPropertyWebkitBackgroundComposite:
1916     case CSSPropertyWebkitBackgroundOrigin:
1917     case CSSPropertyWebkitBackgroundSize:
1918     case CSSPropertyWebkitBorderFit:
1919     case CSSPropertyWebkitBorderHorizontalSpacing:
1920     case CSSPropertyWebkitBorderImage:
1921     case CSSPropertyWebkitBorderVerticalSpacing:
1922     case CSSPropertyWebkitBoxAlign:
1923     case CSSPropertyWebkitBoxDecorationBreak:
1924     case CSSPropertyWebkitBoxDirection:
1925     case CSSPropertyWebkitBoxFlex:
1926     case CSSPropertyWebkitBoxFlexGroup:
1927     case CSSPropertyWebkitBoxLines:
1928     case CSSPropertyWebkitBoxOrdinalGroup:
1929     case CSSPropertyWebkitBoxOrient:
1930     case CSSPropertyWebkitBoxPack:
1931     case CSSPropertyWebkitBoxShadow:
1932     case CSSPropertyWebkitColumnAxis:
1933     case CSSPropertyWebkitColumnBreakAfter:
1934     case CSSPropertyWebkitColumnBreakBefore:
1935     case CSSPropertyWebkitColumnBreakInside:
1936     case CSSPropertyWebkitColumnCount:
1937     case CSSPropertyColumnFill:
1938     case CSSPropertyWebkitColumnGap:
1939     case CSSPropertyWebkitColumnProgression:
1940     case CSSPropertyWebkitColumnRuleColor:
1941     case CSSPropertyWebkitColumnRuleStyle:
1942     case CSSPropertyWebkitColumnRuleWidth:
1943     case CSSPropertyWebkitColumnSpan:
1944     case CSSPropertyWebkitColumnWidth:
1945     case CSSPropertyAlignContent:
1946     case CSSPropertyFlexBasis:
1947     case CSSPropertyFlexDirection:
1948     case CSSPropertyFlexGrow:
1949     case CSSPropertyFlexShrink:
1950     case CSSPropertyFlexWrap:
1951     case CSSPropertyJustifyContent:
1952     case CSSPropertyOrder:
1953     case CSSPropertyWebkitFlowFrom:
1954     case CSSPropertyWebkitFlowInto:
1955     case CSSPropertyWebkitFontSmoothing:
1956     case CSSPropertyWebkitFontVariantLigatures:
1957     case CSSPropertyWebkitHighlight:
1958     case CSSPropertyWebkitHyphenateCharacter:
1959     case CSSPropertyWebkitLineAlign:
1960     case CSSPropertyWebkitLineBreak:
1961     case CSSPropertyWebkitLineClamp:
1962     case CSSPropertyWebkitLineGrid:
1963     case CSSPropertyWebkitLineSnap:
1964     case CSSPropertyInternalMarqueeDirection:
1965     case CSSPropertyInternalMarqueeIncrement:
1966     case CSSPropertyInternalMarqueeRepetition:
1967     case CSSPropertyInternalMarqueeSpeed:
1968     case CSSPropertyInternalMarqueeStyle:
1969     case CSSPropertyWebkitMaskBoxImage:
1970     case CSSPropertyWebkitMaskBoxImageOutset:
1971     case CSSPropertyWebkitMaskBoxImageRepeat:
1972     case CSSPropertyWebkitMaskBoxImageSlice:
1973     case CSSPropertyWebkitMaskBoxImageSource:
1974     case CSSPropertyWebkitMaskBoxImageWidth:
1975     case CSSPropertyWebkitMaskClip:
1976     case CSSPropertyWebkitMaskComposite:
1977     case CSSPropertyWebkitMaskImage:
1978     case CSSPropertyWebkitMaskOrigin:
1979     case CSSPropertyWebkitMaskPositionX:
1980     case CSSPropertyWebkitMaskPositionY:
1981     case CSSPropertyWebkitMaskRepeatX:
1982     case CSSPropertyWebkitMaskRepeatY:
1983     case CSSPropertyWebkitMaskSize:
1984     case CSSPropertyWebkitPerspectiveOrigin:
1985     case CSSPropertyWebkitPerspectiveOriginX:
1986     case CSSPropertyWebkitPerspectiveOriginY:
1987     case CSSPropertyWebkitPrintColorAdjust:
1988     case CSSPropertyWebkitRegionBreakAfter:
1989     case CSSPropertyWebkitRegionBreakBefore:
1990     case CSSPropertyWebkitRegionBreakInside:
1991     case CSSPropertyWebkitRegionFragment:
1992     case CSSPropertyWebkitRtlOrdering:
1993     case CSSPropertyWebkitRubyPosition:
1994     case CSSPropertyWebkitTextCombine:
1995     case CSSPropertyTextUnderlinePosition:
1996     case CSSPropertyWebkitTextEmphasisColor:
1997     case CSSPropertyWebkitTextEmphasisPosition:
1998     case CSSPropertyWebkitTextEmphasisStyle:
1999     case CSSPropertyWebkitTextFillColor:
2000     case CSSPropertyWebkitTextSecurity:
2001     case CSSPropertyWebkitTextStrokeColor:
2002     case CSSPropertyWebkitTransformOriginX:
2003     case CSSPropertyWebkitTransformOriginY:
2004     case CSSPropertyWebkitTransformOriginZ:
2005     case CSSPropertyWebkitTransformStyle:
2006     case CSSPropertyWebkitTransitionDelay:
2007     case CSSPropertyWebkitTransitionDuration:
2008     case CSSPropertyWebkitTransitionProperty:
2009     case CSSPropertyWebkitTransitionTimingFunction:
2010     case CSSPropertyWebkitUserDrag:
2011     case CSSPropertyWebkitUserModify:
2012     case CSSPropertyWebkitUserSelect:
2013     case CSSPropertyWebkitClipPath:
2014     case CSSPropertyWebkitWrapFlow:
2015     case CSSPropertyShapeMargin:
2016     case CSSPropertyShapePadding:
2017     case CSSPropertyShapeImageThreshold:
2018     case CSSPropertyWebkitWrapThrough:
2019     case CSSPropertyShapeInside:
2020     case CSSPropertyShapeOutside:
2021     case CSSPropertyWhiteSpace:
2022     case CSSPropertyWidows:
2023     case CSSPropertyWidth:
2024     case CSSPropertyWordBreak:
2025     case CSSPropertyWordSpacing:
2026     case CSSPropertyWordWrap:
2027     case CSSPropertyZIndex:
2028     case CSSPropertyZoom:
2029     case CSSPropertyFontFamily:
2030     case CSSPropertyGridAutoFlow:
2031     case CSSPropertyMarker:
2032     case CSSPropertyAlignmentBaseline:
2033     case CSSPropertyBufferedRendering:
2034     case CSSPropertyClipRule:
2035     case CSSPropertyColorInterpolation:
2036     case CSSPropertyColorInterpolationFilters:
2037     case CSSPropertyColorRendering:
2038     case CSSPropertyDominantBaseline:
2039     case CSSPropertyFillRule:
2040     case CSSPropertyMaskSourceType:
2041     case CSSPropertyMaskType:
2042     case CSSPropertyShapeRendering:
2043     case CSSPropertyStrokeLinecap:
2044     case CSSPropertyStrokeLinejoin:
2045     case CSSPropertyTextAnchor:
2046     case CSSPropertyVectorEffect:
2047     case CSSPropertyWritingMode:
2048     case CSSPropertyClipPath:
2049     case CSSPropertyFillOpacity:
2050     case CSSPropertyFilter:
2051     case CSSPropertyFloodOpacity:
2052     case CSSPropertyKerning:
2053     case CSSPropertyMarkerEnd:
2054     case CSSPropertyMarkerMid:
2055     case CSSPropertyMarkerStart:
2056     case CSSPropertyMask:
2057     case CSSPropertyStopOpacity:
2058     case CSSPropertyStrokeDashoffset:
2059     case CSSPropertyStrokeMiterlimit:
2060     case CSSPropertyStrokeOpacity:
2061     case CSSPropertyStrokeWidth:
2062         ASSERT_NOT_REACHED();
2063         return;
2064     // Only used in @viewport rules
2065     case CSSPropertyMaxZoom:
2066     case CSSPropertyMinZoom:
2067     case CSSPropertyOrientation:
2068     case CSSPropertyUserZoom:
2069         return;
2070
2071     case CSSPropertyBaselineShift:
2072     {
2073         HANDLE_SVG_INHERIT_AND_INITIAL(baselineShift, BaselineShift);
2074         if (!primitiveValue)
2075             break;
2076
2077         SVGRenderStyle* svgStyle = state.style()->accessSVGStyle();
2078         if (primitiveValue->getValueID()) {
2079             switch (primitiveValue->getValueID()) {
2080             case CSSValueBaseline:
2081                 svgStyle->setBaselineShift(BS_BASELINE);
2082                 break;
2083             case CSSValueSub:
2084                 svgStyle->setBaselineShift(BS_SUB);
2085                 break;
2086             case CSSValueSuper:
2087                 svgStyle->setBaselineShift(BS_SUPER);
2088                 break;
2089             default:
2090                 break;
2091             }
2092         } else {
2093             svgStyle->setBaselineShift(BS_LENGTH);
2094             svgStyle->setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
2095         }
2096
2097         break;
2098     }
2099     case CSSPropertyColorProfile:
2100     {
2101         // Not implemented.
2102         break;
2103     }
2104     // end of ident only properties
2105     case CSSPropertyFill:
2106     {
2107         SVGRenderStyle* svgStyle = state.style()->accessSVGStyle();
2108         if (isInherit) {
2109             const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle();
2110             svgStyle->setFillPaint(svgParentStyle->fillPaintType(), svgParentStyle->fillPaintColor(), svgParentStyle->fillPaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
2111             return;
2112         }
2113         if (isInitial) {
2114             svgStyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
2115             return;
2116         }
2117         if (value->isSVGPaint()) {
2118             SVGPaint* svgPaint = toSVGPaint(value);
2119             svgStyle->setFillPaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
2120         }
2121         break;
2122     }
2123     case CSSPropertyStroke:
2124     {
2125         SVGRenderStyle* svgStyle = state.style()->accessSVGStyle();
2126         if (isInherit) {
2127             const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle();
2128             svgStyle->setStrokePaint(svgParentStyle->strokePaintType(), svgParentStyle->strokePaintColor(), svgParentStyle->strokePaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
2129             return;
2130         }
2131         if (isInitial) {
2132             svgStyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
2133             return;
2134         }
2135         if (value->isSVGPaint()) {
2136             SVGPaint* svgPaint = toSVGPaint(value);
2137             svgStyle->setStrokePaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
2138         }
2139         break;
2140     }
2141     case CSSPropertyStrokeDasharray:
2142     {
2143         HANDLE_SVG_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
2144         if (!value->isValueList()) {
2145             state.style()->accessSVGStyle()->setStrokeDashArray(SVGRenderStyle::initialStrokeDashArray());
2146             break;
2147         }
2148
2149         CSSValueList* dashes = toCSSValueList(value);
2150
2151         RefPtr<SVGLengthList> array = SVGLengthList::create();
2152         size_t length = dashes->length();
2153         for (size_t i = 0; i < length; ++i) {
2154             CSSValue* currValue = dashes->itemWithoutBoundsCheck(i);
2155             if (!currValue->isPrimitiveValue())
2156                 continue;
2157
2158             CSSPrimitiveValue* dash = toCSSPrimitiveValue(dashes->itemWithoutBoundsCheck(i));
2159             array->append(SVGLength::fromCSSPrimitiveValue(dash));
2160         }
2161
2162         state.style()->accessSVGStyle()->setStrokeDashArray(array.release());
2163         break;
2164     }
2165     case CSSPropertyStopColor:
2166     {
2167         HANDLE_SVG_INHERIT_AND_INITIAL(stopColor, StopColor);
2168         if (value->isSVGColor())
2169             state.style()->accessSVGStyle()->setStopColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
2170         break;
2171     }
2172     case CSSPropertyLightingColor:
2173     {
2174         HANDLE_SVG_INHERIT_AND_INITIAL(lightingColor, LightingColor);
2175         if (value->isSVGColor())
2176             state.style()->accessSVGStyle()->setLightingColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
2177         break;
2178     }
2179     case CSSPropertyFloodColor:
2180     {
2181         HANDLE_SVG_INHERIT_AND_INITIAL(floodColor, FloodColor);
2182         if (value->isSVGColor())
2183             state.style()->accessSVGStyle()->setFloodColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
2184         break;
2185     }
2186     case CSSPropertyGlyphOrientationHorizontal:
2187     {
2188         HANDLE_SVG_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal)
2189         EGlyphOrientation orientation;
2190         if (degreeToGlyphOrientation(primitiveValue, orientation))
2191             state.style()->accessSVGStyle()->setGlyphOrientationHorizontal(orientation);
2192         break;
2193     }
2194     case CSSPropertyPaintOrder: {
2195         HANDLE_SVG_INHERIT_AND_INITIAL(paintOrder, PaintOrder)
2196         if (value->isValueList())
2197             state.style()->accessSVGStyle()->setPaintOrder(paintOrderFlattened(value));
2198         break;
2199     }
2200     case CSSPropertyGlyphOrientationVertical:
2201     {
2202         HANDLE_SVG_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical)
2203         if (primitiveValue->getValueID() == CSSValueAuto) {
2204             state.style()->accessSVGStyle()->setGlyphOrientationVertical(GO_AUTO);
2205             break;
2206         }
2207         EGlyphOrientation orientation;
2208         if (degreeToGlyphOrientation(primitiveValue, orientation))
2209             state.style()->accessSVGStyle()->setGlyphOrientationVertical(orientation);
2210         break;
2211     }
2212     case CSSPropertyEnableBackground:
2213         // Silently ignoring this property for now
2214         // http://bugs.webkit.org/show_bug.cgi?id=6022
2215         break;
2216     }
2217 }
2218
2219 } // namespace WebCore