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