Home | History | Annotate | Download | only in resolver
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      4  *           (C) 2004-2005 Allan Sandfeld Jensen (kde (at) carewolf.com)
      5  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit (at) 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 (at) webkit.org>
      8  * Copyright (C) 2007, 2008 Eric Seidel <eric (at) 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 
     89 namespace WebCore {
     90 
     91 static Length clipConvertToLength(StyleResolverState& state, CSSPrimitiveValue* value)
     92 {
     93     return value->convertToLength<FixedIntegerConversion | PercentConversion | FractionConversion | AutoConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom());
     94 }
     95 
     96 void StyleBuilderFunctions::applyInitialCSSPropertyClip(StyleResolverState& state)
     97 {
     98     state.style()->setClip(Length(), Length(), Length(), Length());
     99     state.style()->setHasClip(false);
    100 }
    101 
    102 void 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 
    111 void 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 
    131 void StyleBuilderFunctions::applyInitialCSSPropertyCursor(StyleResolverState& state)
    132 {
    133     state.style()->clearCursorList();
    134     state.style()->setCursor(RenderStyle::initialCursor());
    135 }
    136 
    137 void StyleBuilderFunctions::applyInheritCSSPropertyCursor(StyleResolverState& state)
    138 {
    139     state.style()->setCursor(state.parentStyle()->cursor());
    140     state.style()->setCursorList(state.parentStyle()->cursors());
    141 }
    142 
    143 void 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 
    170 void 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 
    178 static 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 
    185 void 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 
    193 void 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 
    206 void StyleBuilderFunctions::applyInitialCSSPropertyFontFamily(StyleResolverState& state)
    207 {
    208     state.fontBuilder().setFontFamilyInitial(state.style()->effectiveZoom());
    209 }
    210 
    211 void StyleBuilderFunctions::applyInheritCSSPropertyFontFamily(StyleResolverState& state)
    212 {
    213     state.fontBuilder().setFontFamilyInherit(state.parentFontDescription());
    214 }
    215 
    216 void StyleBuilderFunctions::applyValueCSSPropertyFontFamily(StyleResolverState& state, CSSValue* value)
    217 {
    218     state.fontBuilder().setFontFamilyValue(value, state.style()->effectiveZoom());
    219 }
    220 
    221 void StyleBuilderFunctions::applyInitialCSSPropertyFontSize(StyleResolverState& state)
    222 {
    223     state.fontBuilder().setFontSizeInitial(state.style()->effectiveZoom());
    224 }
    225 
    226 void StyleBuilderFunctions::applyInheritCSSPropertyFontSize(StyleResolverState& state)
    227 {
    228     state.fontBuilder().setFontSizeInherit(state.parentFontDescription(), state.style()->effectiveZoom());
    229 }
    230 
    231 void StyleBuilderFunctions::applyValueCSSPropertyFontSize(StyleResolverState& state, CSSValue* value)
    232 {
    233     state.fontBuilder().setFontSizeValue(value, state.parentStyle(), state.rootElementStyle(), state.style()->effectiveZoom());
    234 }
    235 
    236 void StyleBuilderFunctions::applyInitialCSSPropertyFontWeight(StyleResolverState& state)
    237 {
    238     state.fontBuilder().setWeight(FontWeightNormal);
    239 }
    240 
    241 void StyleBuilderFunctions::applyInheritCSSPropertyFontWeight(StyleResolverState& state)
    242 {
    243     state.fontBuilder().setWeight(state.parentFontDescription().weight());
    244 }
    245 
    246 void 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 
    266 void 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 
    295 void StyleBuilderFunctions::applyValueCSSPropertyListStyleImage(StyleResolverState& state, CSSValue* value)
    296 {
    297     state.style()->setListStyleImage(state.styleImage(CSSPropertyListStyleImage, value));
    298 }
    299 
    300 void StyleBuilderFunctions::applyInitialCSSPropertyOutlineStyle(StyleResolverState& state)
    301 {
    302     state.style()->setOutlineStyleIsAuto(RenderStyle::initialOutlineStyleIsAuto());
    303     state.style()->setOutlineStyle(RenderStyle::initialBorderStyle());
    304 }
    305 
    306 void StyleBuilderFunctions::applyInheritCSSPropertyOutlineStyle(StyleResolverState& state)
    307 {
    308     state.style()->setOutlineStyleIsAuto(state.parentStyle()->outlineStyleIsAuto());
    309     state.style()->setOutlineStyle(state.parentStyle()->outlineStyle());
    310 }
    311 
    312 void StyleBuilderFunctions::applyValueCSSPropertyOutlineStyle(StyleResolverState& state, CSSValue* value)
    313 {
    314     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    315     state.style()->setOutlineStyleIsAuto(*primitiveValue);
    316     state.style()->setOutlineStyle(*primitiveValue);
    317 }
    318 
    319 void 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 
    340 static Length mmLength(double mm) { return CSSPrimitiveValue::create(mm, CSSPrimitiveValue::CSS_MM)->computeLength<Length>(0, 0); }
    341 static Length inchLength(double inch) { return CSSPrimitiveValue::create(inch, CSSPrimitiveValue::CSS_IN)->computeLength<Length>(0, 0); }
    342 static 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 
    416 void StyleBuilderFunctions::applyInitialCSSPropertySize(StyleResolverState&) { }
    417 void StyleBuilderFunctions::applyInheritCSSPropertySize(StyleResolverState&) { }
    418 void 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 
    485 void 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 
    506 void 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 
    516 void 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 
    524 void 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 
    532 void 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 
    559 void 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 
    572 static 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 
    578 void StyleBuilderFunctions::applyInitialCSSPropertyZoom(StyleResolverState& state)
    579 {
    580     resetEffectiveZoom(state);
    581     state.setZoom(RenderStyle::initialZoom());
    582 }
    583 
    584 void StyleBuilderFunctions::applyInheritCSSPropertyZoom(StyleResolverState& state)
    585 {
    586     resetEffectiveZoom(state);
    587     state.setZoom(state.parentStyle()->zoom());
    588 }
    589 
    590 void 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 
    616 void 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 
    623 void 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 
    632 void 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 
    644 void 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 
    661 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state)
    662 {
    663     state.fontBuilder().setFontVariantLigaturesInitial();
    664 }
    665 
    666 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state)
    667 {
    668     state.fontBuilder().setFontVariantLigaturesInherit(state.parentFontDescription());
    669 }
    670 
    671 void StyleBuilderFunctions::applyValueCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state, CSSValue* value)
    672 {
    673     state.fontBuilder().setFontVariantLigaturesValue(value);
    674 }
    675 
    676 void 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 
    703 void 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)
    731 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitPerspectiveOrigin(StyleResolverState& state)
    732 {
    733     applyInitialCSSPropertyWebkitPerspectiveOriginX(state);
    734     applyInitialCSSPropertyWebkitPerspectiveOriginY(state);
    735 }
    736 
    737 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitPerspectiveOrigin(StyleResolverState& state)
    738 {
    739     applyInheritCSSPropertyWebkitPerspectiveOriginX(state);
    740     applyInheritCSSPropertyWebkitPerspectiveOriginY(state);
    741 }
    742 
    743 void StyleBuilderFunctions::applyValueCSSPropertyWebkitPerspectiveOrigin(StyleResolverState&, CSSValue* value)
    744 {
    745     // This is expanded in the parser
    746     ASSERT_NOT_REACHED();
    747 }
    748 
    749 void 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 
    756 void 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 
    763 void 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)
    808 void 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 
    827 Length 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 
    836 Length 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 
    845 Length 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 
    871 Length 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 
    879 LengthSize 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 
    893 float 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) \
    907 if (isInherit) { \
    908     state.style()->set##Prop(state.parentStyle()->prop()); \
    909     return; \
    910 }
    911 
    912 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
    913 HANDLE_INHERIT(prop, Prop) \
    914 if (isInitial) { \
    915     state.style()->set##Prop(RenderStyle::initial##Prop()); \
    916     return; \
    917 }
    918 
    919 #define HANDLE_SVG_INHERIT(prop, Prop) \
    920 if (isInherit) { \
    921     state.style()->accessSVGStyle()->set##Prop(state.parentStyle()->svgStyle()->prop()); \
    922     return; \
    923 }
    924 
    925 #define HANDLE_SVG_INHERIT_AND_INITIAL(prop, Prop) \
    926 HANDLE_SVG_INHERIT(prop, Prop) \
    927 if (isInitial) { \
    928     state.style()->accessSVGStyle()->set##Prop(SVGRenderStyle::initial##Prop()); \
    929     return; \
    930 }
    931 
    932 static 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 
    960 static 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 
    985 static 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 
   1022 static 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 
   1076 static 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 
   1102 static 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 
   1112 static 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 
   1122 static 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 
   1134 static 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 
   1141 static 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 
   1166 static 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?
   1193 static 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 
   1219 void 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 
   1261 void 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