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