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