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