• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
4  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
5  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
6  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
7  * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
8  * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
9  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
10  * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
11  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are
14  * met:
15  *
16  *     * Redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer.
18  *     * Redistributions in binary form must reproduce the above
19  * copyright notice, this list of conditions and the following disclaimer
20  * in the documentation and/or other materials provided with the
21  * distribution.
22  *     * Neither the name of Google Inc. nor the names of its
23  * contributors may be used to endorse or promote products derived from
24  * this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #include "config.h"
40 
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/parser/BisonCSSParser.h"
55 #include "core/css/CSSPrimitiveValueMappings.h"
56 #include "core/css/CSSProperty.h"
57 #include "core/css/Counter.h"
58 #include "core/css/Pair.h"
59 #include "core/css/Rect.h"
60 #include "core/css/StylePropertySet.h"
61 #include "core/css/StyleRule.h"
62 #include "core/css/resolver/ElementStyleResources.h"
63 #include "core/css/resolver/FilterOperationResolver.h"
64 #include "core/css/resolver/FontBuilder.h"
65 #include "core/css/resolver/StyleBuilder.h"
66 #include "core/css/resolver/TransformBuilder.h"
67 #include "core/frame/LocalFrame.h"
68 #include "core/frame/Settings.h"
69 #include "core/rendering/style/CounterContent.h"
70 #include "core/rendering/style/QuotesData.h"
71 #include "core/rendering/style/RenderStyle.h"
72 #include "core/rendering/style/RenderStyleConstants.h"
73 #include "core/rendering/style/SVGRenderStyle.h"
74 #include "core/rendering/style/StyleGeneratedImage.h"
75 #include "platform/fonts/FontDescription.h"
76 #include "wtf/MathExtras.h"
77 #include "wtf/StdLibExtras.h"
78 #include "wtf/Vector.h"
79 
80 namespace WebCore {
81 
82 namespace {
83 
isValidVisitedLinkProperty(CSSPropertyID id)84 static inline bool isValidVisitedLinkProperty(CSSPropertyID id)
85 {
86     switch (id) {
87     case CSSPropertyBackgroundColor:
88     case CSSPropertyBorderLeftColor:
89     case CSSPropertyBorderRightColor:
90     case CSSPropertyBorderTopColor:
91     case CSSPropertyBorderBottomColor:
92     case CSSPropertyColor:
93     case CSSPropertyFill:
94     case CSSPropertyOutlineColor:
95     case CSSPropertyStroke:
96     case CSSPropertyTextDecorationColor:
97     case CSSPropertyWebkitColumnRuleColor:
98     case CSSPropertyWebkitTextEmphasisColor:
99     case CSSPropertyWebkitTextFillColor:
100     case CSSPropertyWebkitTextStrokeColor:
101         return true;
102     default:
103         return false;
104     }
105 }
106 
107 } // namespace
108 
applyProperty(CSSPropertyID id,StyleResolverState & state,CSSValue * value)109 void StyleBuilder::applyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value)
110 {
111     ASSERT_WITH_MESSAGE(!isExpandedShorthand(id), "Shorthand property id = %d wasn't expanded at parsing time", id);
112 
113     bool isInherit = state.parentNode() && value->isInheritedValue();
114     bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue());
115 
116     ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
117     ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle())
118 
119     if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
120         // Limit the properties that can be applied to only the ones honored by :visited.
121         return;
122     }
123 
124     CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0;
125     if (primitiveValue && primitiveValue->getValueID() == CSSValueCurrentcolor)
126         state.style()->setHasCurrentColor();
127 
128     if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(id))
129         state.parentStyle()->setHasExplicitlyInheritedProperties();
130 
131     StyleBuilder::applyProperty(id, state, value, isInitial, isInherit);
132 }
133 
clipConvertToLength(StyleResolverState & state,CSSPrimitiveValue * value)134 static Length clipConvertToLength(StyleResolverState& state, CSSPrimitiveValue* value)
135 {
136     return value->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
137 }
138 
applyInitialCSSPropertyClip(StyleResolverState & state)139 void StyleBuilderFunctions::applyInitialCSSPropertyClip(StyleResolverState& state)
140 {
141     state.style()->setClip(Length(), Length(), Length(), Length());
142     state.style()->setHasClip(false);
143 }
144 
applyInheritCSSPropertyClip(StyleResolverState & state)145 void StyleBuilderFunctions::applyInheritCSSPropertyClip(StyleResolverState& state)
146 {
147     RenderStyle* parentStyle = state.parentStyle();
148     if (!parentStyle->hasClip())
149         return applyInitialCSSPropertyClip(state);
150     state.style()->setClip(parentStyle->clipTop(), parentStyle->clipRight(), parentStyle->clipBottom(), parentStyle->clipLeft());
151     state.style()->setHasClip(true);
152 }
153 
applyValueCSSPropertyClip(StyleResolverState & state,CSSValue * value)154 void StyleBuilderFunctions::applyValueCSSPropertyClip(StyleResolverState& state, CSSValue* value)
155 {
156     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
157 
158     if (primitiveValue->getValueID() == CSSValueAuto) {
159         state.style()->setClip(Length(), Length(), Length(), Length());
160         state.style()->setHasClip(false);
161         return;
162     }
163 
164     Rect* rect = primitiveValue->getRectValue();
165     Length top = clipConvertToLength(state, rect->top());
166     Length right = clipConvertToLength(state, rect->right());
167     Length bottom = clipConvertToLength(state, rect->bottom());
168     Length left = clipConvertToLength(state, rect->left());
169     state.style()->setClip(top, right, bottom, left);
170     state.style()->setHasClip(true);
171 }
172 
applyInitialCSSPropertyColor(StyleResolverState & state)173 void StyleBuilderFunctions::applyInitialCSSPropertyColor(StyleResolverState& state)
174 {
175     Color color = RenderStyle::initialColor();
176     if (state.applyPropertyToRegularStyle())
177         state.style()->setColor(color);
178     if (state.applyPropertyToVisitedLinkStyle())
179         state.style()->setVisitedLinkColor(color);
180 }
181 
applyInheritCSSPropertyColor(StyleResolverState & state)182 void StyleBuilderFunctions::applyInheritCSSPropertyColor(StyleResolverState& state)
183 {
184     Color color = state.parentStyle()->color();
185     if (state.applyPropertyToRegularStyle())
186         state.style()->setColor(color);
187     if (state.applyPropertyToVisitedLinkStyle())
188         state.style()->setVisitedLinkColor(color);
189 }
190 
applyValueCSSPropertyColor(StyleResolverState & state,CSSValue * value)191 void StyleBuilderFunctions::applyValueCSSPropertyColor(StyleResolverState& state, CSSValue* value)
192 {
193     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
194     // As per the spec, 'color: currentColor' is treated as 'color: inherit'
195     if (primitiveValue->getValueID() == CSSValueCurrentcolor) {
196         applyInheritCSSPropertyColor(state);
197         return;
198     }
199 
200     if (state.applyPropertyToRegularStyle())
201         state.style()->setColor(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color()));
202     if (state.applyPropertyToVisitedLinkStyle())
203         state.style()->setVisitedLinkColor(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color(), true));
204 }
205 
applyInitialCSSPropertyCursor(StyleResolverState & state)206 void StyleBuilderFunctions::applyInitialCSSPropertyCursor(StyleResolverState& state)
207 {
208     state.style()->clearCursorList();
209     state.style()->setCursor(RenderStyle::initialCursor());
210 }
211 
applyInheritCSSPropertyCursor(StyleResolverState & state)212 void StyleBuilderFunctions::applyInheritCSSPropertyCursor(StyleResolverState& state)
213 {
214     state.style()->setCursor(state.parentStyle()->cursor());
215     state.style()->setCursorList(state.parentStyle()->cursors());
216 }
217 
applyValueCSSPropertyCursor(StyleResolverState & state,CSSValue * value)218 void StyleBuilderFunctions::applyValueCSSPropertyCursor(StyleResolverState& state, CSSValue* value)
219 {
220     state.style()->clearCursorList();
221     if (value->isValueList()) {
222         CSSValueList* list = toCSSValueList(value);
223         int len = list->length();
224         state.style()->setCursor(CURSOR_AUTO);
225         for (int i = 0; i < len; i++) {
226             CSSValue* item = list->itemWithoutBoundsCheck(i);
227             if (item->isCursorImageValue()) {
228                 CSSCursorImageValue* image = toCSSCursorImageValue(item);
229                 if (image->updateIfSVGCursorIsUsed(state.element())) // Elements with SVG cursors are not allowed to share style.
230                     state.style()->setUnique();
231                 state.style()->addCursor(state.styleImage(CSSPropertyCursor, image), image->hotSpot());
232             } else {
233                 state.style()->setCursor(*toCSSPrimitiveValue(item));
234             }
235         }
236     } else {
237         state.style()->setCursor(*toCSSPrimitiveValue(value));
238     }
239 }
240 
applyValueCSSPropertyDirection(StyleResolverState & state,CSSValue * value)241 void StyleBuilderFunctions::applyValueCSSPropertyDirection(StyleResolverState& state, CSSValue* value)
242 {
243     state.style()->setDirection(*toCSSPrimitiveValue(value));
244     Element* element = state.element();
245     if (element && element == element->document().documentElement())
246         element->document().setDirectionSetOnDocumentElement(true);
247 }
248 
isValidDisplayValue(StyleResolverState & state,EDisplay displayPropertyValue)249 static inline bool isValidDisplayValue(StyleResolverState& state, EDisplay displayPropertyValue)
250 {
251     if (state.element() && state.element()->isSVGElement() && state.style()->styleType() == NOPSEUDO)
252         return (displayPropertyValue == INLINE || displayPropertyValue == BLOCK || displayPropertyValue == NONE);
253     return true;
254 }
255 
applyInheritCSSPropertyDisplay(StyleResolverState & state)256 void StyleBuilderFunctions::applyInheritCSSPropertyDisplay(StyleResolverState& state)
257 {
258     EDisplay display = state.parentStyle()->display();
259     if (!isValidDisplayValue(state, display))
260         return;
261     state.style()->setDisplay(display);
262 }
263 
applyValueCSSPropertyDisplay(StyleResolverState & state,CSSValue * value)264 void StyleBuilderFunctions::applyValueCSSPropertyDisplay(StyleResolverState& state, CSSValue* value)
265 {
266     EDisplay display = *toCSSPrimitiveValue(value);
267     if (!isValidDisplayValue(state, display))
268         return;
269     state.style()->setDisplay(display);
270 }
271 
applyInitialCSSPropertyFontFamily(StyleResolverState & state)272 void StyleBuilderFunctions::applyInitialCSSPropertyFontFamily(StyleResolverState& state)
273 {
274     state.fontBuilder().setFontFamilyInitial();
275 }
276 
applyInheritCSSPropertyFontFamily(StyleResolverState & state)277 void StyleBuilderFunctions::applyInheritCSSPropertyFontFamily(StyleResolverState& state)
278 {
279     state.fontBuilder().setFontFamilyInherit(state.parentFontDescription());
280 }
281 
applyValueCSSPropertyFontFamily(StyleResolverState & state,CSSValue * value)282 void StyleBuilderFunctions::applyValueCSSPropertyFontFamily(StyleResolverState& state, CSSValue* value)
283 {
284     state.fontBuilder().setFontFamilyValue(value);
285 }
286 
applyInitialCSSPropertyFontSize(StyleResolverState & state)287 void StyleBuilderFunctions::applyInitialCSSPropertyFontSize(StyleResolverState& state)
288 {
289     state.fontBuilder().setFontSizeInitial();
290 }
291 
applyInheritCSSPropertyFontSize(StyleResolverState & state)292 void StyleBuilderFunctions::applyInheritCSSPropertyFontSize(StyleResolverState& state)
293 {
294     state.fontBuilder().setFontSizeInherit(state.parentFontDescription());
295 }
296 
applyValueCSSPropertyFontSize(StyleResolverState & state,CSSValue * value)297 void StyleBuilderFunctions::applyValueCSSPropertyFontSize(StyleResolverState& state, CSSValue* value)
298 {
299     state.fontBuilder().setFontSizeValue(value, state.parentStyle(), state.rootElementStyle());
300 }
301 
applyInitialCSSPropertyFontWeight(StyleResolverState & state)302 void StyleBuilderFunctions::applyInitialCSSPropertyFontWeight(StyleResolverState& state)
303 {
304     state.fontBuilder().setWeight(FontWeightNormal);
305 }
306 
applyInheritCSSPropertyFontWeight(StyleResolverState & state)307 void StyleBuilderFunctions::applyInheritCSSPropertyFontWeight(StyleResolverState& state)
308 {
309     state.fontBuilder().setWeight(state.parentFontDescription().weight());
310 }
311 
applyValueCSSPropertyFontWeight(StyleResolverState & state,CSSValue * value)312 void StyleBuilderFunctions::applyValueCSSPropertyFontWeight(StyleResolverState& state, CSSValue* value)
313 {
314     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
315     switch (primitiveValue->getValueID()) {
316     case CSSValueInvalid:
317         ASSERT_NOT_REACHED();
318         break;
319     case CSSValueBolder:
320         state.fontBuilder().setWeight(state.parentStyle()->fontDescription().weight());
321         state.fontBuilder().setWeightBolder();
322         break;
323     case CSSValueLighter:
324         state.fontBuilder().setWeight(state.parentStyle()->fontDescription().weight());
325         state.fontBuilder().setWeightLighter();
326         break;
327     default:
328         state.fontBuilder().setWeight(*primitiveValue);
329     }
330 }
331 
applyValueCSSPropertyGlyphOrientationVertical(StyleResolverState & state,CSSValue * value)332 void StyleBuilderFunctions::applyValueCSSPropertyGlyphOrientationVertical(StyleResolverState& state, CSSValue* value)
333 {
334     if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueAuto)
335         state.style()->accessSVGStyle()->setGlyphOrientationVertical(GO_AUTO);
336     else
337         state.style()->accessSVGStyle()->setGlyphOrientationVertical(StyleBuilderConverter::convertGlyphOrientation(state, value));
338 }
339 
applyInitialCSSPropertyGridTemplateAreas(StyleResolverState & state)340 void StyleBuilderFunctions::applyInitialCSSPropertyGridTemplateAreas(StyleResolverState& state)
341 {
342     state.style()->setNamedGridArea(RenderStyle::initialNamedGridArea());
343     state.style()->setNamedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount());
344     state.style()->setNamedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount());
345 }
346 
applyInheritCSSPropertyGridTemplateAreas(StyleResolverState & state)347 void StyleBuilderFunctions::applyInheritCSSPropertyGridTemplateAreas(StyleResolverState& state)
348 {
349     state.style()->setNamedGridArea(state.parentStyle()->namedGridArea());
350     state.style()->setNamedGridAreaRowCount(state.parentStyle()->namedGridAreaRowCount());
351     state.style()->setNamedGridAreaColumnCount(state.parentStyle()->namedGridAreaColumnCount());
352 }
353 
applyValueCSSPropertyGridTemplateAreas(StyleResolverState & state,CSSValue * value)354 void StyleBuilderFunctions::applyValueCSSPropertyGridTemplateAreas(StyleResolverState& state, CSSValue* value)
355 {
356     if (value->isPrimitiveValue()) {
357         // FIXME: Shouldn't we clear the grid-area values
358         ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
359         return;
360     }
361 
362     CSSGridTemplateAreasValue* gridTemplateAreasValue = toCSSGridTemplateAreasValue(value);
363     const NamedGridAreaMap& newNamedGridAreas = gridTemplateAreasValue->gridAreaMap();
364 
365     NamedGridLinesMap namedGridColumnLines = state.style()->namedGridColumnLines();
366     NamedGridLinesMap namedGridRowLines = state.style()->namedGridRowLines();
367     StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridColumnLines, ForColumns);
368     StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridRowLines, ForRows);
369     state.style()->setNamedGridColumnLines(namedGridColumnLines);
370     state.style()->setNamedGridRowLines(namedGridRowLines);
371 
372     state.style()->setNamedGridArea(newNamedGridAreas);
373     state.style()->setNamedGridAreaRowCount(gridTemplateAreasValue->rowCount());
374     state.style()->setNamedGridAreaColumnCount(gridTemplateAreasValue->columnCount());
375 }
376 
applyValueCSSPropertyLineHeight(StyleResolverState & state,CSSValue * value)377 void StyleBuilderFunctions::applyValueCSSPropertyLineHeight(StyleResolverState& state, CSSValue* value)
378 {
379     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
380     Length lineHeight;
381 
382     if (primitiveValue->getValueID() == CSSValueNormal) {
383         lineHeight = RenderStyle::initialLineHeight();
384     } else if (primitiveValue->isLength()) {
385         float multiplier = state.style()->effectiveZoom();
386         if (LocalFrame* frame = state.document().frame())
387             multiplier *= frame->textZoomFactor();
388         lineHeight = primitiveValue->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier));
389     } else if (primitiveValue->isPercentage()) {
390         lineHeight = Length((state.style()->computedFontSize() * primitiveValue->getIntValue()) / 100.0, Fixed);
391     } else if (primitiveValue->isNumber()) {
392         lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
393     } else if (primitiveValue->isCalculated()) {
394         double multiplier = state.style()->effectiveZoom();
395         if (LocalFrame* frame = state.document().frame())
396             multiplier *= frame->textZoomFactor();
397         Length zoomedLength = Length(primitiveValue->cssCalcValue()->toCalcValue(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier)));
398         lineHeight = Length(valueForLength(zoomedLength, state.style()->fontSize()), Fixed);
399     } else {
400         return;
401     }
402     state.style()->setLineHeight(lineHeight);
403 }
404 
applyValueCSSPropertyListStyleImage(StyleResolverState & state,CSSValue * value)405 void StyleBuilderFunctions::applyValueCSSPropertyListStyleImage(StyleResolverState& state, CSSValue* value)
406 {
407     state.style()->setListStyleImage(state.styleImage(CSSPropertyListStyleImage, value));
408 }
409 
applyInitialCSSPropertyOutlineStyle(StyleResolverState & state)410 void StyleBuilderFunctions::applyInitialCSSPropertyOutlineStyle(StyleResolverState& state)
411 {
412     state.style()->setOutlineStyleIsAuto(RenderStyle::initialOutlineStyleIsAuto());
413     state.style()->setOutlineStyle(RenderStyle::initialBorderStyle());
414 }
415 
applyInheritCSSPropertyOutlineStyle(StyleResolverState & state)416 void StyleBuilderFunctions::applyInheritCSSPropertyOutlineStyle(StyleResolverState& state)
417 {
418     state.style()->setOutlineStyleIsAuto(state.parentStyle()->outlineStyleIsAuto());
419     state.style()->setOutlineStyle(state.parentStyle()->outlineStyle());
420 }
421 
applyValueCSSPropertyOutlineStyle(StyleResolverState & state,CSSValue * value)422 void StyleBuilderFunctions::applyValueCSSPropertyOutlineStyle(StyleResolverState& state, CSSValue* value)
423 {
424     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
425     state.style()->setOutlineStyleIsAuto(*primitiveValue);
426     state.style()->setOutlineStyle(*primitiveValue);
427 }
428 
applyValueCSSPropertyResize(StyleResolverState & state,CSSValue * value)429 void StyleBuilderFunctions::applyValueCSSPropertyResize(StyleResolverState& state, CSSValue* value)
430 {
431     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
432 
433     EResize r = RESIZE_NONE;
434     if (primitiveValue->getValueID() == CSSValueAuto) {
435         if (Settings* settings = state.document().settings())
436             r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE;
437     } else {
438         r = *primitiveValue;
439     }
440     state.style()->setResize(r);
441 }
442 
mmLength(double mm)443 static Length mmLength(double mm) { return Length(mm * cssPixelsPerMillimeter, Fixed); }
inchLength(double inch)444 static Length inchLength(double inch) { return Length(inch * cssPixelsPerInch, Fixed); }
getPageSizeFromName(CSSPrimitiveValue * pageSizeName,CSSPrimitiveValue * pageOrientation,Length & width,Length & height)445 static bool getPageSizeFromName(CSSPrimitiveValue* pageSizeName, CSSPrimitiveValue* pageOrientation, Length& width, Length& height)
446 {
447     DEFINE_STATIC_LOCAL(Length, a5Width, (mmLength(148)));
448     DEFINE_STATIC_LOCAL(Length, a5Height, (mmLength(210)));
449     DEFINE_STATIC_LOCAL(Length, a4Width, (mmLength(210)));
450     DEFINE_STATIC_LOCAL(Length, a4Height, (mmLength(297)));
451     DEFINE_STATIC_LOCAL(Length, a3Width, (mmLength(297)));
452     DEFINE_STATIC_LOCAL(Length, a3Height, (mmLength(420)));
453     DEFINE_STATIC_LOCAL(Length, b5Width, (mmLength(176)));
454     DEFINE_STATIC_LOCAL(Length, b5Height, (mmLength(250)));
455     DEFINE_STATIC_LOCAL(Length, b4Width, (mmLength(250)));
456     DEFINE_STATIC_LOCAL(Length, b4Height, (mmLength(353)));
457     DEFINE_STATIC_LOCAL(Length, letterWidth, (inchLength(8.5)));
458     DEFINE_STATIC_LOCAL(Length, letterHeight, (inchLength(11)));
459     DEFINE_STATIC_LOCAL(Length, legalWidth, (inchLength(8.5)));
460     DEFINE_STATIC_LOCAL(Length, legalHeight, (inchLength(14)));
461     DEFINE_STATIC_LOCAL(Length, ledgerWidth, (inchLength(11)));
462     DEFINE_STATIC_LOCAL(Length, ledgerHeight, (inchLength(17)));
463 
464     if (!pageSizeName)
465         return false;
466 
467     switch (pageSizeName->getValueID()) {
468     case CSSValueA5:
469         width = a5Width;
470         height = a5Height;
471         break;
472     case CSSValueA4:
473         width = a4Width;
474         height = a4Height;
475         break;
476     case CSSValueA3:
477         width = a3Width;
478         height = a3Height;
479         break;
480     case CSSValueB5:
481         width = b5Width;
482         height = b5Height;
483         break;
484     case CSSValueB4:
485         width = b4Width;
486         height = b4Height;
487         break;
488     case CSSValueLetter:
489         width = letterWidth;
490         height = letterHeight;
491         break;
492     case CSSValueLegal:
493         width = legalWidth;
494         height = legalHeight;
495         break;
496     case CSSValueLedger:
497         width = ledgerWidth;
498         height = ledgerHeight;
499         break;
500     default:
501         return false;
502     }
503 
504     if (pageOrientation) {
505         switch (pageOrientation->getValueID()) {
506         case CSSValueLandscape:
507             std::swap(width, height);
508             break;
509         case CSSValuePortrait:
510             // Nothing to do.
511             break;
512         default:
513             return false;
514         }
515     }
516     return true;
517 }
518 
applyInitialCSSPropertySize(StyleResolverState &)519 void StyleBuilderFunctions::applyInitialCSSPropertySize(StyleResolverState&) { }
applyInheritCSSPropertySize(StyleResolverState &)520 void StyleBuilderFunctions::applyInheritCSSPropertySize(StyleResolverState&) { }
applyValueCSSPropertySize(StyleResolverState & state,CSSValue * value)521 void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value)
522 {
523     state.style()->resetPageSizeType();
524     Length width;
525     Length height;
526     PageSizeType pageSizeType = PAGE_SIZE_AUTO;
527     CSSValueListInspector inspector(value);
528     switch (inspector.length()) {
529     case 2: {
530         // <length>{2} | <page-size> <orientation>
531         if (!inspector.first()->isPrimitiveValue() || !inspector.second()->isPrimitiveValue())
532             return;
533         CSSPrimitiveValue* first = toCSSPrimitiveValue(inspector.first());
534         CSSPrimitiveValue* second = toCSSPrimitiveValue(inspector.second());
535         if (first->isLength()) {
536             // <length>{2}
537             if (!second->isLength())
538                 return;
539             width = first->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
540             height = second->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
541         } else {
542             // <page-size> <orientation>
543             // The value order is guaranteed. See BisonCSSParser::parseSizeParameter.
544             if (!getPageSizeFromName(first, second, width, height))
545                 return;
546         }
547         pageSizeType = PAGE_SIZE_RESOLVED;
548         break;
549     }
550     case 1: {
551         // <length> | auto | <page-size> | [ portrait | landscape]
552         if (!inspector.first()->isPrimitiveValue())
553             return;
554         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(inspector.first());
555         if (primitiveValue->isLength()) {
556             // <length>
557             pageSizeType = PAGE_SIZE_RESOLVED;
558             width = height = primitiveValue->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
559         } else {
560             switch (primitiveValue->getValueID()) {
561             case 0:
562                 return;
563             case CSSValueAuto:
564                 pageSizeType = PAGE_SIZE_AUTO;
565                 break;
566             case CSSValuePortrait:
567                 pageSizeType = PAGE_SIZE_AUTO_PORTRAIT;
568                 break;
569             case CSSValueLandscape:
570                 pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE;
571                 break;
572             default:
573                 // <page-size>
574                 pageSizeType = PAGE_SIZE_RESOLVED;
575                 if (!getPageSizeFromName(primitiveValue, 0, width, height))
576                     return;
577             }
578         }
579         break;
580     }
581     default:
582         return;
583     }
584     state.style()->setPageSizeType(pageSizeType);
585     state.style()->setPageSize(LengthSize(width, height));
586 }
587 
applyValueCSSPropertyTextAlign(StyleResolverState & state,CSSValue * value)588 void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value)
589 {
590     if (!value->isPrimitiveValue())
591         return;
592 
593     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
594     // FIXME : Per http://www.w3.org/TR/css3-text/#text-align0 can now take <string> but this is not implemented in the
595     // rendering code.
596     if (primitiveValue->isString())
597         return;
598 
599     if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent)
600         state.style()->setTextAlign(*primitiveValue);
601     else if (state.parentStyle()->textAlign() == TASTART)
602         state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT);
603     else if (state.parentStyle()->textAlign() == TAEND)
604         state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT);
605     else
606         state.style()->setTextAlign(state.parentStyle()->textAlign());
607 }
608 
applyValueCSSPropertyTextDecoration(StyleResolverState & state,CSSValue * value)609 void StyleBuilderFunctions::applyValueCSSPropertyTextDecoration(StyleResolverState& state, CSSValue* value)
610 {
611     TextDecoration t = RenderStyle::initialTextDecoration();
612     for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
613         CSSValue* item = i.value();
614         t |= *toCSSPrimitiveValue(item);
615     }
616     state.style()->setTextDecoration(t);
617 }
618 
applyInheritCSSPropertyTextIndent(StyleResolverState & state)619 void StyleBuilderFunctions::applyInheritCSSPropertyTextIndent(StyleResolverState& state)
620 {
621     state.style()->setTextIndent(state.parentStyle()->textIndent());
622     state.style()->setTextIndentLine(state.parentStyle()->textIndentLine());
623     state.style()->setTextIndentType(state.parentStyle()->textIndentType());
624 }
625 
applyInitialCSSPropertyTextIndent(StyleResolverState & state)626 void StyleBuilderFunctions::applyInitialCSSPropertyTextIndent(StyleResolverState& state)
627 {
628     state.style()->setTextIndent(RenderStyle::initialTextIndent());
629     state.style()->setTextIndentLine(RenderStyle::initialTextIndentLine());
630     state.style()->setTextIndentType(RenderStyle::initialTextIndentType());
631 }
632 
applyValueCSSPropertyTextIndent(StyleResolverState & state,CSSValue * value)633 void StyleBuilderFunctions::applyValueCSSPropertyTextIndent(StyleResolverState& state, CSSValue* value)
634 {
635     if (!value->isValueList())
636         return;
637 
638     Length lengthOrPercentageValue;
639     TextIndentLine textIndentLineValue = RenderStyle::initialTextIndentLine();
640     TextIndentType textIndentTypeValue = RenderStyle::initialTextIndentType();
641 
642     for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
643         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value());
644         if (!primitiveValue->getValueID())
645             lengthOrPercentageValue = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
646         else if (primitiveValue->getValueID() == CSSValueEachLine)
647             textIndentLineValue = TextIndentEachLine;
648         else if (primitiveValue->getValueID() == CSSValueHanging)
649             textIndentTypeValue = TextIndentHanging;
650         else
651             ASSERT_NOT_REACHED();
652     }
653 
654     state.style()->setTextIndent(lengthOrPercentageValue);
655     state.style()->setTextIndentLine(textIndentLineValue);
656     state.style()->setTextIndentType(textIndentTypeValue);
657 }
658 
applyValueCSSPropertyTransform(StyleResolverState & state,CSSValue * value)659 void StyleBuilderFunctions::applyValueCSSPropertyTransform(StyleResolverState& state, CSSValue* value)
660 {
661     TransformOperations operations;
662     TransformBuilder::createTransformOperations(value, state.cssToLengthConversionData(), operations);
663     state.style()->setTransform(operations);
664 }
665 
applyInitialCSSPropertyTransformOrigin(StyleResolverState & state)666 void StyleBuilderFunctions::applyInitialCSSPropertyTransformOrigin(StyleResolverState& state)
667 {
668     applyInitialCSSPropertyWebkitTransformOriginX(state);
669     applyInitialCSSPropertyWebkitTransformOriginY(state);
670     applyInitialCSSPropertyWebkitTransformOriginZ(state);
671 }
672 
applyInheritCSSPropertyTransformOrigin(StyleResolverState & state)673 void StyleBuilderFunctions::applyInheritCSSPropertyTransformOrigin(StyleResolverState& state)
674 {
675     applyInheritCSSPropertyWebkitTransformOriginX(state);
676     applyInheritCSSPropertyWebkitTransformOriginY(state);
677     applyInheritCSSPropertyWebkitTransformOriginZ(state);
678 }
679 
applyValueCSSPropertyTransformOrigin(StyleResolverState & state,CSSValue * value)680 void StyleBuilderFunctions::applyValueCSSPropertyTransformOrigin(StyleResolverState& state, CSSValue* value)
681 {
682     CSSValueList* list = toCSSValueList(value);
683     ASSERT(list->length() == 3);
684     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
685     if (primitiveValue->isValueID()) {
686         switch (primitiveValue->getValueID()) {
687         case CSSValueLeft:
688             state.style()->setTransformOriginX(Length(0, Percent));
689             break;
690         case CSSValueRight:
691             state.style()->setTransformOriginX(Length(100, Percent));
692             break;
693         case CSSValueCenter:
694             state.style()->setTransformOriginX(Length(50, Percent));
695             break;
696         default:
697             ASSERT_NOT_REACHED();
698         }
699     } else {
700         state.style()->setTransformOriginX(StyleBuilderConverter::convertLength(state, primitiveValue));
701     }
702 
703     primitiveValue = toCSSPrimitiveValue(list->item(1));
704     if (primitiveValue->isValueID()) {
705         switch (primitiveValue->getValueID()) {
706         case CSSValueTop:
707             state.style()->setTransformOriginY(Length(0, Percent));
708             break;
709         case CSSValueBottom:
710             state.style()->setTransformOriginY(Length(100, Percent));
711             break;
712         case CSSValueCenter:
713             state.style()->setTransformOriginY(Length(50, Percent));
714             break;
715         default:
716             ASSERT_NOT_REACHED();
717         }
718     } else {
719         state.style()->setTransformOriginY(StyleBuilderConverter::convertLength(state, primitiveValue));
720     }
721 
722     primitiveValue = toCSSPrimitiveValue(list->item(2));
723     state.style()->setTransformOriginZ(StyleBuilderConverter::convertComputedLength<float>(state, primitiveValue));
724 }
725 
applyInitialCSSPropertyPerspectiveOrigin(StyleResolverState & state)726 void StyleBuilderFunctions::applyInitialCSSPropertyPerspectiveOrigin(StyleResolverState& state)
727 {
728     applyInitialCSSPropertyWebkitPerspectiveOriginX(state);
729     applyInitialCSSPropertyWebkitPerspectiveOriginY(state);
730 }
731 
applyInheritCSSPropertyPerspectiveOrigin(StyleResolverState & state)732 void StyleBuilderFunctions::applyInheritCSSPropertyPerspectiveOrigin(StyleResolverState& state)
733 {
734     applyInheritCSSPropertyWebkitPerspectiveOriginX(state);
735     applyInheritCSSPropertyWebkitPerspectiveOriginY(state);
736 }
737 
applyValueCSSPropertyPerspectiveOrigin(StyleResolverState & state,CSSValue * value)738 void StyleBuilderFunctions::applyValueCSSPropertyPerspectiveOrigin(StyleResolverState& state, CSSValue* value)
739 {
740     CSSValueList* list = toCSSValueList(value);
741     ASSERT(list->length() == 2);
742     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
743     if (primitiveValue->isValueID()) {
744         switch (primitiveValue->getValueID()) {
745         case CSSValueLeft:
746             state.style()->setPerspectiveOriginX(Length(0, Percent));
747             break;
748         case CSSValueRight:
749             state.style()->setPerspectiveOriginX(Length(100, Percent));
750             break;
751         case CSSValueCenter:
752             state.style()->setPerspectiveOriginX(Length(50, Percent));
753             break;
754         default:
755             ASSERT_NOT_REACHED();
756         }
757     } else {
758         state.style()->setPerspectiveOriginX(StyleBuilderConverter::convertLength(state, primitiveValue));
759     }
760 
761     primitiveValue = toCSSPrimitiveValue(list->item(1));
762     if (primitiveValue->isValueID()) {
763         switch (primitiveValue->getValueID()) {
764         case CSSValueTop:
765             state.style()->setPerspectiveOriginY(Length(0, Percent));
766             break;
767         case CSSValueBottom:
768             state.style()->setPerspectiveOriginY(Length(100, Percent));
769             break;
770         case CSSValueCenter:
771             state.style()->setPerspectiveOriginY(Length(50, Percent));
772             break;
773         default:
774             ASSERT_NOT_REACHED();
775         }
776     } else {
777         state.style()->setPerspectiveOriginY(StyleBuilderConverter::convertLength(state, primitiveValue));
778     }
779 }
780 
applyInheritCSSPropertyVerticalAlign(StyleResolverState & state)781 void StyleBuilderFunctions::applyInheritCSSPropertyVerticalAlign(StyleResolverState& state)
782 {
783     EVerticalAlign verticalAlign = state.parentStyle()->verticalAlign();
784     state.style()->setVerticalAlign(verticalAlign);
785     if (verticalAlign == LENGTH)
786         state.style()->setVerticalAlignLength(state.parentStyle()->verticalAlignLength());
787 }
788 
applyValueCSSPropertyVerticalAlign(StyleResolverState & state,CSSValue * value)789 void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value)
790 {
791     if (!value->isPrimitiveValue())
792         return;
793 
794     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
795 
796     if (primitiveValue->getValueID()) {
797         state.style()->setVerticalAlign(*primitiveValue);
798         return;
799     }
800 
801     state.style()->setVerticalAlignLength(primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()));
802 }
803 
applyValueCSSPropertyTouchAction(StyleResolverState & state,CSSValue * value)804 void StyleBuilderFunctions::applyValueCSSPropertyTouchAction(StyleResolverState& state, CSSValue* value)
805 {
806     TouchAction action = RenderStyle::initialTouchAction();
807     for (CSSValueListIterator i(value); i.hasMore(); i.advance())
808         action |= *toCSSPrimitiveValue(i.value());
809 
810     state.style()->setTouchAction(action);
811 }
812 
resetEffectiveZoom(StyleResolverState & state)813 static void resetEffectiveZoom(StyleResolverState& state)
814 {
815     // Reset the zoom in effect. This allows the setZoom method to accurately compute a new zoom in effect.
816     state.setEffectiveZoom(state.parentStyle() ? state.parentStyle()->effectiveZoom() : RenderStyle::initialZoom());
817 }
818 
applyInitialCSSPropertyZoom(StyleResolverState & state)819 void StyleBuilderFunctions::applyInitialCSSPropertyZoom(StyleResolverState& state)
820 {
821     resetEffectiveZoom(state);
822     state.setZoom(RenderStyle::initialZoom());
823 }
824 
applyInheritCSSPropertyZoom(StyleResolverState & state)825 void StyleBuilderFunctions::applyInheritCSSPropertyZoom(StyleResolverState& state)
826 {
827     resetEffectiveZoom(state);
828     state.setZoom(state.parentStyle()->zoom());
829 }
830 
applyValueCSSPropertyZoom(StyleResolverState & state,CSSValue * value)831 void StyleBuilderFunctions::applyValueCSSPropertyZoom(StyleResolverState& state, CSSValue* value)
832 {
833     ASSERT_WITH_SECURITY_IMPLICATION(value->isPrimitiveValue());
834     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
835 
836     if (primitiveValue->getValueID() == CSSValueNormal) {
837         resetEffectiveZoom(state);
838         state.setZoom(RenderStyle::initialZoom());
839     } else if (primitiveValue->getValueID() == CSSValueReset) {
840         state.setEffectiveZoom(RenderStyle::initialZoom());
841         state.setZoom(RenderStyle::initialZoom());
842     } else if (primitiveValue->getValueID() == CSSValueDocument) {
843         float docZoom = state.rootElementStyle() ? state.rootElementStyle()->zoom() : RenderStyle::initialZoom();
844         state.setEffectiveZoom(docZoom);
845         state.setZoom(docZoom);
846     } else if (primitiveValue->isPercentage()) {
847         resetEffectiveZoom(state);
848         if (float percent = primitiveValue->getFloatValue())
849             state.setZoom(percent / 100.0f);
850     } else if (primitiveValue->isNumber()) {
851         resetEffectiveZoom(state);
852         if (float number = primitiveValue->getFloatValue())
853             state.setZoom(number);
854     }
855 }
856 
applyInitialCSSPropertyWebkitAspectRatio(StyleResolverState & state)857 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitAspectRatio(StyleResolverState& state)
858 {
859     state.style()->setHasAspectRatio(RenderStyle::initialHasAspectRatio());
860     state.style()->setAspectRatioDenominator(RenderStyle::initialAspectRatioDenominator());
861     state.style()->setAspectRatioNumerator(RenderStyle::initialAspectRatioNumerator());
862 }
863 
applyInheritCSSPropertyWebkitAspectRatio(StyleResolverState & state)864 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitAspectRatio(StyleResolverState& state)
865 {
866     if (!state.parentStyle()->hasAspectRatio())
867         return;
868     state.style()->setHasAspectRatio(true);
869     state.style()->setAspectRatioDenominator(state.parentStyle()->aspectRatioDenominator());
870     state.style()->setAspectRatioNumerator(state.parentStyle()->aspectRatioNumerator());
871 }
872 
applyValueCSSPropertyWebkitAspectRatio(StyleResolverState & state,CSSValue * value)873 void StyleBuilderFunctions::applyValueCSSPropertyWebkitAspectRatio(StyleResolverState& state, CSSValue* value)
874 {
875     if (!value->isAspectRatioValue()) {
876         state.style()->setHasAspectRatio(false);
877         return;
878     }
879     CSSAspectRatioValue* aspectRatioValue = toCSSAspectRatioValue(value);
880     state.style()->setHasAspectRatio(true);
881     state.style()->setAspectRatioDenominator(aspectRatioValue->denominatorValue());
882     state.style()->setAspectRatioNumerator(aspectRatioValue->numeratorValue());
883 }
884 
applyValueCSSPropertyWebkitBorderImage(StyleResolverState & state,CSSValue * value)885 void StyleBuilderFunctions::applyValueCSSPropertyWebkitBorderImage(StyleResolverState& state, CSSValue* value)
886 {
887     NinePieceImage image;
888     state.styleMap().mapNinePieceImage(state.style(), CSSPropertyWebkitBorderImage, value, image);
889     state.style()->setBorderImage(image);
890 }
891 
applyValueCSSPropertyWebkitClipPath(StyleResolverState & state,CSSValue * value)892 void StyleBuilderFunctions::applyValueCSSPropertyWebkitClipPath(StyleResolverState& state, CSSValue* value)
893 {
894     if (value->isPrimitiveValue()) {
895         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
896         if (primitiveValue->getValueID() == CSSValueNone) {
897             state.style()->setClipPath(nullptr);
898         } else if (primitiveValue->isShape()) {
899             state.style()->setClipPath(ShapeClipPathOperation::create(basicShapeForValue(state, primitiveValue->getShapeValue())));
900         } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_URI) {
901             String cssURLValue = primitiveValue->getStringValue();
902             KURL url = state.document().completeURL(cssURLValue);
903             // FIXME: It doesn't work with forward or external SVG references (see https://bugs.webkit.org/show_bug.cgi?id=90405)
904             state.style()->setClipPath(ReferenceClipPathOperation::create(cssURLValue, AtomicString(url.fragmentIdentifier())));
905         }
906     }
907 }
908 
applyValueCSSPropertyWebkitFilter(StyleResolverState & state,CSSValue * value)909 void StyleBuilderFunctions::applyValueCSSPropertyWebkitFilter(StyleResolverState& state, CSSValue* value)
910 {
911     FilterOperations operations;
912     if (FilterOperationResolver::createFilterOperations(value, state.cssToLengthConversionData(), operations, state))
913         state.style()->setFilter(operations);
914 }
915 
applyInitialCSSPropertyFontVariantLigatures(StyleResolverState & state)916 void StyleBuilderFunctions::applyInitialCSSPropertyFontVariantLigatures(StyleResolverState& state)
917 {
918     state.fontBuilder().setFontVariantLigaturesInitial();
919 }
920 
applyInheritCSSPropertyFontVariantLigatures(StyleResolverState & state)921 void StyleBuilderFunctions::applyInheritCSSPropertyFontVariantLigatures(StyleResolverState& state)
922 {
923     state.fontBuilder().setFontVariantLigaturesInherit(state.parentFontDescription());
924 }
925 
applyValueCSSPropertyFontVariantLigatures(StyleResolverState & state,CSSValue * value)926 void StyleBuilderFunctions::applyValueCSSPropertyFontVariantLigatures(StyleResolverState& state, CSSValue* value)
927 {
928     state.fontBuilder().setFontVariantLigaturesValue(value);
929 }
930 
applyValueCSSPropertyInternalMarqueeIncrement(StyleResolverState & state,CSSValue * value)931 void StyleBuilderFunctions::applyValueCSSPropertyInternalMarqueeIncrement(StyleResolverState& state, CSSValue* value)
932 {
933     if (!value->isPrimitiveValue())
934         return;
935 
936     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
937     if (primitiveValue->getValueID()) {
938         switch (primitiveValue->getValueID()) {
939         case CSSValueSmall:
940             state.style()->setMarqueeIncrement(Length(1, Fixed)); // 1px.
941             break;
942         case CSSValueNormal:
943             state.style()->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default.
944             break;
945         case CSSValueLarge:
946             state.style()->setMarqueeIncrement(Length(36, Fixed)); // 36px.
947             break;
948         default:
949             break;
950         }
951     } else {
952         Length marqueeLength = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
953         state.style()->setMarqueeIncrement(marqueeLength);
954     }
955 }
956 
applyValueCSSPropertyInternalMarqueeSpeed(StyleResolverState & state,CSSValue * value)957 void StyleBuilderFunctions::applyValueCSSPropertyInternalMarqueeSpeed(StyleResolverState& state, CSSValue* value)
958 {
959     if (!value->isPrimitiveValue())
960         return;
961 
962     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
963     if (CSSValueID valueID = primitiveValue->getValueID()) {
964         switch (valueID) {
965         case CSSValueSlow:
966             state.style()->setMarqueeSpeed(500); // 500 msec.
967             break;
968         case CSSValueNormal:
969             state.style()->setMarqueeSpeed(85); // 85msec. The WinIE default.
970             break;
971         case CSSValueFast:
972             state.style()->setMarqueeSpeed(10); // 10msec. Super fast.
973             break;
974         default:
975             break;
976         }
977     } else if (primitiveValue->isTime()) {
978         state.style()->setMarqueeSpeed(primitiveValue->computeTime<int, CSSPrimitiveValue::Milliseconds>());
979     } else if (primitiveValue->isNumber()) { // For scrollamount support.
980         state.style()->setMarqueeSpeed(primitiveValue->getIntValue());
981     }
982 }
983 
984 // FIXME: We should use the same system for this as the rest of the pseudo-shorthands (e.g. background-position)
applyInitialCSSPropertyWebkitPerspectiveOrigin(StyleResolverState & state)985 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitPerspectiveOrigin(StyleResolverState& state)
986 {
987     applyInitialCSSPropertyWebkitPerspectiveOriginX(state);
988     applyInitialCSSPropertyWebkitPerspectiveOriginY(state);
989 }
990 
applyInheritCSSPropertyWebkitPerspectiveOrigin(StyleResolverState & state)991 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitPerspectiveOrigin(StyleResolverState& state)
992 {
993     applyInheritCSSPropertyWebkitPerspectiveOriginX(state);
994     applyInheritCSSPropertyWebkitPerspectiveOriginY(state);
995 }
996 
applyValueCSSPropertyWebkitPerspectiveOrigin(StyleResolverState &,CSSValue * value)997 void StyleBuilderFunctions::applyValueCSSPropertyWebkitPerspectiveOrigin(StyleResolverState&, CSSValue* value)
998 {
999     // This is expanded in the parser
1000     ASSERT_NOT_REACHED();
1001 }
1002 
applyValueCSSPropertyWebkitTapHighlightColor(StyleResolverState & state,CSSValue * value)1003 void StyleBuilderFunctions::applyValueCSSPropertyWebkitTapHighlightColor(StyleResolverState& state, CSSValue* value)
1004 {
1005     if (!value->isPrimitiveValue())
1006         return;
1007     Color color = state.document().textLinkColors().colorFromPrimitiveValue(toCSSPrimitiveValue(value), state.style()->color());
1008     state.style()->setTapHighlightColor(color);
1009 }
1010 
applyInitialCSSPropertyWebkitTextEmphasisStyle(StyleResolverState & state)1011 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state)
1012 {
1013     state.style()->setTextEmphasisFill(RenderStyle::initialTextEmphasisFill());
1014     state.style()->setTextEmphasisMark(RenderStyle::initialTextEmphasisMark());
1015     state.style()->setTextEmphasisCustomMark(RenderStyle::initialTextEmphasisCustomMark());
1016 }
1017 
applyInheritCSSPropertyWebkitTextEmphasisStyle(StyleResolverState & state)1018 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state)
1019 {
1020     state.style()->setTextEmphasisFill(state.parentStyle()->textEmphasisFill());
1021     state.style()->setTextEmphasisMark(state.parentStyle()->textEmphasisMark());
1022     state.style()->setTextEmphasisCustomMark(state.parentStyle()->textEmphasisCustomMark());
1023 }
1024 
applyValueCSSPropertyWebkitTextEmphasisStyle(StyleResolverState & state,CSSValue * value)1025 void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state, CSSValue* value)
1026 {
1027     if (value->isValueList()) {
1028         CSSValueList* list = toCSSValueList(value);
1029         ASSERT(list->length() == 2);
1030         if (list->length() != 2)
1031             return;
1032         for (unsigned i = 0; i < 2; ++i) {
1033             CSSValue* item = list->itemWithoutBoundsCheck(i);
1034             if (!item->isPrimitiveValue())
1035                 continue;
1036 
1037             CSSPrimitiveValue* value = toCSSPrimitiveValue(item);
1038             if (value->getValueID() == CSSValueFilled || value->getValueID() == CSSValueOpen)
1039                 state.style()->setTextEmphasisFill(*value);
1040             else
1041                 state.style()->setTextEmphasisMark(*value);
1042         }
1043         state.style()->setTextEmphasisCustomMark(nullAtom);
1044         return;
1045     }
1046 
1047     if (!value->isPrimitiveValue())
1048         return;
1049     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1050 
1051     if (primitiveValue->isString()) {
1052         state.style()->setTextEmphasisFill(TextEmphasisFillFilled);
1053         state.style()->setTextEmphasisMark(TextEmphasisMarkCustom);
1054         state.style()->setTextEmphasisCustomMark(AtomicString(primitiveValue->getStringValue()));
1055         return;
1056     }
1057 
1058     state.style()->setTextEmphasisCustomMark(nullAtom);
1059 
1060     if (primitiveValue->getValueID() == CSSValueFilled || primitiveValue->getValueID() == CSSValueOpen) {
1061         state.style()->setTextEmphasisFill(*primitiveValue);
1062         state.style()->setTextEmphasisMark(TextEmphasisMarkAuto);
1063     } else {
1064         state.style()->setTextEmphasisFill(TextEmphasisFillFilled);
1065         state.style()->setTextEmphasisMark(*primitiveValue);
1066     }
1067 }
1068 
applyValueCSSPropertyTextUnderlinePosition(StyleResolverState & state,CSSValue * value)1069 void StyleBuilderFunctions::applyValueCSSPropertyTextUnderlinePosition(StyleResolverState& state, CSSValue* value)
1070 {
1071     // This is true if value is 'auto' or 'alphabetic'.
1072     if (value->isPrimitiveValue()) {
1073         TextUnderlinePosition t = *toCSSPrimitiveValue(value);
1074         state.style()->setTextUnderlinePosition(t);
1075         return;
1076     }
1077 
1078     unsigned t = 0;
1079     for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
1080         CSSValue* item = i.value();
1081         TextUnderlinePosition t2 = *toCSSPrimitiveValue(item);
1082         t |= t2;
1083     }
1084     state.style()->setTextUnderlinePosition(static_cast<TextUnderlinePosition>(t));
1085 }
1086 
applyInitialCSSPropertyWillChange(StyleResolverState & state)1087 void StyleBuilderFunctions::applyInitialCSSPropertyWillChange(StyleResolverState& state)
1088 {
1089     state.style()->setWillChangeContents(false);
1090     state.style()->setWillChangeScrollPosition(false);
1091     state.style()->setWillChangeProperties(Vector<CSSPropertyID>());
1092     state.style()->setSubtreeWillChangeContents(state.parentStyle()->subtreeWillChangeContents());
1093 }
1094 
applyInheritCSSPropertyWillChange(StyleResolverState & state)1095 void StyleBuilderFunctions::applyInheritCSSPropertyWillChange(StyleResolverState& state)
1096 {
1097     state.style()->setWillChangeContents(state.parentStyle()->willChangeContents());
1098     state.style()->setWillChangeScrollPosition(state.parentStyle()->willChangeScrollPosition());
1099     state.style()->setWillChangeProperties(state.parentStyle()->willChangeProperties());
1100     state.style()->setSubtreeWillChangeContents(state.parentStyle()->subtreeWillChangeContents());
1101 }
1102 
applyValueCSSPropertyWillChange(StyleResolverState & state,CSSValue * value)1103 void StyleBuilderFunctions::applyValueCSSPropertyWillChange(StyleResolverState& state, CSSValue* value)
1104 {
1105     ASSERT(value->isValueList());
1106     bool willChangeContents = false;
1107     bool willChangeScrollPosition = false;
1108     Vector<CSSPropertyID> willChangeProperties;
1109 
1110     for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
1111         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value());
1112         if (CSSPropertyID propertyID = primitiveValue->getPropertyID())
1113             willChangeProperties.append(propertyID);
1114         else if (primitiveValue->getValueID() == CSSValueContents)
1115             willChangeContents = true;
1116         else if (primitiveValue->getValueID() == CSSValueScrollPosition)
1117             willChangeScrollPosition = true;
1118         else
1119             ASSERT_NOT_REACHED();
1120     }
1121     state.style()->setWillChangeContents(willChangeContents);
1122     state.style()->setWillChangeScrollPosition(willChangeScrollPosition);
1123     state.style()->setWillChangeProperties(willChangeProperties);
1124     state.style()->setSubtreeWillChangeContents(willChangeContents || state.parentStyle()->subtreeWillChangeContents());
1125 }
1126 
applyInitialCSSPropertyContent(StyleResolverState & state)1127 void StyleBuilderFunctions::applyInitialCSSPropertyContent(StyleResolverState& state)
1128 {
1129     state.style()->clearContent();
1130 }
1131 
applyInheritCSSPropertyContent(StyleResolverState &)1132 void StyleBuilderFunctions::applyInheritCSSPropertyContent(StyleResolverState&)
1133 {
1134     // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This
1135     // note is a reminder that eventually "inherit" needs to be supported.
1136 }
1137 
applyValueCSSPropertyContent(StyleResolverState & state,CSSValue * value)1138 void StyleBuilderFunctions::applyValueCSSPropertyContent(StyleResolverState& state, CSSValue* value)
1139 {
1140     // list of string, uri, counter, attr, i
1141 
1142     if (!value->isValueList())
1143         return;
1144 
1145     bool didSet = false;
1146     for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
1147         CSSValue* item = i.value();
1148         if (item->isImageGeneratorValue()) {
1149             if (item->isGradientValue())
1150                 state.style()->setContent(StyleGeneratedImage::create(toCSSGradientValue(item)->gradientWithStylesResolved(state.document().textLinkColors(), state.style()->color()).get()), didSet);
1151             else
1152                 state.style()->setContent(StyleGeneratedImage::create(toCSSImageGeneratorValue(item)), didSet);
1153             didSet = true;
1154         } else if (item->isImageSetValue()) {
1155             state.style()->setContent(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item)), didSet);
1156             didSet = true;
1157         }
1158 
1159         if (item->isImageValue()) {
1160             state.style()->setContent(state.elementStyleResources().cachedOrPendingFromValue(state.document(), CSSPropertyContent, toCSSImageValue(item)), didSet);
1161             didSet = true;
1162             continue;
1163         }
1164 
1165         if (!item->isPrimitiveValue())
1166             continue;
1167 
1168         CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item);
1169 
1170         if (contentValue->isString()) {
1171             state.style()->setContent(contentValue->getStringValue().impl(), didSet);
1172             didSet = true;
1173         } else if (contentValue->isAttr()) {
1174             // FIXME: Can a namespace be specified for an attr(foo)?
1175             if (state.style()->styleType() == NOPSEUDO)
1176                 state.style()->setUnique();
1177             else
1178                 state.parentStyle()->setUnique();
1179             QualifiedName attr(nullAtom, AtomicString(contentValue->getStringValue()), nullAtom);
1180             const AtomicString& value = state.element()->getAttribute(attr);
1181             state.style()->setContent(value.isNull() ? emptyString() : value.string(), didSet);
1182             didSet = true;
1183             // register the fact that the attribute value affects the style
1184             state.contentAttrValues().append(attr.localName());
1185         } else if (contentValue->isCounter()) {
1186             Counter* counterValue = contentValue->getCounterValue();
1187             EListStyleType listStyleType = NoneListStyle;
1188             CSSValueID listStyleIdent = counterValue->listStyleIdent();
1189             if (listStyleIdent != CSSValueNone)
1190                 listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
1191             OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(AtomicString(counterValue->identifier()), listStyleType, AtomicString(counterValue->separator())));
1192             state.style()->setContent(counter.release(), didSet);
1193             didSet = true;
1194         } else {
1195             switch (contentValue->getValueID()) {
1196             case CSSValueOpenQuote:
1197                 state.style()->setContent(OPEN_QUOTE, didSet);
1198                 didSet = true;
1199                 break;
1200             case CSSValueCloseQuote:
1201                 state.style()->setContent(CLOSE_QUOTE, didSet);
1202                 didSet = true;
1203                 break;
1204             case CSSValueNoOpenQuote:
1205                 state.style()->setContent(NO_OPEN_QUOTE, didSet);
1206                 didSet = true;
1207                 break;
1208             case CSSValueNoCloseQuote:
1209                 state.style()->setContent(NO_CLOSE_QUOTE, didSet);
1210                 didSet = true;
1211                 break;
1212             default:
1213                 // normal and none do not have any effect.
1214                 { }
1215             }
1216         }
1217     }
1218     if (!didSet)
1219         state.style()->clearContent();
1220 }
1221 
applyInitialCSSPropertyFont(StyleResolverState &)1222 void StyleBuilderFunctions::applyInitialCSSPropertyFont(StyleResolverState&)
1223 {
1224     ASSERT_NOT_REACHED();
1225 }
1226 
applyInheritCSSPropertyFont(StyleResolverState &)1227 void StyleBuilderFunctions::applyInheritCSSPropertyFont(StyleResolverState&)
1228 {
1229     ASSERT_NOT_REACHED();
1230 }
1231 
applyValueCSSPropertyFont(StyleResolverState & state,CSSValue * value)1232 void StyleBuilderFunctions::applyValueCSSPropertyFont(StyleResolverState& state, CSSValue* value)
1233 {
1234     // Only System Font identifiers should come through this method
1235     // all other values should have been handled when the shorthand
1236     // was expanded by the parser.
1237     // FIXME: System Font identifiers should not hijack this
1238     // short-hand CSSProperty like this (crbug.com/353932)
1239     state.style()->setLineHeight(RenderStyle::initialLineHeight());
1240     state.setLineHeightValue(0);
1241     state.fontBuilder().fromSystemFont(toCSSPrimitiveValue(value)->getValueID(), state.style()->effectiveZoom());
1242 }
1243 
applyValueCSSPropertyWebkitLocale(StyleResolverState & state,CSSValue * value)1244 void StyleBuilderFunctions::applyValueCSSPropertyWebkitLocale(StyleResolverState& state, CSSValue* value)
1245 {
1246     if (!value->isPrimitiveValue())
1247         return;
1248     const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1249     if (primitiveValue->getValueID() == CSSValueAuto)
1250         state.style()->setLocale(nullAtom);
1251     else
1252         state.style()->setLocale(AtomicString(primitiveValue->getStringValue()));
1253     state.fontBuilder().setScript(state.style()->locale());
1254 }
1255 
applyInitialCSSPropertyWebkitAppRegion(StyleResolverState &)1256 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitAppRegion(StyleResolverState&)
1257 {
1258 }
1259 
applyInheritCSSPropertyWebkitAppRegion(StyleResolverState &)1260 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitAppRegion(StyleResolverState&)
1261 {
1262 }
1263 
applyValueCSSPropertyWebkitAppRegion(StyleResolverState & state,CSSValue * value)1264 void StyleBuilderFunctions::applyValueCSSPropertyWebkitAppRegion(StyleResolverState& state, CSSValue* value)
1265 {
1266     if (!value->isPrimitiveValue())
1267         return;
1268     const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1269     if (!primitiveValue->getValueID())
1270         return;
1271     state.style()->setDraggableRegionMode(primitiveValue->getValueID() == CSSValueDrag ? DraggableRegionDrag : DraggableRegionNoDrag);
1272     state.document().setHasAnnotatedRegions(true);
1273 }
1274 
applyInitialCSSPropertyWebkitPerspective(StyleResolverState & state)1275 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitPerspective(StyleResolverState& state)
1276 {
1277     applyInitialCSSPropertyPerspective(state);
1278 }
1279 
applyInheritCSSPropertyWebkitPerspective(StyleResolverState & state)1280 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitPerspective(StyleResolverState& state)
1281 {
1282     applyInheritCSSPropertyPerspective(state);
1283 }
1284 
applyValueCSSPropertyWebkitPerspective(StyleResolverState & state,CSSValue * value)1285 void StyleBuilderFunctions::applyValueCSSPropertyWebkitPerspective(StyleResolverState& state, CSSValue* value)
1286 {
1287     if (!value->isPrimitiveValue())
1288         return;
1289     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1290     if (primitiveValue->isNumber()) {
1291         float perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(state.cssToLengthConversionData());
1292         if (perspectiveValue >= 0.0f)
1293             state.style()->setPerspective(perspectiveValue);
1294     } else {
1295         applyValueCSSPropertyPerspective(state, value);
1296     }
1297 }
1298 
applyValueCSSPropertyPerspective(StyleResolverState & state,CSSValue * value)1299 void StyleBuilderFunctions::applyValueCSSPropertyPerspective(StyleResolverState& state, CSSValue* value)
1300 {
1301     if (!value->isPrimitiveValue())
1302         return;
1303     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1304     if (primitiveValue->getValueID() == CSSValueNone) {
1305         state.style()->setPerspective(0);
1306         return;
1307     }
1308 
1309     if (!primitiveValue->isLength())
1310         return;
1311     float perspectiveValue = primitiveValue->computeLength<float>(state.cssToLengthConversionData());
1312     if (perspectiveValue >= 0.0f)
1313         state.style()->setPerspective(perspectiveValue);
1314 }
1315 
applyInitialCSSPropertyInternalCallback(StyleResolverState & state)1316 void StyleBuilderFunctions::applyInitialCSSPropertyInternalCallback(StyleResolverState& state)
1317 {
1318 }
1319 
applyInheritCSSPropertyInternalCallback(StyleResolverState & state)1320 void StyleBuilderFunctions::applyInheritCSSPropertyInternalCallback(StyleResolverState& state)
1321 {
1322 }
1323 
applyValueCSSPropertyInternalCallback(StyleResolverState & state,CSSValue * value)1324 void StyleBuilderFunctions::applyValueCSSPropertyInternalCallback(StyleResolverState& state, CSSValue* value)
1325 {
1326     if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueInternalPresence)
1327         state.style()->addCallbackSelector(state.currentRule()->selectorList().selectorsText());
1328 }
1329 
applyValueCSSPropertyWebkitWritingMode(StyleResolverState & state,CSSValue * value)1330 void StyleBuilderFunctions::applyValueCSSPropertyWebkitWritingMode(StyleResolverState& state, CSSValue* value)
1331 {
1332     if (value->isPrimitiveValue())
1333         state.setWritingMode(*toCSSPrimitiveValue(value));
1334 
1335     // FIXME: It is not ok to modify document state while applying style.
1336     if (state.element() && state.element() == state.document().documentElement())
1337         state.document().setWritingModeSetOnDocumentElement(true);
1338 }
1339 
applyValueCSSPropertyWebkitTextOrientation(StyleResolverState & state,CSSValue * value)1340 void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextOrientation(StyleResolverState& state, CSSValue* value)
1341 {
1342     if (value->isPrimitiveValue())
1343         state.setTextOrientation(*toCSSPrimitiveValue(value));
1344 }
1345 
1346 // FIXME: We should handle initial and inherit for font-feature-settings
applyInitialCSSPropertyWebkitFontFeatureSettings(StyleResolverState & state)1347 void StyleBuilderFunctions::applyInitialCSSPropertyWebkitFontFeatureSettings(StyleResolverState& state)
1348 {
1349 }
1350 
applyInheritCSSPropertyWebkitFontFeatureSettings(StyleResolverState & state)1351 void StyleBuilderFunctions::applyInheritCSSPropertyWebkitFontFeatureSettings(StyleResolverState& state)
1352 {
1353 }
1354 
applyValueCSSPropertyWebkitFontFeatureSettings(StyleResolverState & state,CSSValue * value)1355 void StyleBuilderFunctions::applyValueCSSPropertyWebkitFontFeatureSettings(StyleResolverState& state, CSSValue* value)
1356 {
1357     if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal) {
1358         state.fontBuilder().setFeatureSettingsNormal();
1359         return;
1360     }
1361 
1362     if (value->isValueList())
1363         state.fontBuilder().setFeatureSettingsValue(value);
1364 }
1365 
1366 
applyValueCSSPropertyBaselineShift(StyleResolverState & state,CSSValue * value)1367 void StyleBuilderFunctions::applyValueCSSPropertyBaselineShift(StyleResolverState& state, CSSValue* value)
1368 {
1369     if (!value->isPrimitiveValue())
1370         return;
1371 
1372     SVGRenderStyle* svgStyle = state.style()->accessSVGStyle();
1373     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1374     if (primitiveValue->getValueID()) {
1375         switch (primitiveValue->getValueID()) {
1376         case CSSValueBaseline:
1377             svgStyle->setBaselineShift(BS_BASELINE);
1378             break;
1379         case CSSValueSub:
1380             svgStyle->setBaselineShift(BS_SUB);
1381             break;
1382         case CSSValueSuper:
1383             svgStyle->setBaselineShift(BS_SUPER);
1384             break;
1385         default:
1386             break;
1387         }
1388     } else {
1389         svgStyle->setBaselineShift(BS_LENGTH);
1390         svgStyle->setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
1391     }
1392 }
1393 
1394 } // namespace WebCore
1395