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