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