[CSS Grid Layout] Implement justify-self and justify-item css properties.
[WebKit-https.git] / Source / WebCore / css / StyleBuilderCustom.h
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  * Copyright (C) 2014 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #ifndef StyleBuilderCustom_h
28 #define StyleBuilderCustom_h
29
30 #include "CSSAspectRatioValue.h"
31 #include "CSSCursorImageValue.h"
32 #include "CSSFontFamily.h"
33 #include "CSSFontValue.h"
34 #include "CSSGradientValue.h"
35 #include "CSSShadowValue.h"
36 #include "Counter.h"
37 #include "CounterContent.h"
38 #include "CursorList.h"
39 #include "DashboardRegion.h"
40 #include "ElementAncestorIterator.h"
41 #include "Frame.h"
42 #include "HTMLElement.h"
43 #include "LocaleToScriptMapping.h"
44 #include "Rect.h"
45 #include "RenderTheme.h"
46 #include "SVGElement.h"
47 #include "SVGRenderStyle.h"
48 #include "StyleBuilderConverter.h"
49 #include "StyleFontSizeFunctions.h"
50 #include "StyleGeneratedImage.h"
51 #include "StyleResolver.h"
52
53 namespace WebCore {
54
55 #define DECLARE_PROPERTY_CUSTOM_HANDLERS(property) \
56     static void applyInherit##property(StyleResolver&); \
57     static void applyInitial##property(StyleResolver&); \
58     static void applyValue##property(StyleResolver&, CSSValue&)
59
60 // Note that we assume the CSS parser only allows valid CSSValue types.
61 class StyleBuilderCustom {
62 public:
63     // Custom handling of inherit, initial and value setting.
64     DECLARE_PROPERTY_CUSTOM_HANDLERS(BorderImageOutset);
65     DECLARE_PROPERTY_CUSTOM_HANDLERS(BorderImageRepeat);
66     DECLARE_PROPERTY_CUSTOM_HANDLERS(BorderImageSlice);
67     DECLARE_PROPERTY_CUSTOM_HANDLERS(BorderImageWidth);
68     DECLARE_PROPERTY_CUSTOM_HANDLERS(BoxShadow);
69     DECLARE_PROPERTY_CUSTOM_HANDLERS(Clip);
70     DECLARE_PROPERTY_CUSTOM_HANDLERS(ColumnGap);
71     DECLARE_PROPERTY_CUSTOM_HANDLERS(Content);
72     DECLARE_PROPERTY_CUSTOM_HANDLERS(CounterIncrement);
73     DECLARE_PROPERTY_CUSTOM_HANDLERS(CounterReset);
74     DECLARE_PROPERTY_CUSTOM_HANDLERS(Cursor);
75     DECLARE_PROPERTY_CUSTOM_HANDLERS(Fill);
76     DECLARE_PROPERTY_CUSTOM_HANDLERS(FontFamily);
77     DECLARE_PROPERTY_CUSTOM_HANDLERS(FontSize);
78     DECLARE_PROPERTY_CUSTOM_HANDLERS(FontWeight);
79 #if ENABLE(CSS_IMAGE_RESOLUTION)
80     DECLARE_PROPERTY_CUSTOM_HANDLERS(ImageResolution);
81 #endif
82 #if ENABLE(IOS_TEXT_AUTOSIZING)
83     DECLARE_PROPERTY_CUSTOM_HANDLERS(LineHeight);
84 #endif
85     DECLARE_PROPERTY_CUSTOM_HANDLERS(OutlineStyle);
86     DECLARE_PROPERTY_CUSTOM_HANDLERS(Size);
87     DECLARE_PROPERTY_CUSTOM_HANDLERS(Stroke);
88     DECLARE_PROPERTY_CUSTOM_HANDLERS(TextIndent);
89     DECLARE_PROPERTY_CUSTOM_HANDLERS(TextShadow);
90     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitAspectRatio);
91     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitBoxShadow);
92     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitFontVariantLigatures);
93 #if ENABLE(CSS_GRID_LAYOUT)
94     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitGridTemplateAreas);
95     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitGridTemplateColumns);
96     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitGridTemplateRows);
97 #endif // ENABLE(CSS_GRID_LAYOUT)
98     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitMaskBoxImageOutset);
99     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitMaskBoxImageRepeat);
100     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitMaskBoxImageSlice);
101     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitMaskBoxImageWidth);
102     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitSvgShadow);
103     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitTextEmphasisStyle);
104     DECLARE_PROPERTY_CUSTOM_HANDLERS(Zoom);
105     DECLARE_PROPERTY_CUSTOM_HANDLERS(JustifySelf);
106     DECLARE_PROPERTY_CUSTOM_HANDLERS(JustifyItems);
107     DECLARE_PROPERTY_CUSTOM_HANDLERS(AlignItems);
108     DECLARE_PROPERTY_CUSTOM_HANDLERS(AlignSelf);
109
110     // Custom handling of initial + inherit value setting only.
111     static void applyInitialWebkitMaskImage(StyleResolver&) { }
112     static void applyInheritWebkitMaskImage(StyleResolver&) { }
113     static void applyInitialWebkitFontFeatureSettings(StyleResolver&) { }
114     static void applyInheritWebkitFontFeatureSettings(StyleResolver&) { }
115
116     // Custom handling of inherit + value setting only.
117     static void applyInheritDisplay(StyleResolver&);
118     static void applyValueDisplay(StyleResolver&, CSSValue&);
119
120     // Custom handling of value setting only.
121     static void applyValueBaselineShift(StyleResolver&, CSSValue&);
122     static void applyValueDirection(StyleResolver&, CSSValue&);
123     static void applyValueVerticalAlign(StyleResolver&, CSSValue&);
124 #if ENABLE(DASHBOARD_SUPPORT)
125     static void applyValueWebkitDashboardRegion(StyleResolver&, CSSValue&);
126 #endif
127     static void applyValueWebkitLocale(StyleResolver&, CSSValue&);
128     static void applyValueWebkitTextOrientation(StyleResolver&, CSSValue&);
129 #if ENABLE(IOS_TEXT_AUTOSIZING)
130     static void applyValueWebkitTextSizeAdjust(StyleResolver&, CSSValue&);
131 #endif
132     static void applyValueWebkitWritingMode(StyleResolver&, CSSValue&);
133     static void applyValueAlt(StyleResolver&, CSSValue&);
134 #if ENABLE(CSS_SCROLL_SNAP)
135     static void applyInitialWebkitScrollSnapPointsX(StyleResolver&);
136     static void applyInheritWebkitScrollSnapPointsX(StyleResolver&);
137     static void applyInitialWebkitScrollSnapPointsY(StyleResolver&);
138     static void applyInheritWebkitScrollSnapPointsY(StyleResolver&);
139 #endif
140
141 private:
142     static void resetEffectiveZoom(StyleResolver&);
143
144     static Length mmLength(double mm);
145     static Length inchLength(double inch);
146     static bool getPageSizeFromName(CSSPrimitiveValue* pageSizeName, CSSPrimitiveValue* pageOrientation, Length& width, Length& height);
147
148     template <CSSPropertyID id>
149     static void applyTextOrBoxShadowValue(StyleResolver&, CSSValue&);
150     static bool isValidDisplayValue(StyleResolver&, EDisplay);
151
152     enum CounterBehavior {Increment = 0, Reset};
153     template <CounterBehavior counterBehavior>
154     static void applyInheritCounter(StyleResolver&);
155     template <CounterBehavior counterBehavior>
156     static void applyValueCounter(StyleResolver&, CSSValue&);
157
158     static float largerFontSize(float size);
159     static float smallerFontSize(float size);
160     static float determineRubyTextSizeMultiplier(StyleResolver&);
161 };
162
163 inline void StyleBuilderCustom::applyValueDirection(StyleResolver& styleResolver, CSSValue& value)
164 {
165     styleResolver.style()->setDirection(downcast<CSSPrimitiveValue>(value));
166
167     Element* element = styleResolver.element();
168     if (element && styleResolver.element() == element->document().documentElement())
169         element->document().setDirectionSetOnDocumentElement(true);
170 }
171
172 inline void StyleBuilderCustom::resetEffectiveZoom(StyleResolver& styleResolver)
173 {
174     // Reset the zoom in effect. This allows the setZoom method to accurately compute a new zoom in effect.
175     styleResolver.setEffectiveZoom(styleResolver.parentStyle() ? styleResolver.parentStyle()->effectiveZoom() : RenderStyle::initialZoom());
176 }
177
178 inline void StyleBuilderCustom::applyInitialZoom(StyleResolver& styleResolver)
179 {
180     resetEffectiveZoom(styleResolver);
181     styleResolver.setZoom(RenderStyle::initialZoom());
182 }
183
184 inline void StyleBuilderCustom::applyInheritZoom(StyleResolver& styleResolver)
185 {
186     resetEffectiveZoom(styleResolver);
187     styleResolver.setZoom(styleResolver.parentStyle()->zoom());
188 }
189
190 inline void StyleBuilderCustom::applyValueZoom(StyleResolver& styleResolver, CSSValue& value)
191 {
192     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
193
194     if (primitiveValue.getValueID() == CSSValueNormal) {
195         resetEffectiveZoom(styleResolver);
196         styleResolver.setZoom(RenderStyle::initialZoom());
197     } else if (primitiveValue.getValueID() == CSSValueReset) {
198         styleResolver.setEffectiveZoom(RenderStyle::initialZoom());
199         styleResolver.setZoom(RenderStyle::initialZoom());
200     } else if (primitiveValue.getValueID() == CSSValueDocument) {
201         float docZoom = styleResolver.rootElementStyle() ? styleResolver.rootElementStyle()->zoom() : RenderStyle::initialZoom();
202         styleResolver.setEffectiveZoom(docZoom);
203         styleResolver.setZoom(docZoom);
204     } else if (primitiveValue.isPercentage()) {
205         resetEffectiveZoom(styleResolver);
206         if (float percent = primitiveValue.getFloatValue())
207             styleResolver.setZoom(percent / 100.0f);
208     } else if (primitiveValue.isNumber()) {
209         resetEffectiveZoom(styleResolver);
210         if (float number = primitiveValue.getFloatValue())
211             styleResolver.setZoom(number);
212     }
213 }
214 inline Length StyleBuilderCustom::mmLength(double mm)
215 {
216     Ref<CSSPrimitiveValue> value(CSSPrimitiveValue::create(mm, CSSPrimitiveValue::CSS_MM));
217     return value.get().computeLength<Length>(CSSToLengthConversionData());
218 }
219 inline Length StyleBuilderCustom::inchLength(double inch)
220 {
221     Ref<CSSPrimitiveValue> value(CSSPrimitiveValue::create(inch, CSSPrimitiveValue::CSS_IN));
222     return value.get().computeLength<Length>(CSSToLengthConversionData());
223 }
224 bool StyleBuilderCustom::getPageSizeFromName(CSSPrimitiveValue* pageSizeName, CSSPrimitiveValue* pageOrientation, Length& width, Length& height)
225 {
226     static NeverDestroyed<Length> a5Width(mmLength(148));
227     static NeverDestroyed<Length> a5Height(mmLength(210));
228     static NeverDestroyed<Length> a4Width(mmLength(210));
229     static NeverDestroyed<Length> a4Height(mmLength(297));
230     static NeverDestroyed<Length> a3Width(mmLength(297));
231     static NeverDestroyed<Length> a3Height(mmLength(420));
232     static NeverDestroyed<Length> b5Width(mmLength(176));
233     static NeverDestroyed<Length> b5Height(mmLength(250));
234     static NeverDestroyed<Length> b4Width(mmLength(250));
235     static NeverDestroyed<Length> b4Height(mmLength(353));
236     static NeverDestroyed<Length> letterWidth(inchLength(8.5));
237     static NeverDestroyed<Length> letterHeight(inchLength(11));
238     static NeverDestroyed<Length> legalWidth(inchLength(8.5));
239     static NeverDestroyed<Length> legalHeight(inchLength(14));
240     static NeverDestroyed<Length> ledgerWidth(inchLength(11));
241     static NeverDestroyed<Length> ledgerHeight(inchLength(17));
242
243     if (!pageSizeName)
244         return false;
245
246     switch (pageSizeName->getValueID()) {
247     case CSSValueA5:
248         width = a5Width;
249         height = a5Height;
250         break;
251     case CSSValueA4:
252         width = a4Width;
253         height = a4Height;
254         break;
255     case CSSValueA3:
256         width = a3Width;
257         height = a3Height;
258         break;
259     case CSSValueB5:
260         width = b5Width;
261         height = b5Height;
262         break;
263     case CSSValueB4:
264         width = b4Width;
265         height = b4Height;
266         break;
267     case CSSValueLetter:
268         width = letterWidth;
269         height = letterHeight;
270         break;
271     case CSSValueLegal:
272         width = legalWidth;
273         height = legalHeight;
274         break;
275     case CSSValueLedger:
276         width = ledgerWidth;
277         height = ledgerHeight;
278         break;
279     default:
280         return false;
281     }
282
283     if (pageOrientation) {
284         switch (pageOrientation->getValueID()) {
285         case CSSValueLandscape:
286             std::swap(width, height);
287             break;
288         case CSSValuePortrait:
289             // Nothing to do.
290             break;
291         default:
292             return false;
293         }
294     }
295     return true;
296 }
297
298 inline void StyleBuilderCustom::applyValueVerticalAlign(StyleResolver& styleResolver, CSSValue& value)
299 {
300     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
301     if (primitiveValue.getValueID())
302         styleResolver.style()->setVerticalAlign(primitiveValue);
303     else
304         styleResolver.style()->setVerticalAlignLength(primitiveValue.convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion>(styleResolver.state().cssToLengthConversionData()));
305 }
306
307 #if ENABLE(DASHBOARD_SUPPORT)
308 static Length convertToIntLength(const CSSPrimitiveValue* primitiveValue, const CSSToLengthConversionData& conversionData)
309 {
310     return primitiveValue ? primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion>(conversionData) : Length(Undefined);
311 }
312
313 inline void StyleBuilderCustom::applyValueWebkitDashboardRegion(StyleResolver& styleResolver, CSSValue& value)
314 {
315     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
316     if (primitiveValue.getValueID() == CSSValueNone) {
317         styleResolver.style()->setDashboardRegions(RenderStyle::noneDashboardRegions());
318         return;
319     }
320
321     DashboardRegion* region = primitiveValue.getDashboardRegionValue();
322     if (!region)
323         return;
324
325     DashboardRegion* first = region;
326     while (region) {
327         Length top = convertToIntLength(region->top(), styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
328         Length right = convertToIntLength(region->right(), styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
329         Length bottom = convertToIntLength(region->bottom(), styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
330         Length left = convertToIntLength(region->left(), styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
331
332         if (top.isUndefined())
333             top = Length();
334         if (right.isUndefined())
335             right = Length();
336         if (bottom.isUndefined())
337             bottom = Length();
338         if (left.isUndefined())
339             left = Length();
340
341         if (region->m_isCircle)
342             styleResolver.style()->setDashboardRegion(StyleDashboardRegion::Circle, region->m_label, top, right, bottom, left, region == first ? false : true);
343         else if (region->m_isRectangle)
344             styleResolver.style()->setDashboardRegion(StyleDashboardRegion::Rectangle, region->m_label, top, right, bottom, left, region == first ? false : true);
345         region = region->m_next.get();
346     }
347
348     styleResolver.document().setHasAnnotatedRegions(true);
349 }
350 #endif // ENABLE(DASHBOARD_SUPPORT)
351
352 #if ENABLE(CSS_IMAGE_RESOLUTION)
353 inline void StyleBuilderCustom::applyInheritImageResolution(StyleResolver& styleResolver)
354 {
355     styleResolver.style()->setImageResolutionSource(styleResolver.parentStyle()->imageResolutionSource());
356     styleResolver.style()->setImageResolutionSnap(styleResolver.parentStyle()->imageResolutionSnap());
357     styleResolver.style()->setImageResolution(styleResolver.parentStyle()->imageResolution());
358 }
359
360 inline void StyleBuilderCustom::applyInitialImageResolution(StyleResolver& styleResolver)
361 {
362     styleResolver.style()->setImageResolutionSource(RenderStyle::initialImageResolutionSource());
363     styleResolver.style()->setImageResolutionSnap(RenderStyle::initialImageResolutionSnap());
364     styleResolver.style()->setImageResolution(RenderStyle::initialImageResolution());
365 }
366
367 inline void StyleBuilderCustom::applyValueImageResolution(StyleResolver& styleResolver, CSSValue& value)
368 {
369     ImageResolutionSource source = RenderStyle::initialImageResolutionSource();
370     ImageResolutionSnap snap = RenderStyle::initialImageResolutionSnap();
371     double resolution = RenderStyle::initialImageResolution();
372     for (auto& item : downcast<CSSValueList>(value)) {
373         CSSPrimitiveValue& primitiveValue = downcast<CSSPrimitiveValue>(item.get());
374         if (primitiveValue.getValueID() == CSSValueFromImage)
375             source = ImageResolutionFromImage;
376         else if (primitiveValue.getValueID() == CSSValueSnap)
377             snap = ImageResolutionSnapPixels;
378         else
379             resolution = primitiveValue.getDoubleValue(CSSPrimitiveValue::CSS_DPPX);
380     }
381     styleResolver.style()->setImageResolutionSource(source);
382     styleResolver.style()->setImageResolutionSnap(snap);
383     styleResolver.style()->setImageResolution(resolution);
384 }
385 #endif // ENABLE(CSS_IMAGE_RESOLUTION)
386
387 inline void StyleBuilderCustom::applyInheritSize(StyleResolver&) { }
388 inline void StyleBuilderCustom::applyInitialSize(StyleResolver&) { }
389 inline void StyleBuilderCustom::applyValueSize(StyleResolver& styleResolver, CSSValue& value)
390 {
391     styleResolver.style()->resetPageSizeType();
392     Length width;
393     Length height;
394     PageSizeType pageSizeType = PAGE_SIZE_AUTO;
395     if (!is<CSSValueList>(value))
396         return;
397
398     auto& valueList = downcast<CSSValueList>(value);
399     switch (valueList.length()) {
400     case 2: {
401         CSSValue* firstValue = valueList.itemWithoutBoundsCheck(0);
402         CSSValue* secondValue = valueList.itemWithoutBoundsCheck(1);
403         // <length>{2} | <page-size> <orientation>
404         if (!is<CSSPrimitiveValue>(*firstValue) || !is<CSSPrimitiveValue>(*secondValue))
405             return;
406         auto& firstPrimitiveValue = downcast<CSSPrimitiveValue>(*firstValue);
407         auto& secondPrimitiveValue = downcast<CSSPrimitiveValue>(*secondValue);
408         if (firstPrimitiveValue.isLength()) {
409             // <length>{2}
410             if (!secondPrimitiveValue.isLength())
411                 return;
412             CSSToLengthConversionData conversionData = styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f);
413             width = firstPrimitiveValue.computeLength<Length>(conversionData);
414             height = secondPrimitiveValue.computeLength<Length>(conversionData);
415         } else {
416             // <page-size> <orientation>
417             // The value order is guaranteed. See CSSParser::parseSizeParameter.
418             if (!getPageSizeFromName(&firstPrimitiveValue, &secondPrimitiveValue, width, height))
419                 return;
420         }
421         pageSizeType = PAGE_SIZE_RESOLVED;
422         break;
423     }
424     case 1: {
425         CSSValue* value = valueList.itemWithoutBoundsCheck(0);
426         // <length> | auto | <page-size> | [ portrait | landscape]
427         if (!is<CSSPrimitiveValue>(*value))
428             return;
429         auto& primitiveValue = downcast<CSSPrimitiveValue>(*value);
430         if (primitiveValue.isLength()) {
431             // <length>
432             pageSizeType = PAGE_SIZE_RESOLVED;
433             width = height = primitiveValue.computeLength<Length>(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
434         } else {
435             switch (primitiveValue.getValueID()) {
436             case 0:
437                 return;
438             case CSSValueAuto:
439                 pageSizeType = PAGE_SIZE_AUTO;
440                 break;
441             case CSSValuePortrait:
442                 pageSizeType = PAGE_SIZE_AUTO_PORTRAIT;
443                 break;
444             case CSSValueLandscape:
445                 pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE;
446                 break;
447             default:
448                 // <page-size>
449                 pageSizeType = PAGE_SIZE_RESOLVED;
450                 if (!getPageSizeFromName(&primitiveValue, nullptr, width, height))
451                     return;
452             }
453         }
454         break;
455     }
456     default:
457         return;
458     }
459     styleResolver.style()->setPageSizeType(pageSizeType);
460     styleResolver.style()->setPageSize(LengthSize(width, height));
461 }
462
463 inline void StyleBuilderCustom::applyInheritTextIndent(StyleResolver& styleResolver)
464 {
465     styleResolver.style()->setTextIndent(styleResolver.parentStyle()->textIndent());
466 #if ENABLE(CSS3_TEXT)
467     styleResolver.style()->setTextIndentLine(styleResolver.parentStyle()->textIndentLine());
468     styleResolver.style()->setTextIndentType(styleResolver.parentStyle()->textIndentType());
469 #endif
470 }
471
472 inline void StyleBuilderCustom::applyInitialTextIndent(StyleResolver& styleResolver)
473 {
474     styleResolver.style()->setTextIndent(RenderStyle::initialTextIndent());
475 #if ENABLE(CSS3_TEXT)
476     styleResolver.style()->setTextIndentLine(RenderStyle::initialTextIndentLine());
477     styleResolver.style()->setTextIndentType(RenderStyle::initialTextIndentType());
478 #endif
479 }
480
481 inline void StyleBuilderCustom::applyValueTextIndent(StyleResolver& styleResolver, CSSValue& value)
482 {
483     Length lengthOrPercentageValue;
484 #if ENABLE(CSS3_TEXT)
485     TextIndentLine textIndentLineValue = RenderStyle::initialTextIndentLine();
486     TextIndentType textIndentTypeValue = RenderStyle::initialTextIndentType();
487 #endif
488     for (auto& item : downcast<CSSValueList>(value)) {
489         auto& primitiveValue = downcast<CSSPrimitiveValue>(item.get());
490         if (!primitiveValue.getValueID())
491             lengthOrPercentageValue = primitiveValue.convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion>(styleResolver.state().cssToLengthConversionData());
492 #if ENABLE(CSS3_TEXT)
493         else if (primitiveValue.getValueID() == CSSValueWebkitEachLine)
494             textIndentLineValue = TextIndentEachLine;
495         else if (primitiveValue.getValueID() == CSSValueWebkitHanging)
496             textIndentTypeValue = TextIndentHanging;
497 #endif
498     }
499
500     if (lengthOrPercentageValue.isUndefined())
501         return;
502
503     styleResolver.style()->setTextIndent(lengthOrPercentageValue);
504 #if ENABLE(CSS3_TEXT)
505     styleResolver.style()->setTextIndentLine(textIndentLineValue);
506     styleResolver.style()->setTextIndentType(textIndentTypeValue);
507 #endif
508 }
509
510 inline void StyleBuilderCustom::applyInheritAlignSelf(StyleResolver& styleResolver)
511 {
512     styleResolver.style()->setAlignSelf(styleResolver.parentStyle()->alignSelf());
513     styleResolver.style()->setAlignSelfOverflowAlignment(styleResolver.parentStyle()->alignSelfOverflowAlignment());
514 }
515
516 inline void StyleBuilderCustom::applyInitialAlignSelf(StyleResolver& styleResolver)
517 {
518     styleResolver.style()->setAlignSelf(RenderStyle::initialAlignSelf());
519     styleResolver.style()->setAlignSelfOverflowAlignment(RenderStyle::initialAlignSelfOverflowAlignment());
520 }
521
522 inline void StyleBuilderCustom::applyValueAlignSelf(StyleResolver& styleResolver, CSSValue& value)
523 {
524     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
525     if (Pair* pairValue = primitiveValue.getPairValue()) {
526         styleResolver.style()->setAlignSelf(*pairValue->first());
527         styleResolver.style()->setAlignSelfOverflowAlignment(*pairValue->second());
528     } else {
529         styleResolver.style()->setAlignSelf(primitiveValue);
530         styleResolver.style()->setAlignSelfOverflowAlignment(RenderStyle::initialAlignSelfOverflowAlignment());
531     }
532 }
533
534 inline void StyleBuilderCustom::applyInheritAlignItems(StyleResolver& styleResolver)
535 {
536     styleResolver.style()->setAlignItems(styleResolver.parentStyle()->alignItems());
537     styleResolver.style()->setAlignItemsOverflowAlignment(styleResolver.parentStyle()->alignItemsOverflowAlignment());
538 }
539
540 inline void StyleBuilderCustom::applyInitialAlignItems(StyleResolver& styleResolver)
541 {
542     styleResolver.style()->setAlignItems(RenderStyle::initialAlignItems());
543     styleResolver.style()->setAlignItemsOverflowAlignment(RenderStyle::initialAlignItemsOverflowAlignment());
544 }
545
546 inline void StyleBuilderCustom::applyValueAlignItems(StyleResolver& styleResolver, CSSValue& value)
547 {
548     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
549     if (Pair* pairValue = primitiveValue.getPairValue()) {
550         styleResolver.style()->setAlignItems(*pairValue->first());
551         styleResolver.style()->setAlignItemsOverflowAlignment(*pairValue->second());
552     } else {
553         styleResolver.style()->setAlignItems(primitiveValue);
554         styleResolver.style()->setAlignItemsOverflowAlignment(RenderStyle::initialAlignItemsOverflowAlignment());
555     }
556 }
557
558 inline void StyleBuilderCustom::applyInheritJustifySelf(StyleResolver& styleResolver)
559 {
560     styleResolver.style()->setJustifySelf(styleResolver.parentStyle()->justifySelf());
561     styleResolver.style()->setJustifySelfOverflowAlignment(styleResolver.parentStyle()->justifySelfOverflowAlignment());
562 }
563
564 inline void StyleBuilderCustom::applyInitialJustifySelf(StyleResolver& styleResolver)
565 {
566     styleResolver.style()->setJustifySelf(RenderStyle::initialJustifySelf());
567     styleResolver.style()->setJustifySelfOverflowAlignment(RenderStyle::initialJustifySelfOverflowAlignment());
568 }
569
570 inline void StyleBuilderCustom::applyValueJustifySelf(StyleResolver& styleResolver, CSSValue& value)
571 {
572     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
573     if (Pair* pairValue = primitiveValue.getPairValue()) {
574         styleResolver.style()->setJustifySelf(*pairValue->first());
575         styleResolver.style()->setJustifySelfOverflowAlignment(*pairValue->second());
576     } else {
577         styleResolver.style()->setJustifySelf(primitiveValue);
578         styleResolver.style()->setJustifySelfOverflowAlignment(RenderStyle::initialJustifySelfOverflowAlignment());
579     }
580 }
581
582 inline void StyleBuilderCustom::applyInheritJustifyItems(StyleResolver& styleResolver)
583 {
584     styleResolver.style()->setJustifyItems(styleResolver.parentStyle()->justifyItems());
585     styleResolver.style()->setJustifyItemsOverflowAlignment(styleResolver.parentStyle()->justifyItemsOverflowAlignment());
586     styleResolver.style()->setJustifyItemsPositionType(styleResolver.parentStyle()->justifyItemsPositionType());
587 }
588
589 inline void StyleBuilderCustom::applyInitialJustifyItems(StyleResolver& styleResolver)
590 {
591     styleResolver.style()->setJustifyItems(RenderStyle::initialJustifyItems());
592     styleResolver.style()->setJustifyItemsOverflowAlignment(RenderStyle::initialJustifyItemsOverflowAlignment());
593     styleResolver.style()->setJustifyItemsPositionType(RenderStyle::initialJustifyItemsPositionType());
594 }
595
596 inline void StyleBuilderCustom::applyValueJustifyItems(StyleResolver& styleResolver, CSSValue& value)
597 {
598     styleResolver.style()->setJustifyItems(RenderStyle::initialJustifyItems());
599     styleResolver.style()->setJustifyItemsOverflowAlignment(RenderStyle::initialJustifyItemsOverflowAlignment());
600     styleResolver.style()->setJustifyItemsPositionType(RenderStyle::initialJustifyItemsPositionType());
601
602     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
603     if (Pair* pairValue = primitiveValue.getPairValue()) {
604         if (pairValue->first()->getValueID() == CSSValueLegacy) {
605             styleResolver.style()->setJustifyItemsPositionType(LegacyPosition);
606             styleResolver.style()->setJustifyItems(*pairValue->second());
607         } else {
608             styleResolver.style()->setJustifyItems(*pairValue->first());
609             styleResolver.style()->setJustifyItemsOverflowAlignment(*pairValue->second());
610         }
611     } else
612         styleResolver.style()->setJustifyItems(primitiveValue);
613 }
614
615 enum BorderImageType { BorderImage, WebkitMaskBoxImage };
616 enum BorderImageModifierType { Outset, Repeat, Slice, Width };
617 template <BorderImageType type, BorderImageModifierType modifier>
618 class ApplyPropertyBorderImageModifier {
619 public:
620     static void applyInheritValue(StyleResolver& styleResolver)
621     {
622         NinePieceImage image(getValue(styleResolver.style()));
623         switch (modifier) {
624         case Outset:
625             image.copyOutsetFrom(getValue(styleResolver.parentStyle()));
626             break;
627         case Repeat:
628             image.copyRepeatFrom(getValue(styleResolver.parentStyle()));
629             break;
630         case Slice:
631             image.copyImageSlicesFrom(getValue(styleResolver.parentStyle()));
632             break;
633         case Width:
634             image.copyBorderSlicesFrom(getValue(styleResolver.parentStyle()));
635             break;
636         }
637         setValue(styleResolver.style(), image);
638     }
639
640     static void applyInitialValue(StyleResolver& styleResolver)
641     {
642         NinePieceImage image(getValue(styleResolver.style()));
643         switch (modifier) {
644         case Outset:
645             image.setOutset(LengthBox(0));
646             break;
647         case Repeat:
648             image.setHorizontalRule(StretchImageRule);
649             image.setVerticalRule(StretchImageRule);
650             break;
651         case Slice:
652             // Masks have a different initial value for slices. Preserve the value of 0 for backwards compatibility.
653             image.setImageSlices(type == BorderImage ? LengthBox(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent)) : LengthBox());
654             image.setFill(false);
655             break;
656         case Width:
657             // Masks have a different initial value for widths. They use an 'auto' value rather than trying to fit to the border.
658             image.setBorderSlices(type == BorderImage ? LengthBox(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative)) : LengthBox());
659             break;
660         }
661         setValue(styleResolver.style(), image);
662     }
663
664     static void applyValue(StyleResolver& styleResolver, CSSValue& value)
665     {
666         NinePieceImage image(getValue(styleResolver.style()));
667         switch (modifier) {
668         case Outset:
669             image.setOutset(styleResolver.styleMap()->mapNinePieceImageQuad(value));
670             break;
671         case Repeat:
672             styleResolver.styleMap()->mapNinePieceImageRepeat(value, image);
673             break;
674         case Slice:
675             styleResolver.styleMap()->mapNinePieceImageSlice(value, image);
676             break;
677         case Width:
678             image.setBorderSlices(styleResolver.styleMap()->mapNinePieceImageQuad(value));
679             break;
680         }
681         setValue(styleResolver.style(), image);
682     }
683
684 private:
685     static const NinePieceImage& getValue(RenderStyle* style)
686     {
687         return type == BorderImage ? style->borderImage() : style->maskBoxImage();
688     }
689
690     static void setValue(RenderStyle* style, const NinePieceImage& value)
691     {
692         return type == BorderImage ? style->setBorderImage(value) : style->setMaskBoxImage(value);
693     }
694 };
695
696 #define DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(type, modifier) \
697 inline void StyleBuilderCustom::applyInherit##type##modifier(StyleResolver& styleResolver) \
698 { \
699     ApplyPropertyBorderImageModifier<type, modifier>::applyInheritValue(styleResolver); \
700 } \
701 inline void StyleBuilderCustom::applyInitial##type##modifier(StyleResolver& styleResolver) \
702 { \
703     ApplyPropertyBorderImageModifier<type, modifier>::applyInitialValue(styleResolver); \
704 } \
705 inline void StyleBuilderCustom::applyValue##type##modifier(StyleResolver& styleResolver, CSSValue& value) \
706 { \
707     ApplyPropertyBorderImageModifier<type, modifier>::applyValue(styleResolver, value); \
708 }
709
710 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(BorderImage, Outset)
711 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(BorderImage, Repeat)
712 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(BorderImage, Slice)
713 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(BorderImage, Width)
714 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(WebkitMaskBoxImage, Outset)
715 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(WebkitMaskBoxImage, Repeat)
716 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(WebkitMaskBoxImage, Slice)
717 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(WebkitMaskBoxImage, Width)
718
719 #if ENABLE(IOS_TEXT_AUTOSIZING)
720
721 inline void StyleBuilderCustom::applyInheritLineHeight(StyleResolver& styleResolver)
722 {
723     styleResolver.style()->setLineHeight(styleResolver.parentStyle()->lineHeight());
724     styleResolver.style()->setSpecifiedLineHeight(styleResolver.parentStyle()->specifiedLineHeight());
725 }
726
727 inline void StyleBuilderCustom::applyInitialLineHeight(StyleResolver& styleResolver)
728 {
729     styleResolver.style()->setLineHeight(RenderStyle::initialLineHeight());
730     styleResolver.style()->setSpecifiedLineHeight(RenderStyle::initialSpecifiedLineHeight());
731 }
732
733 inline void StyleBuilderCustom::applyValueLineHeight(StyleResolver& styleResolver, CSSValue& value)
734 {
735     float multiplier = styleResolver.style()->textSizeAdjust().isPercentage() ? styleResolver.style()->textSizeAdjust().multiplier() : 1.f;
736     Optional<Length> lineHeight = StyleBuilderConverter::convertLineHeight(styleResolver, value, multiplier);
737     if (!lineHeight)
738         return;
739
740     styleResolver.style()->setLineHeight(lineHeight.value());
741     styleResolver.style()->setSpecifiedLineHeight(lineHeight.value());
742 }
743
744 #endif
745
746 inline void StyleBuilderCustom::applyInheritOutlineStyle(StyleResolver& styleResolver)
747 {
748     styleResolver.style()->setOutlineStyleIsAuto(styleResolver.parentStyle()->outlineStyleIsAuto());
749     styleResolver.style()->setOutlineStyle(styleResolver.parentStyle()->outlineStyle());
750 }
751
752 inline void StyleBuilderCustom::applyInitialOutlineStyle(StyleResolver& styleResolver)
753 {
754     styleResolver.style()->setOutlineStyleIsAuto(RenderStyle::initialOutlineStyleIsAuto());
755     styleResolver.style()->setOutlineStyle(RenderStyle::initialBorderStyle());
756 }
757
758 inline void StyleBuilderCustom::applyValueOutlineStyle(StyleResolver& styleResolver, CSSValue& value)
759 {
760     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
761
762     styleResolver.style()->setOutlineStyleIsAuto(primitiveValue);
763     styleResolver.style()->setOutlineStyle(primitiveValue);
764 }
765
766 inline void StyleBuilderCustom::applyInitialClip(StyleResolver& styleResolver)
767 {
768     styleResolver.style()->setClip(Length(), Length(), Length(), Length());
769     styleResolver.style()->setHasClip(false);
770 }
771
772 inline void StyleBuilderCustom::applyInheritClip(StyleResolver& styleResolver)
773 {
774     RenderStyle* parentStyle = styleResolver.parentStyle();
775     if (!parentStyle->hasClip())
776         return applyInitialClip(styleResolver);
777     styleResolver.style()->setClip(parentStyle->clipTop(), parentStyle->clipRight(), parentStyle->clipBottom(), parentStyle->clipLeft());
778     styleResolver.style()->setHasClip(true);
779 }
780
781 inline void StyleBuilderCustom::applyValueClip(StyleResolver& styleResolver, CSSValue& value)
782 {
783     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
784
785     if (Rect* rect = primitiveValue.getRectValue()) {
786         auto conversionData = styleResolver.state().cssToLengthConversionData();
787         Length top = rect->top()->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(conversionData);
788         Length right = rect->right()->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(conversionData);
789         Length bottom = rect->bottom()->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(conversionData);
790         Length left = rect->left()->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(conversionData);
791         styleResolver.style()->setClip(top, right, bottom, left);
792         styleResolver.style()->setHasClip(true);
793     } else {
794         ASSERT(primitiveValue.getValueID() == CSSValueAuto);
795         applyInitialClip(styleResolver);
796     }
797 }
798
799 inline void StyleBuilderCustom::applyValueWebkitLocale(StyleResolver& styleResolver, CSSValue& value)
800 {
801     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
802
803     if (primitiveValue.getValueID() == CSSValueAuto)
804         styleResolver.style()->setLocale(nullAtom);
805     else
806         styleResolver.style()->setLocale(primitiveValue.getStringValue());
807     
808     FontDescription fontDescription = styleResolver.style()->fontDescription();
809     fontDescription.setScript(localeToScriptCodeForFontSelection(styleResolver.style()->locale()));
810     styleResolver.setFontDescription(fontDescription);
811 }
812
813 inline void StyleBuilderCustom::applyValueWebkitWritingMode(StyleResolver& styleResolver, CSSValue& value)
814 {
815     styleResolver.setWritingMode(downcast<CSSPrimitiveValue>(value));
816
817     // FIXME: It is not ok to modify document state while applying style.
818     auto& state = styleResolver.state();
819     if (state.element() && state.element() == state.document().documentElement())
820         state.document().setWritingModeSetOnDocumentElement(true);
821 }
822
823 inline void StyleBuilderCustom::applyValueWebkitTextOrientation(StyleResolver& styleResolver, CSSValue& value)
824 {
825     styleResolver.setTextOrientation(downcast<CSSPrimitiveValue>(value));
826 }
827
828 #if ENABLE(IOS_TEXT_AUTOSIZING)
829 inline void StyleBuilderCustom::applyValueWebkitTextSizeAdjust(StyleResolver& styleResolver, CSSValue& value)
830 {
831     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
832     if (primitiveValue.getValueID() == CSSValueAuto)
833         styleResolver.style()->setTextSizeAdjust(TextSizeAdjustment(AutoTextSizeAdjustment));
834     else if (primitiveValue.getValueID() == CSSValueNone)
835         styleResolver.style()->setTextSizeAdjust(TextSizeAdjustment(NoTextSizeAdjustment));
836     else
837         styleResolver.style()->setTextSizeAdjust(TextSizeAdjustment(primitiveValue.getFloatValue()));
838
839     styleResolver.state().setFontDirty(true);
840 }
841 #endif
842
843 template <CSSPropertyID id>
844 inline void StyleBuilderCustom::applyTextOrBoxShadowValue(StyleResolver& styleResolver, CSSValue& value)
845 {
846     if (is<CSSPrimitiveValue>(value)) {
847         ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNone);
848         if (id == CSSPropertyTextShadow)
849             styleResolver.style()->setTextShadow(nullptr);
850         else
851             styleResolver.style()->setBoxShadow(nullptr);
852         return;
853     }
854
855     bool isFirstEntry = true;
856     for (auto& item : downcast<CSSValueList>(value)) {
857         auto& shadowValue = downcast<CSSShadowValue>(item.get());
858         auto conversionData = styleResolver.state().cssToLengthConversionData();
859         int x = shadowValue.x->computeLength<int>(conversionData);
860         int y = shadowValue.y->computeLength<int>(conversionData);
861         int blur = shadowValue.blur ? shadowValue.blur->computeLength<int>(conversionData) : 0;
862         int spread = shadowValue.spread ? shadowValue.spread->computeLength<int>(conversionData) : 0;
863         ShadowStyle shadowStyle = shadowValue.style && shadowValue.style->getValueID() == CSSValueInset ? Inset : Normal;
864         Color color;
865         if (shadowValue.color)
866             color = styleResolver.colorFromPrimitiveValue(*shadowValue.color);
867         else
868             color = styleResolver.style()->color();
869         auto shadowData = std::make_unique<ShadowData>(IntPoint(x, y), blur, spread, shadowStyle, id == CSSPropertyWebkitBoxShadow, color.isValid() ? color : Color::transparent);
870         if (id == CSSPropertyTextShadow)
871             styleResolver.style()->setTextShadow(WTF::move(shadowData), !isFirstEntry); // add to the list if this is not the first entry
872         else
873             styleResolver.style()->setBoxShadow(WTF::move(shadowData), !isFirstEntry); // add to the list if this is not the first entry
874         isFirstEntry = false;
875     }
876 }
877
878 inline void StyleBuilderCustom::applyInitialTextShadow(StyleResolver& styleResolver)
879 {
880     styleResolver.style()->setTextShadow(nullptr);
881 }
882
883 inline void StyleBuilderCustom::applyInheritTextShadow(StyleResolver& styleResolver)
884 {
885     styleResolver.style()->setTextShadow(styleResolver.parentStyle()->textShadow() ? std::make_unique<ShadowData>(*styleResolver.parentStyle()->textShadow()) : nullptr);
886 }
887
888 inline void StyleBuilderCustom::applyValueTextShadow(StyleResolver& styleResolver, CSSValue& value)
889 {
890     applyTextOrBoxShadowValue<CSSPropertyTextShadow>(styleResolver, value);
891 }
892
893 inline void StyleBuilderCustom::applyInitialBoxShadow(StyleResolver& styleResolver)
894 {
895     styleResolver.style()->setBoxShadow(nullptr);
896 }
897
898 inline void StyleBuilderCustom::applyInheritBoxShadow(StyleResolver& styleResolver)
899 {
900     styleResolver.style()->setBoxShadow(styleResolver.parentStyle()->boxShadow() ? std::make_unique<ShadowData>(*styleResolver.parentStyle()->boxShadow()) : nullptr);
901 }
902
903 inline void StyleBuilderCustom::applyValueBoxShadow(StyleResolver& styleResolver, CSSValue& value)
904 {
905     applyTextOrBoxShadowValue<CSSPropertyBoxShadow>(styleResolver, value);
906 }
907
908 inline void StyleBuilderCustom::applyInitialWebkitBoxShadow(StyleResolver& styleResolver)
909 {
910     applyInitialBoxShadow(styleResolver);
911 }
912
913 inline void StyleBuilderCustom::applyInheritWebkitBoxShadow(StyleResolver& styleResolver)
914 {
915     applyInheritBoxShadow(styleResolver);
916 }
917
918 inline void StyleBuilderCustom::applyValueWebkitBoxShadow(StyleResolver& styleResolver, CSSValue& value)
919 {
920     applyTextOrBoxShadowValue<CSSPropertyWebkitBoxShadow>(styleResolver, value);
921 }
922
923 inline void StyleBuilderCustom::applyInitialFontFamily(StyleResolver& styleResolver)
924 {
925     FontDescription fontDescription = styleResolver.style()->fontDescription();
926     FontDescription initialDesc = FontDescription();
927
928     // We need to adjust the size to account for the generic family change from monospace to non-monospace.
929     if (fontDescription.useFixedDefaultSize()) {
930         if (CSSValueID sizeIdentifier = fontDescription.keywordSizeAsIdentifier())
931             styleResolver.setFontSize(fontDescription, Style::fontSizeForKeyword(sizeIdentifier, false, styleResolver.document()));
932     }
933     if (!initialDesc.firstFamily().isEmpty())
934         fontDescription.setFamilies(initialDesc.families());
935
936     styleResolver.setFontDescription(fontDescription);
937 }
938
939 inline void StyleBuilderCustom::applyInheritFontFamily(StyleResolver& styleResolver)
940 {
941     FontDescription fontDescription = styleResolver.style()->fontDescription();
942     FontDescription parentFontDescription = styleResolver.parentStyle()->fontDescription();
943
944     fontDescription.setFamilies(parentFontDescription.families());
945     fontDescription.setIsSpecifiedFont(parentFontDescription.isSpecifiedFont());
946     styleResolver.setFontDescription(fontDescription);
947 }
948
949 inline void StyleBuilderCustom::applyValueFontFamily(StyleResolver& styleResolver, CSSValue& value)
950 {
951     auto& valueList = downcast<CSSValueList>(value);
952
953     FontDescription fontDescription = styleResolver.style()->fontDescription();
954     // Before mapping in a new font-family property, we should reset the generic family.
955     bool oldFamilyUsedFixedDefaultSize = fontDescription.useFixedDefaultSize();
956
957     Vector<AtomicString> families;
958     families.reserveInitialCapacity(valueList.length());
959
960     for (auto& item : valueList) {
961         auto& contentValue = downcast<CSSPrimitiveValue>(item.get());
962         AtomicString family;
963         bool isGenericFamily = false;
964         if (contentValue.isFontFamily()) {
965             const CSSFontFamily& fontFamily = contentValue.fontFamily();
966             family = fontFamily.familyName;
967             // If the family name was resolved by the CSS parser from a system font ID, then it is generic.
968             isGenericFamily = fontFamily.fromSystemFontID;
969         } else {
970             switch (contentValue.getValueID()) {
971             case CSSValueWebkitBody:
972                 if (Settings* settings = styleResolver.document().settings())
973                     family = settings->standardFontFamily();
974                 break;
975             case CSSValueSerif:
976                 family = serifFamily;
977                 isGenericFamily = true;
978                 break;
979             case CSSValueSansSerif:
980                 family = sansSerifFamily;
981                 isGenericFamily = true;
982                 break;
983             case CSSValueCursive:
984                 family = cursiveFamily;
985                 isGenericFamily = true;
986                 break;
987             case CSSValueFantasy:
988                 family = fantasyFamily;
989                 isGenericFamily = true;
990                 break;
991             case CSSValueMonospace:
992                 family = monospaceFamily;
993                 isGenericFamily = true;
994                 break;
995             case CSSValueWebkitPictograph:
996                 family = pictographFamily;
997                 isGenericFamily = true;
998                 break;
999             default:
1000                 break;
1001             }
1002         }
1003
1004         if (family.isEmpty())
1005             continue;
1006         if (families.isEmpty())
1007             fontDescription.setIsSpecifiedFont(!isGenericFamily);
1008         families.uncheckedAppend(family);
1009     }
1010
1011     if (families.isEmpty())
1012         return;
1013     fontDescription.setFamilies(families);
1014
1015     if (fontDescription.useFixedDefaultSize() != oldFamilyUsedFixedDefaultSize) {
1016         if (CSSValueID sizeIdentifier = fontDescription.keywordSizeAsIdentifier())
1017             styleResolver.setFontSize(fontDescription, Style::fontSizeForKeyword(sizeIdentifier, !oldFamilyUsedFixedDefaultSize, styleResolver.document()));
1018     }
1019
1020     styleResolver.setFontDescription(fontDescription);
1021 }
1022
1023 inline bool StyleBuilderCustom::isValidDisplayValue(StyleResolver& styleResolver, EDisplay display)
1024 {
1025     if (is<SVGElement>(styleResolver.element()) && styleResolver.style()->styleType() == NOPSEUDO)
1026         return display == INLINE || display == BLOCK || display == NONE;
1027     return true;
1028 }
1029
1030 inline void StyleBuilderCustom::applyInheritDisplay(StyleResolver& styleResolver)
1031 {
1032     EDisplay display = styleResolver.parentStyle()->display();
1033     if (isValidDisplayValue(styleResolver, display))
1034         styleResolver.style()->setDisplay(display);
1035 }
1036
1037 inline void StyleBuilderCustom::applyValueDisplay(StyleResolver& styleResolver, CSSValue& value)
1038 {
1039     EDisplay display = downcast<CSSPrimitiveValue>(value);
1040     if (isValidDisplayValue(styleResolver, display))
1041         styleResolver.style()->setDisplay(display);
1042 }
1043
1044 inline void StyleBuilderCustom::applyValueBaselineShift(StyleResolver& styleResolver, CSSValue& value)
1045 {
1046     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1047     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1048     if (primitiveValue.isValueID()) {
1049         switch (primitiveValue.getValueID()) {
1050         case CSSValueBaseline:
1051             svgStyle.setBaselineShift(BS_BASELINE);
1052             break;
1053         case CSSValueSub:
1054             svgStyle.setBaselineShift(BS_SUB);
1055             break;
1056         case CSSValueSuper:
1057             svgStyle.setBaselineShift(BS_SUPER);
1058             break;
1059         default:
1060             break;
1061         }
1062     } else {
1063         svgStyle.setBaselineShift(BS_LENGTH);
1064         svgStyle.setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
1065     }
1066 }
1067
1068 inline void StyleBuilderCustom::applyInitialWebkitAspectRatio(StyleResolver& styleResolver)
1069 {
1070     styleResolver.style()->setAspectRatioType(RenderStyle::initialAspectRatioType());
1071     styleResolver.style()->setAspectRatioDenominator(RenderStyle::initialAspectRatioDenominator());
1072     styleResolver.style()->setAspectRatioNumerator(RenderStyle::initialAspectRatioNumerator());
1073 }
1074
1075 inline void StyleBuilderCustom::applyInheritWebkitAspectRatio(StyleResolver& styleResolver)
1076 {
1077     if (styleResolver.parentStyle()->aspectRatioType() == AspectRatioAuto)
1078         return;
1079     styleResolver.style()->setAspectRatioType(styleResolver.parentStyle()->aspectRatioType());
1080     styleResolver.style()->setAspectRatioDenominator(styleResolver.parentStyle()->aspectRatioDenominator());
1081     styleResolver.style()->setAspectRatioNumerator(styleResolver.parentStyle()->aspectRatioNumerator());
1082 }
1083
1084 inline void StyleBuilderCustom::applyValueWebkitAspectRatio(StyleResolver& styleResolver, CSSValue& value)
1085 {
1086     if (is<CSSPrimitiveValue>(value)) {
1087         auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1088
1089         if (primitiveValue.getValueID() == CSSValueFromDimensions)
1090             return styleResolver.style()->setAspectRatioType(AspectRatioFromDimensions);
1091         if (primitiveValue.getValueID() == CSSValueFromIntrinsic)
1092             return styleResolver.style()->setAspectRatioType(AspectRatioFromIntrinsic);
1093
1094         ASSERT(primitiveValue.getValueID() == CSSValueAuto);
1095         return styleResolver.style()->setAspectRatioType(AspectRatioAuto);
1096     }
1097
1098     auto& aspectRatioValue = downcast<CSSAspectRatioValue>(value);
1099     styleResolver.style()->setAspectRatioType(AspectRatioSpecified);
1100     styleResolver.style()->setAspectRatioDenominator(aspectRatioValue.denominatorValue());
1101     styleResolver.style()->setAspectRatioNumerator(aspectRatioValue.numeratorValue());
1102 }
1103
1104 inline void StyleBuilderCustom::applyInitialWebkitTextEmphasisStyle(StyleResolver& styleResolver)
1105 {
1106     styleResolver.style()->setTextEmphasisFill(RenderStyle::initialTextEmphasisFill());
1107     styleResolver.style()->setTextEmphasisMark(RenderStyle::initialTextEmphasisMark());
1108     styleResolver.style()->setTextEmphasisCustomMark(RenderStyle::initialTextEmphasisCustomMark());
1109 }
1110
1111 inline void StyleBuilderCustom::applyInheritWebkitTextEmphasisStyle(StyleResolver& styleResolver)
1112 {
1113     styleResolver.style()->setTextEmphasisFill(styleResolver.parentStyle()->textEmphasisFill());
1114     styleResolver.style()->setTextEmphasisMark(styleResolver.parentStyle()->textEmphasisMark());
1115     styleResolver.style()->setTextEmphasisCustomMark(styleResolver.parentStyle()->textEmphasisCustomMark());
1116 }
1117
1118 inline void StyleBuilderCustom::applyValueWebkitTextEmphasisStyle(StyleResolver& styleResolver, CSSValue& value)
1119 {
1120     if (is<CSSValueList>(value)) {
1121         auto& list = downcast<CSSValueList>(value);
1122         ASSERT(list.length() == 2);
1123
1124         for (auto& item : list) {
1125             CSSPrimitiveValue& value = downcast<CSSPrimitiveValue>(item.get());
1126             if (value.getValueID() == CSSValueFilled || value.getValueID() == CSSValueOpen)
1127                 styleResolver.style()->setTextEmphasisFill(value);
1128             else
1129                 styleResolver.style()->setTextEmphasisMark(value);
1130         }
1131         styleResolver.style()->setTextEmphasisCustomMark(nullAtom);
1132         return;
1133     }
1134
1135     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1136     if (primitiveValue.isString()) {
1137         styleResolver.style()->setTextEmphasisFill(TextEmphasisFillFilled);
1138         styleResolver.style()->setTextEmphasisMark(TextEmphasisMarkCustom);
1139         styleResolver.style()->setTextEmphasisCustomMark(primitiveValue.getStringValue());
1140         return;
1141     }
1142
1143     styleResolver.style()->setTextEmphasisCustomMark(nullAtom);
1144
1145     if (primitiveValue.getValueID() == CSSValueFilled || primitiveValue.getValueID() == CSSValueOpen) {
1146         styleResolver.style()->setTextEmphasisFill(primitiveValue);
1147         styleResolver.style()->setTextEmphasisMark(TextEmphasisMarkAuto);
1148     } else {
1149         styleResolver.style()->setTextEmphasisFill(TextEmphasisFillFilled);
1150         styleResolver.style()->setTextEmphasisMark(primitiveValue);
1151     }
1152 }
1153
1154 template <StyleBuilderCustom::CounterBehavior counterBehavior>
1155 inline void StyleBuilderCustom::applyInheritCounter(StyleResolver& styleResolver)
1156 {
1157     CounterDirectiveMap& map = styleResolver.style()->accessCounterDirectives();
1158     for (auto& keyValue : styleResolver.parentStyle()->accessCounterDirectives()) {
1159         CounterDirectives& directives = map.add(keyValue.key, CounterDirectives()).iterator->value;
1160         if (counterBehavior == Reset)
1161             directives.inheritReset(keyValue.value);
1162         else
1163             directives.inheritIncrement(keyValue.value);
1164     }
1165 }
1166
1167 template <StyleBuilderCustom::CounterBehavior counterBehavior>
1168 inline void StyleBuilderCustom::applyValueCounter(StyleResolver& styleResolver, CSSValue& value)
1169 {
1170     bool setCounterIncrementToNone = counterBehavior == Increment && is<CSSPrimitiveValue>(value) && downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNone;
1171
1172     if (!is<CSSValueList>(value) && !setCounterIncrementToNone)
1173         return;
1174
1175     CounterDirectiveMap& map = styleResolver.style()->accessCounterDirectives();
1176     for (auto& keyValue : map) {
1177         if (counterBehavior == Reset)
1178             keyValue.value.clearReset();
1179         else
1180             keyValue.value.clearIncrement();
1181     }
1182
1183     if (setCounterIncrementToNone)
1184         return;
1185
1186     for (auto& item : downcast<CSSValueList>(value)) {
1187         Pair* pair = downcast<CSSPrimitiveValue>(item.get()).getPairValue();
1188         if (!pair || !pair->first() || !pair->second())
1189             continue;
1190
1191         AtomicString identifier = pair->first()->getStringValue();
1192         int value = pair->second()->getIntValue();
1193         CounterDirectives& directives = map.add(identifier, CounterDirectives()).iterator->value;
1194         if (counterBehavior == Reset)
1195             directives.setResetValue(value);
1196         else
1197             directives.addIncrementValue(value);
1198     }
1199 }
1200
1201 inline void StyleBuilderCustom::applyInitialCounterIncrement(StyleResolver&) { }
1202
1203 inline void StyleBuilderCustom::applyInheritCounterIncrement(StyleResolver& styleResolver)
1204 {
1205     applyInheritCounter<Increment>(styleResolver);
1206 }
1207
1208 inline void StyleBuilderCustom::applyValueCounterIncrement(StyleResolver& styleResolver, CSSValue& value)
1209 {
1210     applyValueCounter<Increment>(styleResolver, value);
1211 }
1212
1213 inline void StyleBuilderCustom::applyInitialCounterReset(StyleResolver&) { }
1214
1215 inline void StyleBuilderCustom::applyInheritCounterReset(StyleResolver& styleResolver)
1216 {
1217     applyInheritCounter<Reset>(styleResolver);
1218 }
1219
1220 inline void StyleBuilderCustom::applyValueCounterReset(StyleResolver& styleResolver, CSSValue& value)
1221 {
1222     applyValueCounter<Reset>(styleResolver, value);
1223 }
1224
1225 inline void StyleBuilderCustom::applyInitialCursor(StyleResolver& styleResolver)
1226 {
1227     styleResolver.style()->clearCursorList();
1228     styleResolver.style()->setCursor(RenderStyle::initialCursor());
1229 }
1230
1231 inline void StyleBuilderCustom::applyInheritCursor(StyleResolver& styleResolver)
1232 {
1233     styleResolver.style()->setCursor(styleResolver.parentStyle()->cursor());
1234     styleResolver.style()->setCursorList(styleResolver.parentStyle()->cursors());
1235 }
1236
1237 inline void StyleBuilderCustom::applyValueCursor(StyleResolver& styleResolver, CSSValue& value)
1238 {
1239     styleResolver.style()->clearCursorList();
1240     if (is<CSSPrimitiveValue>(value)) {
1241         ECursor cursor = downcast<CSSPrimitiveValue>(value);
1242         if (styleResolver.style()->cursor() != cursor)
1243             styleResolver.style()->setCursor(cursor);
1244         return;
1245     }
1246
1247     styleResolver.style()->setCursor(CursorAuto);
1248     auto& list = downcast<CSSValueList>(value);
1249     for (auto& item : list) {
1250         if (is<CSSCursorImageValue>(item.get())) {
1251             auto& image = downcast<CSSCursorImageValue>(item.get());
1252             if (image.updateIfSVGCursorIsUsed(styleResolver.element())) // Elements with SVG cursors are not allowed to share style.
1253                 styleResolver.style()->setUnique();
1254             styleResolver.style()->addCursor(styleResolver.styleImage(CSSPropertyCursor, image), image.hotSpot());
1255             continue;
1256         }
1257
1258         styleResolver.style()->setCursor(downcast<CSSPrimitiveValue>(item.get()));
1259         ASSERT_WITH_MESSAGE(item.ptr() == list.item(list.length() - 1), "Cursor ID fallback should always be last in the list");
1260         return;
1261     }
1262 }
1263
1264 inline void StyleBuilderCustom::applyInitialFill(StyleResolver& styleResolver)
1265 {
1266     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1267     svgStyle.setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1268 }
1269
1270 inline void StyleBuilderCustom::applyInheritFill(StyleResolver& styleResolver)
1271 {
1272     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1273     const SVGRenderStyle& svgParentStyle = styleResolver.parentStyle()->svgStyle();
1274     svgStyle.setFillPaint(svgParentStyle.fillPaintType(), svgParentStyle.fillPaintColor(), svgParentStyle.fillPaintUri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1275
1276 }
1277
1278 inline void StyleBuilderCustom::applyValueFill(StyleResolver& styleResolver, CSSValue& value)
1279 {
1280     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1281     SVGPaint& svgPaint = downcast<SVGPaint>(value);
1282     svgStyle.setFillPaint(svgPaint.paintType(), StyleBuilderConverter::convertSVGColor(styleResolver, svgPaint), svgPaint.uri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1283 }
1284
1285 inline void StyleBuilderCustom::applyInitialStroke(StyleResolver& styleResolver)
1286 {
1287     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1288     svgStyle.setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1289 }
1290
1291 inline void StyleBuilderCustom::applyInheritStroke(StyleResolver& styleResolver)
1292 {
1293     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1294     const SVGRenderStyle& svgParentStyle = styleResolver.parentStyle()->svgStyle();
1295     svgStyle.setStrokePaint(svgParentStyle.strokePaintType(), svgParentStyle.strokePaintColor(), svgParentStyle.strokePaintUri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1296 }
1297
1298 inline void StyleBuilderCustom::applyValueStroke(StyleResolver& styleResolver, CSSValue& value)
1299 {
1300     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1301     SVGPaint& svgPaint = downcast<SVGPaint>(value);
1302     svgStyle.setStrokePaint(svgPaint.paintType(), StyleBuilderConverter::convertSVGColor(styleResolver, svgPaint), svgPaint.uri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1303 }
1304
1305 inline void StyleBuilderCustom::applyInitialWebkitSvgShadow(StyleResolver& styleResolver)
1306 {
1307     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1308     svgStyle.setShadow(nullptr);
1309 }
1310
1311 inline void StyleBuilderCustom::applyInheritWebkitSvgShadow(StyleResolver& styleResolver)
1312 {
1313     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1314     const SVGRenderStyle& svgParentStyle = styleResolver.parentStyle()->svgStyle();
1315     svgStyle.setShadow(svgParentStyle.shadow() ? std::make_unique<ShadowData>(*svgParentStyle.shadow()) : nullptr);
1316 }
1317
1318 inline void StyleBuilderCustom::applyValueWebkitSvgShadow(StyleResolver& styleResolver, CSSValue& value)
1319 {
1320     SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1321     if (is<CSSPrimitiveValue>(value)) {
1322         ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNone);
1323         svgStyle.setShadow(nullptr);
1324         return;
1325     }
1326
1327     auto& shadowValue = downcast<CSSShadowValue>(*downcast<CSSValueList>(value).itemWithoutBoundsCheck(0));
1328     IntPoint location(shadowValue.x->computeLength<int>(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f)),
1329         shadowValue.y->computeLength<int>(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f)));
1330     int blur = shadowValue.blur ? shadowValue.blur->computeLength<int>(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f)) : 0;
1331     Color color;
1332     if (shadowValue.color)
1333         color = styleResolver.colorFromPrimitiveValue(*shadowValue.color);
1334
1335     // -webkit-svg-shadow does should not have a spread or style
1336     ASSERT(!shadowValue.spread);
1337     ASSERT(!shadowValue.style);
1338
1339     svgStyle.setShadow(std::make_unique<ShadowData>(location, blur, 0, Normal, false, color.isValid() ? color : Color::transparent));
1340 }
1341
1342 inline void StyleBuilderCustom::applyInitialFontWeight(StyleResolver& styleResolver)
1343 {
1344     FontDescription fontDescription = styleResolver.fontDescription();
1345     fontDescription.setWeight(FontWeightNormal);
1346     styleResolver.setFontDescription(fontDescription);
1347 }
1348
1349 inline void StyleBuilderCustom::applyInheritFontWeight(StyleResolver& styleResolver)
1350 {
1351     FontDescription fontDescription = styleResolver.fontDescription();
1352     fontDescription.setWeight(styleResolver.parentFontDescription().weight());
1353     styleResolver.setFontDescription(fontDescription);
1354 }
1355
1356 inline void StyleBuilderCustom::applyValueFontWeight(StyleResolver& styleResolver, CSSValue& value)
1357 {
1358     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1359     FontDescription fontDescription = styleResolver.fontDescription();
1360     switch (primitiveValue.getValueID()) {
1361     case CSSValueInvalid:
1362         ASSERT_NOT_REACHED();
1363         break;
1364     case CSSValueBolder:
1365         fontDescription.setWeight(styleResolver.parentStyle()->fontDescription().weight());
1366         fontDescription.setWeight(fontDescription.bolderWeight());
1367         break;
1368     case CSSValueLighter:
1369         fontDescription.setWeight(styleResolver.parentStyle()->fontDescription().weight());
1370         fontDescription.setWeight(fontDescription.lighterWeight());
1371         break;
1372     default:
1373         fontDescription.setWeight(primitiveValue);
1374     }
1375     styleResolver.setFontDescription(fontDescription);
1376 }
1377
1378 inline void StyleBuilderCustom::applyInitialColumnGap(StyleResolver& styleResolver)
1379 {
1380     styleResolver.style()->setHasNormalColumnGap();
1381 }
1382
1383 inline void StyleBuilderCustom::applyInheritColumnGap(StyleResolver& styleResolver)
1384 {
1385     if (styleResolver.parentStyle()->hasNormalColumnGap())
1386         styleResolver.style()->setHasNormalColumnGap();
1387     else
1388         styleResolver.style()->setColumnGap(styleResolver.parentStyle()->columnGap());
1389 }
1390
1391 inline void StyleBuilderCustom::applyValueColumnGap(StyleResolver& styleResolver, CSSValue& value)
1392 {
1393     if (downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNormal)
1394         styleResolver.style()->setHasNormalColumnGap();
1395     else
1396         styleResolver.style()->setColumnGap(StyleBuilderConverter::convertComputedLength<float>(styleResolver, value));
1397 }
1398
1399 inline void StyleBuilderCustom::applyInitialContent(StyleResolver& styleResolver)
1400 {
1401     styleResolver.style()->clearContent();
1402 }
1403
1404 inline void StyleBuilderCustom::applyInheritContent(StyleResolver&)
1405 {
1406     // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This
1407     // note is a reminder that eventually "inherit" needs to be supported.
1408 }
1409
1410 inline void StyleBuilderCustom::applyValueContent(StyleResolver& styleResolver, CSSValue& value)
1411 {
1412     bool didSet = false;
1413     for (auto& item : downcast<CSSValueList>(value)) {
1414         if (is<CSSImageGeneratorValue>(item.get())) {
1415             if (is<CSSGradientValue>(item.get()))
1416                 styleResolver.style()->setContent(StyleGeneratedImage::create(*downcast<CSSGradientValue>(item.get()).gradientWithStylesResolved(&styleResolver)), didSet);
1417             else
1418                 styleResolver.style()->setContent(StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(item.get())), didSet);
1419             didSet = true;
1420 #if ENABLE(CSS_IMAGE_SET)
1421         } else if (is<CSSImageSetValue>(item.get())) {
1422             styleResolver.style()->setContent(styleResolver.setOrPendingFromValue(CSSPropertyContent, downcast<CSSImageSetValue>(item.get())), didSet);
1423             didSet = true;
1424 #endif
1425         }
1426
1427         if (is<CSSImageValue>(item.get())) {
1428             styleResolver.style()->setContent(styleResolver.cachedOrPendingFromValue(CSSPropertyContent, downcast<CSSImageValue>(item.get())), didSet);
1429             didSet = true;
1430             continue;
1431         }
1432
1433         if (!is<CSSPrimitiveValue>(item.get()))
1434             continue;
1435
1436         auto& contentValue = downcast<CSSPrimitiveValue>(item.get());
1437         if (contentValue.isString()) {
1438             styleResolver.style()->setContent(contentValue.getStringValue().impl(), didSet);
1439             didSet = true;
1440         } else if (contentValue.isAttr()) {
1441             // FIXME: Can a namespace be specified for an attr(foo)?
1442             if (styleResolver.style()->styleType() == NOPSEUDO)
1443                 styleResolver.style()->setUnique();
1444             else
1445                 styleResolver.parentStyle()->setUnique();
1446             QualifiedName attr(nullAtom, contentValue.getStringValue().impl(), nullAtom);
1447             const AtomicString& value = styleResolver.element()->getAttribute(attr);
1448             styleResolver.style()->setContent(value.isNull() ? emptyAtom : value.impl(), didSet);
1449             didSet = true;
1450             // Register the fact that the attribute value affects the style.
1451             styleResolver.ruleSets().features().attributeCanonicalLocalNamesInRules.add(attr.localName().impl());
1452             styleResolver.ruleSets().features().attributeLocalNamesInRules.add(attr.localName().impl());
1453         } else if (contentValue.isCounter()) {
1454             Counter* counterValue = contentValue.getCounterValue();
1455             EListStyleType listStyleType = NoneListStyle;
1456             CSSValueID listStyleIdent = counterValue->listStyleIdent();
1457             if (listStyleIdent != CSSValueNone)
1458                 listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
1459             auto counter = std::make_unique<CounterContent>(counterValue->identifier(), listStyleType, counterValue->separator());
1460             styleResolver.style()->setContent(WTF::move(counter), didSet);
1461             didSet = true;
1462         } else {
1463             switch (contentValue.getValueID()) {
1464             case CSSValueOpenQuote:
1465                 styleResolver.style()->setContent(OPEN_QUOTE, didSet);
1466                 didSet = true;
1467                 break;
1468             case CSSValueCloseQuote:
1469                 styleResolver.style()->setContent(CLOSE_QUOTE, didSet);
1470                 didSet = true;
1471                 break;
1472             case CSSValueNoOpenQuote:
1473                 styleResolver.style()->setContent(NO_OPEN_QUOTE, didSet);
1474                 didSet = true;
1475                 break;
1476             case CSSValueNoCloseQuote:
1477                 styleResolver.style()->setContent(NO_CLOSE_QUOTE, didSet);
1478                 didSet = true;
1479                 break;
1480             default:
1481                 // normal and none do not have any effect.
1482                 break;
1483             }
1484         }
1485     }
1486     if (!didSet)
1487         styleResolver.style()->clearContent();
1488 }
1489
1490 inline void StyleBuilderCustom::applyInitialWebkitFontVariantLigatures(StyleResolver& styleResolver)
1491 {
1492     FontDescription fontDescription = styleResolver.fontDescription();
1493
1494     fontDescription.setCommonLigaturesState(FontDescription::NormalLigaturesState);
1495     fontDescription.setDiscretionaryLigaturesState(FontDescription::NormalLigaturesState);
1496     fontDescription.setHistoricalLigaturesState(FontDescription::NormalLigaturesState);
1497
1498     styleResolver.setFontDescription(fontDescription);
1499 }
1500
1501 inline void StyleBuilderCustom::applyInheritWebkitFontVariantLigatures(StyleResolver& styleResolver)
1502 {
1503     const FontDescription& parentFontDescription = styleResolver.parentFontDescription();
1504     FontDescription fontDescription = styleResolver.fontDescription();
1505
1506     fontDescription.setCommonLigaturesState(parentFontDescription.commonLigaturesState());
1507     fontDescription.setDiscretionaryLigaturesState(parentFontDescription.discretionaryLigaturesState());
1508     fontDescription.setHistoricalLigaturesState(parentFontDescription.historicalLigaturesState());
1509
1510     styleResolver.setFontDescription(fontDescription);
1511 }
1512
1513 inline void StyleBuilderCustom::applyValueWebkitFontVariantLigatures(StyleResolver& styleResolver, CSSValue& value)
1514 {
1515     FontDescription::LigaturesState commonLigaturesState = FontDescription::NormalLigaturesState;
1516     FontDescription::LigaturesState discretionaryLigaturesState = FontDescription::NormalLigaturesState;
1517     FontDescription::LigaturesState historicalLigaturesState = FontDescription::NormalLigaturesState;
1518
1519     if (is<CSSValueList>(value)) {
1520         for (auto& item : downcast<CSSValueList>(value)) {
1521             switch (downcast<CSSPrimitiveValue>(item.get()).getValueID()) {
1522             case CSSValueNoCommonLigatures:
1523                 commonLigaturesState = FontDescription::DisabledLigaturesState;
1524                 break;
1525             case CSSValueCommonLigatures:
1526                 commonLigaturesState = FontDescription::EnabledLigaturesState;
1527                 break;
1528             case CSSValueNoDiscretionaryLigatures:
1529                 discretionaryLigaturesState = FontDescription::DisabledLigaturesState;
1530                 break;
1531             case CSSValueDiscretionaryLigatures:
1532                 discretionaryLigaturesState = FontDescription::EnabledLigaturesState;
1533                 break;
1534             case CSSValueNoHistoricalLigatures:
1535                 historicalLigaturesState = FontDescription::DisabledLigaturesState;
1536                 break;
1537             case CSSValueHistoricalLigatures:
1538                 historicalLigaturesState = FontDescription::EnabledLigaturesState;
1539                 break;
1540             default:
1541                 ASSERT_NOT_REACHED();
1542                 break;
1543             }
1544         }
1545     } else
1546         ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNormal);
1547
1548     FontDescription fontDescription = styleResolver.fontDescription();
1549     fontDescription.setCommonLigaturesState(commonLigaturesState);
1550     fontDescription.setDiscretionaryLigaturesState(discretionaryLigaturesState);
1551     fontDescription.setHistoricalLigaturesState(historicalLigaturesState);
1552     styleResolver.setFontDescription(fontDescription);
1553 }
1554
1555 inline void StyleBuilderCustom::applyInitialFontSize(StyleResolver& styleResolver)
1556 {
1557     FontDescription fontDescription = styleResolver.style()->fontDescription();
1558     float size = Style::fontSizeForKeyword(CSSValueMedium, fontDescription.useFixedDefaultSize(), styleResolver.document());
1559
1560     if (size < 0)
1561         return;
1562
1563     fontDescription.setKeywordSizeFromIdentifier(CSSValueMedium);
1564     styleResolver.setFontSize(fontDescription, size);
1565     styleResolver.setFontDescription(fontDescription);
1566 }
1567
1568 inline void StyleBuilderCustom::applyInheritFontSize(StyleResolver& styleResolver)
1569 {
1570     const FontDescription& parentFontDescription = styleResolver.parentStyle()->fontDescription();
1571     float size = parentFontDescription.specifiedSize();
1572
1573     if (size < 0)
1574         return;
1575
1576     FontDescription fontDescription = styleResolver.style()->fontDescription();
1577     fontDescription.setKeywordSize(parentFontDescription.keywordSize());
1578     styleResolver.setFontSize(fontDescription, size);
1579     styleResolver.setFontDescription(fontDescription);
1580 }
1581
1582 // When the CSS keyword "larger" is used, this function will attempt to match within the keyword
1583 // table, and failing that, will simply multiply by 1.2.
1584 inline float StyleBuilderCustom::largerFontSize(float size)
1585 {
1586     // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale up to
1587     // the next size level.
1588     return size * 1.2f;
1589 }
1590
1591 // Like the previous function, but for the keyword "smaller".
1592 inline float StyleBuilderCustom::smallerFontSize(float size)
1593 {
1594     // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale down to
1595     // the next size level.
1596     return size / 1.2f;
1597 }
1598
1599 inline float StyleBuilderCustom::determineRubyTextSizeMultiplier(StyleResolver& styleResolver)
1600 {
1601     if (styleResolver.style()->rubyPosition() != RubyPositionInterCharacter)
1602         return 0.5f;
1603
1604     // FIXME: This hack is to ensure tone marks are the same size as
1605     // the bopomofo. This code will go away if we make a special renderer
1606     // for the tone marks eventually.
1607     if (auto* element = styleResolver.state().element()) {
1608         for (auto& ancestor : ancestorsOfType<HTMLElement>(*element)) {
1609             if (ancestor.hasTagName(HTMLNames::rtTag))
1610                 return 1.0f;
1611         }
1612     }
1613     return 0.25f;
1614 }
1615
1616 inline void StyleBuilderCustom::applyValueFontSize(StyleResolver& styleResolver, CSSValue& value)
1617 {
1618     FontDescription fontDescription = styleResolver.style()->fontDescription();
1619     fontDescription.setKeywordSizeFromIdentifier(CSSValueInvalid);
1620
1621     float parentSize = 0;
1622     bool parentIsAbsoluteSize = false;
1623     if (auto* parentStyle = styleResolver.parentStyle()) {
1624         parentSize = parentStyle->fontDescription().specifiedSize();
1625         parentIsAbsoluteSize = parentStyle->fontDescription().isAbsoluteSize();
1626     }
1627
1628     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1629     float size;
1630     if (CSSValueID ident = primitiveValue.getValueID()) {
1631         fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize && (ident == CSSValueLarger || ident == CSSValueSmaller || ident == CSSValueWebkitRubyText));
1632
1633         // Keywords are being used.
1634         switch (ident) {
1635         case CSSValueXxSmall:
1636         case CSSValueXSmall:
1637         case CSSValueSmall:
1638         case CSSValueMedium:
1639         case CSSValueLarge:
1640         case CSSValueXLarge:
1641         case CSSValueXxLarge:
1642         case CSSValueWebkitXxxLarge:
1643             size = Style::fontSizeForKeyword(ident, fontDescription.useFixedDefaultSize(), styleResolver.document());
1644             fontDescription.setKeywordSizeFromIdentifier(ident);
1645             break;
1646         case CSSValueLarger:
1647             size = largerFontSize(parentSize);
1648             break;
1649         case CSSValueSmaller:
1650             size = smallerFontSize(parentSize);
1651             break;
1652         case CSSValueWebkitRubyText:
1653             size = determineRubyTextSizeMultiplier(styleResolver) * parentSize;
1654             break;
1655         default:
1656             return;
1657         }
1658     } else {
1659         fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize || !(primitiveValue.isPercentage() || primitiveValue.isFontRelativeLength()));
1660         if (primitiveValue.isLength()) {
1661             size = primitiveValue.computeLength<float>(CSSToLengthConversionData(styleResolver.parentStyle(), styleResolver.rootElementStyle(), styleResolver.document().renderView(), 1.0f, true));
1662             styleResolver.state().setFontSizeHasViewportUnits(primitiveValue.isViewportPercentageLength());
1663         } else if (primitiveValue.isPercentage())
1664             size = (primitiveValue.getFloatValue() * parentSize) / 100.0f;
1665         else if (primitiveValue.isCalculatedPercentageWithLength())
1666             size = primitiveValue.cssCalcValue()->createCalculationValue(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f))->evaluate(parentSize);
1667         else
1668             return;
1669     }
1670
1671     if (size < 0)
1672         return;
1673
1674     styleResolver.setFontSize(fontDescription, std::min(maximumAllowedFontSize, size));
1675     styleResolver.setFontDescription(fontDescription);
1676 }
1677
1678 #if ENABLE(CSS_GRID_LAYOUT)
1679 inline void StyleBuilderCustom::applyInitialWebkitGridTemplateAreas(StyleResolver& styleResolver)
1680 {
1681     styleResolver.style()->setNamedGridArea(RenderStyle::initialNamedGridArea());
1682     styleResolver.style()->setNamedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount());
1683     styleResolver.style()->setNamedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount());
1684 }
1685
1686 inline void StyleBuilderCustom::applyInheritWebkitGridTemplateAreas(StyleResolver& styleResolver)
1687 {
1688     styleResolver.style()->setNamedGridArea(styleResolver.parentStyle()->namedGridArea());
1689     styleResolver.style()->setNamedGridAreaRowCount(styleResolver.parentStyle()->namedGridAreaRowCount());
1690     styleResolver.style()->setNamedGridAreaColumnCount(styleResolver.parentStyle()->namedGridAreaColumnCount());
1691 }
1692
1693 inline void StyleBuilderCustom::applyValueWebkitGridTemplateAreas(StyleResolver& styleResolver, CSSValue& value)
1694 {
1695     if (is<CSSPrimitiveValue>(value)) {
1696         ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNone);
1697         return;
1698     }
1699
1700     auto& gridTemplateAreasValue = downcast<CSSGridTemplateAreasValue>(value);
1701     const NamedGridAreaMap& newNamedGridAreas = gridTemplateAreasValue.gridAreaMap();
1702
1703     NamedGridLinesMap namedGridColumnLines = styleResolver.style()->namedGridColumnLines();
1704     NamedGridLinesMap namedGridRowLines = styleResolver.style()->namedGridRowLines();
1705     StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridColumnLines, ForColumns);
1706     StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridRowLines, ForRows);
1707     styleResolver.style()->setNamedGridColumnLines(namedGridColumnLines);
1708     styleResolver.style()->setNamedGridRowLines(namedGridRowLines);
1709
1710     styleResolver.style()->setNamedGridArea(gridTemplateAreasValue.gridAreaMap());
1711     styleResolver.style()->setNamedGridAreaRowCount(gridTemplateAreasValue.rowCount());
1712     styleResolver.style()->setNamedGridAreaColumnCount(gridTemplateAreasValue.columnCount());
1713 }
1714
1715 inline void StyleBuilderCustom::applyInitialWebkitGridTemplateColumns(StyleResolver& styleResolver)
1716 {
1717     styleResolver.style()->setGridColumns(RenderStyle::initialGridColumns());
1718     styleResolver.style()->setNamedGridColumnLines(RenderStyle::initialNamedGridColumnLines());
1719     styleResolver.style()->setOrderedNamedGridColumnLines(RenderStyle::initialOrderedNamedGridColumnLines());
1720 }
1721
1722 inline void StyleBuilderCustom::applyInheritWebkitGridTemplateColumns(StyleResolver& styleResolver)
1723 {
1724     styleResolver.style()->setGridColumns(styleResolver.parentStyle()->gridColumns());
1725     styleResolver.style()->setNamedGridColumnLines(styleResolver.parentStyle()->namedGridColumnLines());
1726     styleResolver.style()->setOrderedNamedGridColumnLines(styleResolver.parentStyle()->orderedNamedGridColumnLines());
1727 }
1728
1729 inline void StyleBuilderCustom::applyValueWebkitGridTemplateColumns(StyleResolver& styleResolver, CSSValue& value)
1730 {
1731     Vector<GridTrackSize> trackSizes;
1732     NamedGridLinesMap namedGridLines;
1733     OrderedNamedGridLinesMap orderedNamedGridLines;
1734     if (!StyleBuilderConverter::createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, styleResolver))
1735         return;
1736     const NamedGridAreaMap& namedGridAreas = styleResolver.style()->namedGridArea();
1737     if (!namedGridAreas.isEmpty())
1738         StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(namedGridAreas, namedGridLines, ForColumns);
1739
1740     styleResolver.style()->setGridColumns(trackSizes);
1741     styleResolver.style()->setNamedGridColumnLines(namedGridLines);
1742     styleResolver.style()->setOrderedNamedGridColumnLines(orderedNamedGridLines);
1743 }
1744
1745 inline void StyleBuilderCustom::applyInitialWebkitGridTemplateRows(StyleResolver& styleResolver)
1746 {
1747     styleResolver.style()->setGridRows(RenderStyle::initialGridRows());
1748     styleResolver.style()->setNamedGridRowLines(RenderStyle::initialNamedGridRowLines());
1749     styleResolver.style()->setOrderedNamedGridRowLines(RenderStyle::initialOrderedNamedGridRowLines());
1750 }
1751
1752 inline void StyleBuilderCustom::applyInheritWebkitGridTemplateRows(StyleResolver& styleResolver)
1753 {
1754     styleResolver.style()->setGridRows(styleResolver.parentStyle()->gridRows());
1755     styleResolver.style()->setNamedGridRowLines(styleResolver.parentStyle()->namedGridRowLines());
1756     styleResolver.style()->setOrderedNamedGridRowLines(styleResolver.parentStyle()->orderedNamedGridRowLines());
1757 }
1758
1759 inline void StyleBuilderCustom::applyValueWebkitGridTemplateRows(StyleResolver& styleResolver, CSSValue& value)
1760 {
1761     Vector<GridTrackSize> trackSizes;
1762     NamedGridLinesMap namedGridLines;
1763     OrderedNamedGridLinesMap orderedNamedGridLines;
1764     if (!StyleBuilderConverter::createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, styleResolver))
1765         return;
1766     const NamedGridAreaMap& namedGridAreas = styleResolver.style()->namedGridArea();
1767     if (!namedGridAreas.isEmpty())
1768         StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(namedGridAreas, namedGridLines, ForRows);
1769
1770     styleResolver.style()->setGridRows(trackSizes);
1771     styleResolver.style()->setNamedGridRowLines(namedGridLines);
1772     styleResolver.style()->setOrderedNamedGridRowLines(orderedNamedGridLines);
1773 }
1774 #endif // ENABLE(CSS_GRID_LAYOUT)
1775
1776 void StyleBuilderCustom::applyValueAlt(StyleResolver& styleResolver, CSSValue& value)
1777 {
1778     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1779     if (primitiveValue.isString())
1780         styleResolver.style()->setContentAltText(primitiveValue.getStringValue());
1781     else if (primitiveValue.isAttr()) {
1782         // FIXME: Can a namespace be specified for an attr(foo)?
1783         if (styleResolver.style()->styleType() == NOPSEUDO)
1784             styleResolver.style()->setUnique();
1785         else
1786             styleResolver.parentStyle()->setUnique();
1787
1788         QualifiedName attr(nullAtom, primitiveValue.getStringValue(), nullAtom);
1789         const AtomicString& value = styleResolver.element()->getAttribute(attr);
1790         styleResolver.style()->setContentAltText(value.isNull() ? emptyAtom : value);
1791
1792         // Register the fact that the attribute value affects the style.
1793         styleResolver.ruleSets().features().attributeCanonicalLocalNamesInRules.add(attr.localName().impl());
1794         styleResolver.ruleSets().features().attributeLocalNamesInRules.add(attr.localName().impl());
1795     } else
1796         styleResolver.style()->setContentAltText(emptyAtom);
1797 }
1798
1799 #if ENABLE(CSS_SCROLL_SNAP)
1800 inline void StyleBuilderCustom::applyInitialWebkitScrollSnapPointsX(StyleResolver& styleResolver)
1801 {
1802     styleResolver.style()->setScrollSnapPointsX(nullptr);
1803 }
1804
1805 inline void StyleBuilderCustom::applyInheritWebkitScrollSnapPointsX(StyleResolver& styleResolver)
1806 {
1807     styleResolver.style()->setScrollSnapPointsX(styleResolver.parentStyle()->scrollSnapPointsX() ? std::make_unique<ScrollSnapPoints>(*styleResolver.parentStyle()->scrollSnapPointsX()) : nullptr);
1808 }
1809
1810 inline void StyleBuilderCustom::applyInitialWebkitScrollSnapPointsY(StyleResolver& styleResolver)
1811 {
1812     styleResolver.style()->setScrollSnapPointsY(nullptr);
1813 }
1814
1815 inline void StyleBuilderCustom::applyInheritWebkitScrollSnapPointsY(StyleResolver& styleResolver)
1816 {
1817     styleResolver.style()->setScrollSnapPointsY(styleResolver.parentStyle()->scrollSnapPointsY() ? std::make_unique<ScrollSnapPoints>(*styleResolver.parentStyle()->scrollSnapPointsY()) : nullptr);
1818 }
1819 #endif
1820
1821 } // namespace WebCore
1822
1823 #endif // StyleBuilderCustom_h