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