2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * Copyright (C) 2014 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
27 #ifndef StyleBuilderCustom_h
28 #define StyleBuilderCustom_h
30 #include "CSSAspectRatioValue.h"
31 #include "CSSCursorImageValue.h"
32 #include "CSSFontFamily.h"
33 #include "CSSFontValue.h"
34 #include "CSSGradientValue.h"
35 #include "CSSShadowValue.h"
37 #include "CounterContent.h"
38 #include "CursorList.h"
39 #include "DashboardRegion.h"
40 #include "ElementAncestorIterator.h"
42 #include "HTMLElement.h"
43 #include "LocaleToScriptMapping.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 #include "WillChangeData.h"
56 #define DECLARE_PROPERTY_CUSTOM_HANDLERS(property) \
57 static void applyInherit##property(StyleResolver&); \
58 static void applyInitial##property(StyleResolver&); \
59 static void applyValue##property(StyleResolver&, CSSValue&)
61 // Note that we assume the CSS parser only allows valid CSSValue types.
62 class StyleBuilderCustom {
64 // Custom handling of inherit, initial and value setting.
65 DECLARE_PROPERTY_CUSTOM_HANDLERS(BorderImageOutset);
66 DECLARE_PROPERTY_CUSTOM_HANDLERS(BorderImageRepeat);
67 DECLARE_PROPERTY_CUSTOM_HANDLERS(BorderImageSlice);
68 DECLARE_PROPERTY_CUSTOM_HANDLERS(BorderImageWidth);
69 DECLARE_PROPERTY_CUSTOM_HANDLERS(BoxShadow);
70 DECLARE_PROPERTY_CUSTOM_HANDLERS(Clip);
71 DECLARE_PROPERTY_CUSTOM_HANDLERS(ColumnGap);
72 DECLARE_PROPERTY_CUSTOM_HANDLERS(Content);
73 DECLARE_PROPERTY_CUSTOM_HANDLERS(CounterIncrement);
74 DECLARE_PROPERTY_CUSTOM_HANDLERS(CounterReset);
75 DECLARE_PROPERTY_CUSTOM_HANDLERS(Cursor);
76 DECLARE_PROPERTY_CUSTOM_HANDLERS(Fill);
77 DECLARE_PROPERTY_CUSTOM_HANDLERS(FontFamily);
78 DECLARE_PROPERTY_CUSTOM_HANDLERS(FontSize);
79 DECLARE_PROPERTY_CUSTOM_HANDLERS(FontWeight);
80 #if ENABLE(CSS_IMAGE_RESOLUTION)
81 DECLARE_PROPERTY_CUSTOM_HANDLERS(ImageResolution);
83 #if ENABLE(IOS_TEXT_AUTOSIZING)
84 DECLARE_PROPERTY_CUSTOM_HANDLERS(LineHeight);
86 DECLARE_PROPERTY_CUSTOM_HANDLERS(OutlineStyle);
87 DECLARE_PROPERTY_CUSTOM_HANDLERS(Size);
88 DECLARE_PROPERTY_CUSTOM_HANDLERS(Stroke);
89 DECLARE_PROPERTY_CUSTOM_HANDLERS(TextIndent);
90 DECLARE_PROPERTY_CUSTOM_HANDLERS(TextShadow);
91 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitAspectRatio);
92 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitBoxShadow);
93 DECLARE_PROPERTY_CUSTOM_HANDLERS(FontVariantLigatures);
94 DECLARE_PROPERTY_CUSTOM_HANDLERS(FontVariantNumeric);
95 DECLARE_PROPERTY_CUSTOM_HANDLERS(FontVariantEastAsian);
96 #if ENABLE(CSS_GRID_LAYOUT)
97 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitGridTemplateAreas);
98 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitGridTemplateColumns);
99 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitGridTemplateRows);
100 #endif // ENABLE(CSS_GRID_LAYOUT)
101 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitMaskBoxImageOutset);
102 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitMaskBoxImageRepeat);
103 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitMaskBoxImageSlice);
104 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitMaskBoxImageWidth);
105 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitSvgShadow);
106 DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitTextEmphasisStyle);
107 DECLARE_PROPERTY_CUSTOM_HANDLERS(Zoom);
109 // Custom handling of initial + inherit value setting only.
110 static void applyInitialWebkitMaskImage(StyleResolver&) { }
111 static void applyInheritWebkitMaskImage(StyleResolver&) { }
112 static void applyInitialFontFeatureSettings(StyleResolver&) { }
113 static void applyInheritFontFeatureSettings(StyleResolver&) { }
115 // Custom handling of inherit + value setting only.
116 static void applyInheritDisplay(StyleResolver&);
117 static void applyValueDisplay(StyleResolver&, CSSValue&);
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&);
126 static void applyValueWebkitLocale(StyleResolver&, CSSValue&);
127 static void applyValueWebkitTextOrientation(StyleResolver&, CSSValue&);
128 #if ENABLE(IOS_TEXT_AUTOSIZING)
129 static void applyValueWebkitTextSizeAdjust(StyleResolver&, CSSValue&);
131 static void applyValueWebkitTextZoom(StyleResolver&, CSSValue&);
132 static void applyValueWebkitWritingMode(StyleResolver&, CSSValue&);
133 static void applyValueAlt(StyleResolver&, CSSValue&);
134 #if ENABLE(CSS_SCROLL_SNAP)
135 static void applyInitialWebkitScrollSnapPointsX(StyleResolver&);
136 static void applyInheritWebkitScrollSnapPointsX(StyleResolver&);
137 static void applyInitialWebkitScrollSnapPointsY(StyleResolver&);
138 static void applyInheritWebkitScrollSnapPointsY(StyleResolver&);
140 static void applyValueWillChange(StyleResolver&, CSSValue&);
143 static void resetEffectiveZoom(StyleResolver&);
145 static Length mmLength(double mm);
146 static Length inchLength(double inch);
147 static bool getPageSizeFromName(CSSPrimitiveValue* pageSizeName, CSSPrimitiveValue* pageOrientation, Length& width, Length& height);
149 template <CSSPropertyID id>
150 static void applyTextOrBoxShadowValue(StyleResolver&, CSSValue&);
151 static bool isValidDisplayValue(StyleResolver&, EDisplay);
153 enum CounterBehavior {Increment = 0, Reset};
154 template <CounterBehavior counterBehavior>
155 static void applyInheritCounter(StyleResolver&);
156 template <CounterBehavior counterBehavior>
157 static void applyValueCounter(StyleResolver&, CSSValue&);
159 static float largerFontSize(float size);
160 static float smallerFontSize(float size);
161 static float determineRubyTextSizeMultiplier(StyleResolver&);
164 inline void StyleBuilderCustom::applyValueDirection(StyleResolver& styleResolver, CSSValue& value)
166 styleResolver.style()->setDirection(downcast<CSSPrimitiveValue>(value));
168 Element* element = styleResolver.element();
169 if (element && styleResolver.element() == element->document().documentElement())
170 element->document().setDirectionSetOnDocumentElement(true);
173 inline void StyleBuilderCustom::resetEffectiveZoom(StyleResolver& styleResolver)
175 // Reset the zoom in effect. This allows the setZoom method to accurately compute a new zoom in effect.
176 styleResolver.setEffectiveZoom(styleResolver.parentStyle() ? styleResolver.parentStyle()->effectiveZoom() : RenderStyle::initialZoom());
179 inline void StyleBuilderCustom::applyInitialZoom(StyleResolver& styleResolver)
181 resetEffectiveZoom(styleResolver);
182 styleResolver.setZoom(RenderStyle::initialZoom());
185 inline void StyleBuilderCustom::applyInheritZoom(StyleResolver& styleResolver)
187 resetEffectiveZoom(styleResolver);
188 styleResolver.setZoom(styleResolver.parentStyle()->zoom());
191 inline void StyleBuilderCustom::applyValueZoom(StyleResolver& styleResolver, CSSValue& value)
193 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
195 if (primitiveValue.getValueID() == CSSValueNormal) {
196 resetEffectiveZoom(styleResolver);
197 styleResolver.setZoom(RenderStyle::initialZoom());
198 } else if (primitiveValue.getValueID() == CSSValueReset) {
199 styleResolver.setEffectiveZoom(RenderStyle::initialZoom());
200 styleResolver.setZoom(RenderStyle::initialZoom());
201 } else if (primitiveValue.getValueID() == CSSValueDocument) {
202 float docZoom = styleResolver.rootElementStyle() ? styleResolver.rootElementStyle()->zoom() : RenderStyle::initialZoom();
203 styleResolver.setEffectiveZoom(docZoom);
204 styleResolver.setZoom(docZoom);
205 } else if (primitiveValue.isPercentage()) {
206 resetEffectiveZoom(styleResolver);
207 if (float percent = primitiveValue.getFloatValue())
208 styleResolver.setZoom(percent / 100.0f);
209 } else if (primitiveValue.isNumber()) {
210 resetEffectiveZoom(styleResolver);
211 if (float number = primitiveValue.getFloatValue())
212 styleResolver.setZoom(number);
215 inline Length StyleBuilderCustom::mmLength(double mm)
217 Ref<CSSPrimitiveValue> value(CSSPrimitiveValue::create(mm, CSSPrimitiveValue::CSS_MM));
218 return value.get().computeLength<Length>(CSSToLengthConversionData());
220 inline Length StyleBuilderCustom::inchLength(double inch)
222 Ref<CSSPrimitiveValue> value(CSSPrimitiveValue::create(inch, CSSPrimitiveValue::CSS_IN));
223 return value.get().computeLength<Length>(CSSToLengthConversionData());
225 bool StyleBuilderCustom::getPageSizeFromName(CSSPrimitiveValue* pageSizeName, CSSPrimitiveValue* pageOrientation, Length& width, Length& height)
227 static NeverDestroyed<Length> a5Width(mmLength(148));
228 static NeverDestroyed<Length> a5Height(mmLength(210));
229 static NeverDestroyed<Length> a4Width(mmLength(210));
230 static NeverDestroyed<Length> a4Height(mmLength(297));
231 static NeverDestroyed<Length> a3Width(mmLength(297));
232 static NeverDestroyed<Length> a3Height(mmLength(420));
233 static NeverDestroyed<Length> b5Width(mmLength(176));
234 static NeverDestroyed<Length> b5Height(mmLength(250));
235 static NeverDestroyed<Length> b4Width(mmLength(250));
236 static NeverDestroyed<Length> b4Height(mmLength(353));
237 static NeverDestroyed<Length> letterWidth(inchLength(8.5));
238 static NeverDestroyed<Length> letterHeight(inchLength(11));
239 static NeverDestroyed<Length> legalWidth(inchLength(8.5));
240 static NeverDestroyed<Length> legalHeight(inchLength(14));
241 static NeverDestroyed<Length> ledgerWidth(inchLength(11));
242 static NeverDestroyed<Length> ledgerHeight(inchLength(17));
247 switch (pageSizeName->getValueID()) {
270 height = letterHeight;
274 height = legalHeight;
278 height = ledgerHeight;
284 if (pageOrientation) {
285 switch (pageOrientation->getValueID()) {
286 case CSSValueLandscape:
287 std::swap(width, height);
289 case CSSValuePortrait:
299 inline void StyleBuilderCustom::applyValueVerticalAlign(StyleResolver& styleResolver, CSSValue& value)
301 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
302 if (primitiveValue.getValueID())
303 styleResolver.style()->setVerticalAlign(primitiveValue);
305 styleResolver.style()->setVerticalAlignLength(primitiveValue.convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion>(styleResolver.state().cssToLengthConversionData()));
308 #if ENABLE(DASHBOARD_SUPPORT)
309 static Length convertToIntLength(const CSSPrimitiveValue* primitiveValue, const CSSToLengthConversionData& conversionData)
311 return primitiveValue ? primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion>(conversionData) : Length(Undefined);
314 inline void StyleBuilderCustom::applyValueWebkitDashboardRegion(StyleResolver& styleResolver, CSSValue& value)
316 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
317 if (primitiveValue.getValueID() == CSSValueNone) {
318 styleResolver.style()->setDashboardRegions(RenderStyle::noneDashboardRegions());
322 DashboardRegion* region = primitiveValue.getDashboardRegionValue();
326 DashboardRegion* first = region;
328 Length top = convertToIntLength(region->top(), styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
329 Length right = convertToIntLength(region->right(), styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
330 Length bottom = convertToIntLength(region->bottom(), styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
331 Length left = convertToIntLength(region->left(), styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
333 if (top.isUndefined())
335 if (right.isUndefined())
337 if (bottom.isUndefined())
339 if (left.isUndefined())
342 if (region->m_isCircle)
343 styleResolver.style()->setDashboardRegion(StyleDashboardRegion::Circle, region->m_label, top, right, bottom, left, region == first ? false : true);
344 else if (region->m_isRectangle)
345 styleResolver.style()->setDashboardRegion(StyleDashboardRegion::Rectangle, region->m_label, top, right, bottom, left, region == first ? false : true);
346 region = region->m_next.get();
349 styleResolver.document().setHasAnnotatedRegions(true);
351 #endif // ENABLE(DASHBOARD_SUPPORT)
353 #if ENABLE(CSS_IMAGE_RESOLUTION)
354 inline void StyleBuilderCustom::applyInheritImageResolution(StyleResolver& styleResolver)
356 styleResolver.style()->setImageResolutionSource(styleResolver.parentStyle()->imageResolutionSource());
357 styleResolver.style()->setImageResolutionSnap(styleResolver.parentStyle()->imageResolutionSnap());
358 styleResolver.style()->setImageResolution(styleResolver.parentStyle()->imageResolution());
361 inline void StyleBuilderCustom::applyInitialImageResolution(StyleResolver& styleResolver)
363 styleResolver.style()->setImageResolutionSource(RenderStyle::initialImageResolutionSource());
364 styleResolver.style()->setImageResolutionSnap(RenderStyle::initialImageResolutionSnap());
365 styleResolver.style()->setImageResolution(RenderStyle::initialImageResolution());
368 inline void StyleBuilderCustom::applyValueImageResolution(StyleResolver& styleResolver, CSSValue& value)
370 ImageResolutionSource source = RenderStyle::initialImageResolutionSource();
371 ImageResolutionSnap snap = RenderStyle::initialImageResolutionSnap();
372 double resolution = RenderStyle::initialImageResolution();
373 for (auto& item : downcast<CSSValueList>(value)) {
374 CSSPrimitiveValue& primitiveValue = downcast<CSSPrimitiveValue>(item.get());
375 if (primitiveValue.getValueID() == CSSValueFromImage)
376 source = ImageResolutionFromImage;
377 else if (primitiveValue.getValueID() == CSSValueSnap)
378 snap = ImageResolutionSnapPixels;
380 resolution = primitiveValue.getDoubleValue(CSSPrimitiveValue::CSS_DPPX);
382 styleResolver.style()->setImageResolutionSource(source);
383 styleResolver.style()->setImageResolutionSnap(snap);
384 styleResolver.style()->setImageResolution(resolution);
386 #endif // ENABLE(CSS_IMAGE_RESOLUTION)
388 inline void StyleBuilderCustom::applyInheritSize(StyleResolver&) { }
389 inline void StyleBuilderCustom::applyInitialSize(StyleResolver&) { }
390 inline void StyleBuilderCustom::applyValueSize(StyleResolver& styleResolver, CSSValue& value)
392 styleResolver.style()->resetPageSizeType();
395 PageSizeType pageSizeType = PAGE_SIZE_AUTO;
396 if (!is<CSSValueList>(value))
399 auto& valueList = downcast<CSSValueList>(value);
400 switch (valueList.length()) {
402 CSSValue* firstValue = valueList.itemWithoutBoundsCheck(0);
403 CSSValue* secondValue = valueList.itemWithoutBoundsCheck(1);
404 // <length>{2} | <page-size> <orientation>
405 if (!is<CSSPrimitiveValue>(*firstValue) || !is<CSSPrimitiveValue>(*secondValue))
407 auto& firstPrimitiveValue = downcast<CSSPrimitiveValue>(*firstValue);
408 auto& secondPrimitiveValue = downcast<CSSPrimitiveValue>(*secondValue);
409 if (firstPrimitiveValue.isLength()) {
411 if (!secondPrimitiveValue.isLength())
413 CSSToLengthConversionData conversionData = styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f);
414 width = firstPrimitiveValue.computeLength<Length>(conversionData);
415 height = secondPrimitiveValue.computeLength<Length>(conversionData);
417 // <page-size> <orientation>
418 // The value order is guaranteed. See CSSParser::parseSizeParameter.
419 if (!getPageSizeFromName(&firstPrimitiveValue, &secondPrimitiveValue, width, height))
422 pageSizeType = PAGE_SIZE_RESOLVED;
426 CSSValue* value = valueList.itemWithoutBoundsCheck(0);
427 // <length> | auto | <page-size> | [ portrait | landscape]
428 if (!is<CSSPrimitiveValue>(*value))
430 auto& primitiveValue = downcast<CSSPrimitiveValue>(*value);
431 if (primitiveValue.isLength()) {
433 pageSizeType = PAGE_SIZE_RESOLVED;
434 width = height = primitiveValue.computeLength<Length>(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f));
436 switch (primitiveValue.getValueID()) {
440 pageSizeType = PAGE_SIZE_AUTO;
442 case CSSValuePortrait:
443 pageSizeType = PAGE_SIZE_AUTO_PORTRAIT;
445 case CSSValueLandscape:
446 pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE;
450 pageSizeType = PAGE_SIZE_RESOLVED;
451 if (!getPageSizeFromName(&primitiveValue, nullptr, width, height))
460 styleResolver.style()->setPageSizeType(pageSizeType);
461 styleResolver.style()->setPageSize(LengthSize(width, height));
464 inline void StyleBuilderCustom::applyInheritTextIndent(StyleResolver& styleResolver)
466 styleResolver.style()->setTextIndent(styleResolver.parentStyle()->textIndent());
467 #if ENABLE(CSS3_TEXT)
468 styleResolver.style()->setTextIndentLine(styleResolver.parentStyle()->textIndentLine());
469 styleResolver.style()->setTextIndentType(styleResolver.parentStyle()->textIndentType());
473 inline void StyleBuilderCustom::applyInitialTextIndent(StyleResolver& styleResolver)
475 styleResolver.style()->setTextIndent(RenderStyle::initialTextIndent());
476 #if ENABLE(CSS3_TEXT)
477 styleResolver.style()->setTextIndentLine(RenderStyle::initialTextIndentLine());
478 styleResolver.style()->setTextIndentType(RenderStyle::initialTextIndentType());
482 inline void StyleBuilderCustom::applyValueTextIndent(StyleResolver& styleResolver, CSSValue& value)
484 Length lengthOrPercentageValue;
485 #if ENABLE(CSS3_TEXT)
486 TextIndentLine textIndentLineValue = RenderStyle::initialTextIndentLine();
487 TextIndentType textIndentTypeValue = RenderStyle::initialTextIndentType();
489 for (auto& item : downcast<CSSValueList>(value)) {
490 auto& primitiveValue = downcast<CSSPrimitiveValue>(item.get());
491 if (!primitiveValue.getValueID())
492 lengthOrPercentageValue = primitiveValue.convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion>(styleResolver.state().cssToLengthConversionData());
493 #if ENABLE(CSS3_TEXT)
494 else if (primitiveValue.getValueID() == CSSValueWebkitEachLine)
495 textIndentLineValue = TextIndentEachLine;
496 else if (primitiveValue.getValueID() == CSSValueWebkitHanging)
497 textIndentTypeValue = TextIndentHanging;
501 if (lengthOrPercentageValue.isUndefined())
504 styleResolver.style()->setTextIndent(lengthOrPercentageValue);
505 #if ENABLE(CSS3_TEXT)
506 styleResolver.style()->setTextIndentLine(textIndentLineValue);
507 styleResolver.style()->setTextIndentType(textIndentTypeValue);
511 enum BorderImageType { BorderImage, WebkitMaskBoxImage };
512 enum BorderImageModifierType { Outset, Repeat, Slice, Width };
513 template <BorderImageType type, BorderImageModifierType modifier>
514 class ApplyPropertyBorderImageModifier {
516 static void applyInheritValue(StyleResolver& styleResolver)
518 NinePieceImage image(getValue(styleResolver.style()));
521 image.copyOutsetFrom(getValue(styleResolver.parentStyle()));
524 image.copyRepeatFrom(getValue(styleResolver.parentStyle()));
527 image.copyImageSlicesFrom(getValue(styleResolver.parentStyle()));
530 image.copyBorderSlicesFrom(getValue(styleResolver.parentStyle()));
533 setValue(styleResolver.style(), image);
536 static void applyInitialValue(StyleResolver& styleResolver)
538 NinePieceImage image(getValue(styleResolver.style()));
541 image.setOutset(LengthBox(0));
544 image.setHorizontalRule(StretchImageRule);
545 image.setVerticalRule(StretchImageRule);
548 // Masks have a different initial value for slices. Preserve the value of 0 for backwards compatibility.
549 image.setImageSlices(type == BorderImage ? LengthBox(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent)) : LengthBox());
550 image.setFill(false);
553 // Masks have a different initial value for widths. They use an 'auto' value rather than trying to fit to the border.
554 image.setBorderSlices(type == BorderImage ? LengthBox(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative)) : LengthBox());
557 setValue(styleResolver.style(), image);
560 static void applyValue(StyleResolver& styleResolver, CSSValue& value)
562 NinePieceImage image(getValue(styleResolver.style()));
565 image.setOutset(styleResolver.styleMap()->mapNinePieceImageQuad(value));
568 styleResolver.styleMap()->mapNinePieceImageRepeat(value, image);
571 styleResolver.styleMap()->mapNinePieceImageSlice(value, image);
574 image.setBorderSlices(styleResolver.styleMap()->mapNinePieceImageQuad(value));
577 setValue(styleResolver.style(), image);
581 static const NinePieceImage& getValue(RenderStyle* style)
583 return type == BorderImage ? style->borderImage() : style->maskBoxImage();
586 static void setValue(RenderStyle* style, const NinePieceImage& value)
588 return type == BorderImage ? style->setBorderImage(value) : style->setMaskBoxImage(value);
592 #define DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(type, modifier) \
593 inline void StyleBuilderCustom::applyInherit##type##modifier(StyleResolver& styleResolver) \
595 ApplyPropertyBorderImageModifier<type, modifier>::applyInheritValue(styleResolver); \
597 inline void StyleBuilderCustom::applyInitial##type##modifier(StyleResolver& styleResolver) \
599 ApplyPropertyBorderImageModifier<type, modifier>::applyInitialValue(styleResolver); \
601 inline void StyleBuilderCustom::applyValue##type##modifier(StyleResolver& styleResolver, CSSValue& value) \
603 ApplyPropertyBorderImageModifier<type, modifier>::applyValue(styleResolver, value); \
606 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(BorderImage, Outset)
607 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(BorderImage, Repeat)
608 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(BorderImage, Slice)
609 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(BorderImage, Width)
610 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(WebkitMaskBoxImage, Outset)
611 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(WebkitMaskBoxImage, Repeat)
612 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(WebkitMaskBoxImage, Slice)
613 DEFINE_BORDER_IMAGE_MODIFIER_HANDLER(WebkitMaskBoxImage, Width)
615 #if ENABLE(IOS_TEXT_AUTOSIZING)
617 inline void StyleBuilderCustom::applyInheritLineHeight(StyleResolver& styleResolver)
619 styleResolver.style()->setLineHeight(styleResolver.parentStyle()->lineHeight());
620 styleResolver.style()->setSpecifiedLineHeight(styleResolver.parentStyle()->specifiedLineHeight());
623 inline void StyleBuilderCustom::applyInitialLineHeight(StyleResolver& styleResolver)
625 styleResolver.style()->setLineHeight(RenderStyle::initialLineHeight());
626 styleResolver.style()->setSpecifiedLineHeight(RenderStyle::initialSpecifiedLineHeight());
629 inline void StyleBuilderCustom::applyValueLineHeight(StyleResolver& styleResolver, CSSValue& value)
631 float multiplier = styleResolver.style()->textSizeAdjust().isPercentage() ? styleResolver.style()->textSizeAdjust().multiplier() : 1.f;
632 Optional<Length> lineHeight = StyleBuilderConverter::convertLineHeight(styleResolver, value, multiplier);
636 styleResolver.style()->setLineHeight(lineHeight.value());
637 styleResolver.style()->setSpecifiedLineHeight(lineHeight.value());
642 inline void StyleBuilderCustom::applyInheritOutlineStyle(StyleResolver& styleResolver)
644 styleResolver.style()->setOutlineStyleIsAuto(styleResolver.parentStyle()->outlineStyleIsAuto());
645 styleResolver.style()->setOutlineStyle(styleResolver.parentStyle()->outlineStyle());
648 inline void StyleBuilderCustom::applyInitialOutlineStyle(StyleResolver& styleResolver)
650 styleResolver.style()->setOutlineStyleIsAuto(RenderStyle::initialOutlineStyleIsAuto());
651 styleResolver.style()->setOutlineStyle(RenderStyle::initialBorderStyle());
654 inline void StyleBuilderCustom::applyValueOutlineStyle(StyleResolver& styleResolver, CSSValue& value)
656 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
658 styleResolver.style()->setOutlineStyleIsAuto(primitiveValue);
659 styleResolver.style()->setOutlineStyle(primitiveValue);
662 inline void StyleBuilderCustom::applyInitialClip(StyleResolver& styleResolver)
664 styleResolver.style()->setClip(Length(), Length(), Length(), Length());
665 styleResolver.style()->setHasClip(false);
668 inline void StyleBuilderCustom::applyInheritClip(StyleResolver& styleResolver)
670 RenderStyle* parentStyle = styleResolver.parentStyle();
671 if (!parentStyle->hasClip())
672 return applyInitialClip(styleResolver);
673 styleResolver.style()->setClip(parentStyle->clipTop(), parentStyle->clipRight(), parentStyle->clipBottom(), parentStyle->clipLeft());
674 styleResolver.style()->setHasClip(true);
677 inline void StyleBuilderCustom::applyValueClip(StyleResolver& styleResolver, CSSValue& value)
679 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
681 if (Rect* rect = primitiveValue.getRectValue()) {
682 auto conversionData = styleResolver.state().cssToLengthConversionData();
683 Length top = rect->top()->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(conversionData);
684 Length right = rect->right()->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(conversionData);
685 Length bottom = rect->bottom()->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(conversionData);
686 Length left = rect->left()->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(conversionData);
687 styleResolver.style()->setClip(top, right, bottom, left);
688 styleResolver.style()->setHasClip(true);
690 ASSERT(primitiveValue.getValueID() == CSSValueAuto);
691 applyInitialClip(styleResolver);
695 inline void StyleBuilderCustom::applyValueWebkitLocale(StyleResolver& styleResolver, CSSValue& value)
697 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
698 if (primitiveValue.getValueID() == CSSValueAuto)
699 styleResolver.style()->setLocale(nullAtom);
701 styleResolver.style()->setLocale(primitiveValue.getStringValue());
703 FontCascadeDescription fontDescription = styleResolver.style()->fontDescription();
704 fontDescription.setScript(localeToScriptCodeForFontSelection(styleResolver.style()->locale()));
705 styleResolver.setFontDescription(fontDescription);
708 inline void StyleBuilderCustom::applyValueWebkitWritingMode(StyleResolver& styleResolver, CSSValue& value)
710 styleResolver.setWritingMode(downcast<CSSPrimitiveValue>(value));
712 // FIXME: It is not ok to modify document state while applying style.
713 auto& state = styleResolver.state();
714 if (state.element() && state.element() == state.document().documentElement())
715 state.document().setWritingModeSetOnDocumentElement(true);
718 inline void StyleBuilderCustom::applyValueWebkitTextOrientation(StyleResolver& styleResolver, CSSValue& value)
720 styleResolver.setTextOrientation(downcast<CSSPrimitiveValue>(value));
723 #if ENABLE(IOS_TEXT_AUTOSIZING)
724 inline void StyleBuilderCustom::applyValueWebkitTextSizeAdjust(StyleResolver& styleResolver, CSSValue& value)
726 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
727 if (primitiveValue.getValueID() == CSSValueAuto)
728 styleResolver.style()->setTextSizeAdjust(TextSizeAdjustment(AutoTextSizeAdjustment));
729 else if (primitiveValue.getValueID() == CSSValueNone)
730 styleResolver.style()->setTextSizeAdjust(TextSizeAdjustment(NoTextSizeAdjustment));
732 styleResolver.style()->setTextSizeAdjust(TextSizeAdjustment(primitiveValue.getFloatValue()));
734 styleResolver.state().setFontDirty(true);
738 inline void StyleBuilderCustom::applyValueWebkitTextZoom(StyleResolver& styleResolver, CSSValue& value)
740 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
741 if (primitiveValue.getValueID() == CSSValueNormal)
742 styleResolver.style()->setTextZoom(TextZoomNormal);
743 else if (primitiveValue.getValueID() == CSSValueReset)
744 styleResolver.style()->setTextZoom(TextZoomReset);
745 styleResolver.state().setFontDirty(true);
748 template <CSSPropertyID id>
749 inline void StyleBuilderCustom::applyTextOrBoxShadowValue(StyleResolver& styleResolver, CSSValue& value)
751 if (is<CSSPrimitiveValue>(value)) {
752 ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNone);
753 if (id == CSSPropertyTextShadow)
754 styleResolver.style()->setTextShadow(nullptr);
756 styleResolver.style()->setBoxShadow(nullptr);
760 bool isFirstEntry = true;
761 for (auto& item : downcast<CSSValueList>(value)) {
762 auto& shadowValue = downcast<CSSShadowValue>(item.get());
763 auto conversionData = styleResolver.state().cssToLengthConversionData();
764 int x = shadowValue.x->computeLength<int>(conversionData);
765 int y = shadowValue.y->computeLength<int>(conversionData);
766 int blur = shadowValue.blur ? shadowValue.blur->computeLength<int>(conversionData) : 0;
767 int spread = shadowValue.spread ? shadowValue.spread->computeLength<int>(conversionData) : 0;
768 ShadowStyle shadowStyle = shadowValue.style && shadowValue.style->getValueID() == CSSValueInset ? Inset : Normal;
770 if (shadowValue.color)
771 color = styleResolver.colorFromPrimitiveValue(*shadowValue.color);
773 color = styleResolver.style()->color();
774 auto shadowData = std::make_unique<ShadowData>(IntPoint(x, y), blur, spread, shadowStyle, id == CSSPropertyWebkitBoxShadow, color.isValid() ? color : Color::transparent);
775 if (id == CSSPropertyTextShadow)
776 styleResolver.style()->setTextShadow(WTF::move(shadowData), !isFirstEntry); // add to the list if this is not the first entry
778 styleResolver.style()->setBoxShadow(WTF::move(shadowData), !isFirstEntry); // add to the list if this is not the first entry
779 isFirstEntry = false;
783 inline void StyleBuilderCustom::applyInitialTextShadow(StyleResolver& styleResolver)
785 styleResolver.style()->setTextShadow(nullptr);
788 inline void StyleBuilderCustom::applyInheritTextShadow(StyleResolver& styleResolver)
790 styleResolver.style()->setTextShadow(styleResolver.parentStyle()->textShadow() ? std::make_unique<ShadowData>(*styleResolver.parentStyle()->textShadow()) : nullptr);
793 inline void StyleBuilderCustom::applyValueTextShadow(StyleResolver& styleResolver, CSSValue& value)
795 applyTextOrBoxShadowValue<CSSPropertyTextShadow>(styleResolver, value);
798 inline void StyleBuilderCustom::applyInitialBoxShadow(StyleResolver& styleResolver)
800 styleResolver.style()->setBoxShadow(nullptr);
803 inline void StyleBuilderCustom::applyInheritBoxShadow(StyleResolver& styleResolver)
805 styleResolver.style()->setBoxShadow(styleResolver.parentStyle()->boxShadow() ? std::make_unique<ShadowData>(*styleResolver.parentStyle()->boxShadow()) : nullptr);
808 inline void StyleBuilderCustom::applyValueBoxShadow(StyleResolver& styleResolver, CSSValue& value)
810 applyTextOrBoxShadowValue<CSSPropertyBoxShadow>(styleResolver, value);
813 inline void StyleBuilderCustom::applyInitialWebkitBoxShadow(StyleResolver& styleResolver)
815 applyInitialBoxShadow(styleResolver);
818 inline void StyleBuilderCustom::applyInheritWebkitBoxShadow(StyleResolver& styleResolver)
820 applyInheritBoxShadow(styleResolver);
823 inline void StyleBuilderCustom::applyValueWebkitBoxShadow(StyleResolver& styleResolver, CSSValue& value)
825 applyTextOrBoxShadowValue<CSSPropertyWebkitBoxShadow>(styleResolver, value);
828 inline void StyleBuilderCustom::applyInitialFontFamily(StyleResolver& styleResolver)
830 auto fontDescription = styleResolver.style()->fontDescription();
831 auto initialDesc = FontCascadeDescription();
833 // We need to adjust the size to account for the generic family change from monospace to non-monospace.
834 if (fontDescription.useFixedDefaultSize()) {
835 if (CSSValueID sizeIdentifier = fontDescription.keywordSizeAsIdentifier())
836 styleResolver.setFontSize(fontDescription, Style::fontSizeForKeyword(sizeIdentifier, false, styleResolver.document()));
838 if (!initialDesc.firstFamily().isEmpty())
839 fontDescription.setFamilies(initialDesc.families());
841 styleResolver.setFontDescription(fontDescription);
844 inline void StyleBuilderCustom::applyInheritFontFamily(StyleResolver& styleResolver)
846 auto fontDescription = styleResolver.style()->fontDescription();
847 auto parentFontDescription = styleResolver.parentStyle()->fontDescription();
849 fontDescription.setFamilies(parentFontDescription.families());
850 fontDescription.setIsSpecifiedFont(parentFontDescription.isSpecifiedFont());
851 styleResolver.setFontDescription(fontDescription);
854 inline void StyleBuilderCustom::applyValueFontFamily(StyleResolver& styleResolver, CSSValue& value)
856 auto& valueList = downcast<CSSValueList>(value);
858 auto fontDescription = styleResolver.style()->fontDescription();
859 // Before mapping in a new font-family property, we should reset the generic family.
860 bool oldFamilyUsedFixedDefaultSize = fontDescription.useFixedDefaultSize();
862 Vector<AtomicString> families;
863 families.reserveInitialCapacity(valueList.length());
865 for (auto& item : valueList) {
866 auto& contentValue = downcast<CSSPrimitiveValue>(item.get());
868 bool isGenericFamily = false;
869 if (contentValue.isFontFamily()) {
870 const CSSFontFamily& fontFamily = contentValue.fontFamily();
871 family = fontFamily.familyName;
872 // If the family name was resolved by the CSS parser from a system font ID, then it is generic.
873 isGenericFamily = fontFamily.fromSystemFontID;
875 switch (contentValue.getValueID()) {
876 case CSSValueWebkitBody:
877 if (Settings* settings = styleResolver.document().settings())
878 family = settings->standardFontFamily();
881 family = serifFamily;
882 isGenericFamily = true;
884 case CSSValueSansSerif:
885 family = sansSerifFamily;
886 isGenericFamily = true;
888 case CSSValueCursive:
889 family = cursiveFamily;
890 isGenericFamily = true;
892 case CSSValueFantasy:
893 family = fantasyFamily;
894 isGenericFamily = true;
896 case CSSValueMonospace:
897 family = monospaceFamily;
898 isGenericFamily = true;
900 case CSSValueWebkitPictograph:
901 family = pictographFamily;
902 isGenericFamily = true;
909 if (family.isEmpty())
911 if (families.isEmpty())
912 fontDescription.setIsSpecifiedFont(!isGenericFamily);
913 families.uncheckedAppend(family);
916 if (families.isEmpty())
918 fontDescription.setFamilies(families);
920 if (fontDescription.useFixedDefaultSize() != oldFamilyUsedFixedDefaultSize) {
921 if (CSSValueID sizeIdentifier = fontDescription.keywordSizeAsIdentifier())
922 styleResolver.setFontSize(fontDescription, Style::fontSizeForKeyword(sizeIdentifier, !oldFamilyUsedFixedDefaultSize, styleResolver.document()));
925 styleResolver.setFontDescription(fontDescription);
928 inline bool StyleBuilderCustom::isValidDisplayValue(StyleResolver& styleResolver, EDisplay display)
930 if (is<SVGElement>(styleResolver.element()) && styleResolver.style()->styleType() == NOPSEUDO)
931 return display == INLINE || display == BLOCK || display == NONE;
935 inline void StyleBuilderCustom::applyInheritDisplay(StyleResolver& styleResolver)
937 EDisplay display = styleResolver.parentStyle()->display();
938 if (isValidDisplayValue(styleResolver, display))
939 styleResolver.style()->setDisplay(display);
942 inline void StyleBuilderCustom::applyValueDisplay(StyleResolver& styleResolver, CSSValue& value)
944 EDisplay display = downcast<CSSPrimitiveValue>(value);
945 if (isValidDisplayValue(styleResolver, display))
946 styleResolver.style()->setDisplay(display);
949 inline void StyleBuilderCustom::applyValueBaselineShift(StyleResolver& styleResolver, CSSValue& value)
951 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
952 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
953 if (primitiveValue.isValueID()) {
954 switch (primitiveValue.getValueID()) {
955 case CSSValueBaseline:
956 svgStyle.setBaselineShift(BS_BASELINE);
959 svgStyle.setBaselineShift(BS_SUB);
962 svgStyle.setBaselineShift(BS_SUPER);
968 svgStyle.setBaselineShift(BS_LENGTH);
969 svgStyle.setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
973 inline void StyleBuilderCustom::applyInitialWebkitAspectRatio(StyleResolver& styleResolver)
975 styleResolver.style()->setAspectRatioType(RenderStyle::initialAspectRatioType());
976 styleResolver.style()->setAspectRatioDenominator(RenderStyle::initialAspectRatioDenominator());
977 styleResolver.style()->setAspectRatioNumerator(RenderStyle::initialAspectRatioNumerator());
980 inline void StyleBuilderCustom::applyInheritWebkitAspectRatio(StyleResolver& styleResolver)
982 if (styleResolver.parentStyle()->aspectRatioType() == AspectRatioAuto)
984 styleResolver.style()->setAspectRatioType(styleResolver.parentStyle()->aspectRatioType());
985 styleResolver.style()->setAspectRatioDenominator(styleResolver.parentStyle()->aspectRatioDenominator());
986 styleResolver.style()->setAspectRatioNumerator(styleResolver.parentStyle()->aspectRatioNumerator());
989 inline void StyleBuilderCustom::applyValueWebkitAspectRatio(StyleResolver& styleResolver, CSSValue& value)
991 if (is<CSSPrimitiveValue>(value)) {
992 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
994 if (primitiveValue.getValueID() == CSSValueFromDimensions)
995 return styleResolver.style()->setAspectRatioType(AspectRatioFromDimensions);
996 if (primitiveValue.getValueID() == CSSValueFromIntrinsic)
997 return styleResolver.style()->setAspectRatioType(AspectRatioFromIntrinsic);
999 ASSERT(primitiveValue.getValueID() == CSSValueAuto);
1000 return styleResolver.style()->setAspectRatioType(AspectRatioAuto);
1003 auto& aspectRatioValue = downcast<CSSAspectRatioValue>(value);
1004 styleResolver.style()->setAspectRatioType(AspectRatioSpecified);
1005 styleResolver.style()->setAspectRatioDenominator(aspectRatioValue.denominatorValue());
1006 styleResolver.style()->setAspectRatioNumerator(aspectRatioValue.numeratorValue());
1009 inline void StyleBuilderCustom::applyInitialWebkitTextEmphasisStyle(StyleResolver& styleResolver)
1011 styleResolver.style()->setTextEmphasisFill(RenderStyle::initialTextEmphasisFill());
1012 styleResolver.style()->setTextEmphasisMark(RenderStyle::initialTextEmphasisMark());
1013 styleResolver.style()->setTextEmphasisCustomMark(RenderStyle::initialTextEmphasisCustomMark());
1016 inline void StyleBuilderCustom::applyInheritWebkitTextEmphasisStyle(StyleResolver& styleResolver)
1018 styleResolver.style()->setTextEmphasisFill(styleResolver.parentStyle()->textEmphasisFill());
1019 styleResolver.style()->setTextEmphasisMark(styleResolver.parentStyle()->textEmphasisMark());
1020 styleResolver.style()->setTextEmphasisCustomMark(styleResolver.parentStyle()->textEmphasisCustomMark());
1023 inline void StyleBuilderCustom::applyValueWebkitTextEmphasisStyle(StyleResolver& styleResolver, CSSValue& value)
1025 if (is<CSSValueList>(value)) {
1026 auto& list = downcast<CSSValueList>(value);
1027 ASSERT(list.length() == 2);
1029 for (auto& item : list) {
1030 CSSPrimitiveValue& value = downcast<CSSPrimitiveValue>(item.get());
1031 if (value.getValueID() == CSSValueFilled || value.getValueID() == CSSValueOpen)
1032 styleResolver.style()->setTextEmphasisFill(value);
1034 styleResolver.style()->setTextEmphasisMark(value);
1036 styleResolver.style()->setTextEmphasisCustomMark(nullAtom);
1040 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1041 if (primitiveValue.isString()) {
1042 styleResolver.style()->setTextEmphasisFill(TextEmphasisFillFilled);
1043 styleResolver.style()->setTextEmphasisMark(TextEmphasisMarkCustom);
1044 styleResolver.style()->setTextEmphasisCustomMark(primitiveValue.getStringValue());
1048 styleResolver.style()->setTextEmphasisCustomMark(nullAtom);
1050 if (primitiveValue.getValueID() == CSSValueFilled || primitiveValue.getValueID() == CSSValueOpen) {
1051 styleResolver.style()->setTextEmphasisFill(primitiveValue);
1052 styleResolver.style()->setTextEmphasisMark(TextEmphasisMarkAuto);
1054 styleResolver.style()->setTextEmphasisFill(TextEmphasisFillFilled);
1055 styleResolver.style()->setTextEmphasisMark(primitiveValue);
1059 template <StyleBuilderCustom::CounterBehavior counterBehavior>
1060 inline void StyleBuilderCustom::applyInheritCounter(StyleResolver& styleResolver)
1062 CounterDirectiveMap& map = styleResolver.style()->accessCounterDirectives();
1063 for (auto& keyValue : styleResolver.parentStyle()->accessCounterDirectives()) {
1064 CounterDirectives& directives = map.add(keyValue.key, CounterDirectives()).iterator->value;
1065 if (counterBehavior == Reset)
1066 directives.inheritReset(keyValue.value);
1068 directives.inheritIncrement(keyValue.value);
1072 template <StyleBuilderCustom::CounterBehavior counterBehavior>
1073 inline void StyleBuilderCustom::applyValueCounter(StyleResolver& styleResolver, CSSValue& value)
1075 bool setCounterIncrementToNone = counterBehavior == Increment && is<CSSPrimitiveValue>(value) && downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNone;
1077 if (!is<CSSValueList>(value) && !setCounterIncrementToNone)
1080 CounterDirectiveMap& map = styleResolver.style()->accessCounterDirectives();
1081 for (auto& keyValue : map) {
1082 if (counterBehavior == Reset)
1083 keyValue.value.clearReset();
1085 keyValue.value.clearIncrement();
1088 if (setCounterIncrementToNone)
1091 for (auto& item : downcast<CSSValueList>(value)) {
1092 Pair* pair = downcast<CSSPrimitiveValue>(item.get()).getPairValue();
1093 if (!pair || !pair->first() || !pair->second())
1096 AtomicString identifier = pair->first()->getStringValue();
1097 int value = pair->second()->getIntValue();
1098 CounterDirectives& directives = map.add(identifier, CounterDirectives()).iterator->value;
1099 if (counterBehavior == Reset)
1100 directives.setResetValue(value);
1102 directives.addIncrementValue(value);
1106 inline void StyleBuilderCustom::applyInitialCounterIncrement(StyleResolver&) { }
1108 inline void StyleBuilderCustom::applyInheritCounterIncrement(StyleResolver& styleResolver)
1110 applyInheritCounter<Increment>(styleResolver);
1113 inline void StyleBuilderCustom::applyValueCounterIncrement(StyleResolver& styleResolver, CSSValue& value)
1115 applyValueCounter<Increment>(styleResolver, value);
1118 inline void StyleBuilderCustom::applyInitialCounterReset(StyleResolver&) { }
1120 inline void StyleBuilderCustom::applyInheritCounterReset(StyleResolver& styleResolver)
1122 applyInheritCounter<Reset>(styleResolver);
1125 inline void StyleBuilderCustom::applyValueCounterReset(StyleResolver& styleResolver, CSSValue& value)
1127 applyValueCounter<Reset>(styleResolver, value);
1130 inline void StyleBuilderCustom::applyInitialCursor(StyleResolver& styleResolver)
1132 styleResolver.style()->clearCursorList();
1133 styleResolver.style()->setCursor(RenderStyle::initialCursor());
1136 inline void StyleBuilderCustom::applyInheritCursor(StyleResolver& styleResolver)
1138 styleResolver.style()->setCursor(styleResolver.parentStyle()->cursor());
1139 styleResolver.style()->setCursorList(styleResolver.parentStyle()->cursors());
1142 inline void StyleBuilderCustom::applyValueCursor(StyleResolver& styleResolver, CSSValue& value)
1144 styleResolver.style()->clearCursorList();
1145 if (is<CSSPrimitiveValue>(value)) {
1146 ECursor cursor = downcast<CSSPrimitiveValue>(value);
1147 if (styleResolver.style()->cursor() != cursor)
1148 styleResolver.style()->setCursor(cursor);
1152 styleResolver.style()->setCursor(CursorAuto);
1153 auto& list = downcast<CSSValueList>(value);
1154 for (auto& item : list) {
1155 if (is<CSSCursorImageValue>(item.get())) {
1156 auto& image = downcast<CSSCursorImageValue>(item.get());
1157 if (image.updateIfSVGCursorIsUsed(styleResolver.element())) // Elements with SVG cursors are not allowed to share style.
1158 styleResolver.style()->setUnique();
1159 styleResolver.style()->addCursor(styleResolver.styleImage(CSSPropertyCursor, image), image.hotSpot());
1163 styleResolver.style()->setCursor(downcast<CSSPrimitiveValue>(item.get()));
1164 ASSERT_WITH_MESSAGE(item.ptr() == list.item(list.length() - 1), "Cursor ID fallback should always be last in the list");
1169 inline void StyleBuilderCustom::applyInitialFill(StyleResolver& styleResolver)
1171 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1172 svgStyle.setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1175 inline void StyleBuilderCustom::applyInheritFill(StyleResolver& styleResolver)
1177 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1178 const SVGRenderStyle& svgParentStyle = styleResolver.parentStyle()->svgStyle();
1179 svgStyle.setFillPaint(svgParentStyle.fillPaintType(), svgParentStyle.fillPaintColor(), svgParentStyle.fillPaintUri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1183 inline void StyleBuilderCustom::applyValueFill(StyleResolver& styleResolver, CSSValue& value)
1185 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1186 SVGPaint& svgPaint = downcast<SVGPaint>(value);
1187 svgStyle.setFillPaint(svgPaint.paintType(), StyleBuilderConverter::convertSVGColor(styleResolver, svgPaint), svgPaint.uri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1190 inline void StyleBuilderCustom::applyInitialStroke(StyleResolver& styleResolver)
1192 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1193 svgStyle.setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1196 inline void StyleBuilderCustom::applyInheritStroke(StyleResolver& styleResolver)
1198 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1199 const SVGRenderStyle& svgParentStyle = styleResolver.parentStyle()->svgStyle();
1200 svgStyle.setStrokePaint(svgParentStyle.strokePaintType(), svgParentStyle.strokePaintColor(), svgParentStyle.strokePaintUri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1203 inline void StyleBuilderCustom::applyValueStroke(StyleResolver& styleResolver, CSSValue& value)
1205 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1206 SVGPaint& svgPaint = downcast<SVGPaint>(value);
1207 svgStyle.setStrokePaint(svgPaint.paintType(), StyleBuilderConverter::convertSVGColor(styleResolver, svgPaint), svgPaint.uri(), styleResolver.applyPropertyToRegularStyle(), styleResolver.applyPropertyToVisitedLinkStyle());
1210 inline void StyleBuilderCustom::applyInitialWebkitSvgShadow(StyleResolver& styleResolver)
1212 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1213 svgStyle.setShadow(nullptr);
1216 inline void StyleBuilderCustom::applyInheritWebkitSvgShadow(StyleResolver& styleResolver)
1218 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1219 const SVGRenderStyle& svgParentStyle = styleResolver.parentStyle()->svgStyle();
1220 svgStyle.setShadow(svgParentStyle.shadow() ? std::make_unique<ShadowData>(*svgParentStyle.shadow()) : nullptr);
1223 inline void StyleBuilderCustom::applyValueWebkitSvgShadow(StyleResolver& styleResolver, CSSValue& value)
1225 SVGRenderStyle& svgStyle = styleResolver.style()->accessSVGStyle();
1226 if (is<CSSPrimitiveValue>(value)) {
1227 ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNone);
1228 svgStyle.setShadow(nullptr);
1232 auto& shadowValue = downcast<CSSShadowValue>(*downcast<CSSValueList>(value).itemWithoutBoundsCheck(0));
1233 IntPoint location(shadowValue.x->computeLength<int>(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f)),
1234 shadowValue.y->computeLength<int>(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f)));
1235 int blur = shadowValue.blur ? shadowValue.blur->computeLength<int>(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f)) : 0;
1237 if (shadowValue.color)
1238 color = styleResolver.colorFromPrimitiveValue(*shadowValue.color);
1240 // -webkit-svg-shadow does should not have a spread or style
1241 ASSERT(!shadowValue.spread);
1242 ASSERT(!shadowValue.style);
1244 svgStyle.setShadow(std::make_unique<ShadowData>(location, blur, 0, Normal, false, color.isValid() ? color : Color::transparent));
1247 inline void StyleBuilderCustom::applyInitialFontWeight(StyleResolver& styleResolver)
1249 auto fontDescription = styleResolver.fontDescription();
1250 fontDescription.setWeight(FontWeightNormal);
1251 styleResolver.setFontDescription(fontDescription);
1254 inline void StyleBuilderCustom::applyInheritFontWeight(StyleResolver& styleResolver)
1256 auto fontDescription = styleResolver.fontDescription();
1257 fontDescription.setWeight(styleResolver.parentFontDescription().weight());
1258 styleResolver.setFontDescription(fontDescription);
1261 inline void StyleBuilderCustom::applyValueFontWeight(StyleResolver& styleResolver, CSSValue& value)
1263 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1264 auto fontDescription = styleResolver.fontDescription();
1265 switch (primitiveValue.getValueID()) {
1266 case CSSValueInvalid:
1267 ASSERT_NOT_REACHED();
1269 case CSSValueBolder:
1270 fontDescription.setWeight(styleResolver.parentStyle()->fontDescription().weight());
1271 fontDescription.setWeight(fontDescription.bolderWeight());
1273 case CSSValueLighter:
1274 fontDescription.setWeight(styleResolver.parentStyle()->fontDescription().weight());
1275 fontDescription.setWeight(fontDescription.lighterWeight());
1278 fontDescription.setWeight(primitiveValue);
1280 styleResolver.setFontDescription(fontDescription);
1283 inline void StyleBuilderCustom::applyInitialColumnGap(StyleResolver& styleResolver)
1285 styleResolver.style()->setHasNormalColumnGap();
1288 inline void StyleBuilderCustom::applyInheritColumnGap(StyleResolver& styleResolver)
1290 if (styleResolver.parentStyle()->hasNormalColumnGap())
1291 styleResolver.style()->setHasNormalColumnGap();
1293 styleResolver.style()->setColumnGap(styleResolver.parentStyle()->columnGap());
1296 inline void StyleBuilderCustom::applyValueColumnGap(StyleResolver& styleResolver, CSSValue& value)
1298 if (downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNormal)
1299 styleResolver.style()->setHasNormalColumnGap();
1301 styleResolver.style()->setColumnGap(StyleBuilderConverter::convertComputedLength<float>(styleResolver, value));
1304 inline void StyleBuilderCustom::applyInitialContent(StyleResolver& styleResolver)
1306 styleResolver.style()->clearContent();
1309 inline void StyleBuilderCustom::applyInheritContent(StyleResolver&)
1311 // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This
1312 // note is a reminder that eventually "inherit" needs to be supported.
1315 inline void StyleBuilderCustom::applyValueContent(StyleResolver& styleResolver, CSSValue& value)
1317 bool didSet = false;
1318 for (auto& item : downcast<CSSValueList>(value)) {
1319 if (is<CSSImageGeneratorValue>(item.get())) {
1320 if (is<CSSGradientValue>(item.get()))
1321 styleResolver.style()->setContent(StyleGeneratedImage::create(*downcast<CSSGradientValue>(item.get()).gradientWithStylesResolved(&styleResolver)), didSet);
1323 styleResolver.style()->setContent(StyleGeneratedImage::create(downcast<CSSImageGeneratorValue>(item.get())), didSet);
1325 #if ENABLE(CSS_IMAGE_SET)
1326 } else if (is<CSSImageSetValue>(item.get())) {
1327 styleResolver.style()->setContent(styleResolver.setOrPendingFromValue(CSSPropertyContent, downcast<CSSImageSetValue>(item.get())), didSet);
1332 if (is<CSSImageValue>(item.get())) {
1333 styleResolver.style()->setContent(styleResolver.cachedOrPendingFromValue(CSSPropertyContent, downcast<CSSImageValue>(item.get())), didSet);
1338 if (!is<CSSPrimitiveValue>(item.get()))
1341 auto& contentValue = downcast<CSSPrimitiveValue>(item.get());
1342 if (contentValue.isString()) {
1343 styleResolver.style()->setContent(contentValue.getStringValue().impl(), didSet);
1345 } else if (contentValue.isAttr()) {
1346 // FIXME: Can a namespace be specified for an attr(foo)?
1347 if (styleResolver.style()->styleType() == NOPSEUDO)
1348 styleResolver.style()->setUnique();
1350 styleResolver.parentStyle()->setUnique();
1351 QualifiedName attr(nullAtom, contentValue.getStringValue().impl(), nullAtom);
1352 const AtomicString& value = styleResolver.element()->getAttribute(attr);
1353 styleResolver.style()->setContent(value.isNull() ? emptyAtom : value.impl(), didSet);
1355 // Register the fact that the attribute value affects the style.
1356 styleResolver.ruleSets().features().attributeCanonicalLocalNamesInRules.add(attr.localName().impl());
1357 styleResolver.ruleSets().features().attributeLocalNamesInRules.add(attr.localName().impl());
1358 } else if (contentValue.isCounter()) {
1359 Counter* counterValue = contentValue.getCounterValue();
1360 EListStyleType listStyleType = NoneListStyle;
1361 CSSValueID listStyleIdent = counterValue->listStyleIdent();
1362 if (listStyleIdent != CSSValueNone)
1363 listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
1364 auto counter = std::make_unique<CounterContent>(counterValue->identifier(), listStyleType, counterValue->separator());
1365 styleResolver.style()->setContent(WTF::move(counter), didSet);
1368 switch (contentValue.getValueID()) {
1369 case CSSValueOpenQuote:
1370 styleResolver.style()->setContent(OPEN_QUOTE, didSet);
1373 case CSSValueCloseQuote:
1374 styleResolver.style()->setContent(CLOSE_QUOTE, didSet);
1377 case CSSValueNoOpenQuote:
1378 styleResolver.style()->setContent(NO_OPEN_QUOTE, didSet);
1381 case CSSValueNoCloseQuote:
1382 styleResolver.style()->setContent(NO_CLOSE_QUOTE, didSet);
1386 // normal and none do not have any effect.
1392 styleResolver.style()->clearContent();
1395 inline void StyleBuilderCustom::applyInheritFontVariantLigatures(StyleResolver& styleResolver)
1397 auto fontDescription = styleResolver.fontDescription();
1398 fontDescription.setVariantCommonLigatures(styleResolver.parentFontDescription().variantCommonLigatures());
1399 fontDescription.setVariantDiscretionaryLigatures(styleResolver.parentFontDescription().variantDiscretionaryLigatures());
1400 fontDescription.setVariantHistoricalLigatures(styleResolver.parentFontDescription().variantHistoricalLigatures());
1401 fontDescription.setVariantContextualAlternates(styleResolver.parentFontDescription().variantContextualAlternates());
1402 styleResolver.setFontDescription(fontDescription);
1405 inline void StyleBuilderCustom::applyInitialFontVariantLigatures(StyleResolver& styleResolver)
1407 auto fontDescription = styleResolver.fontDescription();
1408 fontDescription.setVariantCommonLigatures(FontVariantLigatures::Normal);
1409 fontDescription.setVariantDiscretionaryLigatures(FontVariantLigatures::Normal);
1410 fontDescription.setVariantHistoricalLigatures(FontVariantLigatures::Normal);
1411 fontDescription.setVariantContextualAlternates(FontVariantLigatures::Normal);
1412 styleResolver.setFontDescription(fontDescription);
1415 inline void StyleBuilderCustom::applyValueFontVariantLigatures(StyleResolver& styleResolver, CSSValue& value)
1417 FontVariantLigatures common = FontVariantLigatures::Normal;
1418 FontVariantLigatures discretionary = FontVariantLigatures::Normal;
1419 FontVariantLigatures historical = FontVariantLigatures::Normal;
1420 FontVariantLigatures contextualAlternates = FontVariantLigatures::Normal;
1422 if (is<CSSValueList>(value)) {
1423 for (auto& item : downcast<CSSValueList>(value)) {
1424 switch (downcast<CSSPrimitiveValue>(item.get()).getValueID()) {
1425 case CSSValueNoCommonLigatures:
1426 common = FontVariantLigatures::No;
1428 case CSSValueCommonLigatures:
1429 common = FontVariantLigatures::Yes;
1431 case CSSValueNoDiscretionaryLigatures:
1432 discretionary = FontVariantLigatures::No;
1434 case CSSValueDiscretionaryLigatures:
1435 discretionary = FontVariantLigatures::Yes;
1437 case CSSValueNoHistoricalLigatures:
1438 historical = FontVariantLigatures::No;
1440 case CSSValueHistoricalLigatures:
1441 historical = FontVariantLigatures::Yes;
1443 case CSSValueContextual:
1444 contextualAlternates = FontVariantLigatures::Yes;
1446 case CSSValueNoContextual:
1447 contextualAlternates = FontVariantLigatures::No;
1450 ASSERT_NOT_REACHED();
1455 switch (downcast<CSSPrimitiveValue>(value).getValueID()) {
1456 case CSSValueNormal:
1459 common = FontVariantLigatures::No;
1460 discretionary = FontVariantLigatures::No;
1461 historical = FontVariantLigatures::No;
1462 contextualAlternates = FontVariantLigatures::No;
1465 ASSERT_NOT_REACHED();
1470 auto fontDescription = styleResolver.fontDescription();
1471 fontDescription.setVariantCommonLigatures(common);
1472 fontDescription.setVariantDiscretionaryLigatures(discretionary);
1473 fontDescription.setVariantHistoricalLigatures(historical);
1474 fontDescription.setVariantContextualAlternates(contextualAlternates);
1475 styleResolver.setFontDescription(fontDescription);
1478 inline void StyleBuilderCustom::applyInheritFontVariantNumeric(StyleResolver& styleResolver)
1480 auto fontDescription = styleResolver.fontDescription();
1481 fontDescription.setVariantNumericFigure(styleResolver.parentFontDescription().variantNumericFigure());
1482 fontDescription.setVariantNumericSpacing(styleResolver.parentFontDescription().variantNumericSpacing());
1483 fontDescription.setVariantNumericFraction(styleResolver.parentFontDescription().variantNumericFraction());
1484 fontDescription.setVariantNumericOrdinal(styleResolver.parentFontDescription().variantNumericOrdinal());
1485 fontDescription.setVariantNumericSlashedZero(styleResolver.parentFontDescription().variantNumericSlashedZero());
1486 styleResolver.setFontDescription(fontDescription);
1489 inline void StyleBuilderCustom::applyInitialFontVariantNumeric(StyleResolver& styleResolver)
1491 auto fontDescription = styleResolver.fontDescription();
1492 fontDescription.setVariantNumericFigure(FontVariantNumericFigure::Normal);
1493 fontDescription.setVariantNumericSpacing(FontVariantNumericSpacing::Normal);
1494 fontDescription.setVariantNumericFraction(FontVariantNumericFraction::Normal);
1495 fontDescription.setVariantNumericOrdinal(FontVariantNumericOrdinal::Normal);
1496 fontDescription.setVariantNumericSlashedZero(FontVariantNumericSlashedZero::Normal);
1497 styleResolver.setFontDescription(fontDescription);
1500 inline void StyleBuilderCustom::applyValueFontVariantNumeric(StyleResolver& styleResolver, CSSValue& value)
1502 FontVariantNumericFigure figure = FontVariantNumericFigure::Normal;
1503 FontVariantNumericSpacing spacing = FontVariantNumericSpacing::Normal;
1504 FontVariantNumericFraction fraction = FontVariantNumericFraction::Normal;
1505 FontVariantNumericOrdinal ordinal = FontVariantNumericOrdinal::Normal;
1506 FontVariantNumericSlashedZero slashedZero = FontVariantNumericSlashedZero::Normal;
1508 if (is<CSSValueList>(value)) {
1509 for (auto& item : downcast<CSSValueList>(value)) {
1510 switch (downcast<CSSPrimitiveValue>(item.get()).getValueID()) {
1511 case CSSValueLiningNums:
1512 figure = FontVariantNumericFigure::LiningNumbers;
1514 case CSSValueOldstyleNums:
1515 figure = FontVariantNumericFigure::OldStyleNumbers;
1517 case CSSValueProportionalNums:
1518 spacing = FontVariantNumericSpacing::ProportionalNumbers;
1520 case CSSValueTabularNums:
1521 spacing = FontVariantNumericSpacing::TabularNumbers;
1523 case CSSValueDiagonalFractions:
1524 fraction = FontVariantNumericFraction::DiagonalFractions;
1526 case CSSValueStackedFractions:
1527 fraction = FontVariantNumericFraction::StackedFractions;
1529 case CSSValueOrdinal:
1530 ordinal = FontVariantNumericOrdinal::Yes;
1532 case CSSValueSlashedZero:
1533 slashedZero = FontVariantNumericSlashedZero::Yes;
1536 ASSERT_NOT_REACHED();
1541 ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNormal);
1543 auto fontDescription = styleResolver.fontDescription();
1544 fontDescription.setVariantNumericFigure(figure);
1545 fontDescription.setVariantNumericSpacing(spacing);
1546 fontDescription.setVariantNumericFraction(fraction);
1547 fontDescription.setVariantNumericOrdinal(ordinal);
1548 fontDescription.setVariantNumericSlashedZero(slashedZero);
1549 styleResolver.setFontDescription(fontDescription);
1552 inline void StyleBuilderCustom::applyInheritFontVariantEastAsian(StyleResolver& styleResolver)
1554 auto fontDescription = styleResolver.fontDescription();
1555 fontDescription.setVariantEastAsianVariant(styleResolver.parentFontDescription().variantEastAsianVariant());
1556 fontDescription.setVariantEastAsianWidth(styleResolver.parentFontDescription().variantEastAsianWidth());
1557 fontDescription.setVariantEastAsianRuby(styleResolver.parentFontDescription().variantEastAsianRuby());
1558 styleResolver.setFontDescription(fontDescription);
1561 inline void StyleBuilderCustom::applyInitialFontVariantEastAsian(StyleResolver& styleResolver)
1563 auto fontDescription = styleResolver.fontDescription();
1564 fontDescription.setVariantEastAsianVariant(FontVariantEastAsianVariant::Normal);
1565 fontDescription.setVariantEastAsianWidth(FontVariantEastAsianWidth::Normal);
1566 fontDescription.setVariantEastAsianRuby(FontVariantEastAsianRuby::Normal);
1567 styleResolver.setFontDescription(fontDescription);
1570 inline void StyleBuilderCustom::applyValueFontVariantEastAsian(StyleResolver& styleResolver, CSSValue& value)
1572 FontVariantEastAsianVariant variant = FontVariantEastAsianVariant::Normal;
1573 FontVariantEastAsianWidth width = FontVariantEastAsianWidth::Normal;
1574 FontVariantEastAsianRuby ruby = FontVariantEastAsianRuby::Normal;
1576 if (is<CSSValueList>(value)) {
1577 for (auto& item : downcast<CSSValueList>(value)) {
1578 switch (downcast<CSSPrimitiveValue>(item.get()).getValueID()) {
1580 variant = FontVariantEastAsianVariant::Jis78;
1583 variant = FontVariantEastAsianVariant::Jis83;
1586 variant = FontVariantEastAsianVariant::Jis90;
1589 variant = FontVariantEastAsianVariant::Jis04;
1591 case CSSValueSimplified:
1592 variant = FontVariantEastAsianVariant::Simplified;
1594 case CSSValueTraditional:
1595 variant = FontVariantEastAsianVariant::Traditional;
1597 case CSSValueFullWidth:
1598 width = FontVariantEastAsianWidth::FullWidth;
1600 case CSSValueProportionalWidth:
1601 width = FontVariantEastAsianWidth::ProportionalWidth;
1604 ruby = FontVariantEastAsianRuby::Yes;
1607 ASSERT_NOT_REACHED();
1612 ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNormal);
1614 auto fontDescription = styleResolver.fontDescription();
1615 fontDescription.setVariantEastAsianVariant(variant);
1616 fontDescription.setVariantEastAsianWidth(width);
1617 fontDescription.setVariantEastAsianRuby(ruby);
1618 styleResolver.setFontDescription(fontDescription);
1621 inline void StyleBuilderCustom::applyInitialFontSize(StyleResolver& styleResolver)
1623 auto fontDescription = styleResolver.style()->fontDescription();
1624 float size = Style::fontSizeForKeyword(CSSValueMedium, fontDescription.useFixedDefaultSize(), styleResolver.document());
1629 fontDescription.setKeywordSizeFromIdentifier(CSSValueMedium);
1630 styleResolver.setFontSize(fontDescription, size);
1631 styleResolver.setFontDescription(fontDescription);
1634 inline void StyleBuilderCustom::applyInheritFontSize(StyleResolver& styleResolver)
1636 const auto& parentFontDescription = styleResolver.parentStyle()->fontDescription();
1637 float size = parentFontDescription.specifiedSize();
1642 auto fontDescription = styleResolver.style()->fontDescription();
1643 fontDescription.setKeywordSize(parentFontDescription.keywordSize());
1644 styleResolver.setFontSize(fontDescription, size);
1645 styleResolver.setFontDescription(fontDescription);
1648 // When the CSS keyword "larger" is used, this function will attempt to match within the keyword
1649 // table, and failing that, will simply multiply by 1.2.
1650 inline float StyleBuilderCustom::largerFontSize(float size)
1652 // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale up to
1653 // the next size level.
1657 // Like the previous function, but for the keyword "smaller".
1658 inline float StyleBuilderCustom::smallerFontSize(float size)
1660 // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale down to
1661 // the next size level.
1665 inline float StyleBuilderCustom::determineRubyTextSizeMultiplier(StyleResolver& styleResolver)
1667 if (styleResolver.style()->rubyPosition() != RubyPositionInterCharacter)
1670 // FIXME: This hack is to ensure tone marks are the same size as
1671 // the bopomofo. This code will go away if we make a special renderer
1672 // for the tone marks eventually.
1673 if (auto* element = styleResolver.state().element()) {
1674 for (auto& ancestor : ancestorsOfType<HTMLElement>(*element)) {
1675 if (ancestor.hasTagName(HTMLNames::rtTag))
1682 inline void StyleBuilderCustom::applyValueFontSize(StyleResolver& styleResolver, CSSValue& value)
1684 auto fontDescription = styleResolver.style()->fontDescription();
1685 fontDescription.setKeywordSizeFromIdentifier(CSSValueInvalid);
1687 float parentSize = 0;
1688 bool parentIsAbsoluteSize = false;
1689 if (auto* parentStyle = styleResolver.parentStyle()) {
1690 parentSize = parentStyle->fontDescription().specifiedSize();
1691 parentIsAbsoluteSize = parentStyle->fontDescription().isAbsoluteSize();
1694 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1696 if (CSSValueID ident = primitiveValue.getValueID()) {
1697 fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize && (ident == CSSValueLarger || ident == CSSValueSmaller || ident == CSSValueWebkitRubyText));
1699 // Keywords are being used.
1701 case CSSValueXxSmall:
1702 case CSSValueXSmall:
1704 case CSSValueMedium:
1706 case CSSValueXLarge:
1707 case CSSValueXxLarge:
1708 case CSSValueWebkitXxxLarge:
1709 size = Style::fontSizeForKeyword(ident, fontDescription.useFixedDefaultSize(), styleResolver.document());
1710 fontDescription.setKeywordSizeFromIdentifier(ident);
1712 case CSSValueLarger:
1713 size = largerFontSize(parentSize);
1715 case CSSValueSmaller:
1716 size = smallerFontSize(parentSize);
1718 case CSSValueWebkitRubyText:
1719 size = determineRubyTextSizeMultiplier(styleResolver) * parentSize;
1725 fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize || !(primitiveValue.isPercentage() || primitiveValue.isFontRelativeLength()));
1726 if (primitiveValue.isLength()) {
1727 size = primitiveValue.computeLength<float>(CSSToLengthConversionData(styleResolver.parentStyle(), styleResolver.rootElementStyle(), styleResolver.document().renderView(), 1.0f, true));
1728 styleResolver.state().setFontSizeHasViewportUnits(primitiveValue.isViewportPercentageLength());
1729 } else if (primitiveValue.isPercentage())
1730 size = (primitiveValue.getFloatValue() * parentSize) / 100.0f;
1731 else if (primitiveValue.isCalculatedPercentageWithLength())
1732 size = primitiveValue.cssCalcValue()->createCalculationValue(styleResolver.state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f))->evaluate(parentSize);
1740 styleResolver.setFontSize(fontDescription, std::min(maximumAllowedFontSize, size));
1741 styleResolver.setFontDescription(fontDescription);
1744 #if ENABLE(CSS_GRID_LAYOUT)
1745 inline void StyleBuilderCustom::applyInitialWebkitGridTemplateAreas(StyleResolver& styleResolver)
1747 styleResolver.style()->setNamedGridArea(RenderStyle::initialNamedGridArea());
1748 styleResolver.style()->setNamedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount());
1749 styleResolver.style()->setNamedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount());
1752 inline void StyleBuilderCustom::applyInheritWebkitGridTemplateAreas(StyleResolver& styleResolver)
1754 styleResolver.style()->setNamedGridArea(styleResolver.parentStyle()->namedGridArea());
1755 styleResolver.style()->setNamedGridAreaRowCount(styleResolver.parentStyle()->namedGridAreaRowCount());
1756 styleResolver.style()->setNamedGridAreaColumnCount(styleResolver.parentStyle()->namedGridAreaColumnCount());
1759 inline void StyleBuilderCustom::applyValueWebkitGridTemplateAreas(StyleResolver& styleResolver, CSSValue& value)
1761 if (is<CSSPrimitiveValue>(value)) {
1762 ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueNone);
1766 auto& gridTemplateAreasValue = downcast<CSSGridTemplateAreasValue>(value);
1767 const NamedGridAreaMap& newNamedGridAreas = gridTemplateAreasValue.gridAreaMap();
1769 NamedGridLinesMap namedGridColumnLines = styleResolver.style()->namedGridColumnLines();
1770 NamedGridLinesMap namedGridRowLines = styleResolver.style()->namedGridRowLines();
1771 StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridColumnLines, ForColumns);
1772 StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridRowLines, ForRows);
1773 styleResolver.style()->setNamedGridColumnLines(namedGridColumnLines);
1774 styleResolver.style()->setNamedGridRowLines(namedGridRowLines);
1776 styleResolver.style()->setNamedGridArea(gridTemplateAreasValue.gridAreaMap());
1777 styleResolver.style()->setNamedGridAreaRowCount(gridTemplateAreasValue.rowCount());
1778 styleResolver.style()->setNamedGridAreaColumnCount(gridTemplateAreasValue.columnCount());
1781 inline void StyleBuilderCustom::applyInitialWebkitGridTemplateColumns(StyleResolver& styleResolver)
1783 styleResolver.style()->setGridColumns(RenderStyle::initialGridColumns());
1784 styleResolver.style()->setNamedGridColumnLines(RenderStyle::initialNamedGridColumnLines());
1785 styleResolver.style()->setOrderedNamedGridColumnLines(RenderStyle::initialOrderedNamedGridColumnLines());
1788 inline void StyleBuilderCustom::applyInheritWebkitGridTemplateColumns(StyleResolver& styleResolver)
1790 styleResolver.style()->setGridColumns(styleResolver.parentStyle()->gridColumns());
1791 styleResolver.style()->setNamedGridColumnLines(styleResolver.parentStyle()->namedGridColumnLines());
1792 styleResolver.style()->setOrderedNamedGridColumnLines(styleResolver.parentStyle()->orderedNamedGridColumnLines());
1795 inline void StyleBuilderCustom::applyValueWebkitGridTemplateColumns(StyleResolver& styleResolver, CSSValue& value)
1797 Vector<GridTrackSize> trackSizes;
1798 NamedGridLinesMap namedGridLines;
1799 OrderedNamedGridLinesMap orderedNamedGridLines;
1800 if (!StyleBuilderConverter::createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, styleResolver))
1802 const NamedGridAreaMap& namedGridAreas = styleResolver.style()->namedGridArea();
1803 if (!namedGridAreas.isEmpty())
1804 StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(namedGridAreas, namedGridLines, ForColumns);
1806 styleResolver.style()->setGridColumns(trackSizes);
1807 styleResolver.style()->setNamedGridColumnLines(namedGridLines);
1808 styleResolver.style()->setOrderedNamedGridColumnLines(orderedNamedGridLines);
1811 inline void StyleBuilderCustom::applyInitialWebkitGridTemplateRows(StyleResolver& styleResolver)
1813 styleResolver.style()->setGridRows(RenderStyle::initialGridRows());
1814 styleResolver.style()->setNamedGridRowLines(RenderStyle::initialNamedGridRowLines());
1815 styleResolver.style()->setOrderedNamedGridRowLines(RenderStyle::initialOrderedNamedGridRowLines());
1818 inline void StyleBuilderCustom::applyInheritWebkitGridTemplateRows(StyleResolver& styleResolver)
1820 styleResolver.style()->setGridRows(styleResolver.parentStyle()->gridRows());
1821 styleResolver.style()->setNamedGridRowLines(styleResolver.parentStyle()->namedGridRowLines());
1822 styleResolver.style()->setOrderedNamedGridRowLines(styleResolver.parentStyle()->orderedNamedGridRowLines());
1825 inline void StyleBuilderCustom::applyValueWebkitGridTemplateRows(StyleResolver& styleResolver, CSSValue& value)
1827 Vector<GridTrackSize> trackSizes;
1828 NamedGridLinesMap namedGridLines;
1829 OrderedNamedGridLinesMap orderedNamedGridLines;
1830 if (!StyleBuilderConverter::createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, styleResolver))
1832 const NamedGridAreaMap& namedGridAreas = styleResolver.style()->namedGridArea();
1833 if (!namedGridAreas.isEmpty())
1834 StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(namedGridAreas, namedGridLines, ForRows);
1836 styleResolver.style()->setGridRows(trackSizes);
1837 styleResolver.style()->setNamedGridRowLines(namedGridLines);
1838 styleResolver.style()->setOrderedNamedGridRowLines(orderedNamedGridLines);
1840 #endif // ENABLE(CSS_GRID_LAYOUT)
1842 void StyleBuilderCustom::applyValueAlt(StyleResolver& styleResolver, CSSValue& value)
1844 auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
1845 if (primitiveValue.isString())
1846 styleResolver.style()->setContentAltText(primitiveValue.getStringValue());
1847 else if (primitiveValue.isAttr()) {
1848 // FIXME: Can a namespace be specified for an attr(foo)?
1849 if (styleResolver.style()->styleType() == NOPSEUDO)
1850 styleResolver.style()->setUnique();
1852 styleResolver.parentStyle()->setUnique();
1854 QualifiedName attr(nullAtom, primitiveValue.getStringValue(), nullAtom);
1855 const AtomicString& value = styleResolver.element()->getAttribute(attr);
1856 styleResolver.style()->setContentAltText(value.isNull() ? emptyAtom : value);
1858 // Register the fact that the attribute value affects the style.
1859 styleResolver.ruleSets().features().attributeCanonicalLocalNamesInRules.add(attr.localName().impl());
1860 styleResolver.ruleSets().features().attributeLocalNamesInRules.add(attr.localName().impl());
1862 styleResolver.style()->setContentAltText(emptyAtom);
1865 #if ENABLE(CSS_SCROLL_SNAP)
1866 inline void StyleBuilderCustom::applyInitialWebkitScrollSnapPointsX(StyleResolver& styleResolver)
1868 styleResolver.style()->setScrollSnapPointsX(nullptr);
1871 inline void StyleBuilderCustom::applyInheritWebkitScrollSnapPointsX(StyleResolver& styleResolver)
1873 styleResolver.style()->setScrollSnapPointsX(styleResolver.parentStyle()->scrollSnapPointsX() ? std::make_unique<ScrollSnapPoints>(*styleResolver.parentStyle()->scrollSnapPointsX()) : nullptr);
1876 inline void StyleBuilderCustom::applyInitialWebkitScrollSnapPointsY(StyleResolver& styleResolver)
1878 styleResolver.style()->setScrollSnapPointsY(nullptr);
1881 inline void StyleBuilderCustom::applyInheritWebkitScrollSnapPointsY(StyleResolver& styleResolver)
1883 styleResolver.style()->setScrollSnapPointsY(styleResolver.parentStyle()->scrollSnapPointsY() ? std::make_unique<ScrollSnapPoints>(*styleResolver.parentStyle()->scrollSnapPointsY()) : nullptr);
1887 inline void StyleBuilderCustom::applyValueWillChange(StyleResolver& styleResolver, CSSValue& value)
1889 if (is<CSSPrimitiveValue>(value)) {
1890 ASSERT(downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueAuto);
1891 styleResolver.style()->setWillChange(nullptr);
1895 Ref<WillChangeData> willChange = WillChangeData::create();
1896 for (auto& item : downcast<CSSValueList>(value)) {
1897 if (!is<CSSPrimitiveValue>(item.get()))
1900 const auto& primitiveValue = downcast<CSSPrimitiveValue>(item.get());
1901 switch (primitiveValue.getValueID()) {
1902 case CSSValueScrollPosition:
1903 willChange->addFeature(WillChangeData::Feature::ScrollPosition);
1905 case CSSValueContents:
1906 willChange->addFeature(WillChangeData::Feature::Contents);
1909 if (primitiveValue.isPropertyID())
1910 willChange->addFeature(WillChangeData::Feature::Property, primitiveValue.getPropertyID());
1915 styleResolver.style()->setWillChange(WTF::move(willChange));
1918 } // namespace WebCore
1920 #endif // StyleBuilderCustom_h