2 * Copyright (C) 2004 Zack Rusin <zack@kde.org>
3 * Copyright (C) 2004-2014 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
6 * Copyright (C) 2011 Sencha, Inc. All rights reserved.
7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "CSSComputedStyleDeclaration.h"
28 #include "AnimationController.h"
29 #include "BasicShapeFunctions.h"
30 #include "BasicShapes.h"
31 #include "CSSAnimationTriggerScrollValue.h"
32 #include "CSSAspectRatioValue.h"
33 #include "CSSBasicShapes.h"
34 #include "CSSBorderImage.h"
35 #include "CSSBorderImageSliceValue.h"
36 #include "CSSCustomPropertyValue.h"
37 #include "CSSFontFeatureValue.h"
38 #include "CSSFontValue.h"
39 #include "CSSFontVariationValue.h"
40 #include "CSSFunctionValue.h"
41 #include "CSSLineBoxContainValue.h"
42 #include "CSSParser.h"
43 #include "CSSPrimitiveValue.h"
44 #include "CSSPrimitiveValueMappings.h"
45 #include "CSSPropertyNames.h"
46 #include "CSSReflectValue.h"
47 #include "CSSSelector.h"
48 #include "CSSShadowValue.h"
49 #include "CSSTimingFunctionValue.h"
50 #include "CSSValueList.h"
51 #include "CSSValuePool.h"
52 #include "ComposedTreeAncestorIterator.h"
53 #include "ContentData.h"
54 #include "CounterContent.h"
55 #include "CursorList.h"
57 #include "ExceptionCode.h"
58 #include "FontTaggedSettings.h"
59 #include "HTMLFrameOwnerElement.h"
60 #include "NodeRenderStyle.h"
62 #include "PseudoElement.h"
64 #include "RenderBlock.h"
65 #include "RenderBox.h"
66 #include "RenderStyle.h"
67 #include "RuntimeEnabledFeatures.h"
68 #include "SVGElement.h"
70 #include "ShapeValue.h"
71 #include "StyleInheritedData.h"
72 #include "StyleProperties.h"
73 #include "StylePropertyShorthand.h"
74 #include "StylePropertyShorthandFunctions.h"
75 #include "StyleResolver.h"
76 #include "StyleScope.h"
78 #include "WebKitCSSFilterValue.h"
79 #include "WebKitCSSTransformValue.h"
80 #include "WebKitFontFamilyNames.h"
81 #include "WillChangeData.h"
82 #include <wtf/NeverDestroyed.h>
83 #include <wtf/text/StringBuilder.h>
85 #if ENABLE(CSS_GRID_LAYOUT)
86 #include "CSSGridLineNamesValue.h"
87 #include "CSSGridTemplateAreasValue.h"
88 #include "RenderGrid.h"
91 #if ENABLE(DASHBOARD_SUPPORT)
92 #include "DashboardRegion.h"
95 #if ENABLE(CSS_SCROLL_SNAP)
96 #include "LengthRepeat.h"
97 #include "StyleScrollSnapPoints.h"
100 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
101 #include "AnimationTrigger.h"
106 // List of all properties we know how to compute, omitting shorthands.
107 static const CSSPropertyID computedProperties[] = {
109 CSSPropertyAnimationDelay,
110 CSSPropertyAnimationDirection,
111 CSSPropertyAnimationDuration,
112 CSSPropertyAnimationFillMode,
113 CSSPropertyAnimationIterationCount,
114 CSSPropertyAnimationName,
115 CSSPropertyAnimationPlayState,
116 CSSPropertyAnimationTimingFunction,
117 CSSPropertyBackgroundAttachment,
118 CSSPropertyBackgroundBlendMode,
119 CSSPropertyBackgroundClip,
120 CSSPropertyBackgroundColor,
121 CSSPropertyBackgroundImage,
122 CSSPropertyBackgroundOrigin,
123 CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard
124 CSSPropertyBackgroundRepeat,
125 CSSPropertyBackgroundSize,
126 CSSPropertyBorderBottomColor,
127 CSSPropertyBorderBottomLeftRadius,
128 CSSPropertyBorderBottomRightRadius,
129 CSSPropertyBorderBottomStyle,
130 CSSPropertyBorderBottomWidth,
131 CSSPropertyBorderCollapse,
132 CSSPropertyBorderImageOutset,
133 CSSPropertyBorderImageRepeat,
134 CSSPropertyBorderImageSlice,
135 CSSPropertyBorderImageSource,
136 CSSPropertyBorderImageWidth,
137 CSSPropertyBorderLeftColor,
138 CSSPropertyBorderLeftStyle,
139 CSSPropertyBorderLeftWidth,
140 CSSPropertyBorderRightColor,
141 CSSPropertyBorderRightStyle,
142 CSSPropertyBorderRightWidth,
143 CSSPropertyBorderTopColor,
144 CSSPropertyBorderTopLeftRadius,
145 CSSPropertyBorderTopRightRadius,
146 CSSPropertyBorderTopStyle,
147 CSSPropertyBorderTopWidth,
149 CSSPropertyBoxShadow,
150 CSSPropertyBoxSizing,
151 CSSPropertyCaptionSide,
157 CSSPropertyDirection,
159 CSSPropertyEmptyCells,
161 CSSPropertyFontFamily,
163 CSSPropertyFontStyle,
164 CSSPropertyFontSynthesis,
165 CSSPropertyFontVariant,
166 CSSPropertyFontWeight,
168 #if ENABLE(CSS_IMAGE_ORIENTATION)
169 CSSPropertyImageOrientation,
171 CSSPropertyImageRendering,
172 #if ENABLE(CSS_IMAGE_RESOLUTION)
173 CSSPropertyImageResolution,
176 CSSPropertyLetterSpacing,
177 CSSPropertyLineHeight,
178 CSSPropertyListStyleImage,
179 CSSPropertyListStylePosition,
180 CSSPropertyListStyleType,
181 CSSPropertyMarginBottom,
182 CSSPropertyMarginLeft,
183 CSSPropertyMarginRight,
184 CSSPropertyMarginTop,
185 CSSPropertyMaxHeight,
187 CSSPropertyMinHeight,
191 CSSPropertyOutlineColor,
192 CSSPropertyOutlineOffset,
193 CSSPropertyOutlineStyle,
194 CSSPropertyOutlineWidth,
195 CSSPropertyOverflowWrap,
196 CSSPropertyOverflowX,
197 CSSPropertyOverflowY,
198 CSSPropertyPaddingBottom,
199 CSSPropertyPaddingLeft,
200 CSSPropertyPaddingRight,
201 CSSPropertyPaddingTop,
202 CSSPropertyPageBreakAfter,
203 CSSPropertyPageBreakBefore,
204 CSSPropertyPageBreakInside,
205 CSSPropertyPointerEvents,
210 CSSPropertyTableLayout,
212 CSSPropertyTextAlign,
213 CSSPropertyTextDecoration,
214 #if ENABLE(CSS3_TEXT)
215 CSSPropertyWebkitTextAlignLast,
216 CSSPropertyWebkitTextJustify,
218 CSSPropertyWebkitTextDecorationLine,
219 CSSPropertyWebkitTextDecorationStyle,
220 CSSPropertyWebkitTextDecorationColor,
221 CSSPropertyWebkitTextDecorationSkip,
222 CSSPropertyWebkitTextUnderlinePosition,
223 CSSPropertyTextIndent,
224 CSSPropertyTextRendering,
225 CSSPropertyTextShadow,
226 CSSPropertyTextOverflow,
227 CSSPropertyTextTransform,
229 CSSPropertyTransform,
230 CSSPropertyTransformOrigin,
231 CSSPropertyTransformStyle,
232 CSSPropertyTransitionDelay,
233 CSSPropertyTransitionDuration,
234 CSSPropertyTransitionProperty,
235 CSSPropertyTransitionTimingFunction,
236 CSSPropertyUnicodeBidi,
237 CSSPropertyVerticalAlign,
238 CSSPropertyVisibility,
239 CSSPropertyWhiteSpace,
242 CSSPropertyWordBreak,
243 CSSPropertyWordSpacing,
245 #if ENABLE(CSS_SCROLL_SNAP)
246 CSSPropertyWebkitScrollSnapType,
247 CSSPropertyWebkitScrollSnapPointsX,
248 CSSPropertyWebkitScrollSnapPointsY,
249 CSSPropertyWebkitScrollSnapDestination,
250 CSSPropertyWebkitScrollSnapCoordinate,
254 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
255 CSSPropertyWebkitAnimationTrigger,
257 CSSPropertyWebkitAppearance,
258 CSSPropertyWebkitBackfaceVisibility,
259 CSSPropertyWebkitBackgroundClip,
260 CSSPropertyWebkitBackgroundComposite,
261 CSSPropertyWebkitBackgroundOrigin,
262 CSSPropertyWebkitBackgroundSize,
263 #if ENABLE(CSS_COMPOSITING)
264 CSSPropertyMixBlendMode,
265 CSSPropertyIsolation,
267 CSSPropertyWebkitBorderFit,
268 CSSPropertyWebkitBorderHorizontalSpacing,
269 CSSPropertyWebkitBorderImage,
270 CSSPropertyWebkitBorderVerticalSpacing,
271 CSSPropertyWebkitBoxAlign,
272 #if ENABLE(CSS_BOX_DECORATION_BREAK)
273 CSSPropertyWebkitBoxDecorationBreak,
275 CSSPropertyWebkitBoxDirection,
276 CSSPropertyWebkitBoxFlex,
277 CSSPropertyWebkitBoxFlexGroup,
278 CSSPropertyWebkitBoxLines,
279 CSSPropertyWebkitBoxOrdinalGroup,
280 CSSPropertyWebkitBoxOrient,
281 CSSPropertyWebkitBoxPack,
282 CSSPropertyWebkitBoxReflect,
283 CSSPropertyWebkitBoxShadow,
284 CSSPropertyWebkitClipPath,
285 CSSPropertyWebkitColumnBreakAfter,
286 CSSPropertyWebkitColumnBreakBefore,
287 CSSPropertyWebkitColumnBreakInside,
288 CSSPropertyWebkitColumnAxis,
289 CSSPropertyColumnCount,
290 CSSPropertyColumnFill,
291 CSSPropertyColumnGap,
292 CSSPropertyColumnProgression,
293 CSSPropertyColumnRuleColor,
294 CSSPropertyColumnRuleStyle,
295 CSSPropertyColumnRuleWidth,
296 CSSPropertyColumnSpan,
297 CSSPropertyColumnWidth,
298 #if ENABLE(CURSOR_VISIBILITY)
299 CSSPropertyWebkitCursorVisibility,
301 #if ENABLE(DASHBOARD_SUPPORT)
302 CSSPropertyWebkitDashboardRegion,
304 CSSPropertyAlignContent,
305 CSSPropertyAlignItems,
306 CSSPropertyAlignSelf,
308 CSSPropertyFlexBasis,
310 CSSPropertyFlexShrink,
311 CSSPropertyFlexDirection,
313 CSSPropertyJustifyContent,
314 #if ENABLE(CSS_GRID_LAYOUT)
315 CSSPropertyJustifySelf,
316 CSSPropertyJustifyItems,
318 #if ENABLE(FILTERS_LEVEL_2)
319 CSSPropertyWebkitBackdropFilter,
321 CSSPropertyWebkitFontKerning,
322 CSSPropertyWebkitFontSmoothing,
323 CSSPropertyFontVariantLigatures,
324 CSSPropertyFontVariantPosition,
325 CSSPropertyFontVariantCaps,
326 CSSPropertyFontVariantNumeric,
327 CSSPropertyFontVariantAlternates,
328 CSSPropertyFontVariantEastAsian,
329 #if ENABLE(CSS_GRID_LAYOUT)
330 CSSPropertyGridAutoColumns,
331 CSSPropertyGridAutoFlow,
332 CSSPropertyGridAutoRows,
333 CSSPropertyGridColumnEnd,
334 CSSPropertyGridColumnStart,
335 CSSPropertyGridTemplateAreas,
336 CSSPropertyGridTemplateColumns,
337 CSSPropertyGridTemplateRows,
338 CSSPropertyGridRowEnd,
339 CSSPropertyGridRowStart,
340 CSSPropertyGridColumnGap,
341 CSSPropertyGridRowGap,
343 CSSPropertyWebkitHyphenateCharacter,
344 CSSPropertyWebkitHyphenateLimitAfter,
345 CSSPropertyWebkitHyphenateLimitBefore,
346 CSSPropertyWebkitHyphenateLimitLines,
347 CSSPropertyWebkitHyphens,
348 CSSPropertyWebkitInitialLetter,
349 CSSPropertyWebkitLineAlign,
350 CSSPropertyWebkitLineBoxContain,
351 CSSPropertyWebkitLineBreak,
352 CSSPropertyWebkitLineClamp,
353 CSSPropertyWebkitLineGrid,
354 CSSPropertyWebkitLineSnap,
355 CSSPropertyWebkitLocale,
356 CSSPropertyWebkitMarginBeforeCollapse,
357 CSSPropertyWebkitMarginAfterCollapse,
358 CSSPropertyWebkitMarqueeDirection,
359 CSSPropertyWebkitMarqueeIncrement,
360 CSSPropertyWebkitMarqueeRepetition,
361 CSSPropertyWebkitMarqueeStyle,
362 CSSPropertyWebkitMaskBoxImage,
363 CSSPropertyWebkitMaskBoxImageOutset,
364 CSSPropertyWebkitMaskBoxImageRepeat,
365 CSSPropertyWebkitMaskBoxImageSlice,
366 CSSPropertyWebkitMaskBoxImageSource,
367 CSSPropertyWebkitMaskBoxImageWidth,
368 CSSPropertyWebkitMaskClip,
369 CSSPropertyWebkitMaskComposite,
370 CSSPropertyWebkitMaskImage,
371 CSSPropertyWebkitMaskOrigin,
372 CSSPropertyWebkitMaskPosition,
373 CSSPropertyWebkitMaskRepeat,
374 CSSPropertyWebkitMaskSize,
375 CSSPropertyWebkitMaskSourceType,
376 CSSPropertyWebkitNbspMode,
378 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
379 CSSPropertyWebkitOverflowScrolling,
381 CSSPropertyPerspective,
382 CSSPropertyPerspectiveOrigin,
383 CSSPropertyWebkitPrintColorAdjust,
384 CSSPropertyWebkitRtlOrdering,
386 CSSPropertyWebkitTouchCallout,
388 CSSPropertyShapeOutside,
389 #if ENABLE(TOUCH_EVENTS)
390 CSSPropertyWebkitTapHighlightColor,
392 CSSPropertyWebkitTextCombine,
393 CSSPropertyWebkitTextDecorationsInEffect,
394 CSSPropertyWebkitTextEmphasisColor,
395 CSSPropertyWebkitTextEmphasisPosition,
396 CSSPropertyWebkitTextEmphasisStyle,
397 CSSPropertyWebkitTextFillColor,
398 CSSPropertyWebkitTextOrientation,
399 CSSPropertyWebkitTextSecurity,
400 #if ENABLE(TEXT_AUTOSIZING)
401 CSSPropertyWebkitTextSizeAdjust,
403 CSSPropertyWebkitTextStrokeColor,
404 CSSPropertyWebkitTextStrokeWidth,
405 CSSPropertyWebkitTextZoom,
406 CSSPropertyWebkitTransformStyle,
407 CSSPropertyWebkitUserDrag,
408 CSSPropertyWebkitUserModify,
409 CSSPropertyWebkitUserSelect,
410 CSSPropertyWebkitWritingMode,
411 #if ENABLE(CSS_REGIONS)
412 CSSPropertyWebkitFlowInto,
413 CSSPropertyWebkitFlowFrom,
414 CSSPropertyWebkitRegionBreakAfter,
415 CSSPropertyWebkitRegionBreakBefore,
416 CSSPropertyWebkitRegionBreakInside,
417 CSSPropertyWebkitRegionFragment,
419 CSSPropertyShapeMargin,
420 CSSPropertyShapeImageThreshold,
421 CSSPropertyBufferedRendering,
428 CSSPropertyFloodColor,
429 CSSPropertyFloodOpacity,
430 CSSPropertyLightingColor,
431 CSSPropertyStopColor,
432 CSSPropertyStopOpacity,
433 CSSPropertyColorInterpolation,
434 CSSPropertyColorInterpolationFilters,
435 CSSPropertyColorRendering,
437 CSSPropertyFillOpacity,
439 CSSPropertyMarkerEnd,
440 CSSPropertyMarkerMid,
441 CSSPropertyMarkerStart,
443 CSSPropertyPaintOrder,
447 CSSPropertyShapeRendering,
449 CSSPropertyStrokeDasharray,
450 CSSPropertyStrokeDashoffset,
451 CSSPropertyStrokeLinecap,
452 CSSPropertyStrokeLinejoin,
453 CSSPropertyStrokeMiterlimit,
454 CSSPropertyStrokeOpacity,
455 CSSPropertyStrokeWidth,
456 CSSPropertyAlignmentBaseline,
457 CSSPropertyBaselineShift,
458 CSSPropertyDominantBaseline,
460 CSSPropertyTextAnchor,
461 CSSPropertyWritingMode,
462 CSSPropertyGlyphOrientationHorizontal,
463 CSSPropertyGlyphOrientationVertical,
464 CSSPropertyWebkitSvgShadow,
465 CSSPropertyVectorEffect,
470 const unsigned numComputedProperties = WTF_ARRAY_LENGTH(computedProperties);
472 static CSSValueID valueForRepeatRule(int rule)
475 case RepeatImageRule:
476 return CSSValueRepeat;
478 return CSSValueRound;
480 return CSSValueSpace;
482 return CSSValueStretch;
486 static Ref<CSSPrimitiveValue> valueForImageSliceSide(const Length& length)
488 // These values can be percentages, numbers, or while an animation of mixed types is in progress,
489 // a calculation that combines a percentage and a number.
490 if (length.isPercent())
491 return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
492 if (length.isFixed())
493 return CSSValuePool::singleton().createValue(length.value(), CSSPrimitiveValue::CSS_NUMBER);
495 // Calculating the actual length currently in use would require most of the code from RenderBoxModelObject::paintNinePieceImage.
496 // And even if we could do that, it's not clear if that's exactly what we'd want during animation.
497 // FIXME: For now, just return 0.
498 ASSERT(length.isCalculated());
499 return CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_NUMBER);
502 static Ref<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
504 auto& slices = image.imageSlices();
506 RefPtr<CSSPrimitiveValue> top = valueForImageSliceSide(slices.top());
508 RefPtr<CSSPrimitiveValue> right;
509 RefPtr<CSSPrimitiveValue> bottom;
510 RefPtr<CSSPrimitiveValue> left;
512 if (slices.right() == slices.top() && slices.bottom() == slices.top() && slices.left() == slices.top()) {
517 right = valueForImageSliceSide(slices.right());
519 if (slices.bottom() == slices.top() && slices.right() == slices.left()) {
523 bottom = valueForImageSliceSide(slices.bottom());
525 if (slices.left() == slices.right())
528 left = valueForImageSliceSide(slices.left());
532 auto quad = Quad::create();
533 quad->setTop(WTFMove(top));
534 quad->setRight(WTFMove(right));
535 quad->setBottom(WTFMove(bottom));
536 quad->setLeft(WTFMove(left));
538 return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTFMove(quad)), image.fill());
541 static Ref<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box)
543 RefPtr<CSSPrimitiveValue> top;
544 RefPtr<CSSPrimitiveValue> right;
545 RefPtr<CSSPrimitiveValue> bottom;
546 RefPtr<CSSPrimitiveValue> left;
548 auto& cssValuePool = CSSValuePool::singleton();
550 if (box.top().isRelative())
551 top = cssValuePool.createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER);
553 top = cssValuePool.createValue(box.top());
555 if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) {
560 if (box.right().isRelative())
561 right = cssValuePool.createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER);
563 right = cssValuePool.createValue(box.right());
565 if (box.bottom() == box.top() && box.right() == box.left()) {
569 if (box.bottom().isRelative())
570 bottom = cssValuePool.createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
572 bottom = cssValuePool.createValue(box.bottom());
574 if (box.left() == box.right())
577 if (box.left().isRelative())
578 left = cssValuePool.createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER);
580 left = cssValuePool.createValue(box.left());
585 auto quad = Quad::create();
586 quad->setTop(WTFMove(top));
587 quad->setRight(WTFMove(right));
588 quad->setBottom(WTFMove(bottom));
589 quad->setLeft(WTFMove(left));
591 return cssValuePool.createValue(WTFMove(quad));
594 static Ref<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
596 auto& cssValuePool = CSSValuePool::singleton();
597 RefPtr<CSSPrimitiveValue> horizontalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
599 RefPtr<CSSPrimitiveValue> verticalRepeat;
600 if (image.horizontalRule() == image.verticalRule())
601 verticalRepeat = horizontalRepeat;
603 verticalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.verticalRule()));
604 return cssValuePool.createValue(Pair::create(WTFMove(horizontalRepeat), WTFMove(verticalRepeat)));
607 static Ref<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
609 if (!image.hasImage())
610 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
613 RefPtr<CSSValue> imageValue;
615 imageValue = image.image()->cssValue();
617 // Create the image slice.
618 RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
620 // Create the border area slices.
621 RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices());
623 // Create the border outset.
624 RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset());
626 // Create the repeat rules.
627 RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
629 return createBorderImageValue(WTFMove(imageValue), WTFMove(imageSlices), WTFMove(borderSlices), WTFMove(outset), WTFMove(repeat));
632 inline static Ref<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style)
634 return CSSValuePool::singleton().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
637 inline static Ref<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style)
639 return CSSValuePool::singleton().createValue(value / style.effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
642 static Ref<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style)
644 if (length.isFixed())
645 return zoomAdjustedPixelValue(length.value(), style);
646 return CSSValuePool::singleton().createValue(length, style);
649 static Ref<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style)
652 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
654 RefPtr<CSSPrimitiveValue> offset;
655 if (reflection->offset().isPercentOrCalculated())
656 offset = CSSValuePool::singleton().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
658 offset = zoomAdjustedPixelValue(reflection->offset().value(), style);
660 RefPtr<CSSPrimitiveValue> direction;
661 switch (reflection->direction()) {
662 case ReflectionBelow:
663 direction = CSSValuePool::singleton().createIdentifierValue(CSSValueBelow);
665 case ReflectionAbove:
666 direction = CSSValuePool::singleton().createIdentifierValue(CSSValueAbove);
669 direction = CSSValuePool::singleton().createIdentifierValue(CSSValueLeft);
671 case ReflectionRight:
672 direction = CSSValuePool::singleton().createIdentifierValue(CSSValueRight);
676 return CSSReflectValue::create(direction.releaseNonNull(), offset.releaseNonNull(), valueForNinePieceImage(reflection->mask()));
679 static Ref<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle& style)
681 auto positionList = CSSValueList::createSpaceSeparated();
682 if (layer->isBackgroundOriginSet()) {
683 ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
684 positionList.get().append(CSSValuePool::singleton().createValue(layer->backgroundXOrigin()));
686 positionList.get().append(zoomAdjustedPixelValueForLength(layer->xPosition(), style));
687 if (layer->isBackgroundOriginSet()) {
688 ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
689 positionList.get().append(CSSValuePool::singleton().createValue(layer->backgroundYOrigin()));
691 positionList.get().append(zoomAdjustedPixelValueForLength(layer->yPosition(), style));
695 static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID)
698 switch (propertyID) {
699 case CSSPropertyLeft:
700 length = style.left();
702 case CSSPropertyRight:
703 length = style.right();
706 length = style.top();
708 case CSSPropertyBottom:
709 length = style.bottom();
715 if (style.hasOutOfFlowPosition()) {
716 if (length.isFixed())
717 return zoomAdjustedPixelValue(length.value(), style);
719 return CSSValuePool::singleton().createValue(length);
722 if (style.hasInFlowPosition()) {
723 // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
724 // In other words if left is auto and right is not auto, then left's computed value is negative right().
725 // So we should get the opposite length unit and see if it is auto.
726 return CSSValuePool::singleton().createValue(length);
729 return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
732 RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::currentColorOrValidColor(const RenderStyle* style, const Color& color) const
734 // This function does NOT look at visited information, so that computed style doesn't expose that.
735 if (!color.isValid())
736 return CSSValuePool::singleton().createColorValue(style->color().rgb());
737 return CSSValuePool::singleton().createColorValue(color.rgb());
740 static Ref<CSSPrimitiveValue> percentageOrZoomAdjustedValue(Length length, const RenderStyle& style)
742 if (length.isPercent())
743 return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
745 return zoomAdjustedPixelValue(valueForLength(length, 0), style);
748 static Ref<CSSPrimitiveValue> autoOrZoomAdjustedValue(Length length, const RenderStyle& style)
751 return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
753 return zoomAdjustedPixelValue(valueForLength(length, 0), style);
756 static Ref<CSSValueList> getBorderRadiusCornerValues(const LengthSize& radius, const RenderStyle& style)
758 auto list = CSSValueList::createSpaceSeparated();
759 list.get().append(percentageOrZoomAdjustedValue(radius.width(), style));
760 list.get().append(percentageOrZoomAdjustedValue(radius.height(), style));
764 static Ref<CSSValue> getBorderRadiusCornerValue(const LengthSize& radius, const RenderStyle& style)
766 if (radius.width() == radius.height())
767 return percentageOrZoomAdjustedValue(radius.width(), style);
769 return getBorderRadiusCornerValues(radius, style);
772 static Ref<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle& style)
774 auto list = CSSValueList::createSlashSeparated();
775 bool showHorizontalBottomLeft = style.borderTopRightRadius().width() != style.borderBottomLeftRadius().width();
776 bool showHorizontalBottomRight = showHorizontalBottomLeft || (style.borderBottomRightRadius().width() != style.borderTopLeftRadius().width());
777 bool showHorizontalTopRight = showHorizontalBottomRight || (style.borderTopRightRadius().width() != style.borderTopLeftRadius().width());
779 bool showVerticalBottomLeft = style.borderTopRightRadius().height() != style.borderBottomLeftRadius().height();
780 bool showVerticalBottomRight = showVerticalBottomLeft || (style.borderBottomRightRadius().height() != style.borderTopLeftRadius().height());
781 bool showVerticalTopRight = showVerticalBottomRight || (style.borderTopRightRadius().height() != style.borderTopLeftRadius().height());
783 RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style.borderTopLeftRadius(), style);
784 RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style.borderTopRightRadius(), style);
785 RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style.borderBottomRightRadius(), style);
786 RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style.borderBottomLeftRadius(), style);
788 RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
789 horizontalRadii->append(*topLeftRadius->item(0));
790 if (showHorizontalTopRight)
791 horizontalRadii->append(*topRightRadius->item(0));
792 if (showHorizontalBottomRight)
793 horizontalRadii->append(*bottomRightRadius->item(0));
794 if (showHorizontalBottomLeft)
795 horizontalRadii->append(*bottomLeftRadius->item(0));
797 list.get().append(horizontalRadii.releaseNonNull());
799 RefPtr<CSSValueList> verticalRadiiList = CSSValueList::createSpaceSeparated();
800 verticalRadiiList->append(*topLeftRadius->item(1));
801 if (showVerticalTopRight)
802 verticalRadiiList->append(*topRightRadius->item(1));
803 if (showVerticalBottomRight)
804 verticalRadiiList->append(*bottomRightRadius->item(1));
805 if (showVerticalBottomLeft)
806 verticalRadiiList->append(*bottomLeftRadius->item(1));
808 if (!verticalRadiiList->equals(downcast<CSSValueList>(*list.get().item(0))))
809 list.get().append(verticalRadiiList.releaseNonNull());
814 static LayoutRect sizingBox(RenderObject& renderer)
816 if (!is<RenderBox>(renderer))
819 auto& box = downcast<RenderBox>(renderer);
820 return box.style().boxSizing() == BORDER_BOX ? box.borderBoxRect() : box.computedCSSContentBoxRect();
823 static Ref<WebKitCSSTransformValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle& style)
825 RefPtr<WebKitCSSTransformValue> transformValue;
826 auto& cssValuePool = CSSValuePool::singleton();
827 if (transform.isAffine()) {
828 transformValue = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation);
830 transformValue->append(cssValuePool.createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
831 transformValue->append(cssValuePool.createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
832 transformValue->append(cssValuePool.createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
833 transformValue->append(cssValuePool.createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
834 transformValue->append(zoomAdjustedNumberValue(transform.e(), style));
835 transformValue->append(zoomAdjustedNumberValue(transform.f(), style));
837 transformValue = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation);
839 transformValue->append(cssValuePool.createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
840 transformValue->append(cssValuePool.createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
841 transformValue->append(cssValuePool.createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
842 transformValue->append(cssValuePool.createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
844 transformValue->append(cssValuePool.createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
845 transformValue->append(cssValuePool.createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
846 transformValue->append(cssValuePool.createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
847 transformValue->append(cssValuePool.createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
849 transformValue->append(cssValuePool.createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
850 transformValue->append(cssValuePool.createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
851 transformValue->append(cssValuePool.createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
852 transformValue->append(cssValuePool.createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
854 transformValue->append(zoomAdjustedNumberValue(transform.m41(), style));
855 transformValue->append(zoomAdjustedNumberValue(transform.m42(), style));
856 transformValue->append(zoomAdjustedNumberValue(transform.m43(), style));
857 transformValue->append(cssValuePool.createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
860 return transformValue.releaseNonNull();
863 static Ref<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style)
865 if (!renderer || !renderer->hasTransform())
866 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
868 FloatRect pixelSnappedRect;
869 if (is<RenderBox>(*renderer))
870 pixelSnappedRect = snapRectToDevicePixels(downcast<RenderBox>(*renderer).borderBoxRect(), renderer->document().deviceScaleFactor());
872 TransformationMatrix transform;
873 style.applyTransform(transform, pixelSnappedRect, RenderStyle::ExcludeTransformOrigin);
874 // Note that this does not flatten to an affine transform if ENABLE(3D_TRANSFORMS) is off, by design.
876 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
877 auto list = CSSValueList::createSpaceSeparated();
878 list.get().append(matrixTransformValue(transform, style));
879 return WTFMove(list);
882 static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(double length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
884 return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length, style) : CSSValuePool::singleton().createValue(length, CSSPrimitiveValue::CSS_PX);
887 static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(const Length& length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
889 return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length.value(), style) : CSSValuePool::singleton().createValue(length);
892 Ref<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
894 auto& cssValuePool = CSSValuePool::singleton();
896 return cssValuePool.createIdentifierValue(CSSValueNone);
898 auto list = CSSValueList::createCommaSeparated();
899 for (const ShadowData* currShadowData = shadow; currShadowData; currShadowData = currShadowData->next()) {
900 auto x = adjustLengthForZoom(currShadowData->x(), style, adjust);
901 auto y = adjustLengthForZoom(currShadowData->y(), style, adjust);
902 auto blur = adjustLengthForZoom(currShadowData->radius(), style, adjust);
903 auto spread = propertyID == CSSPropertyTextShadow ? RefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust);
904 auto style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? RefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset);
905 auto color = cssValuePool.createColorValue(currShadowData->color().rgb());
906 list->prepend(CSSShadowValue::create(WTFMove(x), WTFMove(y), WTFMove(blur), WTFMove(spread), WTFMove(style), WTFMove(color)));
908 return WTFMove(list);
911 Ref<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderStyle& style, const FilterOperations& filterOperations, AdjustPixelValuesForComputedStyle adjust)
913 auto& cssValuePool = CSSValuePool::singleton();
914 if (filterOperations.operations().isEmpty())
915 return cssValuePool.createIdentifierValue(CSSValueNone);
917 auto list = CSSValueList::createSpaceSeparated();
919 RefPtr<WebKitCSSFilterValue> filterValue;
921 Vector<RefPtr<FilterOperation>>::const_iterator end = filterOperations.operations().end();
922 for (Vector<RefPtr<FilterOperation>>::const_iterator it = filterOperations.operations().begin(); it != end; ++it) {
923 FilterOperation& filterOperation = **it;
924 switch (filterOperation.type()) {
925 case FilterOperation::REFERENCE: {
926 ReferenceFilterOperation& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation);
927 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation);
928 filterValue->append(cssValuePool.createValue(referenceOperation.url(), CSSPrimitiveValue::CSS_URI));
931 case FilterOperation::GRAYSCALE: {
932 BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
933 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::GrayscaleFilterOperation);
934 filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
937 case FilterOperation::SEPIA: {
938 BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
939 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SepiaFilterOperation);
940 filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
943 case FilterOperation::SATURATE: {
944 BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
945 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SaturateFilterOperation);
946 filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
949 case FilterOperation::HUE_ROTATE: {
950 BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
951 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::HueRotateFilterOperation);
952 filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_DEG));
955 case FilterOperation::INVERT: {
956 BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
957 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::InvertFilterOperation);
958 filterValue->append(cssValuePool.createValue(componentTransferOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
961 case FilterOperation::OPACITY: {
962 BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
963 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::OpacityFilterOperation);
964 filterValue->append(cssValuePool.createValue(componentTransferOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
967 case FilterOperation::BRIGHTNESS: {
968 BasicComponentTransferFilterOperation& brightnessOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
969 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BrightnessFilterOperation);
970 filterValue->append(cssValuePool.createValue(brightnessOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
973 case FilterOperation::CONTRAST: {
974 BasicComponentTransferFilterOperation& contrastOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
975 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ContrastFilterOperation);
976 filterValue->append(cssValuePool.createValue(contrastOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
979 case FilterOperation::BLUR: {
980 BlurFilterOperation& blurOperation = downcast<BlurFilterOperation>(filterOperation);
981 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BlurFilterOperation);
982 filterValue->append(adjustLengthForZoom(blurOperation.stdDeviation(), style, adjust));
985 case FilterOperation::DROP_SHADOW: {
986 DropShadowFilterOperation& dropShadowOperation = downcast<DropShadowFilterOperation>(filterOperation);
987 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::DropShadowFilterOperation);
988 // We want our computed style to look like that of a text shadow (has neither spread nor inset style).
989 ShadowData shadowData = ShadowData(dropShadowOperation.location(), dropShadowOperation.stdDeviation(), 0, Normal, false, dropShadowOperation.color());
990 filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style, adjust));
994 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::UnknownFilterOperation);
997 list.get().append(filterValue.releaseNonNull());
1000 return WTFMove(list);
1003 #if ENABLE(CSS_GRID_LAYOUT)
1004 static Ref<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style)
1006 if (!trackBreadth.isLength())
1007 return CSSValuePool::singleton().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR);
1009 const Length& trackBreadthLength = trackBreadth.length();
1010 if (trackBreadthLength.isAuto())
1011 return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1012 return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
1015 static Ref<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style)
1017 switch (trackSize.type()) {
1018 case LengthTrackSizing:
1019 return specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style);
1020 case FitContentTrackSizing: {
1021 auto fitContentTrackSize = CSSValueList::createCommaSeparated();
1022 fitContentTrackSize->append(zoomAdjustedPixelValueForLength(trackSize.fitContentTrackBreadth().length(), style));
1023 return CSSFunctionValue::create("fit-content(", WTFMove(fitContentTrackSize));
1026 ASSERT(trackSize.type() == MinMaxTrackSizing);
1027 auto minMaxTrackBreadths = CSSValueList::createCommaSeparated();
1028 minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style));
1029 minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style));
1030 return CSSFunctionValue::create("minmax(", WTFMove(minMaxTrackBreadths));
1034 class OrderedNamedLinesCollector {
1035 WTF_MAKE_NONCOPYABLE(OrderedNamedLinesCollector);
1037 OrderedNamedLinesCollector(const RenderStyle& style, bool isRowAxis, unsigned autoRepeatTracksCount)
1038 : m_orderedNamedGridLines(isRowAxis ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines())
1039 , m_orderedNamedAutoRepeatGridLines(isRowAxis ? style.autoRepeatOrderedNamedGridColumnLines() : style.autoRepeatOrderedNamedGridRowLines())
1040 , m_insertionPoint(isRowAxis ? style.gridAutoRepeatColumnsInsertionPoint() : style.gridAutoRepeatRowsInsertionPoint())
1041 , m_autoRepeatTotalTracks(autoRepeatTracksCount)
1042 , m_autoRepeatTrackListLength(isRowAxis ? style.gridAutoRepeatColumns().size() : style.gridAutoRepeatRows().size())
1046 bool isEmpty() const { return m_orderedNamedGridLines.isEmpty() && m_orderedNamedAutoRepeatGridLines.isEmpty(); }
1047 void collectLineNamesForIndex(CSSGridLineNamesValue&, unsigned index) const;
1051 enum NamedLinesType { NamedLines, AutoRepeatNamedLines };
1052 void appendLines(CSSGridLineNamesValue&, unsigned index, NamedLinesType) const;
1054 const OrderedNamedGridLinesMap& m_orderedNamedGridLines;
1055 const OrderedNamedGridLinesMap& m_orderedNamedAutoRepeatGridLines;
1056 unsigned m_insertionPoint;
1057 unsigned m_autoRepeatTotalTracks;
1058 unsigned m_autoRepeatTrackListLength;
1061 void OrderedNamedLinesCollector::appendLines(CSSGridLineNamesValue& lineNamesValue, unsigned index, NamedLinesType type) const
1063 auto iter = type == NamedLines ? m_orderedNamedGridLines.find(index) : m_orderedNamedAutoRepeatGridLines.find(index);
1064 auto endIter = type == NamedLines ? m_orderedNamedGridLines.end() : m_orderedNamedAutoRepeatGridLines.end();
1065 if (iter == endIter)
1068 auto& cssValuePool = CSSValuePool::singleton();
1069 for (auto lineName : iter->value)
1070 lineNamesValue.append(cssValuePool.createValue(lineName, CSSPrimitiveValue::CSS_STRING));
1073 void OrderedNamedLinesCollector::collectLineNamesForIndex(CSSGridLineNamesValue& lineNamesValue, unsigned i) const
1076 if (m_orderedNamedAutoRepeatGridLines.isEmpty() || i < m_insertionPoint) {
1077 appendLines(lineNamesValue, i, NamedLines);
1081 ASSERT(m_autoRepeatTotalTracks);
1083 if (i > m_insertionPoint + m_autoRepeatTotalTracks) {
1084 appendLines(lineNamesValue, i - (m_autoRepeatTotalTracks - 1), NamedLines);
1088 if (i == m_insertionPoint) {
1089 appendLines(lineNamesValue, i, NamedLines);
1090 appendLines(lineNamesValue, 0, AutoRepeatNamedLines);
1094 if (i == m_insertionPoint + m_autoRepeatTotalTracks) {
1095 appendLines(lineNamesValue, m_autoRepeatTrackListLength, AutoRepeatNamedLines);
1096 appendLines(lineNamesValue, m_insertionPoint + 1, NamedLines);
1100 unsigned autoRepeatIndexInFirstRepetition = (i - m_insertionPoint) % m_autoRepeatTrackListLength;
1101 if (!autoRepeatIndexInFirstRepetition && i > m_insertionPoint)
1102 appendLines(lineNamesValue, m_autoRepeatTrackListLength, AutoRepeatNamedLines);
1103 appendLines(lineNamesValue, autoRepeatIndexInFirstRepetition, AutoRepeatNamedLines);
1106 static void addValuesForNamedGridLinesAtIndex(OrderedNamedLinesCollector& collector, unsigned i, CSSValueList& list)
1108 if (collector.isEmpty())
1111 auto lineNames = CSSGridLineNamesValue::create();
1112 collector.collectLineNamesForIndex(lineNames.get(), i);
1113 if (lineNames->length())
1114 list.append(WTFMove(lineNames));
1117 static Ref<CSSValueList> valueForGridTrackSizeList(GridTrackSizingDirection direction, const RenderStyle& style)
1119 auto& autoTrackSizes = direction == ForColumns ? style.gridAutoColumns() : style.gridAutoRows();
1121 auto list = CSSValueList::createSpaceSeparated();
1122 for (auto& trackSize : autoTrackSizes)
1123 list->append(specifiedValueForGridTrackSize(trackSize, style));
1127 static Ref<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style)
1129 bool isRowAxis = direction == ForColumns;
1130 bool isRenderGrid = is<RenderGrid>(renderer);
1131 auto& trackSizes = isRowAxis ? style.gridColumns() : style.gridRows();
1132 auto& autoRepeatTrackSizes = isRowAxis ? style.gridAutoRepeatColumns() : style.gridAutoRepeatRows();
1134 // Handle the 'none' case.
1135 bool trackListIsEmpty = trackSizes.isEmpty() && autoRepeatTrackSizes.isEmpty();
1136 if (isRenderGrid && trackListIsEmpty) {
1137 // For grids we should consider every listed track, whether implicitly or explicitly
1138 // created. Empty grids have a sole grid line per axis.
1139 auto& grid = downcast<RenderGrid>(*renderer);
1140 auto& positions = isRowAxis ? grid.columnPositions() : grid.rowPositions();
1141 trackListIsEmpty = positions.size() == 1;
1144 if (trackListIsEmpty)
1145 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1147 unsigned autoRepeatTotalTracks = isRenderGrid ? downcast<RenderGrid>(renderer)->autoRepeatCountForDirection(direction) : 0;
1148 OrderedNamedLinesCollector collector(style, isRowAxis, autoRepeatTotalTracks);
1149 auto list = CSSValueList::createSpaceSeparated();
1150 unsigned insertionIndex;
1152 auto computedTrackSizes = downcast<RenderGrid>(*renderer).trackSizesForComputedStyle(direction);
1153 unsigned numTracks = computedTrackSizes.size();
1155 for (unsigned i = 0; i < numTracks; ++i) {
1156 addValuesForNamedGridLinesAtIndex(collector, i, list.get());
1157 list->append(zoomAdjustedPixelValue(computedTrackSizes[i], style));
1159 addValuesForNamedGridLinesAtIndex(collector, numTracks + 1, list.get());
1160 insertionIndex = numTracks;
1162 for (unsigned i = 0; i < trackSizes.size(); ++i) {
1163 addValuesForNamedGridLinesAtIndex(collector, i, list.get());
1164 list.get().append(specifiedValueForGridTrackSize(trackSizes[i], style));
1166 insertionIndex = trackSizes.size();
1169 // Those are the trailing <ident>* allowed in the syntax.
1170 addValuesForNamedGridLinesAtIndex(collector, insertionIndex, list.get());
1171 return WTFMove(list);
1174 static Ref<CSSValue> valueForGridPosition(const GridPosition& position)
1176 auto& cssValuePool = CSSValuePool::singleton();
1177 if (position.isAuto())
1178 return cssValuePool.createIdentifierValue(CSSValueAuto);
1180 if (position.isNamedGridArea())
1181 return cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING);
1183 auto list = CSSValueList::createSpaceSeparated();
1184 if (position.isSpan()) {
1185 list.get().append(cssValuePool.createIdentifierValue(CSSValueSpan));
1186 list.get().append(cssValuePool.createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
1188 list.get().append(cssValuePool.createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER));
1190 if (!position.namedGridLine().isNull())
1191 list.get().append(cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
1192 return WTFMove(list);
1196 static Ref<CSSValue> createTransitionPropertyValue(const Animation& animation)
1198 if (animation.animationMode() == Animation::AnimateNone)
1199 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1200 if (animation.animationMode() == Animation::AnimateAll)
1201 return CSSValuePool::singleton().createIdentifierValue(CSSValueAll);
1202 return CSSValuePool::singleton().createValue(getPropertyNameString(animation.property()), CSSPrimitiveValue::CSS_STRING);
1205 static Ref<CSSValueList> getTransitionPropertyValue(const AnimationList* animList)
1207 auto list = CSSValueList::createCommaSeparated();
1209 for (size_t i = 0; i < animList->size(); ++i)
1210 list.get().append(createTransitionPropertyValue(animList->animation(i)));
1212 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAll));
1216 #if ENABLE(CSS_SCROLL_SNAP)
1217 static Ref<CSSValueList> scrollSnapDestination(const RenderStyle& style, const LengthSize& destination)
1219 auto list = CSSValueList::createSpaceSeparated();
1220 list.get().append(zoomAdjustedPixelValueForLength(destination.width(), style));
1221 list.get().append(zoomAdjustedPixelValueForLength(destination.height(), style));
1225 static Ref<CSSValue> scrollSnapPoints(const RenderStyle& style, const ScrollSnapPoints* points)
1228 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1230 if (points->usesElements)
1231 return CSSValuePool::singleton().createIdentifierValue(CSSValueElements);
1232 auto list = CSSValueList::createSpaceSeparated();
1233 for (auto& point : points->offsets)
1234 list.get().append(zoomAdjustedPixelValueForLength(point, style));
1235 if (points->hasRepeat)
1236 list.get().append(CSSValuePool::singleton().createValue(LengthRepeat::create(zoomAdjustedPixelValueForLength(points->repeatOffset, style))));
1237 return WTFMove(list);
1240 static Ref<CSSValue> scrollSnapCoordinates(const RenderStyle& style, const Vector<LengthSize>& coordinates)
1242 if (coordinates.isEmpty())
1243 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1245 auto list = CSSValueList::createCommaSeparated();
1247 for (auto& coordinate : coordinates) {
1248 auto pair = CSSValueList::createSpaceSeparated();
1249 pair.get().append(zoomAdjustedPixelValueForLength(coordinate.width(), style));
1250 pair.get().append(zoomAdjustedPixelValueForLength(coordinate.height(), style));
1251 list.get().append(WTFMove(pair));
1254 return WTFMove(list);
1258 static Ref<CSSValue> getWillChangePropertyValue(const WillChangeData* willChangeData)
1260 auto& cssValuePool = CSSValuePool::singleton();
1261 if (!willChangeData || !willChangeData->numFeatures())
1262 return cssValuePool.createIdentifierValue(CSSValueAuto);
1264 auto list = CSSValueList::createCommaSeparated();
1265 for (size_t i = 0; i < willChangeData->numFeatures(); ++i) {
1266 WillChangeData::FeaturePropertyPair feature = willChangeData->featureAt(i);
1267 switch (feature.first) {
1268 case WillChangeData::ScrollPosition:
1269 list.get().append(cssValuePool.createIdentifierValue(CSSValueScrollPosition));
1271 case WillChangeData::Contents:
1272 list.get().append(cssValuePool.createIdentifierValue(CSSValueContents));
1274 case WillChangeData::Property:
1275 list.get().append(cssValuePool.createIdentifierValue(feature.second));
1277 case WillChangeData::Invalid:
1278 ASSERT_NOT_REACHED();
1283 return WTFMove(list);
1286 static inline void appendLigaturesValue(CSSValueList& list, FontVariantLigatures value, CSSValueID yesValue, CSSValueID noValue)
1289 case FontVariantLigatures::Normal:
1291 case FontVariantLigatures::No:
1292 list.append(CSSValuePool::singleton().createIdentifierValue(noValue));
1294 case FontVariantLigatures::Yes:
1295 list.append(CSSValuePool::singleton().createIdentifierValue(yesValue));
1298 ASSERT_NOT_REACHED();
1301 static Ref<CSSValue> fontVariantLigaturesPropertyValue(FontVariantLigatures common, FontVariantLigatures discretionary, FontVariantLigatures historical, FontVariantLigatures contextualAlternates)
1303 auto& cssValuePool = CSSValuePool::singleton();
1304 if (common == FontVariantLigatures::No && discretionary == FontVariantLigatures::No && historical == FontVariantLigatures::No && contextualAlternates == FontVariantLigatures::No)
1305 return cssValuePool.createIdentifierValue(CSSValueNone);
1306 if (common == FontVariantLigatures::Normal && discretionary == FontVariantLigatures::Normal && historical == FontVariantLigatures::Normal && contextualAlternates == FontVariantLigatures::Normal)
1307 return cssValuePool.createIdentifierValue(CSSValueNormal);
1309 auto valueList = CSSValueList::createSpaceSeparated();
1310 appendLigaturesValue(valueList, common, CSSValueCommonLigatures, CSSValueNoCommonLigatures);
1311 appendLigaturesValue(valueList, discretionary, CSSValueDiscretionaryLigatures, CSSValueNoDiscretionaryLigatures);
1312 appendLigaturesValue(valueList, historical, CSSValueHistoricalLigatures, CSSValueNoHistoricalLigatures);
1313 appendLigaturesValue(valueList, contextualAlternates, CSSValueContextual, CSSValueNoContextual);
1314 return WTFMove(valueList);
1317 static Ref<CSSValue> fontVariantPositionPropertyValue(FontVariantPosition position)
1319 auto& cssValuePool = CSSValuePool::singleton();
1320 CSSValueID valueID = CSSValueNormal;
1322 case FontVariantPosition::Normal:
1324 case FontVariantPosition::Subscript:
1325 valueID = CSSValueSub;
1327 case FontVariantPosition::Superscript:
1328 valueID = CSSValueSuper;
1331 return cssValuePool.createIdentifierValue(valueID);
1334 static Ref<CSSValue> fontVariantCapsPropertyValue(FontVariantCaps caps)
1336 auto& cssValuePool = CSSValuePool::singleton();
1337 CSSValueID valueID = CSSValueNormal;
1339 case FontVariantCaps::Normal:
1341 case FontVariantCaps::Small:
1342 valueID = CSSValueSmallCaps;
1344 case FontVariantCaps::AllSmall:
1345 valueID = CSSValueAllSmallCaps;
1347 case FontVariantCaps::Petite:
1348 valueID = CSSValuePetiteCaps;
1350 case FontVariantCaps::AllPetite:
1351 valueID = CSSValueAllPetiteCaps;
1353 case FontVariantCaps::Unicase:
1354 valueID = CSSValueUnicase;
1356 case FontVariantCaps::Titling:
1357 valueID = CSSValueTitlingCaps;
1360 return cssValuePool.createIdentifierValue(valueID);
1363 static Ref<CSSValue> fontVariantNumericPropertyValue(FontVariantNumericFigure figure, FontVariantNumericSpacing spacing, FontVariantNumericFraction fraction, FontVariantNumericOrdinal ordinal, FontVariantNumericSlashedZero slashedZero)
1365 auto& cssValuePool = CSSValuePool::singleton();
1366 if (figure == FontVariantNumericFigure::Normal && spacing == FontVariantNumericSpacing::Normal && fraction == FontVariantNumericFraction::Normal && ordinal == FontVariantNumericOrdinal::Normal && slashedZero == FontVariantNumericSlashedZero::Normal)
1367 return cssValuePool.createIdentifierValue(CSSValueNormal);
1369 auto valueList = CSSValueList::createSpaceSeparated();
1371 case FontVariantNumericFigure::Normal:
1373 case FontVariantNumericFigure::LiningNumbers:
1374 valueList->append(cssValuePool.createIdentifierValue(CSSValueLiningNums));
1376 case FontVariantNumericFigure::OldStyleNumbers:
1377 valueList->append(cssValuePool.createIdentifierValue(CSSValueOldstyleNums));
1382 case FontVariantNumericSpacing::Normal:
1384 case FontVariantNumericSpacing::ProportionalNumbers:
1385 valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalNums));
1387 case FontVariantNumericSpacing::TabularNumbers:
1388 valueList->append(cssValuePool.createIdentifierValue(CSSValueTabularNums));
1393 case FontVariantNumericFraction::Normal:
1395 case FontVariantNumericFraction::DiagonalFractions:
1396 valueList->append(cssValuePool.createIdentifierValue(CSSValueDiagonalFractions));
1398 case FontVariantNumericFraction::StackedFractions:
1399 valueList->append(cssValuePool.createIdentifierValue(CSSValueStackedFractions));
1403 if (ordinal == FontVariantNumericOrdinal::Yes)
1404 valueList->append(cssValuePool.createIdentifierValue(CSSValueOrdinal));
1405 if (slashedZero == FontVariantNumericSlashedZero::Yes)
1406 valueList->append(cssValuePool.createIdentifierValue(CSSValueSlashedZero));
1408 return WTFMove(valueList);
1411 static Ref<CSSValue> fontVariantAlternatesPropertyValue(FontVariantAlternates alternates)
1413 auto& cssValuePool = CSSValuePool::singleton();
1414 CSSValueID valueID = CSSValueNormal;
1415 switch (alternates) {
1416 case FontVariantAlternates::Normal:
1418 case FontVariantAlternates::HistoricalForms:
1419 valueID = CSSValueHistoricalForms;
1422 return cssValuePool.createIdentifierValue(valueID);
1425 static Ref<CSSValue> fontVariantEastAsianPropertyValue(FontVariantEastAsianVariant variant, FontVariantEastAsianWidth width, FontVariantEastAsianRuby ruby)
1427 auto& cssValuePool = CSSValuePool::singleton();
1428 if (variant == FontVariantEastAsianVariant::Normal && width == FontVariantEastAsianWidth::Normal && ruby == FontVariantEastAsianRuby::Normal)
1429 return cssValuePool.createIdentifierValue(CSSValueNormal);
1431 auto valueList = CSSValueList::createSpaceSeparated();
1433 case FontVariantEastAsianVariant::Normal:
1435 case FontVariantEastAsianVariant::Jis78:
1436 valueList->append(cssValuePool.createIdentifierValue(CSSValueJis78));
1438 case FontVariantEastAsianVariant::Jis83:
1439 valueList->append(cssValuePool.createIdentifierValue(CSSValueJis83));
1441 case FontVariantEastAsianVariant::Jis90:
1442 valueList->append(cssValuePool.createIdentifierValue(CSSValueJis90));
1444 case FontVariantEastAsianVariant::Jis04:
1445 valueList->append(cssValuePool.createIdentifierValue(CSSValueJis04));
1447 case FontVariantEastAsianVariant::Simplified:
1448 valueList->append(cssValuePool.createIdentifierValue(CSSValueSimplified));
1450 case FontVariantEastAsianVariant::Traditional:
1451 valueList->append(cssValuePool.createIdentifierValue(CSSValueTraditional));
1456 case FontVariantEastAsianWidth::Normal:
1458 case FontVariantEastAsianWidth::Full:
1459 valueList->append(cssValuePool.createIdentifierValue(CSSValueFullWidth));
1461 case FontVariantEastAsianWidth::Proportional:
1462 valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalWidth));
1466 if (ruby == FontVariantEastAsianRuby::Yes)
1467 valueList->append(cssValuePool.createIdentifierValue(CSSValueRuby));
1469 return WTFMove(valueList);
1472 static Ref<CSSValueList> getDelayValue(const AnimationList* animList)
1474 auto& cssValuePool = CSSValuePool::singleton();
1475 auto list = CSSValueList::createCommaSeparated();
1477 for (size_t i = 0; i < animList->size(); ++i)
1478 list.get().append(cssValuePool.createValue(animList->animation(i).delay(), CSSPrimitiveValue::CSS_S));
1480 // Note that initialAnimationDelay() is used for both transitions and animations
1481 list.get().append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
1486 static Ref<CSSValueList> getDurationValue(const AnimationList* animList)
1488 auto& cssValuePool = CSSValuePool::singleton();
1489 auto list = CSSValueList::createCommaSeparated();
1491 for (size_t i = 0; i < animList->size(); ++i)
1492 list.get().append(cssValuePool.createValue(animList->animation(i).duration(), CSSPrimitiveValue::CSS_S));
1494 // Note that initialAnimationDuration() is used for both transitions and animations
1495 list.get().append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
1500 static Ref<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
1502 switch (timingFunction->type()) {
1503 case TimingFunction::CubicBezierFunction: {
1504 auto& function = *static_cast<const CubicBezierTimingFunction*>(timingFunction);
1505 if (function.timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
1506 CSSValueID valueId = CSSValueInvalid;
1507 switch (function.timingFunctionPreset()) {
1508 case CubicBezierTimingFunction::Ease:
1509 valueId = CSSValueEase;
1511 case CubicBezierTimingFunction::EaseIn:
1512 valueId = CSSValueEaseIn;
1514 case CubicBezierTimingFunction::EaseOut:
1515 valueId = CSSValueEaseOut;
1518 ASSERT(function.timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
1519 valueId = CSSValueEaseInOut;
1522 return CSSValuePool::singleton().createIdentifierValue(valueId);
1524 return CSSCubicBezierTimingFunctionValue::create(function.x1(), function.y1(), function.x2(), function.y2());
1526 case TimingFunction::StepsFunction: {
1527 auto& function = *static_cast<const StepsTimingFunction*>(timingFunction);
1528 return CSSStepsTimingFunctionValue::create(function.numberOfSteps(), function.stepAtStart());
1530 case TimingFunction::SpringFunction: {
1531 auto& function = *static_cast<const SpringTimingFunction*>(timingFunction);
1532 return CSSSpringTimingFunctionValue::create(function.mass(), function.stiffness(), function.damping(), function.initialVelocity());
1535 ASSERT(timingFunction->type() == TimingFunction::LinearFunction);
1536 return CSSValuePool::singleton().createIdentifierValue(CSSValueLinear);
1540 static Ref<CSSValueList> getTimingFunctionValue(const AnimationList* animList)
1542 auto list = CSSValueList::createCommaSeparated();
1544 for (size_t i = 0; i < animList->size(); ++i)
1545 list.get().append(createTimingFunctionValue(animList->animation(i).timingFunction().get()));
1547 // Note that initialAnimationTimingFunction() is used for both transitions and animations
1548 list.get().append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
1552 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
1553 static Ref<CSSValue> createAnimationTriggerValue(const AnimationTrigger* trigger, const RenderStyle& style)
1555 switch (trigger->type()) {
1556 case AnimationTrigger::AnimationTriggerType::ScrollAnimationTriggerType: {
1557 auto& scrollAnimationTrigger = downcast<ScrollAnimationTrigger>(*trigger);
1558 if (scrollAnimationTrigger.endValue().isAuto())
1559 return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style));
1560 return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style),
1561 zoomAdjustedPixelValueForLength(scrollAnimationTrigger.endValue(), style));
1564 ASSERT(trigger->type() == AnimationTrigger::AnimationTriggerType::AutoAnimationTriggerType);
1565 return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1569 static Ref<CSSValueList> getAnimationTriggerValue(const AnimationList* animList, const RenderStyle& style)
1571 auto list = CSSValueList::createCommaSeparated();
1573 for (size_t i = 0; i < animList->size(); ++i)
1574 list.get().append(createAnimationTriggerValue(animList->animation(i).trigger().get(), style));
1576 list.get().append(createAnimationTriggerValue(Animation::initialTrigger().get(), style));
1582 static Ref<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
1584 if (!lineBoxContain)
1585 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1586 return CSSLineBoxContainValue::create(lineBoxContain);
1589 static Element* styleElementForNode(Node* node)
1593 if (is<Element>(*node))
1594 return downcast<Element>(node);
1595 return composedTreeAncestors(*node).first();
1598 ComputedStyleExtractor::ComputedStyleExtractor(Node* node, bool allowVisitedStyle, PseudoId pseudoElementSpecifier)
1599 : m_element(styleElementForNode(node))
1600 , m_pseudoElementSpecifier(pseudoElementSpecifier)
1601 , m_allowVisitedStyle(allowVisitedStyle)
1605 ComputedStyleExtractor::ComputedStyleExtractor(Element* element, bool allowVisitedStyle, PseudoId pseudoElementSpecifier)
1606 : m_element(element)
1607 , m_pseudoElementSpecifier(pseudoElementSpecifier)
1608 , m_allowVisitedStyle(allowVisitedStyle)
1612 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(Element& element, bool allowVisitedStyle, const String& pseudoElementName)
1613 : m_element(element)
1614 , m_allowVisitedStyle(allowVisitedStyle)
1617 unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
1618 m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoElementType(
1619 (pseudoElementName.substringSharingImpl(nameWithoutColonsStart))));
1622 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
1626 void CSSComputedStyleDeclaration::ref()
1631 void CSSComputedStyleDeclaration::deref()
1638 String CSSComputedStyleDeclaration::cssText() const
1640 StringBuilder result;
1642 for (unsigned i = 0; i < numComputedProperties; i++) {
1645 result.append(getPropertyName(computedProperties[i]));
1646 result.appendLiteral(": ");
1647 result.append(getPropertyValue(computedProperties[i]));
1651 return result.toString();
1654 ExceptionOr<void> CSSComputedStyleDeclaration::setCssText(const String&)
1656 return Exception { NO_MODIFICATION_ALLOWED_ERR };
1659 RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword()
1664 m_element->document().updateLayoutIgnorePendingStylesheets();
1666 auto* style = m_element->computedStyle(m_pseudoElementSpecifier);
1670 if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier())
1671 return CSSValuePool::singleton().createIdentifierValue(sizeIdentifier);
1673 return zoomAdjustedPixelValue(style->fontDescription().computedSize(), *style);
1676 bool ComputedStyleExtractor::useFixedFontDefaultSize()
1680 auto* style = m_element->computedStyle(m_pseudoElementSpecifier);
1684 return style->fontDescription().useFixedDefaultSize();
1688 static CSSValueID identifierForFamily(const AtomicString& family)
1690 if (family == cursiveFamily)
1691 return CSSValueCursive;
1692 if (family == fantasyFamily)
1693 return CSSValueFantasy;
1694 if (family == monospaceFamily)
1695 return CSSValueMonospace;
1696 if (family == pictographFamily)
1697 return CSSValueWebkitPictograph;
1698 if (family == sansSerifFamily)
1699 return CSSValueSansSerif;
1700 if (family == serifFamily)
1701 return CSSValueSerif;
1702 return CSSValueInvalid;
1705 static Ref<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1707 if (CSSValueID familyIdentifier = identifierForFamily(family))
1708 return CSSValuePool::singleton().createIdentifierValue(familyIdentifier);
1709 return CSSValuePool::singleton().createFontFamilyValue(family);
1712 static Ref<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
1714 auto& cssValuePool = CSSValuePool::singleton();
1715 // Blink value is ignored.
1716 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1717 if (textDecoration & TextDecorationUnderline)
1718 list->append(cssValuePool.createIdentifierValue(CSSValueUnderline));
1719 if (textDecoration & TextDecorationOverline)
1720 list->append(cssValuePool.createIdentifierValue(CSSValueOverline));
1721 if (textDecoration & TextDecorationLineThrough)
1722 list->append(cssValuePool.createIdentifierValue(CSSValueLineThrough));
1723 #if ENABLE(LETTERPRESS)
1724 if (textDecoration & TextDecorationLetterpress)
1725 list->append(cssValuePool.createIdentifierValue(CSSValueWebkitLetterpress));
1728 if (!list->length())
1729 return cssValuePool.createIdentifierValue(CSSValueNone);
1730 return list.releaseNonNull();
1733 static Ref<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
1735 switch (textDecorationStyle) {
1736 case TextDecorationStyleSolid:
1737 return CSSValuePool::singleton().createIdentifierValue(CSSValueSolid);
1738 case TextDecorationStyleDouble:
1739 return CSSValuePool::singleton().createIdentifierValue(CSSValueDouble);
1740 case TextDecorationStyleDotted:
1741 return CSSValuePool::singleton().createIdentifierValue(CSSValueDotted);
1742 case TextDecorationStyleDashed:
1743 return CSSValuePool::singleton().createIdentifierValue(CSSValueDashed);
1744 case TextDecorationStyleWavy:
1745 return CSSValuePool::singleton().createIdentifierValue(CSSValueWavy);
1748 ASSERT_NOT_REACHED();
1749 return CSSValuePool::singleton().createExplicitInitialValue();
1752 static Ref<CSSValue> renderTextDecorationSkipFlagsToCSSValue(TextDecorationSkip textDecorationSkip)
1754 switch (textDecorationSkip) {
1755 case TextDecorationSkipAuto:
1756 return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1757 case TextDecorationSkipNone:
1758 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1759 case TextDecorationSkipInk:
1760 return CSSValuePool::singleton().createIdentifierValue(CSSValueInk);
1761 case TextDecorationSkipObjects:
1762 return CSSValuePool::singleton().createIdentifierValue(CSSValueObjects);
1765 ASSERT_NOT_REACHED();
1766 return CSSValuePool::singleton().createExplicitInitialValue();
1769 static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition textEmphasisPosition)
1771 ASSERT(!((textEmphasisPosition & TextEmphasisPositionOver) && (textEmphasisPosition & TextEmphasisPositionUnder)));
1772 ASSERT(!((textEmphasisPosition & TextEmphasisPositionLeft) && (textEmphasisPosition & TextEmphasisPositionRight)));
1773 auto& cssValuePool = CSSValuePool::singleton();
1774 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1775 if (textEmphasisPosition & TextEmphasisPositionOver)
1776 list->append(cssValuePool.createIdentifierValue(CSSValueOver));
1777 if (textEmphasisPosition & TextEmphasisPositionUnder)
1778 list->append(cssValuePool.createIdentifierValue(CSSValueUnder));
1779 if (textEmphasisPosition & TextEmphasisPositionLeft)
1780 list->append(cssValuePool.createIdentifierValue(CSSValueLeft));
1781 if (textEmphasisPosition & TextEmphasisPositionRight)
1782 list->append(cssValuePool.createIdentifierValue(CSSValueRight));
1784 if (!list->length())
1785 return cssValuePool.createIdentifierValue(CSSValueNone);
1786 return list.releaseNonNull();
1789 static Ref<CSSValue> hangingPunctuationToCSSValue(HangingPunctuation hangingPunctuation)
1791 auto& cssValuePool = CSSValuePool::singleton();
1792 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1793 if (hangingPunctuation & FirstHangingPunctuation)
1794 list->append(cssValuePool.createIdentifierValue(CSSValueFirst));
1795 if (hangingPunctuation & AllowEndHangingPunctuation)
1796 list->append(cssValuePool.createIdentifierValue(CSSValueAllowEnd));
1797 if (hangingPunctuation & ForceEndHangingPunctuation)
1798 list->append(cssValuePool.createIdentifierValue(CSSValueForceEnd));
1799 if (hangingPunctuation & LastHangingPunctuation)
1800 list->append(cssValuePool.createIdentifierValue(CSSValueLast));
1801 if (!list->length())
1802 return cssValuePool.createIdentifierValue(CSSValueNone);
1803 return list.releaseNonNull();
1806 static Ref<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1808 // For backwards compatibility, if both values are equal, just return one of them. And
1809 // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1810 auto& cssValuePool = CSSValuePool::singleton();
1811 if (xRepeat == yRepeat)
1812 return cssValuePool.createValue(xRepeat);
1813 if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1814 return cssValuePool.createIdentifierValue(CSSValueRepeatX);
1815 if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1816 return cssValuePool.createIdentifierValue(CSSValueRepeatY);
1818 auto list = CSSValueList::createSpaceSeparated();
1819 list.get().append(cssValuePool.createValue(xRepeat));
1820 list.get().append(cssValuePool.createValue(yRepeat));
1821 return WTFMove(list);
1824 static Ref<CSSValue> fillSourceTypeToCSSValue(EMaskSourceType type)
1828 return CSSValuePool::singleton().createValue(CSSValueAlpha);
1830 ASSERT(type == MaskLuminance);
1831 return CSSValuePool::singleton().createValue(CSSValueLuminance);
1835 static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle& style)
1837 if (fillSize.type == Contain)
1838 return CSSValuePool::singleton().createIdentifierValue(CSSValueContain);
1840 if (fillSize.type == Cover)
1841 return CSSValuePool::singleton().createIdentifierValue(CSSValueCover);
1843 if (fillSize.size.height().isAuto())
1844 return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1846 auto list = CSSValueList::createSpaceSeparated();
1847 list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1848 list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1849 return WTFMove(list);
1852 static Ref<CSSValue> altTextToCSSValue(const RenderStyle* style)
1854 return CSSValuePool::singleton().createValue(style->contentAltText(), CSSPrimitiveValue::CSS_STRING);
1857 static Ref<CSSValueList> contentToCSSValue(const RenderStyle* style)
1859 auto& cssValuePool = CSSValuePool::singleton();
1860 auto list = CSSValueList::createSpaceSeparated();
1861 for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1862 if (is<CounterContentData>(*contentData))
1863 list.get().append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1864 else if (is<ImageContentData>(*contentData))
1865 list.get().append(*downcast<ImageContentData>(*contentData).image().cssValue());
1866 else if (is<TextContentData>(*contentData))
1867 list.get().append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING));
1869 if (style->hasFlowFrom())
1870 list.get().append(cssValuePool.createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1874 static RefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1876 const CounterDirectiveMap* map = style->counterDirectives();
1880 auto& cssValuePool = CSSValuePool::singleton();
1881 auto list = CSSValueList::createSpaceSeparated();
1882 for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1883 list->append(cssValuePool.createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1884 short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1885 list->append(cssValuePool.createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1887 return WTFMove(list);
1890 static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1892 static NeverDestroyed<HashSet<CSSPropertyID>> propertyIDSet;
1893 if (!propertyIDSet.get().add(propertyID).isNewEntry)
1896 LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1899 static Ref<CSSValueList> fontFamilyFromStyle(const RenderStyle* style)
1901 auto list = CSSValueList::createCommaSeparated();
1902 for (unsigned i = 0; i < style->fontCascade().familyCount(); ++i)
1903 list.get().append(valueForFamily(style->fontCascade().familyAt(i)));
1907 static Ref<CSSPrimitiveValue> lineHeightFromStyle(const RenderStyle& style)
1909 Length length = style.lineHeight();
1910 if (length.isNegative()) // If true, line-height not set; use the font's line spacing.
1911 return zoomAdjustedPixelValue(style.fontMetrics().floatLineSpacing(), style);
1912 if (length.isPercent()) {
1913 // This is imperfect, because it doesn't include the zoom factor and the real computation
1914 // for how high to be in pixels does include things like minimum font size and the zoom factor.
1915 // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1916 // that here either.
1917 return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style.fontDescription().specifiedSize()) / 100, style);
1919 return zoomAdjustedPixelValue(floatValueForLength(length, 0), style);
1922 static Ref<CSSPrimitiveValue> fontSizeFromStyle(const RenderStyle& style)
1924 return zoomAdjustedPixelValue(style.fontDescription().computedSize(), style);
1927 static Ref<CSSPrimitiveValue> fontStyleFromStyle(const RenderStyle* style)
1929 if (style->fontDescription().italic())
1930 return CSSValuePool::singleton().createIdentifierValue(CSSValueItalic);
1931 return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1934 static Ref<CSSValue> fontVariantFromStyle(const RenderStyle* style)
1936 if (style->fontDescription().variantSettings().isAllNormal())
1937 return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1939 auto list = CSSValueList::createSpaceSeparated();
1941 switch (style->fontDescription().variantCommonLigatures()) {
1942 case FontVariantLigatures::Normal:
1944 case FontVariantLigatures::Yes:
1945 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures));
1947 case FontVariantLigatures::No:
1948 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures));
1952 switch (style->fontDescription().variantDiscretionaryLigatures()) {
1953 case FontVariantLigatures::Normal:
1955 case FontVariantLigatures::Yes:
1956 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures));
1958 case FontVariantLigatures::No:
1959 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures));
1963 switch (style->fontDescription().variantHistoricalLigatures()) {
1964 case FontVariantLigatures::Normal:
1966 case FontVariantLigatures::Yes:
1967 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures));
1969 case FontVariantLigatures::No:
1970 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures));
1974 switch (style->fontDescription().variantContextualAlternates()) {
1975 case FontVariantLigatures::Normal:
1977 case FontVariantLigatures::Yes:
1978 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual));
1980 case FontVariantLigatures::No:
1981 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual));
1985 switch (style->fontDescription().variantPosition()) {
1986 case FontVariantPosition::Normal:
1988 case FontVariantPosition::Subscript:
1989 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSub));
1991 case FontVariantPosition::Superscript:
1992 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSuper));
1996 switch (style->fontDescription().variantCaps()) {
1997 case FontVariantCaps::Normal:
1999 case FontVariantCaps::Small:
2000 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps));
2002 case FontVariantCaps::AllSmall:
2003 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps));
2005 case FontVariantCaps::Petite:
2006 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps));
2008 case FontVariantCaps::AllPetite:
2009 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps));
2011 case FontVariantCaps::Unicase:
2012 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase));
2014 case FontVariantCaps::Titling:
2015 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps));
2019 switch (style->fontDescription().variantNumericFigure()) {
2020 case FontVariantNumericFigure::Normal:
2022 case FontVariantNumericFigure::LiningNumbers:
2023 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums));
2025 case FontVariantNumericFigure::OldStyleNumbers:
2026 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums));
2030 switch (style->fontDescription().variantNumericSpacing()) {
2031 case FontVariantNumericSpacing::Normal:
2033 case FontVariantNumericSpacing::ProportionalNumbers:
2034 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums));
2036 case FontVariantNumericSpacing::TabularNumbers:
2037 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums));
2041 switch (style->fontDescription().variantNumericFraction()) {
2042 case FontVariantNumericFraction::Normal:
2044 case FontVariantNumericFraction::DiagonalFractions:
2045 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions));
2047 case FontVariantNumericFraction::StackedFractions:
2048 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions));
2052 switch (style->fontDescription().variantNumericOrdinal()) {
2053 case FontVariantNumericOrdinal::Normal:
2055 case FontVariantNumericOrdinal::Yes:
2056 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal));
2060 switch (style->fontDescription().variantNumericSlashedZero()) {
2061 case FontVariantNumericSlashedZero::Normal:
2063 case FontVariantNumericSlashedZero::Yes:
2064 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero));
2068 switch (style->fontDescription().variantAlternates()) {
2069 case FontVariantAlternates::Normal:
2071 case FontVariantAlternates::HistoricalForms:
2072 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms));
2076 switch (style->fontDescription().variantEastAsianVariant()) {
2077 case FontVariantEastAsianVariant::Normal:
2079 case FontVariantEastAsianVariant::Jis78:
2080 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78));
2082 case FontVariantEastAsianVariant::Jis83:
2083 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83));
2085 case FontVariantEastAsianVariant::Jis90:
2086 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90));
2088 case FontVariantEastAsianVariant::Jis04:
2089 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04));
2091 case FontVariantEastAsianVariant::Simplified:
2092 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified));
2094 case FontVariantEastAsianVariant::Traditional:
2095 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional));
2099 switch (style->fontDescription().variantEastAsianWidth()) {
2100 case FontVariantEastAsianWidth::Normal:
2102 case FontVariantEastAsianWidth::Full:
2103 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth));
2105 case FontVariantEastAsianWidth::Proportional:
2106 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth));
2110 switch (style->fontDescription().variantEastAsianRuby()) {
2111 case FontVariantEastAsianRuby::Normal:
2113 case FontVariantEastAsianRuby::Yes:
2114 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby));
2118 return WTFMove(list);
2121 static Ref<CSSPrimitiveValue> fontWeightFromStyle(const RenderStyle* style)
2123 switch (style->fontDescription().weight()) {
2125 return CSSValuePool::singleton().createIdentifierValue(CSSValue100);
2127 return CSSValuePool::singleton().createIdentifierValue(CSSValue200);
2129 return CSSValuePool::singleton().createIdentifierValue(CSSValue300);
2130 case FontWeightNormal:
2131 return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2133 return CSSValuePool::singleton().createIdentifierValue(CSSValue500);
2135 return CSSValuePool::singleton().createIdentifierValue(CSSValue600);
2136 case FontWeightBold:
2137 return CSSValuePool::singleton().createIdentifierValue(CSSValueBold);
2139 return CSSValuePool::singleton().createIdentifierValue(CSSValue800);
2141 return CSSValuePool::singleton().createIdentifierValue(CSSValue900);
2143 ASSERT_NOT_REACHED();
2144 return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2147 static Ref<CSSValue> fontSynthesisFromStyle(const RenderStyle& style)
2149 if (style.fontDescription().fontSynthesis() == FontSynthesisNone)
2150 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2152 auto list = CSSValueList::createSpaceSeparated();
2153 if (style.fontDescription().fontSynthesis() & FontSynthesisStyle)
2154 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
2155 if (style.fontDescription().fontSynthesis() & FontSynthesisWeight)
2156 list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight));
2157 return Ref<CSSValue>(list.get());
2160 typedef const Length& (RenderStyle::*RenderStyleLengthGetter)() const;
2161 typedef LayoutUnit (RenderBoxModelObject::*RenderBoxComputedCSSValueGetter)() const;
2163 template<RenderStyleLengthGetter lengthGetter, RenderBoxComputedCSSValueGetter computedCSSValueGetter>
2164 inline RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(const RenderStyle& style, RenderObject* renderer)
2166 Length unzoomzedLength = (style.*lengthGetter)();
2167 if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed())
2168 return zoomAdjustedPixelValueForLength(unzoomzedLength, style);
2169 return zoomAdjustedPixelValue((downcast<RenderBox>(*renderer).*computedCSSValueGetter)(), style);
2172 template<RenderStyleLengthGetter lengthGetter>
2173 inline bool paddingOrMarginIsRendererDependent(const RenderStyle* style, RenderObject* renderer)
2175 if (!renderer || !renderer->isBox())
2177 return !(style && (style->*lengthGetter)().isFixed());
2180 static CSSValueID convertToPageBreak(BreakBetween value)
2182 if (value == PageBreakBetween || value == LeftPageBreakBetween || value == RightPageBreakBetween
2183 || value == RectoPageBreakBetween || value == VersoPageBreakBetween)
2184 return CSSValueAlways; // CSS 2.1 allows us to map these to always.
2185 if (value == AvoidBreakBetween || value == AvoidPageBreakBetween)
2186 return CSSValueAvoid;
2187 return CSSValueAuto;
2190 static CSSValueID convertToColumnBreak(BreakBetween value)
2192 if (value == ColumnBreakBetween)
2193 return CSSValueAlways;
2194 if (value == AvoidBreakBetween || value == AvoidColumnBreakBetween)
2195 return CSSValueAvoid;
2196 return CSSValueAuto;
2199 static CSSValueID convertToPageBreak(BreakInside value)
2201 if (value == AvoidBreakInside || value == AvoidPageBreakInside)
2202 return CSSValueAvoid;
2203 return CSSValueAuto;
2206 static CSSValueID convertToColumnBreak(BreakInside value)
2208 if (value == AvoidBreakInside || value == AvoidColumnBreakInside)
2209 return CSSValueAvoid;
2210 return CSSValueAuto;
2213 #if ENABLE(CSS_REGIONS)
2214 static CSSValueID convertToRegionBreak(BreakBetween value)
2216 if (value == RegionBreakBetween)
2217 return CSSValueAlways;
2218 if (value == AvoidBreakBetween || value == AvoidRegionBreakBetween)
2219 return CSSValueAvoid;
2220 return CSSValueAuto;
2223 static CSSValueID convertToRegionBreak(BreakInside value)
2225 if (value == AvoidBreakInside || value == AvoidRegionBreakInside)
2226 return CSSValueAvoid;
2227 return CSSValueAuto;
2231 static bool isLayoutDependent(CSSPropertyID propertyID, const RenderStyle* style, RenderObject* renderer)
2233 switch (propertyID) {
2234 case CSSPropertyWidth:
2235 case CSSPropertyHeight:
2236 case CSSPropertyPerspectiveOrigin:
2237 case CSSPropertyTransformOrigin:
2238 case CSSPropertyTransform:
2239 case CSSPropertyFilter:
2240 #if ENABLE(FILTERS_LEVEL_2)
2241 case CSSPropertyWebkitBackdropFilter:
2244 case CSSPropertyMargin: {
2245 if (!renderer || !renderer->isBox())
2247 return !(style && style->marginTop().isFixed() && style->marginRight().isFixed()
2248 && style->marginBottom().isFixed() && style->marginLeft().isFixed());
2250 case CSSPropertyMarginTop:
2251 return paddingOrMarginIsRendererDependent<&RenderStyle::marginTop>(style, renderer);
2252 case CSSPropertyMarginRight:
2253 return paddingOrMarginIsRendererDependent<&RenderStyle::marginRight>(style, renderer);
2254 case CSSPropertyMarginBottom:
2255 return paddingOrMarginIsRendererDependent<&RenderStyle::marginBottom>(style, renderer);
2256 case CSSPropertyMarginLeft:
2257 return paddingOrMarginIsRendererDependent<&RenderStyle::marginLeft>(style, renderer);
2258 case CSSPropertyPadding: {
2259 if (!renderer || !renderer->isBox())
2261 return !(style && style->paddingTop().isFixed() && style->paddingRight().isFixed()
2262 && style->paddingBottom().isFixed() && style->paddingLeft().isFixed());
2264 case CSSPropertyPaddingTop:
2265 return paddingOrMarginIsRendererDependent<&RenderStyle::paddingTop>(style, renderer);
2266 case CSSPropertyPaddingRight:
2267 return paddingOrMarginIsRendererDependent<&RenderStyle::paddingRight>(style, renderer);
2268 case CSSPropertyPaddingBottom:
2269 return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer);
2270 case CSSPropertyPaddingLeft:
2271 return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer);
2272 #if ENABLE(CSS_GRID_LAYOUT)
2273 case CSSPropertyGridTemplateColumns:
2274 case CSSPropertyGridTemplateRows:
2275 case CSSPropertyGridTemplate:
2276 case CSSPropertyGrid:
2277 return renderer && renderer->isRenderGrid();
2284 Element* ComputedStyleExtractor::styledElement()
2288 PseudoElement* pseudoElement;
2289 if (m_pseudoElementSpecifier == BEFORE && (pseudoElement = m_element->beforePseudoElement()))
2290 return pseudoElement;
2291 if (m_pseudoElementSpecifier == AFTER && (pseudoElement = m_element->afterPseudoElement()))
2292 return pseudoElement;
2293 return m_element.get();
2296 #if ENABLE(CSS_GRID_LAYOUT)
2297 static StyleSelfAlignmentData resolveLegacyJustifyItems(const StyleSelfAlignmentData& data)
2299 if (data.positionType() == LegacyPosition)
2300 return { data.position(), OverflowAlignmentDefault };
2304 static StyleSelfAlignmentData resolveJustifyItemsAuto(const StyleSelfAlignmentData& data, Node* parent)
2306 if (data.position() != ItemPositionAuto)
2309 // If the inherited value of justify-items includes the 'legacy' keyword, 'auto' computes to the inherited value.
2310 const auto& inheritedValue = (!parent || !parent->computedStyle()) ? RenderStyle::initialDefaultAlignment() : parent->computedStyle()->justifyItems();
2311 if (inheritedValue.positionType() == LegacyPosition)
2312 return inheritedValue;
2313 if (inheritedValue.position() == ItemPositionAuto)
2314 return resolveJustifyItemsAuto(inheritedValue, parent->parentNode());
2315 return { ItemPositionNormal, OverflowAlignmentDefault };
2318 static StyleSelfAlignmentData resolveJustifySelfAuto(const StyleSelfAlignmentData& data, Node* parent)
2320 if (data.position() != ItemPositionAuto)
2323 // The 'auto' keyword computes to the computed value of justify-items on the parent or 'normal' if the box has no parent.
2324 if (!parent || !parent->computedStyle())
2325 return { ItemPositionNormal, OverflowAlignmentDefault };
2326 return resolveLegacyJustifyItems(resolveJustifyItemsAuto(parent->computedStyle()->justifyItems(), parent->parentNode()));
2330 static StyleSelfAlignmentData resolveAlignSelfAuto(const StyleSelfAlignmentData& data, Node* parent)
2332 if (data.position() != ItemPositionAuto)
2335 // The 'auto' keyword computes to the computed value of align-items on the parent or 'normal' if the box has no parent.
2336 if (!parent || !parent->computedStyle())
2337 return { ItemPositionNormal, OverflowAlignmentDefault };
2338 return parent->computedStyle()->alignItems();
2341 static bool isImplicitlyInheritedGridOrFlexProperty(CSSPropertyID propertyID)
2343 // It would be nice if grid and flex worked within normal CSS mechanisms and not invented their own inheritance system.
2344 switch (propertyID) {
2345 case CSSPropertyAlignSelf:
2346 #if ENABLE(CSS_GRID_LAYOUT)
2347 case CSSPropertyJustifySelf:
2348 case CSSPropertyJustifyItems:
2350 // FIXME: In StyleResolver::adjustRenderStyle z-index is adjusted based on the parent display property for grid/flex.
2351 case CSSPropertyZIndex:
2358 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2360 return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
2363 Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
2365 return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
2368 static inline bool hasValidStyleForProperty(Element& element, CSSPropertyID propertyID)
2370 if (element.styleValidity() != Style::Validity::Valid)
2372 if (element.document().hasPendingForcedStyleRecalc())
2374 if (!element.document().childNeedsStyleRecalc())
2377 bool isInherited = CSSProperty::isInheritedProperty(propertyID) || isImplicitlyInheritedGridOrFlexProperty(propertyID);
2378 bool maybeExplicitlyInherited = !isInherited;
2380 const auto* currentElement = &element;
2381 for (auto& ancestor : composedTreeAncestors(element)) {
2382 if (ancestor.styleValidity() >= Style::Validity::SubtreeInvalid)
2385 if (maybeExplicitlyInherited) {
2386 auto* style = currentElement->renderStyle();
2387 maybeExplicitlyInherited = !style || style->hasExplicitlyInheritedProperties();
2390 if ((isInherited || maybeExplicitlyInherited) && ancestor.styleValidity() == Style::Validity::ElementInvalid)
2393 if (ancestor.directChildNeedsStyleRecalc() && currentElement->styleIsAffectedByPreviousSibling())
2396 currentElement = &ancestor;
2402 static bool updateStyleIfNeededForProperty(Element& element, CSSPropertyID propertyID)
2404 auto& document = element.document();
2406 document.styleScope().flushPendingUpdate();
2408 if (hasValidStyleForProperty(element, propertyID))
2411 document.updateStyleIfNeeded();
2415 static inline const RenderStyle* computeRenderStyleForProperty(Element& element, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID, std::unique_ptr<RenderStyle>& ownedStyle)
2417 auto* renderer = element.renderer();
2419 if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
2420 ownedStyle = renderer->animation().getAnimatedStyleForRenderer(*renderer);
2421 if (pseudoElementSpecifier && !element.isPseudoElement()) {
2422 // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
2423 return ownedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2425 return ownedStyle.get();
2428 return element.computedStyle(element.isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
2431 static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue)
2434 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2436 if (shapeValue->type() == ShapeValue::Type::Box)
2437 return CSSValuePool::singleton().createValue(shapeValue->cssBox());
2439 if (shapeValue->type() == ShapeValue::Type::Image) {
2440 if (shapeValue->image())
2441 return *shapeValue->image()->cssValue();
2442 return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2445 ASSERT(shapeValue->type() == ShapeValue::Type::Shape);
2447 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2448 list->append(valueForBasicShape(style, *shapeValue->shape()));
2449 if (shapeValue->cssBox() != BoxMissing)
2450 list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox()));
2451 return list.releaseNonNull();
2454 static Ref<CSSValueList> valueForItemPositionWithOverflowAlignment(const StyleSelfAlignmentData& data)
2456 auto& cssValuePool = CSSValuePool::singleton();
2457 auto result = CSSValueList::createSpaceSeparated();
2458 if (data.positionType() == LegacyPosition)
2459 result.get().append(cssValuePool.createIdentifierValue(CSSValueLegacy));
2460 result.get().append(cssValuePool.createValue(data.position()));
2461 if (data.position() >= ItemPositionCenter && data.overflow() != OverflowAlignmentDefault)
2462 result.get().append(cssValuePool.createValue(data.overflow()));
2463 ASSERT(result.get().length() <= 2);
2467 static Ref<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data, CSSValueID normalBehaviorValueID)
2469 auto& cssValuePool = CSSValuePool::singleton();
2470 auto result = CSSValueList::createSpaceSeparated();
2471 if (data.distribution() != ContentDistributionDefault)
2472 result.get().append(cssValuePool.createValue(data.distribution()));
2473 if (data.distribution() == ContentDistributionDefault || data.position() != ContentPositionNormal) {
2474 bool gridEnabled = false;
2475 #if ENABLE(CSS_GRID_LAYOUT)
2476 gridEnabled = RuntimeEnabledFeatures::sharedFeatures().isCSSGridLayoutEnabled();
2478 if (data.position() != ContentPositionNormal || gridEnabled)
2479 result.get().append(cssValuePool.createValue(data.position()));
2481 result.get().append(cssValuePool.createIdentifierValue(normalBehaviorValueID));
2483 if ((data.position() >= ContentPositionCenter || data.distribution() != ContentDistributionDefault) && data.overflow() != OverflowAlignmentDefault)
2484 result.get().append(cssValuePool.createValue(data.overflow()));
2485 ASSERT(result.get().length() > 0);
2486 ASSERT(result.get().length() <= 3);
2490 inline static bool isFlexOrGrid(ContainerNode* element)
2492 return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox();
2495 RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName)
2497 Element* styledElement = this->styledElement();
2501 if (updateStyleIfNeededForProperty(*styledElement, CSSPropertyCustom)) {
2502 // Style update may change styledElement() to PseudoElement or back.
2503 styledElement = this->styledElement();
2506 std::unique_ptr<RenderStyle> ownedStyle;
2507 auto* style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle);
2508 if (!style || !style->hasCustomProperty(propertyName))
2511 return style->getCustomPropertyValue(propertyName);
2514 String ComputedStyleExtractor::customPropertyText(const String& propertyName)
2516 RefPtr<CSSValue> propertyValue = customPropertyValue(propertyName);
2517 return propertyValue ? propertyValue->cssText() : emptyString();
2520 RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout)
2522 auto* styledElement = this->styledElement();
2526 std::unique_ptr<RenderStyle> ownedStyle;
2527 const RenderStyle* style = nullptr;
2528 RenderObject* renderer = nullptr;
2529 bool forceFullLayout = false;
2531 Document& document = m_element->document();
2533 if (updateStyleIfNeededForProperty(*styledElement, propertyID)) {
2534 // Style update may change styledElement() to PseudoElement or back.
2535 styledElement = this->styledElement();
2537 renderer = styledElement->renderer();
2539 if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledElement) && !downcast<SVGElement>(*styledElement).isValid())
2542 style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
2544 // FIXME: Some of these cases could be narrowed down or optimized better.
2545 forceFullLayout = isLayoutDependent(propertyID, style, renderer)
2546 || styledElement->isInShadowTree()
2547 || (document.styleScope().resolverIfExists() && document.styleScope().resolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());
2549 if (forceFullLayout) {
2550 document.updateLayoutIgnorePendingStylesheets();
2551 styledElement = this->styledElement();
2555 if (!updateLayout || forceFullLayout) {
2556 style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
2557 renderer = styledElement->renderer();
2563 auto& cssValuePool = CSSValuePool::singleton();
2564 propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
2566 switch (propertyID) {
2567 case CSSPropertyInvalid:
2570 case CSSPropertyBackgroundColor:
2571 return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
2572 case CSSPropertyBackgroundImage:
2573 case CSSPropertyWebkitMaskImage: {
2574 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
2576 return cssValuePool.createIdentifierValue(CSSValueNone);
2578 if (!layers->next()) {
2579 if (layers->image())
2580 return layers->image()->cssValue();
2582 return cssValuePool.createIdentifierValue(CSSValueNone);
2585 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2586 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2587 if (currLayer->image())
2588 list->append(*currLayer->image()->cssValue());
2590 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
2594 case CSSPropertyBackgroundSize:
2595 case CSSPropertyWebkitBackgroundSize:
2596 case CSSPropertyWebkitMaskSize: {
2597 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
2598 if (!layers->next())
2599 return fillSizeToCSSValue(layers->size(), *style);
2601 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2602 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2603 list->append(fillSizeToCSSValue(currLayer->size(), *style));
2607 case CSSPropertyBackgroundRepeat:
2608 case CSSPropertyWebkitMaskRepeat: {
2609 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
2610 if (!layers->next())
2611 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
2613 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2614 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2615 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
2619 case CSSPropertyWebkitMaskSourceType: {
2620 const FillLayer* layers = style->maskLayers();
2623 return cssValuePool.createIdentifierValue(CSSValueNone);
2625 if (!layers->next())
2626 return fillSourceTypeToCSSValue(layers->maskSourceType());
2628 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2629 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2630 list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType()));
2634 case CSSPropertyWebkitBackgroundComposite:
2635 case CSSPropertyWebkitMaskComposite: {
2636 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
2637 if (!layers->next())
2638 return cssValuePool.createValue(layers->composite());
2640 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2641 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2642 list->append(cssValuePool.createValue(currLayer->composite()));
2646 case CSSPropertyBackgroundAttachment: {
2647 const FillLayer* layers = style->backgroundLayers();
2648 if (!layers->next())
2649 return cssValuePool.createValue(layers->attachment());
2651 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2652 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2653 list->append(cssValuePool.createValue(currLayer->attachment()));
2657 case CSSPropertyBackgroundClip:
2658 case CSSPropertyBackgroundOrigin:
2659 case CSSPropertyWebkitBackgroundClip:
2660 case CSSPropertyWebkitBackgroundOrigin:
2661 case CSSPropertyWebkitMaskClip:
2662 case CSSPropertyWebkitMaskOrigin: {
2663 const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
2664 bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
2665 if (!layers->next()) {
2666 EFillBox box = isClip ? layers->clip() : layers->origin();
2667 return cssValuePool.createValue(box);
2670 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2671 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2672 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
2673 list->append(cssValuePool.createValue(box));
2678 case CSSPropertyBackgroundPosition:
2679 case CSSPropertyWebkitMaskPosition: {
2680 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
2681 if (!layers->next())
2682 return createPositionListForLayer(propertyID, layers, *style);
2684 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2685 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2686 list->append(createPositionListForLayer(propertyID, currLayer, *style));
2689 case CSSPropertyBackgroundPositionX:
2690 case CSSPropertyWebkitMaskPositionX: {
2691 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
2692 if (!layers->next())
2693 return cssValuePool.createValue(layers->xPosition());
2695 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2696 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2697 list->append(cssValuePool.createValue(currLayer->xPosition()));
2701 case CSSPropertyBackgroundPositionY:
2702 case CSSPropertyWebkitMaskPositionY: {
2703 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
2704 if (!layers->next())
2705 return cssValuePool.createValue(layers->yPosition());
2707 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2708 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2709 list->append(cssValuePool.createValue(currLayer->yPosition()));
2713 case CSSPropertyBorderCollapse:
2714 if (style->borderCollapse())
2715 return cssValuePool.createIdentifierValue(CSSValueCollapse);
2716 return cssValuePool.createIdentifierValue(CSSValueSeparate);
2717 case CSSPropertyBorderSpacing: {
2718 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2719 list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
2720 list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
2723 case CSSPropertyWebkitBorderHorizontalSpacing:
2724 return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
2725 case CSSPropertyWebkitBorderVerticalSpacing:
2726 return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style);
2727 case CSSPropertyBorderImageSource:
2728 if (style->borderImageSource())
2729 return style->borderImageSource()->cssValue();
2730 return cssValuePool.createIdentifierValue(CSSValueNone);
2731 case CSSPropertyBorderTopColor:
2732 return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style, style->borderTopColor());
2733 case CSSPropertyBorderRightColor:
2734 return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style, style->borderRightColor());
2735 case CSSPropertyBorderBottomColor:
2736 return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style, style->borderBottomColor());
2737 case CSSPropertyBorderLeftColor:
2738 return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style, style->borderLeftColor());
2739 case CSSPropertyBorderTopStyle:
2740 return cssValuePool.createValue(style->borderTopStyle());
2741 case CSSPropertyBorderRightStyle:
2742 return cssValuePool.createValue(style->borderRightStyle());
2743 case CSSPropertyBorderBottomStyle:
2744 return cssValuePool.createValue(style->borderBottomStyle());
2745 case CSSPropertyBorderLeftStyle:
2746 return cssValuePool.createValue(style->borderLeftStyle());
2747 case CSSPropertyBorderTopWidth:
2748 return zoomAdjustedPixelValue(style->borderTopWidth(), *style);
2749 case CSSPropertyBorderRightWidth:
2750 return zoomAdjustedPixelValue(style->borderRightWidth(), *style);
2751 case CSSPropertyBorderBottomWidth:
2752 return zoomAdjustedPixelValue(style->borderBottomWidth(), *style);
2753 case CSSPropertyBorderLeftWidth:
2754 return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
2755 case CSSPropertyBottom:
2756 return positionOffsetValue(*style, CSSPropertyBottom);
2757 case CSSPropertyWebkitBoxAlign:
2758 return cssValuePool.createValue(style->boxAlign());
2759 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2760 case CSSPropertyWebkitBoxDecorationBreak:
2761 if (style->boxDecorationBreak() == DSLICE)
2762 return cssValuePool.createIdentifierValue(CSSValueSlice);
2763 return cssValuePool.createIdentifierValue(CSSValueClone);
2765 case CSSPropertyWebkitBoxDirection:
2766 return cssValuePool.createValue(style->boxDirection());
2767 case CSSPropertyWebkitBoxFlex:
2768 return cssValuePool.createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
2769 case CSSPropertyWebkitBoxFlexGroup:
2770 return cssValuePool.createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
2771 case CSSPropertyWebkitBoxLines:
2772 return cssValuePool.createValue(style->boxLines());
2773 case CSSPropertyWebkitBoxOrdinalGroup:
2774 return cssValuePool.createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
2775 case CSSPropertyWebkitBoxOrient:
2776 return cssValuePool.createValue(style->boxOrient());
2777 case CSSPropertyWebkitBoxPack:
2778 return cssValuePool.createValue(style->boxPack());
2779 case CSSPropertyWebkitBoxReflect:
2780 return valueForReflection(style->boxReflect(), *style);
2781 case CSSPropertyBoxShadow:
2782 case CSSPropertyWebkitBoxShadow:
2783 return valueForShadow(style->boxShadow(), propertyID, *style);
2784 case CSSPropertyCaptionSide:
2785 return cssValuePool.createValue(style->captionSide());
2786 case CSSPropertyClear:
2787 return cssValuePool.createValue(style->clear());
2788 case CSSPropertyColor:
2789 return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
2790 case CSSPropertyWebkitPrintColorAdjust:
2791 return cssValuePool.createValue(style->printColorAdjust());
2792 case CSSPropertyWebkitColumnAxis:
2793 return cssValuePool.createValue(style->columnAxis());
2794 case CSSPropertyColumnCount:
2795 if (style->hasAutoColumnCount())
2796 return cssValuePool.createIdentifierValue(CSSValueAuto);
2797 return cssValuePool.createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
2798 case CSSPropertyColumnFill:
2799 return cssValuePool.createValue(style->columnFill());
2800 case CSSPropertyColumnGap:
2801 if (style->hasNormalColumnGap())
2802 return cssValuePool.createIdentifierValue(CSSValueNormal);
2803 return zoomAdjustedPixelValue(style->columnGap(), *style);
2804 case CSSPropertyColumnProgression:
2805 return cssValuePool.createValue(style->columnProgression());
2806 case CSSPropertyColumnRuleColor:
2807 return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style->columnRuleColor());
2808 case CSSPropertyColumnRuleStyle:
2809 return cssValuePool.createValue(style->columnRuleStyle());
2810 case CSSPropertyColumnRuleWidth:
2811 return zoomAdjustedPixelValue(style->columnRuleWidth(), *style);
2812 case CSSPropertyColumnSpan:
2813 return cssValuePool.createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
2814 case CSSPropertyWebkitColumnBreakAfter:
2815 return cssValuePool.createValue(convertToColumnBreak(style->breakAfter()));
2816 case CSSPropertyWebkitColumnBreakBefore:
2817 return cssValuePool.createValue(convertToColumnBreak(style->breakBefore()));
2818 case CSSPropertyWebkitColumnBreakInside:
2819 return cssValuePool.createValue(convertToColumnBreak(style->breakInside()));
2820 case CSSPropertyColumnWidth:
2821 if (style->hasAutoColumnWidth())
2822 return cssValuePool.createIdentifierValue(CSSValueAuto);
2823 return zoomAdjustedPixelValue(style->columnWidth(), *style);
2824 case CSSPropertyTabSize:
2825 return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
2826 #if ENABLE(CSS_REGIONS)
2827 case CSSPropertyWebkitRegionBreakAfter:
2828 return cssValuePool.createValue(convertToRegionBreak(style->breakAfter()));
2829 case CSSPropertyWebkitRegionBreakBefore:
2830 return cssValuePool.createValue(convertToRegionBreak(style->breakBefore()));
2831 case CSSPropertyWebkitRegionBreakInside:
2832 return cssValuePool.createValue(convertToRegionBreak(style->breakInside()));
2834 case CSSPropertyCursor: {
2835 RefPtr<CSSValueList> list;
2836 CursorList* cursors = style->cursors();
2837 if (cursors && cursors->size() > 0) {
2838 list = CSSValueList::createCommaSeparated();
2839 for (unsigned i = 0; i < cursors->size(); ++i)
2840 if (StyleImage* image = cursors->at(i).image())
2841 list->append(*image->cssValue());
2843 auto value = cssValuePool.createValue(style->cursor());
2845 list->append(WTFMove(value));
2848 return WTFMove(value);
2850 #if ENABLE(CURSOR_VISIBILITY)
2851 case CSSPropertyWebkitCursorVisibility:
2852 return cssValuePool.createValue(style->cursorVisibility());
2854 case CSSPropertyDirection:
2855 return cssValuePool.createValue(style->direction());
2856 case CSSPropertyDisplay:
2857 return cssValuePool.createValue(style->display());
2858 case CSSPropertyEmptyCells:
2859 return cssValuePool.createValue(style->emptyCells());
2860 case CSSPropertyAlignContent:
2861 return valueForContentPositionAndDistributionWithOverflowAlignment(style->alignContent(), CSSValueStretch);
2862 case CSSPropertyAlignItems:
2863 return valueForItemPositionWithOverflowAlignment(style->alignItems());
2864 case CSSPropertyAlignSelf:
2865 return valueForItemPositionWithOverflowAlignment(resolveAlignSelfAuto(style->alignSelf(), styledElement->parentNode()));
2866 case CSSPropertyFlex:
2867 return getCSSPropertyValuesForShorthandProperties(flexShorthand());
2868 case CSSPropertyFlexBasis:
2869 return cssValuePool.createValue(style->flexBasis());
2870 case CSSPropertyFlexDirection:
2871 return cssValuePool.createValue(style->flexDirection());
2872 case CSSPropertyFlexFlow:
2873 return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
2874 case CSSPropertyFlexGrow:
2875 return cssValuePool.createValue(style->flexGrow());
2876 case CSSPropertyFlexShrink:
2877 return cssValuePool.createValue(style->flexShrink());
2878 case CSSPropertyFlexWrap:
2879 return cssValuePool.createValue(style->flexWrap());
2880 case CSSPropertyJustifyContent:
2881 return valueForContentPositionAndDistributionWithOverflowAlignment(style->justifyContent(), CSSValueFlexStart);
2882 #if ENABLE(CSS_GRID_LAYOUT)
2883 case CSSPropertyJustifyItems:
2884 return valueForItemPositionWithOverflowAlignment(resolveJustifyItemsAuto(style->justifyItems(), styledElement->parentNode()));
2885 case CSSPropertyJustifySelf:
2886 return valueForItemPositionWithOverflowAlignment(resolveJustifySelfAuto(style->justifySelf(), styledElement->parentNode()));
2888 case CSSPropertyOrder:
2889 return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
2890 case CSSPropertyFloat:
2891 if (style->display() != NONE && style->hasOutOfFlowPosition())
2892 return cssValuePool.createIdentifierValue(CSSValueNone);
2893 return cssValuePool.createValue(style->floating());
2894 case CSSPropertyFont: {
2895 RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
2896 computedFont->style = fontStyleFromStyle(style);
2897 if (style->fontDescription().variantCaps() == FontVariantCaps::Small)
2898 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
2900 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2901 computedFont->weight = fontWeightFromStyle(style);
2902 computedFont->size = fontSizeFromStyle(*style);
2903 computedFont->lineHeight = lineHeightFromStyle(*style);
2904 computedFont->family = fontFamilyFromStyle(style);
2905 return computedFont;
2907 case CSSPropertyFontFamily: {
2908 RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style);
2909 // If there's only a single family, return that as a CSSPrimitiveValue.
2910 // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
2911 if (fontFamilyList->length() == 1)
2912 return fontFamilyList->item(0);
2913 return fontFamilyList;
2915 case CSSPropertyFontSize:
2916 return fontSizeFromStyle(*style);
2917 case CSSPropertyFontStyle:
2918 return fontStyleFromStyle(style);
2919 case CSSPropertyFontVariant:
2920 return fontVariantFromStyle(style);
2921 case CSSPropertyFontWeight:
2922 return fontWeightFromStyle(style);
2923 case CSSPropertyFontSynthesis:
2924 return fontSynthesisFromStyle(*style);
2925 case CSSPropertyFontFeatureSettings: {
2926 const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings();
2927 if (!featureSettings.size())
2928 return cssValuePool.createIdentifierValue(CSSValueNormal);
2929 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2930 for (auto& feature : featureSettings)
2931 list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value()));
2934 #if ENABLE(VARIATION_FONTS)
2935 case CSSPropertyFontVariationSettings: {
2936 if (styledElement->document().settings() && styledElement->document().settings()->variationFontsEnabled()) {
2937 const FontVariationSettings& variationSettings = style->fontDescription().variationSettings();
2938 if (variationSettings.isEmpty())
2939 return cssValuePool.createIdentifierValue(CSSValueNormal);
2940 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2941 for (auto& feature : variationSettings)
2942 list->append(CSSFontVariationValue::create(feature.tag(), feature.value()));
2948 #if ENABLE(CSS_GRID_LAYOUT)
2949 case CSSPropertyGridAutoFlow: {
2950 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2951 ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
2952 if (style->isGridAutoFlowDirectionRow())
2953 list->append(cssValuePool.createIdentifierValue(CSSValueRow));
2955 list->append(cssValuePool.createIdentifierValue(CSSValueColumn));
2957 if (style->isGridAutoFlowAlgorithmDense())
2958 list->append(cssValuePool.createIdentifierValue(CSSValueDense));
2963 // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
2964 // one for grid-template-{rows|columns} but not for the grid-auto-{rows|columns} as things like
2965 // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
2966 // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
2967 // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
2968 case CSSPropertyGridAutoColumns:
2969 return valueForGridTrackSizeList(ForColumns, *style);
2970 case CSSPropertyGridAutoRows:
2971 return valueForGridTrackSizeList(ForRows, *style);
2973 case CSSPropertyGridTemplateColumns:
2974 return valueForGridTrackList(ForColumns, renderer, *style);
2975 case CSSPropertyGridTemplateRows:
2976 return valueForGridTrackList(ForRows, renderer, *style);
2978 case CSSPropertyGridColumnStart:
2979 return valueForGridPosition(style->gridItemColumnStart());
2980 case CSSPropertyGridColumnEnd:
2981 return valueForGridPosition(style->gridItemColumnEnd());
2982 case CSSPropertyGridRowStart:
2983 return valueForGridPosition(style->gridItemRowStart());
2984 case CSSPropertyGridRowEnd:
2985 return valueForGridPosition(style->gridItemRowEnd());
2986 case CSSPropertyGridArea:
2987 return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
2988 case CSSPropertyGridTemplate:
2989 return getCSSPropertyValuesForGridShorthand(gridTemplateShorthand());
2990 case CSSPropertyGrid:
2991 return getCSSPropertyValuesForGridShorthand(gridShorthand());
2992 case CSSPropertyGridColumn:
2993 return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
2994 case CSSPropertyGridRow:
2995 return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
2997 case CSSPropertyGridTemplateAreas:
2998 if (!style->namedGridAreaRowCount()) {
2999 ASSERT(!style->namedGridAreaColumnCount());
3000 return cssValuePool.createIdentifierValue(CSSValueNone);
3003 return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
3004 case CSSPropertyGridColumnGap:
3005 return zoomAdjustedPixelValueForLength(style->gridColumnGap(), *style);
3006 case CSSPropertyGridRowGap:
3007 return zoomAdjustedPixelValueForLength(style->gridRowGap(), *style);
3008 case CSSPropertyGridGap:
3009 return getCSSPropertyValuesForGridShorthand(gridGapShorthand());
3010 #endif /* ENABLE(CSS_GRID_LAYOUT) */
3011 case CSSPropertyHeight:
3012 if (renderer && !renderer->isRenderSVGModelObject()) {
3013 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
3014 // the "height" property does not apply for non-replaced inline elements.
3015 if (!renderer->isReplaced() && renderer->isInline())
3016 return cssValuePool.createIdentifierValue(CSSValueAuto);
3017 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
3019 return zoomAdjustedPixelValueForLength(style->height(), *style);
3020 case CSSPropertyWebkitHyphens:
3021 return cssValuePool.createValue(style->hyphens());
3022 case CSSPropertyWebkitHyphenateCharacter:
3023 if (style->hyphenationString().isNull())
3024 return cssValuePool.createIdentifierValue(CSSValueAuto);
3025 return cssValuePool.createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
3026 case CSSPropertyWebkitHyphenateLimitAfter:
3027 if (style->hyphenationLimitAfter() < 0)
3028 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
3029 return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
3030 case CSSPropertyWebkitHyphenateLimitBefore:
3031 if (style->hyphenationLimitBefore() < 0)
3032 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
3033 return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
3034 case CSSPropertyWebkitHyphenateLimitLines:
3035 if (style->hyphenationLimitLines() < 0)
3036 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
3037 return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
3038 case CSSPropertyWebkitBorderFit:
3039 if (style->borderFit() == BorderFitBorder)
3040 return cssValuePool.createIdentifierValue(CSSValueBorder);
3041 return cssValuePool.createIdentifierValue(CSSValueLines);
3042 #if ENABLE(CSS_IMAGE_ORIENTATION)
3043 case CSSPropertyImageOrientation:
3044 return cssValuePool.createValue(style->imageOrientation());
3046 case CSSPropertyImageRendering:
3047 return CSSPrimitiveValue::create(style->imageRendering());
3048 #if ENABLE(CSS_IMAGE_RESOLUTION)
3049 case CSSPropertyImageResolution:
3050 return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
3052 case CSSPropertyLeft:
3053 return positionOffsetValue(*style, CSSPropertyLeft);
3054 case CSSPropertyLetterSpacing:
3055 if (!style->letterSpacing())
3056 return cssValuePool.createIdentifierValue(CSSValueNormal);
3057 return zoomAdjustedPixelValue(style->letterSpacing(), *style);
3058 case CSSPropertyWebkitLineClamp:
3059 if (style->lineClamp().isNone())
3060 return cssValuePool.createIdentifierValue(CSSValueNone);
3061 return cssValuePool.createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
3062 case CSSPropertyLineHeight:
3063 return lineHeightFromStyle(*style);
3064 case CSSPropertyListStyleImage:
3065 if (style->listStyleImage())
3066 return style->listStyleImage()->cssValue();
3067 return cssValuePool.createIdentifierValue(CSSValueNone);
3068 case CSSPropertyListStylePosition:
3069 return cssValuePool.createValue(style->listStylePosition());
3070 case CSSPropertyListStyleType:
3071 return cssValuePool.createValue(style->listStyleType());
3072 case CSSPropertyWebkitLocale:
3073 if (style->locale().isNull())
3074 return cssValuePool.createIdentifierValue(CSSValueAuto);
3075 return cssValuePool.createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
3076 case CSSPropertyMarginTop:
3077 return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(*style, renderer);
3078 case CSSPropertyMarginRight: {
3079 Length marginRight = style->marginRight();
3080 if (marginRight.isFixed() || !is<RenderBox>(renderer))
3081 return zoomAdjustedPixelValueForLength(marginRight, *style);
3083 if (marginRight.isPercentOrCalculated()) {
3084 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
3085 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
3086 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
3087 value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
3089 value = downcast<RenderBox>(*renderer).marginRight();
3090 return zoomAdjustedPixelValue(value, *style);
3092 case CSSPropertyMarginBottom:
3093 return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(*style, renderer);
3094 case CSSPropertyMarginLeft:
3095 return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(*style, renderer);
3096 case CSSPropertyWebkitMarqueeDirection:
3097 return cssValuePool.createValue(style->marqueeDirection());
3098 case CSSPropertyWebkitMarqueeIncrement:
3099 return cssValuePool.createValue(style->marqueeIncrement());
3100 case CSSPropertyWebkitMarqueeRepetition:
3101 if (style->marqueeLoopCount() < 0)
3102 return cssValuePool.createIdentifierValue(CSSValueInfinite);
3103 return cssValuePool.createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
3104 case CSSPropertyWebkitMarqueeStyle:
3105 return cssValuePool.createValue(style->marqueeBehavior());
3106 case CSSPropertyWebkitUserModify:
3107 return cssValuePool.createValue(style->userModify());
3108 case CSSPropertyMaxHeight: {
3109 const Length& maxHeight = style->maxHeight();
3110 if (maxHeight.isUndefined())
3111 return cssValuePool.createIdentifierValue(CSSValueNone);
3112 return zoomAdjustedPixelValueForLength(maxHeight, *style);
3114 case CSSPropertyMaxWidth: {
3115 const Length& maxWidth = style->maxWidth();
3116 if (maxWidth.isUndefined())
3117 return cssValuePool.createIdentifierValue(CSSValueNone);
3118 return zoomAdjustedPixelValueForLength(maxWidth, *style);
3120 case CSSPropertyMinHeight:
3121 if (style->minHeight().isAuto()) {
3122 if (isFlexOrGrid(styledElement->parentNode()))
3123 return cssValuePool.createIdentifierValue(CSSValueAuto);
3124 return zoomAdjustedPixelValue(0, *style);
3126 return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
3127 case CSSPropertyMinWidth:
3128 if (style->minWidth().isAuto()) {
3129 if (isFlexOrGrid(styledElement->parentNode()))
3130 return cssValuePool.createIdentifierValue(CSSValueAuto);
3131 return zoomAdjustedPixelValue(0, *style);
3133 return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
3134 case CSSPropertyObjectFit:
3135 return cssValuePool.createValue(style->objectFit());
3136 case CSSPropertyObjectPosition: {
3137 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3138 list->append(zoomAdjustedPixelValueForLength(style->objectPosition().x(), *style));
3139 list->append(zoomAdjustedPixelValueForLength(style->objectPosition().y(), *style));
3142 case CSSPropertyOpacity:
3143 return cssValuePool.createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
3144 case CSSPropertyOrphans:
3145 if (style->hasAutoOrphans())
3146 return cssValuePool.createIdentifierValue(CSSValueAuto);
3147 return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
3148 case CSSPropertyOutlineColor:
3149 return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style->outlineColor());
3150 case CSSPropertyOutlineOffset:
3151 return zoomAdjustedPixelValue(style->outlineOffset(), *style);
3152 case CSSPropertyOutlineStyle:
3153 if (style->outlineStyleIsAuto())
3154 return cssValuePool.createIdentifierValue(CSSValueAuto);
3155 return cssValuePool.createValue(style->outlineStyle());
3156 case CSSPropertyOutlineWidth:
3157 return zoomAdjustedPixelValue(style->outlineWidth(), *style);
3158 case CSSPropertyOverflow:
3159 return cssValuePool.createValue(std::max(style->overflowX(), style->overflowY()));
3160 case CSSPropertyOverflowWrap:
3161 return cssValuePool.createValue(style->overflowWrap());
3162 case CSSPropertyOverflowX:
3163 return cssValuePool.createValue(style->overflowX());
3164 case CSSPropertyOverflowY:
3165 return cssValuePool.createValue(style->overflowY());
3166 case CSSPropertyPaddingTop:
3167 return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(*style, renderer);
3168 case CSSPropertyPaddingRight:
3169 return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(*style, renderer);
3170 case CSSPropertyPaddingBottom:
3171 return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(*style, renderer);
3172 case CSSPropertyPaddingLeft:
3173 return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(*style, renderer);
3174 case CSSPropertyPageBreakAfter:
3175 return cssValuePool.createValue(convertToPageBreak(style->breakAfter()));
3176 case CSSPropertyPageBreakBefore:
3177 return cssValuePool.createValue(convertToPageBreak(style->breakBefore()));
3178 case CSSPropertyPageBreakInside:
3179 return cssValuePool.createValue(convertToPageBreak(style->breakInside()));
3180 case CSSPropertyBreakAfter:
3181 return cssValuePool.createValue(style->breakAfter());
3182 case CSSPropertyBreakBefore:
3183 return cssValuePool.createValue(style->breakBefore());
3184 case CSSPropertyBreakInside:
3185 return cssValuePool.createValue(style->breakInside());
3186 case CSSPropertyHangingPunctuation:
3187 return hangingPunctuationToCSSValue(style->hangingPunctuation());
3188 case CSSPropertyPosition:
3189 return cssValuePool.createValue(style->position());
3190 case CSSPropertyRight:
3191 return positionOffsetValue(*style, CSSPropertyRight);
3192 case CSSPropertyWebkitRubyPosition:
3193 return cssValuePool.createValue(style->rubyPosition());
3194 case CSSPropertyTableLayout:
3195 return cssValuePool.createValue(style->tableLayout());
3196 case CSSPropertyTextAlign:
3197 return cssValuePool.createValue(style->textAlign());
3198 case CSSPropertyTextDecoration:
3199 return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3200 #if ENABLE(CSS3_TEXT)
3201 case CSSPropertyWebkitTextAlignLast:
3202 return cssValuePool.createValue(style->textAlignLast());
3203 case CSSPropertyWebkitTextJustify:
3204 return cssValuePool.createValue(style->textJustify());
3206 case CSSPropertyWebkitTextDecoration:
3207 return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
3208 case CSSPropertyWebkitTextDecorationLine:
3209 return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3210 case CSSPropertyWebkitTextDecorationStyle:
3211 return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
3212 case CSSPropertyWebkitTextDecorationColor:
3213 return currentColorOrValidColor(style, style->textDecorationColor());
3214 case CSSPropertyWebkitTextDecorationSkip:
3215 return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip());
3216 case CSSPropertyWebkitTextUnderlinePosition:
3217 return cssValuePool.createValue(style->textUnderlinePosition());
3218 case CSSPropertyWebkitTextDecorationsInEffect:
3219 return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
3220 case CSSPropertyWebkitTextFillColor:
3221 return currentColorOrValidColor(style, style->textFillColor());
3222 case CSSPropertyWebkitTextEmphasisColor:
3223 return currentColorOrValidColor(style, style->textEmphasisColor());
3224 case CSSPropertyWebkitTextEmphasisPosition:
3225 return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition());
3226 case CSSPropertyWebkitTextEmphasisStyle:
3227 switch (style->textEmphasisMark()) {
3228 case TextEmphasisMarkNone:
3229 return cssValuePool.createIdentifierValue(CSSValueNone);
3230 case TextEmphasisMarkCustom:
3231 return cssValuePool.createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
3232 case TextEmphasisMarkAuto:
3233 ASSERT_NOT_REACHED();
3237 case TextEmphasisMarkDot:
3238 case TextEmphasisMarkCircle:
3239 case TextEmphasisMarkDoubleCircle:
3240 case TextEmphasisMarkTriangle:
3241 case TextEmphasisMarkSesame: {