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