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 
     41 #include "core/CSSPropertyNames.h"
     42 #include "core/CSSValueKeywords.h"
     43 #include "core/StyleBuilderFunctions.h"
     44 #include "core/StylePropertyShorthand.h"
     45 #include "core/css/BasicShapeFunctions.h"
     46 #include "core/css/CSSAspectRatioValue.h"
     47 #include "core/css/CSSCursorImageValue.h"
     48 #include "core/css/CSSFontValue.h"
     49 #include "core/css/CSSGradientValue.h"
     50 #include "core/css/CSSGridTemplateAreasValue.h"
     51 #include "core/css/CSSHelper.h"
     52 #include "core/css/CSSImageSetValue.h"
     53 #include "core/css/CSSLineBoxContainValue.h"
     54 #include "core/css/CSSPrimitiveValueMappings.h"
     55 #include "core/css/CSSPropertyMetadata.h"
     56 #include "core/css/Counter.h"
     57 #include "core/css/Pair.h"
     58 #include "core/css/StylePropertySet.h"
     59 #include "core/css/StyleRule.h"
     60 #include "core/css/resolver/ElementStyleResources.h"
     61 #include "core/css/resolver/FilterOperationResolver.h"
     62 #include "core/css/resolver/FontBuilder.h"
     63 #include "core/css/resolver/StyleBuilder.h"
     64 #include "core/css/resolver/TransformBuilder.h"
     65 #include "core/frame/LocalFrame.h"
     66 #include "core/frame/Settings.h"
     67 #include "core/rendering/style/CounterContent.h"
     68 #include "core/rendering/style/QuotesData.h"
     69 #include "core/rendering/style/RenderStyle.h"
     70 #include "core/rendering/style/RenderStyleConstants.h"
     71 #include "core/rendering/style/SVGRenderStyle.h"
     72 #include "core/rendering/style/StyleGeneratedImage.h"
     73 #include "platform/fonts/FontDescription.h"
     74 #include "wtf/MathExtras.h"
     75 #include "wtf/StdLibExtras.h"
     76 #include "wtf/Vector.h"
     77 
     78 namespace blink {
     79 
     80 namespace {
     81 
     82 static inline bool isValidVisitedLinkProperty(CSSPropertyID id)
     83 {
     84     switch (id) {
     85     case CSSPropertyBackgroundColor:
     86     case CSSPropertyBorderLeftColor:
     87     case CSSPropertyBorderRightColor:
     88     case CSSPropertyBorderTopColor:
     89     case CSSPropertyBorderBottomColor:
     90     case CSSPropertyColor:
     91     case CSSPropertyFill:
     92     case CSSPropertyOutlineColor:
     93     case CSSPropertyStroke:
     94     case CSSPropertyTextDecorationColor:
     95     case CSSPropertyWebkitColumnRuleColor:
     96     case CSSPropertyWebkitTextEmphasisColor:
     97     case CSSPropertyWebkitTextFillColor:
     98     case CSSPropertyWebkitTextStrokeColor:
     99         return true;
    100     default:
    101         return false;
    102     }
    103 }
    104 
    105 } // namespace
    106 
    107 void StyleBuilder::applyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value)
    108 {
    109     ASSERT_WITH_MESSAGE(!isExpandedShorthand(id), "Shorthand property id = %d wasn't expanded at parsing time", id);
    110 
    111     bool isInherit = state.parentNode() && value->isInheritedValue();
    112     bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue());
    113 
    114     ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
    115     ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle())
    116 
    117     if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
    118         // Limit the properties that can be applied to only the ones honored by :visited.
    119         return;
    120     }
    121 
    122     if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSPropertyMetadata::isInheritedProperty(id))
    123         state.parentStyle()->setHasExplicitlyInheritedProperties();
    124 
    125     StyleBuilder::applyProperty(id, state, value, isInitial, isInherit);
    126 }
    127 
    128 void StyleBuilderFunctions::applyInitialCSSPropertyColor(StyleResolverState& state)
    129 {
    130     Color color = RenderStyle::initialColor();
    131     if (state.applyPropertyToRegularStyle())
    132         state.style()->setColor(color);
    133     if (state.applyPropertyToVisitedLinkStyle())
    134         state.style()->setVisitedLinkColor(color);
    135 }
    136 
    137 void StyleBuilderFunctions::applyInheritCSSPropertyColor(StyleResolverState& state)
    138 {
    139     Color color = state.parentStyle()->color();
    140     if (state.applyPropertyToRegularStyle())
    141         state.style()->setColor(color);
    142     if (state.applyPropertyToVisitedLinkStyle())
    143         state.style()->setVisitedLinkColor(color);
    144 }
    145 
    146 void StyleBuilderFunctions::applyValueCSSPropertyColor(StyleResolverState& state, CSSValue* value)
    147 {
    148     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    149     // As per the spec, 'color: currentColor' is treated as 'color: inherit'
    150     if (primitiveValue->getValueID() == CSSValueCurrentcolor) {
    151         applyInheritCSSPropertyColor(state);
    152         return;
    153     }
    154 
    155     if (state.applyPropertyToRegularStyle())
    156         state.style()->setColor(StyleBuilderConverter::convertColor(state, value));
    157     if (state.applyPropertyToVisitedLinkStyle())
    158         state.style()->setVisitedLinkColor(StyleBuilderConverter::convertColor(state, value, true));
    159 }
    160 
    161 void StyleBuilderFunctions::applyInitialCSSPropertyJustifyItems(StyleResolverState& state)
    162 {
    163     state.style()->setJustifyItems(RenderStyle::initialJustifyItems());
    164     state.style()->setJustifyItemsOverflowAlignment(RenderStyle::initialJustifyItemsOverflowAlignment());
    165     state.style()->setJustifyItemsPositionType(RenderStyle::initialJustifyItemsPositionType());
    166 }
    167 
    168 void StyleBuilderFunctions::applyInheritCSSPropertyJustifyItems(StyleResolverState& state)
    169 {
    170     state.style()->setJustifyItems(state.parentStyle()->justifyItems());
    171     state.style()->setJustifyItemsOverflowAlignment(state.parentStyle()->justifyItemsOverflowAlignment());
    172     state.style()->setJustifyItemsPositionType(state.parentStyle()->justifyItemsPositionType());
    173 }
    174 
    175 void StyleBuilderFunctions::applyValueCSSPropertyJustifyItems(StyleResolverState& state, CSSValue* value)
    176 {
    177 
    178     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    179     if (Pair* pairValue = primitiveValue->getPairValue()) {
    180         if (pairValue->first()->getValueID() == CSSValueLegacy) {
    181             state.style()->setJustifyItemsPositionType(LegacyPosition);
    182             state.style()->setJustifyItems(*pairValue->second());
    183         } else {
    184             state.style()->setJustifyItems(*pairValue->first());
    185             state.style()->setJustifyItemsOverflowAlignment(*pairValue->second());
    186         }
    187     } else {
    188         state.style()->setJustifyItems(*primitiveValue);
    189     }
    190 }
    191 
    192 void StyleBuilderFunctions::applyInitialCSSPropertyCursor(StyleResolverState& state)
    193 {
    194     state.style()->clearCursorList();
    195     state.style()->setCursor(RenderStyle::initialCursor());
    196 }
    197 
    198 void StyleBuilderFunctions::applyInheritCSSPropertyCursor(StyleResolverState& state)
    199 {
    200     state.style()->setCursor(state.parentStyle()->cursor());
    201     state.style()->setCursorList(state.parentStyle()->cursors());
    202 }
    203 
    204 void StyleBuilderFunctions::applyValueCSSPropertyCursor(StyleResolverState& state, CSSValue* value)
    205 {
    206     state.style()->clearCursorList();
    207     if (value->isValueList()) {
    208         CSSValueList* list = toCSSValueList(value);
    209         int len = list->length();
    210         state.style()->setCursor(CURSOR_AUTO);
    211         for (int i = 0; i < len; i++) {
    212             CSSValue* item = list->item(i);
    213             if (item->isCursorImageValue()) {
    214                 CSSCursorImageValue* image = toCSSCursorImageValue(item);
    215                 if (image->updateIfSVGCursorIsUsed(state.element())) // Elements with SVG cursors are not allowed to share style.
    216                     state.style()->setUnique();
    217                 state.style()->addCursor(state.styleImage(CSSPropertyCursor, image), image->hotSpot());
    218             } else {
    219                 state.style()->setCursor(*toCSSPrimitiveValue(item));
    220             }
    221         }
    222     } else {
    223         state.style()->setCursor(*toCSSPrimitiveValue(value));
    224     }
    225 }
    226 
    227 void StyleBuilderFunctions::applyValueCSSPropertyDirection(StyleResolverState& state, CSSValue* value)
    228 {
    229     state.style()->setDirection(*toCSSPrimitiveValue(value));
    230     Element* element = state.element();
    231     if (element && element == element->document().documentElement())
    232         element->document().setDirectionSetOnDocumentElement(true);
    233 }
    234 
    235 void StyleBuilderFunctions::applyInitialCSSPropertyFontFamily(StyleResolverState& state)
    236 {
    237     state.fontBuilder().setFontFamilyInitial();
    238 }
    239 
    240 void StyleBuilderFunctions::applyInheritCSSPropertyFontFamily(StyleResolverState& state)
    241 {
    242     state.fontBuilder().setFontFamilyInherit(state.parentFontDescription());
    243 }
    244 
    245 void StyleBuilderFunctions::applyValueCSSPropertyFontFamily(StyleResolverState& state, CSSValue* value)
    246 {
    247     state.fontBuilder().setFontFamilyValue(value);
    248 }
    249 
    250 void StyleBuilderFunctions::applyValueCSSPropertyGlyphOrientationVertical(StyleResolverState& state, CSSValue* value)
    251 {
    252     if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueAuto)
    253         state.style()->accessSVGStyle().setGlyphOrientationVertical(GO_AUTO);
    254     else
    255         state.style()->accessSVGStyle().setGlyphOrientationVertical(StyleBuilderConverter::convertGlyphOrientation(state, value));
    256 }
    257 
    258 void StyleBuilderFunctions::applyInitialCSSPropertyGridTemplateAreas(StyleResolverState& state)
    259 {
    260     state.style()->setNamedGridArea(RenderStyle::initialNamedGridArea());
    261     state.style()->setNamedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount());
    262     state.style()->setNamedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount());
    263 }
    264 
    265 void StyleBuilderFunctions::applyInheritCSSPropertyGridTemplateAreas(StyleResolverState& state)
    266 {
    267     state.style()->setNamedGridArea(state.parentStyle()->namedGridArea());
    268     state.style()->setNamedGridAreaRowCount(state.parentStyle()->namedGridAreaRowCount());
    269     state.style()->setNamedGridAreaColumnCount(state.parentStyle()->namedGridAreaColumnCount());
    270 }
    271 
    272 void StyleBuilderFunctions::applyValueCSSPropertyGridTemplateAreas(StyleResolverState& state, CSSValue* value)
    273 {
    274     if (value->isPrimitiveValue()) {
    275         // FIXME: Shouldn't we clear the grid-area values
    276         ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
    277         return;
    278     }
    279 
    280     CSSGridTemplateAreasValue* gridTemplateAreasValue = toCSSGridTemplateAreasValue(value);
    281     const NamedGridAreaMap& newNamedGridAreas = gridTemplateAreasValue->gridAreaMap();
    282 
    283     NamedGridLinesMap namedGridColumnLines = state.style()->namedGridColumnLines();
    284     NamedGridLinesMap namedGridRowLines = state.style()->namedGridRowLines();
    285     StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridColumnLines, ForColumns);
    286     StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridRowLines, ForRows);
    287     state.style()->setNamedGridColumnLines(namedGridColumnLines);
    288     state.style()->setNamedGridRowLines(namedGridRowLines);
    289 
    290     state.style()->setNamedGridArea(newNamedGridAreas);
    291     state.style()->setNamedGridAreaRowCount(gridTemplateAreasValue->rowCount());
    292     state.style()->setNamedGridAreaColumnCount(gridTemplateAreasValue->columnCount());
    293 }
    294 
    295 void StyleBuilderFunctions::applyValueCSSPropertyLineHeight(StyleResolverState& state, CSSValue* value)
    296 {
    297     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    298     Length lineHeight;
    299 
    300     if (primitiveValue->getValueID() == CSSValueNormal) {
    301         lineHeight = RenderStyle::initialLineHeight();
    302     } else if (primitiveValue->isLength()) {
    303         float multiplier = state.style()->effectiveZoom();
    304         if (LocalFrame* frame = state.document().frame())
    305             multiplier *= frame->textZoomFactor();
    306         lineHeight = primitiveValue->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier));
    307     } else if (primitiveValue->isPercentage()) {
    308         lineHeight = Length((state.style()->computedFontSize() * primitiveValue->getIntValue()) / 100.0, Fixed);
    309     } else if (primitiveValue->isNumber()) {
    310         lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
    311     } else if (primitiveValue->isCalculated()) {
    312         double multiplier = state.style()->effectiveZoom();
    313         if (LocalFrame* frame = state.document().frame())
    314             multiplier *= frame->textZoomFactor();
    315         Length zoomedLength = Length(primitiveValue->cssCalcValue()->toCalcValue(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier)));
    316         lineHeight = Length(valueForLength(zoomedLength, state.style()->fontSize()), Fixed);
    317     } else {
    318         return;
    319     }
    320     state.style()->setLineHeight(lineHeight);
    321 }
    322 
    323 void StyleBuilderFunctions::applyValueCSSPropertyListStyleImage(StyleResolverState& state, CSSValue* value)
    324 {
    325     state.style()->setListStyleImage(state.styleImage(CSSPropertyListStyleImage, value));
    326 }
    327 
    328 void StyleBuilderFunctions::applyInitialCSSPropertyOutlineStyle(StyleResolverState& state)
    329 {
    330     state.style()->setOutlineStyleIsAuto(RenderStyle::initialOutlineStyleIsAuto());
    331     state.style()->setOutlineStyle(RenderStyle::initialBorderStyle());
    332 }
    333 
    334 void StyleBuilderFunctions::applyInheritCSSPropertyOutlineStyle(StyleResolverState& state)
    335 {
    336     state.style()->setOutlineStyleIsAuto(state.parentStyle()->outlineStyleIsAuto());
    337     state.style()->setOutlineStyle(state.parentStyle()->outlineStyle());
    338 }
    339 
    340 void StyleBuilderFunctions::applyValueCSSPropertyOutlineStyle(StyleResolverState& state, CSSValue* value)
    341 {
    342     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    343     state.style()->setOutlineStyleIsAuto(*primitiveValue);
    344     state.style()->setOutlineStyle(*primitiveValue);
    345 }
    346 
    347 void StyleBuilderFunctions::applyValueCSSPropertyResize(StyleResolverState& state, CSSValue* value)
    348 {
    349     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    350 
    351     EResize r = RESIZE_NONE;
    352     if (primitiveValue->getValueID() == CSSValueAuto) {
    353         if (Settings* settings = state.document().settings())
    354             r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE;
    355     } else {
    356         r = *primitiveValue;
    357     }
    358     state.style()->setResize(r);
    359 }
    360 
    361 static Length mmLength(double mm) { return Length(mm * cssPixelsPerMillimeter, Fixed); }
    362 static Length inchLength(double inch) { return Length(inch * cssPixelsPerInch, Fixed); }
    363 static bool getPageSizeFromName(CSSPrimitiveValue* pageSizeName, CSSPrimitiveValue* pageOrientation, Length& width, Length& height)
    364 {
    365     DEFINE_STATIC_LOCAL(Length, a5Width, (mmLength(148)));
    366     DEFINE_STATIC_LOCAL(Length, a5Height, (mmLength(210)));
    367     DEFINE_STATIC_LOCAL(Length, a4Width, (mmLength(210)));
    368     DEFINE_STATIC_LOCAL(Length, a4Height, (mmLength(297)));
    369     DEFINE_STATIC_LOCAL(Length, a3Width, (mmLength(297)));
    370     DEFINE_STATIC_LOCAL(Length, a3Height, (mmLength(420)));
    371     DEFINE_STATIC_LOCAL(Length, b5Width, (mmLength(176)));
    372     DEFINE_STATIC_LOCAL(Length, b5Height, (mmLength(250)));
    373     DEFINE_STATIC_LOCAL(Length, b4Width, (mmLength(250)));
    374     DEFINE_STATIC_LOCAL(Length, b4Height, (mmLength(353)));
    375     DEFINE_STATIC_LOCAL(Length, letterWidth, (inchLength(8.5)));
    376     DEFINE_STATIC_LOCAL(Length, letterHeight, (inchLength(11)));
    377     DEFINE_STATIC_LOCAL(Length, legalWidth, (inchLength(8.5)));
    378     DEFINE_STATIC_LOCAL(Length, legalHeight, (inchLength(14)));
    379     DEFINE_STATIC_LOCAL(Length, ledgerWidth, (inchLength(11)));
    380     DEFINE_STATIC_LOCAL(Length, ledgerHeight, (inchLength(17)));
    381 
    382     if (!pageSizeName)
    383         return false;
    384 
    385     switch (pageSizeName->getValueID()) {
    386     case CSSValueA5:
    387         width = a5Width;
    388         height = a5Height;
    389         break;
    390     case CSSValueA4:
    391         width = a4Width;
    392         height = a4Height;
    393         break;
    394     case CSSValueA3:
    395         width = a3Width;
    396         height = a3Height;
    397         break;
    398     case CSSValueB5:
    399         width = b5Width;
    400         height = b5Height;
    401         break;
    402     case CSSValueB4:
    403         width = b4Width;
    404         height = b4Height;
    405         break;
    406     case CSSValueLetter:
    407         width = letterWidth;
    408         height = letterHeight;
    409         break;
    410     case CSSValueLegal:
    411         width = legalWidth;
    412         height = legalHeight;
    413         break;
    414     case CSSValueLedger:
    415         width = ledgerWidth;
    416         height = ledgerHeight;
    417         break;
    418     default:
    419         return false;
    420     }
    421 
    422     if (pageOrientation) {
    423         switch (pageOrientation->getValueID()) {
    424         case CSSValueLandscape:
    425             std::swap(width, height);
    426             break;
    427         case CSSValuePortrait:
    428             // Nothing to do.
    429             break;
    430         default:
    431             return false;
    432         }
    433     }
    434     return true;
    435 }
    436 
    437 void StyleBuilderFunctions::applyInitialCSSPropertySize(StyleResolverState&) { }
    438 void StyleBuilderFunctions::applyInheritCSSPropertySize(StyleResolverState&) { }
    439 void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value)
    440 {
    441     state.style()->resetPageSizeType();
    442     Length width;
    443     Length height;
    444     PageSizeType pageSizeType = PAGE_SIZE_AUTO;
    445     CSSValueListInspector inspector(value);
    446     switch (inspector.length()) {
    447     case 2: {
    448         // <length>{2} | <page-size> <orientation>
    449         if (!inspector.first()->isPrimitiveValue() || !inspector.second()->isPrimitiveValue())
    450             return;
    451         CSSPrimitiveValue* first = toCSSPrimitiveValue(inspector.first());
    452         CSSPrimitiveValue* second = toCSSPrimitiveValue(inspector.second());
    453         if (first->isLength()) {
    454             // <length>{2}
    455             if (!second->isLength())
    456                 return;
    457             width = first->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
    458             height = second->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
    459         } else {
    460             // <page-size> <orientation>
    461             // The value order is guaranteed. See BisonCSSParser::parseSizeParameter.
    462             if (!getPageSizeFromName(first, second, width, height))
    463                 return;
    464         }
    465         pageSizeType = PAGE_SIZE_RESOLVED;
    466         break;
    467     }
    468     case 1: {
    469         // <length> | auto | <page-size> | [ portrait | landscape]
    470         if (!inspector.first()->isPrimitiveValue())
    471             return;
    472         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(inspector.first());
    473         if (primitiveValue->isLength()) {
    474             // <length>
    475             pageSizeType = PAGE_SIZE_RESOLVED;
    476             width = height = primitiveValue->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
    477         } else {
    478             switch (primitiveValue->getValueID()) {
    479             case 0:
    480                 return;
    481             case CSSValueAuto:
    482                 pageSizeType = PAGE_SIZE_AUTO;
    483                 break;
    484             case CSSValuePortrait:
    485                 pageSizeType = PAGE_SIZE_AUTO_PORTRAIT;
    486                 break;
    487             case CSSValueLandscape:
    488                 pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE;
    489                 break;
    490             default:
    491                 // <page-size>
    492                 pageSizeType = PAGE_SIZE_RESOLVED;
    493                 if (!getPageSizeFromName(primitiveValue, 0, width, height))
    494                     return;
    495             }
    496         }
    497         break;
    498     }
    499     default:
    500         return;
    501     }
    502     state.style()->setPageSizeType(pageSizeType);
    503     state.style()->setPageSize(LengthSize(width, height));
    504 }
    505 
    506 void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value)
    507 {
    508     if (!value->isPrimitiveValue())
    509         return;
    510 
    511     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    512     // FIXME : Per http://www.w3.org/TR/css3-text/#text-align0 can now take <string> but this is not implemented in the
    513     // rendering code.
    514     if (primitiveValue->isString())
    515         return;
    516 
    517     if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent)
    518         state.style()->setTextAlign(*primitiveValue);
    519     else if (state.parentStyle()->textAlign() == TASTART)
    520         state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT);
    521     else if (state.parentStyle()->textAlign() == TAEND)
    522         state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT);
    523     else
    524         state.style()->setTextAlign(state.parentStyle()->textAlign());
    525 }
    526 
    527 void StyleBuilderFunctions::applyInheritCSSPropertyTextIndent(StyleResolverState& state)
    528 {
    529     state.style()->setTextIndent(state.parentStyle()->textIndent());
    530     state.style()->setTextIndentLine(state.parentStyle()->textIndentLine());
    531     state.style()->setTextIndentType(state.parentStyle()->textIndentType());
    532 }
    533 
    534 void StyleBuilderFunctions::applyInitialCSSPropertyTextIndent(StyleResolverState& state)
    535 {
    536     state.style()->setTextIndent(RenderStyle::initialTextIndent());
    537     state.style()->setTextIndentLine(RenderStyle::initialTextIndentLine());
    538     state.style()->setTextIndentType(RenderStyle::initialTextIndentType());
    539 }
    540 
    541 void StyleBuilderFunctions::applyValueCSSPropertyTextIndent(StyleResolverState& state, CSSValue* value)
    542 {
    543     if (!value->isValueList())
    544         return;
    545 
    546     Length lengthOrPercentageValue;
    547     TextIndentLine textIndentLineValue = RenderStyle::initialTextIndentLine();
    548     TextIndentType textIndentTypeValue = RenderStyle::initialTextIndentType();
    549 
    550     for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
    551         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value());
    552         if (!primitiveValue->getValueID())
    553             lengthOrPercentageValue = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
    554         else if (primitiveValue->getValueID() == CSSValueEachLine)
    555             textIndentLineValue = TextIndentEachLine;
    556         else if (primitiveValue->getValueID() == CSSValueHanging)
    557             textIndentTypeValue = TextIndentHanging;
    558         else
    559             ASSERT_NOT_REACHED();
    560     }
    561 
    562     state.style()->setTextIndent(lengthOrPercentageValue);
    563     state.style()->setTextIndentLine(textIndentLineValue);
    564     state.style()->setTextIndentType(textIndentTypeValue);
    565 }
    566 
    567 void StyleBuilderFunctions::applyValueCSSPropertyTransform(StyleResolverState& state, CSSValue* value)
    568 {
    569     TransformOperations operations;
    570     TransformBuilder::createTransformOperations(value, state.cssToLengthConversionData(), operations);
    571     state.style()->setTransform(operations);
    572 }
    573 
    574 void StyleBuilderFunctions::applyInitialCSSPropertyTransformOrigin(StyleResolverState& state)
    575 {
    576     applyInitialCSSPropertyWebkitTransformOriginX(state);
    577     applyInitialCSSPropertyWebkitTransformOriginY(state);
    578     applyInitialCSSPropertyWebkitTransformOriginZ(state);
    579 }
    580 
    581 void StyleBuilderFunctions::applyInheritCSSPropertyTransformOrigin(StyleResolverState& state)
    582 {
    583     applyInheritCSSPropertyWebkitTransformOriginX(state);
    584     applyInheritCSSPropertyWebkitTransformOriginY(state);
    585     applyInheritCSSPropertyWebkitTransformOriginZ(state);
    586 }
    587 
    588 void StyleBuilderFunctions::applyValueCSSPropertyTransformOrigin(StyleResolverState& state, CSSValue* value)
    589 {
    590     CSSValueList* list = toCSSValueList(value);
    591     ASSERT(list->length() == 3);
    592     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
    593     if (primitiveValue->isValueID()) {
    594         switch (primitiveValue->getValueID()) {
    595         case CSSValueLeft:
    596             state.style()->setTransformOriginX(Length(0, Percent));
    597             break;
    598         case CSSValueRight:
    599             state.style()->setTransformOriginX(Length(100, Percent));
    600             break;
    601         case CSSValueCenter:
    602             state.style()->setTransformOriginX(Length(50, Percent));
    603             break;
    604         default:
    605             ASSERT_NOT_REACHED();
    606         }
    607     } else {
    608         state.style()->setTransformOriginX(StyleBuilderConverter::convertLength(state, primitiveValue));
    609     }
    610 
    611     primitiveValue = toCSSPrimitiveValue(list->item(1));
    612     if (primitiveValue->isValueID()) {
    613         switch (primitiveValue->getValueID()) {
    614         case CSSValueTop:
    615             state.style()->setTransformOriginY(Length(0, Percent));
    616             break;
    617         case CSSValueBottom:
    618             state.style()->setTransformOriginY(Length(100, Percent));
    619             break;
    620         case CSSValueCenter:
    621             state.style()->setTransformOriginY(Length(50, Percent));
    622             break;
    623         default:
    624             ASSERT_NOT_REACHED();
    625         }
    626     } else {
    627         state.style()->setTransformOriginY(StyleBuilderConverter::convertLength(state, primitiveValue));
    628     }
    629 
    630     primitiveValue = toCSSPrimitiveValue(list->item(2));
    631     state.style()->setTransformOriginZ(StyleBuilderConverter::convertComputedLength<float>(state, primitiveValue));
    632 }
    633 
    634 void StyleBuilderFunctions::applyInitialCSSPropertyPerspectiveOrigin(StyleResolverState& state)
    635 {
    636     applyInitialCSSPropertyWebkitPerspectiveOriginX(state);
    637     applyInitialCSSPropertyWebkitPerspectiveOriginY(state);
    638 }
    639 
    640 void StyleBuilderFunctions::applyInheritCSSPropertyPerspectiveOrigin(StyleResolverState& state)
    641 {
    642     applyInheritCSSPropertyWebkitPerspectiveOriginX(state);
    643     applyInheritCSSPropertyWebkitPerspectiveOriginY(state);
    644 }
    645 
    646 void StyleBuilderFunctions::applyValueCSSPropertyPerspectiveOrigin(StyleResolverState& state, CSSValue* value)
    647 {
    648     CSSValueList* list = toCSSValueList(value);
    649     ASSERT(list->length() == 2);
    650     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
    651     if (primitiveValue->isValueID()) {
    652         switch (primitiveValue->getValueID()) {
    653         case CSSValueLeft:
    654             state.style()->setPerspectiveOriginX(Length(0, Percent));
    655             break;
    656         case CSSValueRight:
    657             state.style()->setPerspectiveOriginX(Length(100, Percent));
    658             break;
    659         case CSSValueCenter:
    660             state.style()->setPerspectiveOriginX(Length(50, Percent));
    661             break;
    662         default:
    663             ASSERT_NOT_REACHED();
    664         }
    665     } else {
    666         state.style()->setPerspectiveOriginX(StyleBuilderConverter::convertLength(state, primitiveValue));
    667     }
    668 
    669     primitiveValue = toCSSPrimitiveValue(list->item(1));
    670     if (primitiveValue->isValueID()) {
    671         switch (primitiveValue->getValueID()) {
    672         case CSSValueTop:
    673             state.style()->setPerspectiveOriginY(Length(0, Percent));
    674             break;
    675         case CSSValueBottom:
    676             state.style()->setPerspectiveOriginY(Length(100, Percent));
    677             break;
    678         case CSSValueCenter:
    679             state.style()->setPerspectiveOriginY(Length(50, Percent));
    680             break;
    681         default:
    682             ASSERT_NOT_REACHED();
    683         }
    684     } else {
    685         state.style()->setPerspectiveOriginY(StyleBuilderConverter::convertLength(state, primitiveValue));
    686     }
    687 }
    688 
    689 void StyleBuilderFunctions::applyInheritCSSPropertyVerticalAlign(StyleResolverState& state)
    690 {
    691     EVerticalAlign verticalAlign = state.parentStyle()->verticalAlign();
    692     state.style()->setVerticalAlign(verticalAlign);
    693     if (verticalAlign == LENGTH)
    694         state.style()->setVerticalAlignLength(state.parentStyle()->verticalAlignLength());
    695 }
    696 
    697 void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value)
    698 {
    699     if (!value->isPrimitiveValue())
    700         return;
    701 
    702     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    703 
    704     if (primitiveValue->getValueID()) {
    705         state.style()->setVerticalAlign(*primitiveValue);
    706         return;
    707     }
    708 
    709     state.style()->setVerticalAlignLength(primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()));
    710 }
    711 
    712 static void resetEffectiveZoom(StyleResolverState& state)
    713 {
    714     // Reset the zoom in effect. This allows the setZoom method to accurately compute a new zoom in effect.
    715     state.setEffectiveZoom(state.parentStyle() ? state.parentStyle()->effectiveZoom() : RenderStyle::initialZoom());
    716 }
    717 
    718 void StyleBuilderFunctions::applyInitialCSSPropertyZoom(StyleResolverState& state)
    719 {
    720     resetEffectiveZoom(state);
    721     state.setZoom(RenderStyle::initialZoom());
    722 }
    723 
    724 void StyleBuilderFunctions::applyInheritCSSPropertyZoom(StyleResolverState& state)
    725 {
    726     resetEffectiveZoom(state);
    727     state.setZoom(state.parentStyle()->zoom());
    728 }
    729 
    730 void StyleBuilderFunctions::applyValueCSSPropertyZoom(StyleResolverState& state, CSSValue* value)
    731 {
    732     ASSERT_WITH_SECURITY_IMPLICATION(value->isPrimitiveValue());
    733     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    734 
    735     if (primitiveValue->getValueID() == CSSValueNormal) {
    736         resetEffectiveZoom(state);
    737         state.setZoom(RenderStyle::initialZoom());
    738     } else if (primitiveValue->getValueID() == CSSValueReset) {
    739         state.setEffectiveZoom(RenderStyle::initialZoom());
    740         state.setZoom(RenderStyle::initialZoom());
    741     } else if (primitiveValue->getValueID() == CSSValueDocument) {
    742         float docZoom = state.rootElementStyle() ? state.rootElementStyle()->zoom() : RenderStyle::initialZoom();
    743         state.setEffectiveZoom(docZoom);
    744         state.setZoom(docZoom);
    745     } else if (primitiveValue->isPercentage()) {
    746         resetEffectiveZoom(state);
    747         if (float percent = primitiveValue->getFloatValue())
    748             state.setZoom(percent / 100.0f);
    749     } else if (primitiveValue->isNumber()) {
    750         resetEffectiveZoom(state);
    751         if (float number = primitiveValue->getFloatValue())
    752             state.setZoom(number);
    753     }
    754 }
    755 
    756 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitAspectRatio(StyleResolverState& state)
    757 {
    758     state.style()->setHasAspectRatio(RenderStyle::initialHasAspectRatio());
    759     state.style()->setAspectRatioDenominator(RenderStyle::initialAspectRatioDenominator());
    760     state.style()->setAspectRatioNumerator(RenderStyle::initialAspectRatioNumerator());
    761 }
    762 
    763 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitAspectRatio(StyleResolverState& state)
    764 {
    765     if (!state.parentStyle()->hasAspectRatio())
    766         return;
    767     state.style()->setHasAspectRatio(true);
    768     state.style()->setAspectRatioDenominator(state.parentStyle()->aspectRatioDenominator());
    769     state.style()->setAspectRatioNumerator(state.parentStyle()->aspectRatioNumerator());
    770 }
    771 
    772 void StyleBuilderFunctions::applyValueCSSPropertyWebkitAspectRatio(StyleResolverState& state, CSSValue* value)
    773 {
    774     if (!value->isAspectRatioValue()) {
    775         state.style()->setHasAspectRatio(false);
    776         return;
    777     }
    778     CSSAspectRatioValue* aspectRatioValue = toCSSAspectRatioValue(value);
    779     state.style()->setHasAspectRatio(true);
    780     state.style()->setAspectRatioDenominator(aspectRatioValue->denominatorValue());
    781     state.style()->setAspectRatioNumerator(aspectRatioValue->numeratorValue());
    782 }
    783 
    784 void StyleBuilderFunctions::applyValueCSSPropertyWebkitBorderImage(StyleResolverState& state, CSSValue* value)
    785 {
    786     NinePieceImage image;
    787     state.styleMap().mapNinePieceImage(state.style(), CSSPropertyWebkitBorderImage, value, image);
    788     state.style()->setBorderImage(image);
    789 }
    790 
    791 void StyleBuilderFunctions::applyValueCSSPropertyWebkitClipPath(StyleResolverState& state, CSSValue* value)
    792 {
    793     if (value->isPrimitiveValue()) {
    794         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    795         if (primitiveValue->getValueID() == CSSValueNone) {
    796             state.style()->setClipPath(nullptr);
    797         } else if (primitiveValue->isShape()) {
    798             state.style()->setClipPath(ShapeClipPathOperation::create(basicShapeForValue(state, primitiveValue->getShapeValue())));
    799         } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_URI) {
    800             String cssURLValue = primitiveValue->getStringValue();
    801             KURL url = state.document().completeURL(cssURLValue);
    802             // FIXME: It doesn't work with forward or external SVG references (see https://bugs.webkit.org/show_bug.cgi?id=90405)
    803             state.style()->setClipPath(ReferenceClipPathOperation::create(cssURLValue, AtomicString(url.fragmentIdentifier())));
    804         }
    805     }
    806 }
    807 
    808 void StyleBuilderFunctions::applyValueCSSPropertyWebkitFilter(StyleResolverState& state, CSSValue* value)
    809 {
    810     FilterOperations operations;
    811     if (FilterOperationResolver::createFilterOperations(value, state.cssToLengthConversionData(), operations, state))
    812         state.style()->setFilter(operations);
    813 }
    814 
    815 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state)
    816 {
    817     state.style()->setTextEmphasisFill(RenderStyle::initialTextEmphasisFill());
    818     state.style()->setTextEmphasisMark(RenderStyle::initialTextEmphasisMark());
    819     state.style()->setTextEmphasisCustomMark(RenderStyle::initialTextEmphasisCustomMark());
    820 }
    821 
    822 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state)
    823 {
    824     state.style()->setTextEmphasisFill(state.parentStyle()->textEmphasisFill());
    825     state.style()->setTextEmphasisMark(state.parentStyle()->textEmphasisMark());
    826     state.style()->setTextEmphasisCustomMark(state.parentStyle()->textEmphasisCustomMark());
    827 }
    828 
    829 void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state, CSSValue* value)
    830 {
    831     if (value->isValueList()) {
    832         CSSValueList* list = toCSSValueList(value);
    833         ASSERT(list->length() == 2);
    834         if (list->length() != 2)
    835             return;
    836         for (unsigned i = 0; i < 2; ++i) {
    837             CSSValue* item = list->item(i);
    838             if (!item->isPrimitiveValue())
    839                 continue;
    840 
    841             CSSPrimitiveValue* value = toCSSPrimitiveValue(item);
    842             if (value->getValueID() == CSSValueFilled || value->getValueID() == CSSValueOpen)
    843                 state.style()->setTextEmphasisFill(*value);
    844             else
    845                 state.style()->setTextEmphasisMark(*value);
    846         }
    847         state.style()->setTextEmphasisCustomMark(nullAtom);
    848         return;
    849     }
    850 
    851     if (!value->isPrimitiveValue())
    852         return;
    853     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
    854 
    855     if (primitiveValue->isString()) {
    856         state.style()->setTextEmphasisFill(TextEmphasisFillFilled);
    857         state.style()->setTextEmphasisMark(TextEmphasisMarkCustom);
    858         state.style()->setTextEmphasisCustomMark(AtomicString(primitiveValue->getStringValue()));
    859         return;
    860     }
    861 
    862     state.style()->setTextEmphasisCustomMark(nullAtom);
    863 
    864     if (primitiveValue->getValueID() == CSSValueFilled || primitiveValue->getValueID() == CSSValueOpen) {
    865         state.style()->setTextEmphasisFill(*primitiveValue);
    866         state.style()->setTextEmphasisMark(TextEmphasisMarkAuto);
    867     } else {
    868         state.style()->setTextEmphasisFill(TextEmphasisFillFilled);
    869         state.style()->setTextEmphasisMark(*primitiveValue);
    870     }
    871 }
    872 
    873 void StyleBuilderFunctions::applyInitialCSSPropertyWillChange(StyleResolverState& state)
    874 {
    875     state.style()->setWillChangeContents(false);
    876     state.style()->setWillChangeScrollPosition(false);
    877     state.style()->setWillChangeProperties(Vector<CSSPropertyID>());
    878     state.style()->setSubtreeWillChangeContents(state.parentStyle()->subtreeWillChangeContents());
    879 }
    880 
    881 void StyleBuilderFunctions::applyInheritCSSPropertyWillChange(StyleResolverState& state)
    882 {
    883     state.style()->setWillChangeContents(state.parentStyle()->willChangeContents());
    884     state.style()->setWillChangeScrollPosition(state.parentStyle()->willChangeScrollPosition());
    885     state.style()->setWillChangeProperties(state.parentStyle()->willChangeProperties());
    886     state.style()->setSubtreeWillChangeContents(state.parentStyle()->subtreeWillChangeContents());
    887 }
    888 
    889 void StyleBuilderFunctions::applyValueCSSPropertyWillChange(StyleResolverState& state, CSSValue* value)
    890 {
    891     ASSERT(value->isValueList());
    892     bool willChangeContents = false;
    893     bool willChangeScrollPosition = false;
    894     Vector<CSSPropertyID> willChangeProperties;
    895 
    896     for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
    897         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value());
    898         if (CSSPropertyID propertyID = primitiveValue->getPropertyID())
    899             willChangeProperties.append(propertyID);
    900         else if (primitiveValue->getValueID() == CSSValueContents)
    901             willChangeContents = true;
    902         else if (primitiveValue->getValueID() == CSSValueScrollPosition)
    903             willChangeScrollPosition = true;
    904         else
    905             ASSERT_NOT_REACHED();
    906     }
    907     state.style()->setWillChangeContents(willChangeContents);
    908     state.style()->setWillChangeScrollPosition(willChangeScrollPosition);
    909     state.style()->setWillChangeProperties(willChangeProperties);
    910     state.style()->setSubtreeWillChangeContents(willChangeContents || state.parentStyle()->subtreeWillChangeContents());
    911 }
    912 
    913 void StyleBuilderFunctions::applyInitialCSSPropertyContent(StyleResolverState& state)
    914 {
    915     state.style()->clearContent();
    916 }
    917 
    918 void StyleBuilderFunctions::applyInheritCSSPropertyContent(StyleResolverState&)
    919 {
    920     // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This
    921     // note is a reminder that eventually "inherit" needs to be supported.
    922 }
    923 
    924 void StyleBuilderFunctions::applyValueCSSPropertyContent(StyleResolverState& state, CSSValue* value)
    925 {
    926     // list of string, uri, counter, attr, i
    927 
    928     if (!value->isValueList())
    929         return;
    930 
    931     bool didSet = false;
    932     for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
    933         CSSValue* item = i.value();
    934         if (item->isImageGeneratorValue()) {
    935             if (item->isGradientValue())
    936                 state.style()->setContent(StyleGeneratedImage::create(toCSSGradientValue(item)->gradientWithStylesResolved(state.document().textLinkColors(), state.style()->color()).get()), didSet);
    937             else
    938                 state.style()->setContent(StyleGeneratedImage::create(toCSSImageGeneratorValue(item)), didSet);
    939             didSet = true;
    940         } else if (item->isImageSetValue()) {
    941             state.style()->setContent(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item)), didSet);
    942             didSet = true;
    943         }
    944 
    945         if (item->isImageValue()) {
    946             state.style()->setContent(state.elementStyleResources().cachedOrPendingFromValue(state.document(), CSSPropertyContent, toCSSImageValue(item)), didSet);
    947             didSet = true;
    948             continue;
    949         }
    950 
    951         if (!item->isPrimitiveValue())
    952             continue;
    953 
    954         CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item);
    955 
    956         if (contentValue->isString()) {
    957             state.style()->setContent(contentValue->getStringValue().impl(), didSet);
    958             didSet = true;
    959         } else if (contentValue->isAttr()) {
    960             // FIXME: Can a namespace be specified for an attr(foo)?
    961             if (state.style()->styleType() == NOPSEUDO)
    962                 state.style()->setUnique();
    963             else
    964                 state.parentStyle()->setUnique();
    965             QualifiedName attr(nullAtom, AtomicString(contentValue->getStringValue()), nullAtom);
    966             const AtomicString& value = state.element()->getAttribute(attr);
    967             state.style()->setContent(value.isNull() ? emptyString() : value.string(), didSet);
    968             didSet = true;
    969             // register the fact that the attribute value affects the style
    970             state.contentAttrValues().append(attr.localName());
    971         } else if (contentValue->isCounter()) {
    972             Counter* counterValue = contentValue->getCounterValue();
    973             EListStyleType listStyleType = NoneListStyle;
    974             CSSValueID listStyleIdent = counterValue->listStyleIdent();
    975             if (listStyleIdent != CSSValueNone)
    976                 listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
    977             OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(AtomicString(counterValue->identifier()), listStyleType, AtomicString(counterValue->separator())));
    978             state.style()->setContent(counter.release(), didSet);
    979             didSet = true;
    980         } else {
    981             switch (contentValue->getValueID()) {
    982             case CSSValueOpenQuote:
    983                 state.style()->setContent(OPEN_QUOTE, didSet);
    984                 didSet = true;
    985                 break;
    986             case CSSValueCloseQuote:
    987                 state.style()->setContent(CLOSE_QUOTE, didSet);
    988                 didSet = true;
    989                 break;
    990             case CSSValueNoOpenQuote:
    991                 state.style()->setContent(NO_OPEN_QUOTE, didSet);
    992                 didSet = true;
    993                 break;
    994             case CSSValueNoCloseQuote:
    995                 state.style()->setContent(NO_CLOSE_QUOTE, didSet);
    996                 didSet = true;
    997                 break;
    998             default:
    999                 // normal and none do not have any effect.
   1000                 { }
   1001             }
   1002         }
   1003     }
   1004     if (!didSet)
   1005         state.style()->clearContent();
   1006 }
   1007 
   1008 void StyleBuilderFunctions::applyInitialCSSPropertyFont(StyleResolverState&)
   1009 {
   1010     ASSERT_NOT_REACHED();
   1011 }
   1012 
   1013 void StyleBuilderFunctions::applyInheritCSSPropertyFont(StyleResolverState&)
   1014 {
   1015     ASSERT_NOT_REACHED();
   1016 }
   1017 
   1018 void StyleBuilderFunctions::applyValueCSSPropertyFont(StyleResolverState& state, CSSValue* value)
   1019 {
   1020     // Only System Font identifiers should come through this method
   1021     // all other values should have been handled when the shorthand
   1022     // was expanded by the parser.
   1023     // FIXME: System Font identifiers should not hijack this
   1024     // short-hand CSSProperty like this (crbug.com/353932)
   1025     state.style()->setLineHeight(RenderStyle::initialLineHeight());
   1026     state.setLineHeightValue(0);
   1027     state.fontBuilder().fromSystemFont(toCSSPrimitiveValue(value)->getValueID(), state.style()->effectiveZoom());
   1028 }
   1029 
   1030 void StyleBuilderFunctions::applyValueCSSPropertyWebkitLocale(StyleResolverState& state, CSSValue* value)
   1031 {
   1032     if (!value->isPrimitiveValue())
   1033         return;
   1034     const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
   1035     if (primitiveValue->getValueID() == CSSValueAuto)
   1036         state.style()->setLocale(nullAtom);
   1037     else
   1038         state.style()->setLocale(AtomicString(primitiveValue->getStringValue()));
   1039     state.fontBuilder().setScript(state.style()->locale());
   1040 }
   1041 
   1042 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitAppRegion(StyleResolverState&)
   1043 {
   1044 }
   1045 
   1046 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitAppRegion(StyleResolverState&)
   1047 {
   1048 }
   1049 
   1050 void StyleBuilderFunctions::applyValueCSSPropertyWebkitAppRegion(StyleResolverState& state, CSSValue* value)
   1051 {
   1052     if (!value->isPrimitiveValue())
   1053         return;
   1054     const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
   1055     if (!primitiveValue->getValueID())
   1056         return;
   1057     state.style()->setDraggableRegionMode(primitiveValue->getValueID() == CSSValueDrag ? DraggableRegionDrag : DraggableRegionNoDrag);
   1058     state.document().setHasAnnotatedRegions(true);
   1059 }
   1060 
   1061 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitPerspective(StyleResolverState& state)
   1062 {
   1063     applyInitialCSSPropertyPerspective(state);
   1064 }
   1065 
   1066 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitPerspective(StyleResolverState& state)
   1067 {
   1068     applyInheritCSSPropertyPerspective(state);
   1069 }
   1070 
   1071 void StyleBuilderFunctions::applyValueCSSPropertyWebkitPerspective(StyleResolverState& state, CSSValue* value)
   1072 {
   1073     if (!value->isPrimitiveValue())
   1074         return;
   1075     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
   1076     if (primitiveValue->isNumber()) {
   1077         float perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(state.cssToLengthConversionData());
   1078         if (perspectiveValue >= 0.0f)
   1079             state.style()->setPerspective(perspectiveValue);
   1080     } else {
   1081         applyValueCSSPropertyPerspective(state, value);
   1082     }
   1083 }
   1084 
   1085 void StyleBuilderFunctions::applyValueCSSPropertyPerspective(StyleResolverState& state, CSSValue* value)
   1086 {
   1087     if (!value->isPrimitiveValue())
   1088         return;
   1089     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
   1090     if (primitiveValue->getValueID() == CSSValueNone) {
   1091         state.style()->setPerspective(0);
   1092         return;
   1093     }
   1094 
   1095     if (!primitiveValue->isLength())
   1096         return;
   1097     float perspectiveValue = primitiveValue->computeLength<float>(state.cssToLengthConversionData());
   1098     if (perspectiveValue >= 0.0f)
   1099         state.style()->setPerspective(perspectiveValue);
   1100 }
   1101 
   1102 void StyleBuilderFunctions::applyValueCSSPropertyWebkitWritingMode(StyleResolverState& state, CSSValue* value)
   1103 {
   1104     if (value->isPrimitiveValue())
   1105         state.setWritingMode(*toCSSPrimitiveValue(value));
   1106 
   1107     // FIXME: It is not ok to modify document state while applying style.
   1108     if (state.element() && state.element() == state.document().documentElement())
   1109         state.document().setWritingModeSetOnDocumentElement(true);
   1110 }
   1111 
   1112 void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextOrientation(StyleResolverState& state, CSSValue* value)
   1113 {
   1114     if (value->isPrimitiveValue())
   1115         state.setTextOrientation(*toCSSPrimitiveValue(value));
   1116 }
   1117 
   1118 void StyleBuilderFunctions::applyInheritCSSPropertyBaselineShift(StyleResolverState& state)
   1119 {
   1120     const SVGRenderStyle& parentSvgStyle = state.parentStyle()->svgStyle();
   1121     EBaselineShift baselineShift = parentSvgStyle.baselineShift();
   1122     SVGRenderStyle& svgStyle = state.style()->accessSVGStyle();
   1123     svgStyle.setBaselineShift(baselineShift);
   1124     if (baselineShift == BS_LENGTH)
   1125         svgStyle.setBaselineShiftValue(parentSvgStyle.baselineShiftValue());
   1126 }
   1127 
   1128 void StyleBuilderFunctions::applyValueCSSPropertyBaselineShift(StyleResolverState& state, CSSValue* value)
   1129 {
   1130     SVGRenderStyle& svgStyle = state.style()->accessSVGStyle();
   1131     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
   1132     if (!primitiveValue->isValueID()) {
   1133         svgStyle.setBaselineShift(BS_LENGTH);
   1134         svgStyle.setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
   1135         return;
   1136     }
   1137     switch (primitiveValue->getValueID()) {
   1138     case CSSValueBaseline:
   1139         svgStyle.setBaselineShift(BS_BASELINE);
   1140         return;
   1141     case CSSValueSub:
   1142         svgStyle.setBaselineShift(BS_SUB);
   1143         return;
   1144     case CSSValueSuper:
   1145         svgStyle.setBaselineShift(BS_SUPER);
   1146         return;
   1147     default:
   1148         ASSERT_NOT_REACHED();
   1149     }
   1150 }
   1151 
   1152 void StyleBuilderFunctions::applyValueCSSPropertyGridAutoFlow(StyleResolverState& state, CSSValue* value)
   1153 {
   1154     ASSERT(value->isValueList());
   1155     CSSValueList* list = toCSSValueList(value);
   1156 
   1157     CSSPrimitiveValue* first = list->length() >= 1 ? toCSSPrimitiveValue(list->item(0)) : nullptr;
   1158 
   1159     if (!first) {
   1160         applyInitialCSSPropertyGridAutoFlow(state);
   1161         return;
   1162     }
   1163 
   1164     CSSPrimitiveValue* second = list->length() == 2 ? toCSSPrimitiveValue(list->item(1)) : nullptr;
   1165 
   1166     GridAutoFlow autoFlow = RenderStyle::initialGridAutoFlow();
   1167     switch (first->getValueID()) {
   1168     case CSSValueRow:
   1169         if (second) {
   1170             if (second->getValueID() == CSSValueDense)
   1171                 autoFlow = AutoFlowRowDense;
   1172             else
   1173                 autoFlow = AutoFlowStackRow;
   1174         } else {
   1175             autoFlow = AutoFlowRow;
   1176         }
   1177         break;
   1178     case CSSValueColumn:
   1179         if (second) {
   1180             if (second->getValueID() == CSSValueDense)
   1181                 autoFlow = AutoFlowColumnDense;
   1182             else
   1183                 autoFlow = AutoFlowStackColumn;
   1184         } else {
   1185             autoFlow = AutoFlowColumn;
   1186         }
   1187         break;
   1188     case CSSValueDense:
   1189         if (second && second->getValueID() == CSSValueColumn)
   1190             autoFlow = AutoFlowColumnDense;
   1191         else
   1192             autoFlow = AutoFlowRowDense;
   1193         break;
   1194     case CSSValueStack:
   1195         if (second && second->getValueID() == CSSValueColumn)
   1196             autoFlow = AutoFlowStackColumn;
   1197         else
   1198             autoFlow = AutoFlowStackRow;
   1199         break;
   1200     default:
   1201         ASSERT_NOT_REACHED();
   1202         break;
   1203     }
   1204 
   1205     state.style()->setGridAutoFlow(autoFlow);
   1206 }
   1207 
   1208 } // namespace blink
   1209